2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Mitchell Stokes.
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file BL_Action.cpp
30 #include "BL_Action.h"
31 #include "BL_ArmatureObject.h"
32 #include "BL_DeformableGameObject.h"
33 #include "BL_ShapeDeformer.h"
34 #include "KX_IpoConvert.h"
35 #include "KX_GameObject.h"
37 #include "SG_Controller.h"
39 // These three are for getting the action from the logic manager
41 #include "SCA_LogicManager.h"
44 #include "BKE_animsys.h"
45 #include "BKE_action.h"
46 #include "RNA_access.h"
47 #include "RNA_define.h"
49 // Needed for material IPOs
50 #include "BKE_material.h"
51 #include "DNA_material_types.h"
52 #include "DNA_scene_types.h"
55 #include "MEM_guardedalloc.h"
56 #include "BKE_library.h"
57 #include "BKE_global.h"
59 BL_Action::BL_Action(class KX_GameObject* gameobj)
75 m_playmode(ACT_MODE_PLAY),
76 m_blendmode(ACT_BLEND_BLEND),
79 m_calc_localtime(true)
83 BL_Action::~BL_Action()
86 BKE_pose_free(m_blendpose);
88 BKE_pose_free(m_blendinpose);
89 ClearControllerList();
92 BKE_libblock_free(G.main, m_tmpaction);
97 void BL_Action::ClearControllerList()
99 // Clear out the controller list
100 std::vector<SG_Controller*>::iterator it;
101 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
103 m_obj->GetSGNode()->RemoveSGController((*it));
107 m_sg_contr_list.clear();
110 bool BL_Action::Play(const char* name,
118 float playback_speed,
122 // Only start playing a new action if we're done, or if
123 // the new action has a higher priority
124 if (!IsDone() && priority > m_priority)
126 m_priority = priority;
127 bAction* prev_action = m_action;
129 KX_Scene* kxscene = m_obj->GetScene();
131 // First try to load the action
132 m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
135 printf("Failed to load action: %s\n", name);
140 // If we have the same settings, don't play again
141 // This is to resolve potential issues with pulses on sensors such as the ones
142 // reported in bug #29412. The fix is here so it works for both logic bricks and Python.
143 // However, this may eventually lead to issues where a user wants to override an already
144 // playing action with the same action and settings. If this becomes an issue,
145 // then this fix may have to be re-evaluated.
146 if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end
147 && m_priority == priority && m_speed == playback_speed)
150 // Keep a copy of the action for threading purposes
152 BKE_libblock_free(G.main, m_tmpaction);
155 m_tmpaction = BKE_action_copy(m_action);
157 // First get rid of any old controllers
158 ClearControllerList();
160 // Create an SG_Controller
161 SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
162 m_sg_contr_list.push_back(sg_contr);
163 m_obj->GetSGNode()->AddSGController(sg_contr);
164 sg_contr->SetObject(m_obj->GetSGNode());
167 sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter());
169 m_sg_contr_list.push_back(sg_contr);
170 m_obj->GetSGNode()->AddSGController(sg_contr);
171 sg_contr->SetObject(m_obj->GetSGNode());
175 sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
177 m_sg_contr_list.push_back(sg_contr);
178 m_obj->GetSGNode()->AddSGController(sg_contr);
179 sg_contr->SetObject(m_obj->GetSGNode());
183 if (m_obj->GetBlenderObject()->totcol==1) {
184 Material *mat = give_current_material(m_obj->GetBlenderObject(), 1);
186 sg_contr = BL_CreateMaterialIpo(m_action, mat, 0, m_obj, kxscene->GetSceneConverter());
188 m_sg_contr_list.push_back(sg_contr);
189 m_obj->GetSGNode()->AddSGController(sg_contr);
190 sg_contr->SetObject(m_obj->GetSGNode());
195 STR_HashedString matname;
197 for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
198 mat = give_current_material(m_obj->GetBlenderObject(), matidx);
200 matname = mat->id.name;
201 sg_contr = BL_CreateMaterialIpo(m_action, mat, matname.hash(), m_obj, kxscene->GetSceneConverter());
203 m_sg_contr_list.push_back(sg_contr);
204 m_obj->GetSGNode()->AddSGController(sg_contr);
205 sg_contr->SetObject(m_obj->GetSGNode());
212 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
214 sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter());
215 m_sg_contr_list.push_back(sg_contr);
216 m_obj->GetSGNode()->AddSGController(sg_contr);
217 sg_contr->SetObject(m_obj->GetSGNode());
219 else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
221 sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter());
222 m_sg_contr_list.push_back(sg_contr);
223 m_obj->GetSGNode()->AddSGController(sg_contr);
224 sg_contr->SetObject(m_obj->GetSGNode());
227 m_ipo_flags = ipo_flags;
230 // Setup blendin shapes/poses
231 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
233 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
234 obj->GetPose(&m_blendinpose);
238 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
239 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
241 if (shape_deformer && shape_deformer->GetKey())
243 obj->GetShape(m_blendinshape);
245 // Now that we have the previous blend shape saved, we can clear out the key to avoid any
246 // further interference.
248 for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next)
253 // Now that we have an action, we have something we can play
254 m_starttime = -1.f; // We get the start time on our first update
255 m_startframe = m_localtime = start;
258 m_playmode = play_mode;
259 m_blendmode = blend_mode;
263 m_speed = playback_speed;
264 m_layer_weight = layer_weight;
271 void BL_Action::Stop()
276 bool BL_Action::IsDone()
281 void BL_Action::InitIPO()
283 // Initialize the IPOs
284 std::vector<SG_Controller*>::iterator it;
285 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
287 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
288 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE);
289 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD);
290 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL);
294 bAction *BL_Action::GetAction()
296 return (IsDone()) ? NULL : m_action;
299 float BL_Action::GetFrame()
304 const char *BL_Action::GetName()
306 if (m_action != NULL) {
307 return m_action->id.name + 2;
316 void BL_Action::SetFrame(float frame)
318 // Clamp the frame to the start and end frame
319 if (frame < min(m_startframe, m_endframe))
320 frame = min(m_startframe, m_endframe);
321 else if (frame > max(m_startframe, m_endframe))
322 frame = max(m_startframe, m_endframe);
325 m_calc_localtime = false;
328 void BL_Action::SetPlayMode(short play_mode)
330 m_playmode = play_mode;
333 void BL_Action::SetTimes(float start, float end)
335 m_startframe = start;
339 void BL_Action::SetLocalTime(float curtime)
341 float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
343 if (m_endframe < m_startframe)
346 m_localtime = m_startframe + dt;
349 void BL_Action::ResetStartTime(float curtime)
351 float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
353 m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
354 SetLocalTime(curtime);
357 void BL_Action::IncrementBlending(float curtime)
359 // Setup m_blendstart if we need to
360 if (m_blendstart == 0.f)
361 m_blendstart = curtime;
363 // Bump the blend frame
364 m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
367 if (m_blendframe>m_blendin)
368 m_blendframe = m_blendin;
372 void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
374 vector<float>::const_iterator it;
378 dstweight = 1.0F - srcweight;
379 //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
380 for (it=blendshape.begin(), kb = (KeyBlock *)key->block.first;
381 kb && it != blendshape.end();
382 kb = (KeyBlock *)kb->next, it++)
384 //printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
385 kb->curval = kb->curval * dstweight + (*it) * srcweight;
386 //printf("NewKey: %f\n", kb->curval);
391 void BL_Action::Update(float curtime)
393 // Don't bother if we're done with the animation
397 curtime -= KX_KetsjiEngine::GetSuspendedDelta();
399 // Grab the start time here so we don't end up with a negative m_localtime when
400 // suspending and resuming scenes.
402 m_starttime = curtime;
404 if (m_calc_localtime)
405 SetLocalTime(curtime);
408 ResetStartTime(curtime);
409 m_calc_localtime = true;
412 // Handle wrap around
413 if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) {
414 switch (m_playmode) {
417 m_localtime = m_endframe;
421 // Put the time back to the beginning
422 m_localtime = m_startframe;
423 m_starttime = curtime;
425 case ACT_MODE_PING_PONG:
426 // Swap the start and end frames
427 float temp = m_startframe;
428 m_startframe = m_endframe;
431 m_starttime = curtime;
437 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
439 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
441 if (m_layer_weight >= 0)
442 obj->GetPose(&m_blendpose);
444 // Extract the pose from the action
445 obj->SetPoseByAction(m_tmpaction, m_localtime);
447 // Handle blending between armature actions
448 if (m_blendin && m_blendframe<m_blendin)
450 IncrementBlending(curtime);
453 float weight = 1.f - (m_blendframe/m_blendin);
456 obj->BlendInPose(m_blendinpose, weight, ACT_BLEND_BLEND);
460 // Handle layer blending
461 if (m_layer_weight >= 0)
462 obj->BlendInPose(m_blendpose, m_layer_weight, m_blendmode);
464 obj->UpdateTimestep(curtime);
468 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
469 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
471 // Handle shape actions if we have any
472 if (shape_deformer && shape_deformer->GetKey())
474 Key *key = shape_deformer->GetKey();
477 RNA_id_pointer_create(&key->id, &ptrrna);
479 animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localtime);
481 // Handle blending between shape actions
482 if (m_blendin && m_blendframe < m_blendin)
484 IncrementBlending(curtime);
486 float weight = 1.f - (m_blendframe/m_blendin);
488 // We go through and clear out the keyblocks so there isn't any interference
489 // from other shape actions
491 for (kb=(KeyBlock *)key->block.first; kb; kb=(KeyBlock *)kb->next)
494 // Now blend the shape
495 BlendShape(key, weight, m_blendinshape);
498 // Handle layer blending
499 if (m_layer_weight >= 0)
501 obj->GetShape(m_blendshape);
502 BlendShape(key, m_layer_weight, m_blendshape);
505 obj->SetActiveAction(NULL, 0, curtime);
509 // This isn't thread-safe, so we move it into it's own function for now
510 //m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
513 ClearControllerList();
516 void BL_Action::UpdateIPOs()
519 m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);