4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * Contributor(s): Mitchell Stokes.
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file BL_Action.cpp
31 #include "BL_Action.h"
32 #include "BL_ArmatureObject.h"
33 #include "BL_DeformableGameObject.h"
34 #include "BL_ShapeDeformer.h"
35 #include "KX_IpoConvert.h"
36 #include "KX_GameObject.h"
38 // These three are for getting the action from the logic manager
40 #include "KX_PythonInit.h"
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"
50 BL_Action::BL_Action(class KX_GameObject* gameobj)
70 m_calc_localtime(true)
72 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
74 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
76 m_ptrrna = new PointerRNA();
77 RNA_id_pointer_create(&obj->GetArmatureObject()->id, m_ptrrna);
81 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
82 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
86 m_ptrrna = new PointerRNA();
87 RNA_id_pointer_create(&shape_deformer->GetKey()->id, m_ptrrna);
92 BL_Action::~BL_Action()
95 game_free_pose(m_pose);
97 game_free_pose(m_blendpose);
99 game_free_pose(m_blendinpose);
102 ClearControllerList();
105 void BL_Action::ClearControllerList()
107 // Clear out the controller list
108 std::vector<SG_Controller*>::iterator it;
109 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
111 m_obj->GetSGNode()->RemoveSGController((*it));
115 m_sg_contr_list.clear();
118 bool BL_Action::Play(const char* name,
126 float playback_speed)
129 // Only start playing a new action if we're done, or if
130 // the new action has a higher priority
131 if (priority != 0 && !IsDone() && priority >= m_priority)
133 m_priority = priority;
134 bAction* prev_action = m_action;
136 // First try to load the action
137 m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name);
140 printf("Failed to load action: %s\n", name);
145 if (prev_action != m_action)
147 // First get rid of any old controllers
148 ClearControllerList();
150 // Create an SG_Controller
151 SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
152 m_sg_contr_list.push_back(sg_contr);
153 m_obj->GetSGNode()->AddSGController(sg_contr);
154 sg_contr->SetObject(m_obj->GetSGNode());
157 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
159 sg_contr = BL_CreateLampIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
160 m_sg_contr_list.push_back(sg_contr);
161 m_obj->GetSGNode()->AddSGController(sg_contr);
162 sg_contr->SetObject(m_obj->GetSGNode());
164 else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
166 sg_contr = BL_CreateCameraIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
167 m_sg_contr_list.push_back(sg_contr);
168 m_obj->GetSGNode()->AddSGController(sg_contr);
169 sg_contr->SetObject(m_obj->GetSGNode());
173 m_ipo_flags = ipo_flags;
176 // Setup blendin shapes/poses
177 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
179 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
180 obj->GetMRDPose(&m_blendinpose);
184 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
185 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
187 if (shape_deformer && shape_deformer->GetKey())
189 obj->GetShape(m_blendinshape);
191 // Now that we have the previous blend shape saved, we can clear out the key to avoid any
192 // further interference.
194 for (kb=(KeyBlock*)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock*)kb->next)
199 // Now that we have an action, we have something we can play
200 m_starttime = KX_GetActiveEngine()->GetFrameTime();
201 m_startframe = m_localtime = start;
204 m_playmode = play_mode;
208 m_speed = playback_speed;
209 m_layer_weight = layer_weight;
216 void BL_Action::Stop()
221 bool BL_Action::IsDone()
226 void BL_Action::InitIPO()
228 // Initialize the IPOs
229 std::vector<SG_Controller*>::iterator it;
230 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
232 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
233 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE);
234 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD);
235 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL);
239 bAction *BL_Action::GetAction()
241 return (IsDone()) ? NULL : m_action;
244 float BL_Action::GetFrame()
249 void BL_Action::SetFrame(float frame)
251 // Clamp the frame to the start and end frame
252 if (frame < min(m_startframe, m_endframe))
253 frame = min(m_startframe, m_endframe);
254 else if (frame > max(m_startframe, m_endframe))
255 frame = max(m_startframe, m_endframe);
258 m_calc_localtime = false;
261 void BL_Action::SetPlayMode(short play_mode)
263 m_playmode = play_mode;
266 void BL_Action::SetTimes(float start, float end)
268 m_startframe = start;
272 void BL_Action::SetLocalTime(float curtime)
274 float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
276 if (m_endframe < m_startframe)
279 m_localtime = m_startframe + dt;
282 void BL_Action::ResetStartTime(float curtime)
284 float dt = m_localtime - m_startframe;
286 m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
287 SetLocalTime(curtime);
290 void BL_Action::IncrementBlending(float curtime)
292 // Setup m_blendstart if we need to
293 if (m_blendstart == 0.f)
294 m_blendstart = curtime;
296 // Bump the blend frame
297 m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
300 if (m_blendframe>m_blendin)
301 m_blendframe = m_blendin;
305 void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
307 vector<float>::const_iterator it;
311 dstweight = 1.0F - srcweight;
312 //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
313 for (it=blendshape.begin(), kb = (KeyBlock*)key->block.first;
314 kb && it != blendshape.end();
315 kb = (KeyBlock*)kb->next, it++) {
316 //printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
317 kb->curval = kb->curval * dstweight + (*it) * srcweight;
318 //printf("NewKey: %f\n", kb->curval);
323 void BL_Action::Update(float curtime)
325 // Don't bother if we're done with the animation
329 curtime -= KX_KetsjiEngine::GetSuspendedDelta();
331 if (m_calc_localtime)
332 SetLocalTime(curtime);
335 ResetStartTime(curtime);
336 m_calc_localtime = true;
339 // Handle wrap around
340 if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
346 m_localtime = m_endframe;
350 // Put the time back to the beginning
351 m_localtime = m_startframe;
352 m_starttime = curtime;
354 case ACT_MODE_PING_PONG:
355 // Swap the start and end frames
356 float temp = m_startframe;
357 m_startframe = m_endframe;
360 m_starttime = curtime;
369 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
371 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
372 obj->GetPose(&m_pose);
374 // Extract the pose from the action
376 Object *arm = obj->GetArmatureObject();
377 bPose *temp = arm->pose;
380 animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
385 // Handle blending between armature actions
386 if (m_blendin && m_blendframe<m_blendin)
388 IncrementBlending(curtime);
391 float weight = 1.f - (m_blendframe/m_blendin);
394 game_blend_poses(m_pose, m_blendinpose, weight);
398 // Handle layer blending
399 if (m_layer_weight >= 0)
401 obj->GetMRDPose(&m_blendpose);
402 game_blend_poses(m_pose, m_blendpose, m_layer_weight);
405 obj->SetPose(m_pose);
407 obj->SetActiveAction(NULL, 0, curtime);
411 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
412 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
414 // Handle shape actions if we have any
415 if (shape_deformer && shape_deformer->GetKey())
417 Key *key = shape_deformer->GetKey();
420 animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
422 // Handle blending between shape actions
423 if (m_blendin && m_blendframe < m_blendin)
425 IncrementBlending(curtime);
427 float weight = 1.f - (m_blendframe/m_blendin);
429 // We go through and clear out the keyblocks so there isn't any interference
430 // from other shape actions
432 for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next)
435 // Now blend the shape
436 BlendShape(key, weight, m_blendinshape);
439 // Handle layer blending
440 if (m_layer_weight >= 0)
442 obj->GetShape(m_blendshape);
443 BlendShape(key, m_layer_weight, m_blendshape);
446 obj->SetActiveAction(NULL, 0, curtime);
451 m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);