Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Mitchell Stokes. 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00027 #include <cstdlib> 00028 00029 #include "BL_Action.h" 00030 #include "BL_ArmatureObject.h" 00031 #include "BL_DeformableGameObject.h" 00032 #include "BL_ShapeDeformer.h" 00033 #include "KX_IpoConvert.h" 00034 #include "KX_GameObject.h" 00035 00036 // These three are for getting the action from the logic manager 00037 #include "KX_Scene.h" 00038 #include "KX_PythonInit.h" 00039 #include "SCA_LogicManager.h" 00040 00041 extern "C" { 00042 #include "BKE_animsys.h" 00043 #include "BKE_action.h" 00044 #include "RNA_access.h" 00045 #include "RNA_define.h" 00046 } 00047 00048 BL_Action::BL_Action(class KX_GameObject* gameobj) 00049 : 00050 m_action(NULL), 00051 m_pose(NULL), 00052 m_blendpose(NULL), 00053 m_blendinpose(NULL), 00054 m_ptrrna(NULL), 00055 m_obj(gameobj), 00056 m_startframe(0.f), 00057 m_endframe(0.f), 00058 m_endtime(0.f), 00059 m_localtime(0.f), 00060 m_blendin(0.f), 00061 m_blendframe(0.f), 00062 m_blendstart(0.f), 00063 m_speed(0.f), 00064 m_priority(0), 00065 m_playmode(0), 00066 m_ipo_flags(0), 00067 m_done(true), 00068 m_calc_localtime(true) 00069 { 00070 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) 00071 { 00072 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj; 00073 00074 m_ptrrna = new PointerRNA(); 00075 RNA_id_pointer_create(&obj->GetArmatureObject()->id, m_ptrrna); 00076 } 00077 else 00078 { 00079 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj; 00080 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer()); 00081 00082 if (shape_deformer) 00083 { 00084 m_ptrrna = new PointerRNA(); 00085 RNA_id_pointer_create(&shape_deformer->GetKey()->id, m_ptrrna); 00086 } 00087 } 00088 } 00089 00090 BL_Action::~BL_Action() 00091 { 00092 if (m_pose) 00093 game_free_pose(m_pose); 00094 if (m_blendpose) 00095 game_free_pose(m_blendpose); 00096 if (m_blendinpose) 00097 game_free_pose(m_blendinpose); 00098 if (m_ptrrna) 00099 delete m_ptrrna; 00100 ClearControllerList(); 00101 } 00102 00103 void BL_Action::ClearControllerList() 00104 { 00105 // Clear out the controller list 00106 std::vector<SG_Controller*>::iterator it; 00107 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++) 00108 { 00109 m_obj->GetSGNode()->RemoveSGController((*it)); 00110 delete *it; 00111 } 00112 00113 m_sg_contr_list.clear(); 00114 } 00115 00116 bool BL_Action::Play(const char* name, 00117 float start, 00118 float end, 00119 short priority, 00120 float blendin, 00121 short play_mode, 00122 float layer_weight, 00123 short ipo_flags, 00124 float playback_speed) 00125 { 00126 00127 // Only start playing a new action if we're done, or if 00128 // the new action has a higher priority 00129 if (priority != 0 && !IsDone() && priority >= m_priority) 00130 return false; 00131 m_priority = priority; 00132 bAction* prev_action = m_action; 00133 00134 // First try to load the action 00135 m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name); 00136 if (!m_action) 00137 { 00138 printf("Failed to load action: %s\n", name); 00139 m_done = true; 00140 return false; 00141 } 00142 00143 if (prev_action != m_action) 00144 { 00145 // First get rid of any old controllers 00146 ClearControllerList(); 00147 00148 // Create an SG_Controller 00149 SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter()); 00150 m_sg_contr_list.push_back(sg_contr); 00151 m_obj->GetSGNode()->AddSGController(sg_contr); 00152 sg_contr->SetObject(m_obj->GetSGNode()); 00153 00154 // Extra controllers 00155 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT) 00156 { 00157 sg_contr = BL_CreateLampIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter()); 00158 m_sg_contr_list.push_back(sg_contr); 00159 m_obj->GetSGNode()->AddSGController(sg_contr); 00160 sg_contr->SetObject(m_obj->GetSGNode()); 00161 } 00162 else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA) 00163 { 00164 sg_contr = BL_CreateCameraIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter()); 00165 m_sg_contr_list.push_back(sg_contr); 00166 m_obj->GetSGNode()->AddSGController(sg_contr); 00167 sg_contr->SetObject(m_obj->GetSGNode()); 00168 } 00169 } 00170 00171 m_ipo_flags = ipo_flags; 00172 InitIPO(); 00173 00174 // Setup blendin shapes/poses 00175 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) 00176 { 00177 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj; 00178 obj->GetMRDPose(&m_blendinpose); 00179 } 00180 else 00181 { 00182 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj; 00183 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer()); 00184 00185 if (shape_deformer && shape_deformer->GetKey()) 00186 { 00187 obj->GetShape(m_blendinshape); 00188 00189 // Now that we have the previous blend shape saved, we can clear out the key to avoid any 00190 // further interference. 00191 KeyBlock *kb; 00192 for (kb=(KeyBlock*)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock*)kb->next) 00193 kb->curval = 0.f; 00194 } 00195 } 00196 00197 // Now that we have an action, we have something we can play 00198 m_starttime = KX_GetActiveEngine()->GetFrameTime(); 00199 m_startframe = m_localtime = start; 00200 m_endframe = end; 00201 m_blendin = blendin; 00202 m_playmode = play_mode; 00203 m_endtime = 0.f; 00204 m_blendframe = 0.f; 00205 m_blendstart = 0.f; 00206 m_speed = playback_speed; 00207 m_layer_weight = layer_weight; 00208 00209 m_done = false; 00210 00211 return true; 00212 } 00213 00214 void BL_Action::Stop() 00215 { 00216 m_done = true; 00217 } 00218 00219 bool BL_Action::IsDone() 00220 { 00221 return m_done; 00222 } 00223 00224 void BL_Action::InitIPO() 00225 { 00226 // Initialize the IPOs 00227 std::vector<SG_Controller*>::iterator it; 00228 for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++) 00229 { 00230 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true); 00231 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE); 00232 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD); 00233 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL); 00234 } 00235 } 00236 00237 bAction *BL_Action::GetAction() 00238 { 00239 return (IsDone()) ? NULL : m_action; 00240 } 00241 00242 float BL_Action::GetFrame() 00243 { 00244 return m_localtime; 00245 } 00246 00247 void BL_Action::SetFrame(float frame) 00248 { 00249 // Clamp the frame to the start and end frame 00250 if (frame < min(m_startframe, m_endframe)) 00251 frame = min(m_startframe, m_endframe); 00252 else if (frame > max(m_startframe, m_endframe)) 00253 frame = max(m_startframe, m_endframe); 00254 00255 m_localtime = frame; 00256 m_calc_localtime = false; 00257 } 00258 00259 void BL_Action::SetPlayMode(short play_mode) 00260 { 00261 m_playmode = play_mode; 00262 } 00263 00264 void BL_Action::SetTimes(float start, float end) 00265 { 00266 m_startframe = start; 00267 m_endframe = end; 00268 } 00269 00270 void BL_Action::SetLocalTime(float curtime) 00271 { 00272 float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed; 00273 00274 if (m_endframe < m_startframe) 00275 dt = -dt; 00276 00277 m_localtime = m_startframe + dt; 00278 } 00279 00280 void BL_Action::ResetStartTime(float curtime) 00281 { 00282 float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime; 00283 00284 m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed); 00285 SetLocalTime(curtime); 00286 } 00287 00288 void BL_Action::IncrementBlending(float curtime) 00289 { 00290 // Setup m_blendstart if we need to 00291 if (m_blendstart == 0.f) 00292 m_blendstart = curtime; 00293 00294 // Bump the blend frame 00295 m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate(); 00296 00297 // Clamp 00298 if (m_blendframe>m_blendin) 00299 m_blendframe = m_blendin; 00300 } 00301 00302 00303 void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape) 00304 { 00305 vector<float>::const_iterator it; 00306 float dstweight; 00307 KeyBlock *kb; 00308 00309 dstweight = 1.0F - srcweight; 00310 //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight); 00311 for (it=blendshape.begin(), kb = (KeyBlock*)key->block.first; 00312 kb && it != blendshape.end(); 00313 kb = (KeyBlock*)kb->next, it++) 00314 { 00315 //printf("OirgKeys: %f\t%f\n", kb->curval, (*it)); 00316 kb->curval = kb->curval * dstweight + (*it) * srcweight; 00317 //printf("NewKey: %f\n", kb->curval); 00318 } 00319 //printf("\n"); 00320 } 00321 00322 void BL_Action::Update(float curtime) 00323 { 00324 // Don't bother if we're done with the animation 00325 if (m_done) 00326 return; 00327 00328 curtime -= KX_KetsjiEngine::GetSuspendedDelta(); 00329 00330 if (m_calc_localtime) 00331 SetLocalTime(curtime); 00332 else 00333 { 00334 ResetStartTime(curtime); 00335 m_calc_localtime = true; 00336 } 00337 00338 // Handle wrap around 00339 if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) 00340 { 00341 switch(m_playmode) 00342 { 00343 case ACT_MODE_PLAY: 00344 // Clamp 00345 m_localtime = m_endframe; 00346 m_done = true; 00347 break; 00348 case ACT_MODE_LOOP: 00349 // Put the time back to the beginning 00350 m_localtime = m_startframe; 00351 m_starttime = curtime; 00352 break; 00353 case ACT_MODE_PING_PONG: 00354 // Swap the start and end frames 00355 float temp = m_startframe; 00356 m_startframe = m_endframe; 00357 m_endframe = temp; 00358 00359 m_starttime = curtime; 00360 00361 break; 00362 } 00363 } 00364 00365 if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) 00366 { 00367 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj; 00368 obj->GetPose(&m_pose); 00369 00370 // Extract the pose from the action 00371 { 00372 Object *arm = obj->GetArmatureObject(); 00373 bPose *temp = arm->pose; 00374 00375 arm->pose = m_pose; 00376 animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime); 00377 00378 arm->pose = temp; 00379 } 00380 00381 // Handle blending between armature actions 00382 if (m_blendin && m_blendframe<m_blendin) 00383 { 00384 IncrementBlending(curtime); 00385 00386 // Calculate weight 00387 float weight = 1.f - (m_blendframe/m_blendin); 00388 00389 // Blend the poses 00390 game_blend_poses(m_pose, m_blendinpose, weight); 00391 } 00392 00393 00394 // Handle layer blending 00395 if (m_layer_weight >= 0) 00396 { 00397 obj->GetMRDPose(&m_blendpose); 00398 game_blend_poses(m_pose, m_blendpose, m_layer_weight); 00399 } 00400 00401 obj->SetPose(m_pose); 00402 00403 obj->SetActiveAction(NULL, 0, curtime); 00404 } 00405 else 00406 { 00407 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj; 00408 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer()); 00409 00410 // Handle shape actions if we have any 00411 if (shape_deformer && shape_deformer->GetKey()) 00412 { 00413 Key *key = shape_deformer->GetKey(); 00414 00415 00416 animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime); 00417 00418 // Handle blending between shape actions 00419 if (m_blendin && m_blendframe < m_blendin) 00420 { 00421 IncrementBlending(curtime); 00422 00423 float weight = 1.f - (m_blendframe/m_blendin); 00424 00425 // We go through and clear out the keyblocks so there isn't any interference 00426 // from other shape actions 00427 KeyBlock *kb; 00428 for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next) 00429 kb->curval = 0.f; 00430 00431 // Now blend the shape 00432 BlendShape(key, weight, m_blendinshape); 00433 } 00434 00435 // Handle layer blending 00436 if (m_layer_weight >= 0) 00437 { 00438 obj->GetShape(m_blendshape); 00439 BlendShape(key, m_layer_weight, m_blendshape); 00440 } 00441 00442 obj->SetActiveAction(NULL, 0, curtime); 00443 } 00444 00445 m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD); 00446 } 00447 }