BGE: Fix T45945: Action bouncing.
[blender.git] / source / gameengine / Ketsji / BL_Action.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Mitchell Stokes.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file BL_Action.cpp
24  *  \ingroup ketsji
25  */
26
27 #include <cstdlib>
28 #include <stdio.h>
29
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"
36
37 #include "SG_Controller.h"
38
39 // These three are for getting the action from the logic manager
40 #include "KX_Scene.h"
41 #include "SCA_LogicManager.h"
42
43 extern "C" {
44 #include "BKE_animsys.h"
45 #include "BKE_action.h"
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48
49 // Needed for material IPOs
50 #include "BKE_material.h"
51 #include "DNA_material_types.h"
52 #include "DNA_scene_types.h"
53 }
54
55 #include "MEM_guardedalloc.h"
56 #include "BKE_library.h"
57 #include "BKE_global.h"
58
59 #include "BLI_threads.h" // for lock
60
61 /* Lock to solve animation thread issues.
62  * A spin lock is better than a mutex in case of short wait 
63  * because spin lock stop the thread by a loop contrary to mutex
64  * which switch all memory, process.
65  */ 
66 static SpinLock BL_ActionLock;
67
68 BL_Action::BL_Action(class KX_GameObject* gameobj)
69 :
70         m_action(NULL),
71         m_tmpaction(NULL),
72         m_blendpose(NULL),
73         m_blendinpose(NULL),
74         m_obj(gameobj),
75         m_startframe(0.f),
76         m_endframe(0.f),
77         m_localframe(0.f),
78         m_blendin(0.f),
79         m_blendframe(0.f),
80         m_blendstart(0.f),
81         m_speed(0.f),
82         m_priority(0),
83         m_playmode(ACT_MODE_PLAY),
84         m_blendmode(ACT_BLEND_BLEND),
85         m_ipo_flags(0),
86         m_done(true),
87         m_calc_localtime(true),
88         m_initializedTime(false)
89 {
90 }
91
92 BL_Action::~BL_Action()
93 {
94         if (m_blendpose)
95                 BKE_pose_free(m_blendpose);
96         if (m_blendinpose)
97                 BKE_pose_free(m_blendinpose);
98         ClearControllerList();
99
100         if (m_tmpaction) {
101                 BKE_libblock_free(G.main, m_tmpaction);
102                 m_tmpaction = NULL;
103         }
104 }
105
106 void BL_Action::ClearControllerList()
107 {
108         // Clear out the controller list
109         std::vector<SG_Controller*>::iterator it;
110         for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
111         {
112                 m_obj->GetSGNode()->RemoveSGController((*it));
113                 delete *it;
114         }
115
116         m_sg_contr_list.clear();
117 }
118
119 bool BL_Action::Play(const char* name,
120                                         float start,
121                                         float end,
122                                         short priority,
123                                         float blendin,
124                                         short play_mode,
125                                         float layer_weight,
126                                         short ipo_flags,
127                                         float playback_speed,
128                                         short blend_mode)
129 {
130
131         // Only start playing a new action if we're done, or if
132         // the new action has a higher priority
133         if (!IsDone() && priority > m_priority)
134                 return false;
135         m_priority = priority;
136         bAction* prev_action = m_action;
137
138         KX_Scene* kxscene = m_obj->GetScene();
139
140         // First try to load the action
141         m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
142         if (!m_action)
143         {
144                 printf("Failed to load action: %s\n", name);
145                 m_done = true;
146                 return false;
147         }
148
149         // If we have the same settings, don't play again
150         // This is to resolve potential issues with pulses on sensors such as the ones
151         // reported in bug #29412. The fix is here so it works for both logic bricks and Python.
152         // However, this may eventually lead to issues where a user wants to override an already
153         // playing action with the same action and settings. If this becomes an issue,
154         // then this fix may have to be re-evaluated.
155         if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end
156                         && m_priority == priority && m_speed == playback_speed)
157                 return false;
158
159         // Keep a copy of the action for threading purposes
160         if (m_tmpaction) {
161                 BKE_libblock_free(G.main, m_tmpaction);
162                 m_tmpaction = NULL;
163         }
164         m_tmpaction = BKE_action_copy(m_action);
165
166         // First get rid of any old controllers
167         ClearControllerList();
168
169         // Create an SG_Controller
170         SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
171         m_sg_contr_list.push_back(sg_contr);
172         m_obj->GetSGNode()->AddSGController(sg_contr);
173         sg_contr->SetObject(m_obj->GetSGNode());
174
175         // World
176         sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter());
177         if (sg_contr) {
178                 m_sg_contr_list.push_back(sg_contr);
179                 m_obj->GetSGNode()->AddSGController(sg_contr);
180                 sg_contr->SetObject(m_obj->GetSGNode());
181         }
182
183         // Try obcolor
184         sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
185         if (sg_contr) {
186                 m_sg_contr_list.push_back(sg_contr);
187                 m_obj->GetSGNode()->AddSGController(sg_contr);
188                 sg_contr->SetObject(m_obj->GetSGNode());
189         }
190
191         // Now try materials
192         if (m_obj->GetBlenderObject()->totcol==1) {
193                 Material *mat = give_current_material(m_obj->GetBlenderObject(), 1);
194                 if (mat) {
195                         sg_contr = BL_CreateMaterialIpo(m_action, mat, 0, m_obj, kxscene->GetSceneConverter());
196                         if (sg_contr) {
197                                 m_sg_contr_list.push_back(sg_contr);
198                                 m_obj->GetSGNode()->AddSGController(sg_contr);
199                                 sg_contr->SetObject(m_obj->GetSGNode());
200                         }
201                 }
202         } else {
203                 Material *mat;
204                 STR_HashedString matname;
205
206                 for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
207                         mat = give_current_material(m_obj->GetBlenderObject(), matidx);
208                         if (mat) {
209                                 matname = mat->id.name;
210                                 sg_contr = BL_CreateMaterialIpo(m_action, mat, matname.hash(), m_obj, kxscene->GetSceneConverter());
211                                 if (sg_contr) {
212                                         m_sg_contr_list.push_back(sg_contr);
213                                         m_obj->GetSGNode()->AddSGController(sg_contr);
214                                         sg_contr->SetObject(m_obj->GetSGNode());
215                                 }
216                         }
217                 }
218         }
219
220         // Extra controllers
221         if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
222         {
223                 sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter());
224                 m_sg_contr_list.push_back(sg_contr);
225                 m_obj->GetSGNode()->AddSGController(sg_contr);
226                 sg_contr->SetObject(m_obj->GetSGNode());
227         }
228         else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
229         {
230                 sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter());
231                 m_sg_contr_list.push_back(sg_contr);
232                 m_obj->GetSGNode()->AddSGController(sg_contr);
233                 sg_contr->SetObject(m_obj->GetSGNode());
234         }
235         
236         m_ipo_flags = ipo_flags;
237         InitIPO();
238
239         // Setup blendin shapes/poses
240         if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
241         {
242                 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
243                 obj->GetPose(&m_blendinpose);
244         }
245         else
246         {
247                 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
248                 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
249                 
250                 if (shape_deformer && shape_deformer->GetKey())
251                 {
252                         obj->GetShape(m_blendinshape);
253
254                         // Now that we have the previous blend shape saved, we can clear out the key to avoid any
255                         // further interference.
256                         KeyBlock *kb;
257                         for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next)
258                                 kb->curval = 0.f;
259                 }
260         }
261
262         // Now that we have an action, we have something we can play
263         m_starttime = -1.f; // We get the start time on our first update
264         m_startframe = m_localframe = start;
265         m_endframe = end;
266         m_blendin = blendin;
267         m_playmode = play_mode;
268         m_blendmode = blend_mode;
269         m_blendframe = 0.f;
270         m_blendstart = 0.f;
271         m_speed = playback_speed;
272         m_layer_weight = layer_weight;
273         
274         m_done = false;
275         m_initializedTime = false;
276
277         return true;
278 }
279
280 bool BL_Action::IsDone()
281 {
282         return m_done;
283 }
284
285 void BL_Action::InitIPO()
286 {
287         // Initialize the IPOs
288         std::vector<SG_Controller*>::iterator it;
289         for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
290         {
291                 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
292                 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE);
293                 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD);
294                 (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL);
295         }
296 }
297
298 bAction *BL_Action::GetAction()
299 {
300         return (IsDone()) ? NULL : m_action;
301 }
302
303 float BL_Action::GetFrame()
304 {
305         return m_localframe;
306 }
307
308 const char *BL_Action::GetName()
309 {
310         if (m_action != NULL) {
311                 return m_action->id.name + 2;
312         }
313         else {
314                 return "";
315         }
316
317                     
318 }
319
320 void BL_Action::SetFrame(float frame)
321 {
322         // Clamp the frame to the start and end frame
323         if (frame < min(m_startframe, m_endframe))
324                 frame = min(m_startframe, m_endframe);
325         else if (frame > max(m_startframe, m_endframe))
326                 frame = max(m_startframe, m_endframe);
327         
328         m_localframe = frame;
329         m_calc_localtime = false;
330 }
331
332 void BL_Action::SetPlayMode(short play_mode)
333 {
334         m_playmode = play_mode;
335 }
336
337 void BL_Action::SetTimes(float start, float end)
338 {
339         m_startframe = start;
340         m_endframe = end;
341 }
342
343 void BL_Action::SetLocalTime(float curtime)
344 {
345         float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
346
347         if (m_endframe < m_startframe)
348                 dt = -dt;
349
350         m_localframe = m_startframe + dt;
351 }
352
353 void BL_Action::ResetStartTime(float curtime)
354 {
355         float dt = (m_localframe > m_startframe) ? m_localframe - m_startframe : m_startframe - m_localframe;
356
357         m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
358         SetLocalTime(curtime);
359 }
360
361 void BL_Action::IncrementBlending(float curtime)
362 {
363         // Setup m_blendstart if we need to
364         if (m_blendstart == 0.f)
365                 m_blendstart = curtime;
366         
367         // Bump the blend frame
368         m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
369
370         // Clamp
371         if (m_blendframe>m_blendin)
372                 m_blendframe = m_blendin;
373 }
374
375
376 void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
377 {
378         vector<float>::const_iterator it;
379         float dstweight;
380         KeyBlock *kb;
381         
382         dstweight = 1.0F - srcweight;
383         //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
384         for (it=blendshape.begin(), kb = (KeyBlock *)key->block.first; 
385              kb && it != blendshape.end();
386              kb = (KeyBlock *)kb->next, it++)
387         {
388                 //printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
389                 kb->curval = kb->curval * dstweight + (*it) * srcweight;
390                 //printf("NewKey: %f\n", kb->curval);
391         }
392         //printf("\n");
393 }
394
395 void BL_Action::Update(float curtime)
396 {
397         // Don't bother if we're done with the animation
398         if (m_done)
399                 return;
400
401         curtime -= KX_KetsjiEngine::GetSuspendedDelta();
402
403         // Grab the start time here so we don't end up with a negative m_localframe when
404         // suspending and resuming scenes.
405         if (!m_initializedTime) {
406                 m_starttime = curtime;
407                 m_initializedTime = true;
408         }
409
410         if (m_calc_localtime)
411                 SetLocalTime(curtime);
412         else
413         {
414                 ResetStartTime(curtime);
415                 m_calc_localtime = true;
416         }
417
418         // Handle wrap around
419         if (m_localframe < min(m_startframe, m_endframe) || m_localframe > max(m_startframe, m_endframe)) {
420                 switch (m_playmode) {
421                         case ACT_MODE_PLAY:
422                                 // Clamp
423                                 m_localframe = m_endframe;
424                                 m_done = true;
425                                 break;
426                         case ACT_MODE_LOOP:
427                                 // Put the time back to the beginning
428                                 m_localframe = m_startframe;
429                                 m_starttime = curtime;
430                                 break;
431                         case ACT_MODE_PING_PONG:
432                                 // Swap the start and end frames
433                                 float temp = m_startframe;
434                                 m_startframe = m_endframe;
435                                 m_endframe = temp;
436
437                                 m_starttime = curtime;
438
439                                 break;
440                 }
441         }
442
443         if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
444         {
445                 BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
446
447                 if (m_layer_weight >= 0)
448                         obj->GetPose(&m_blendpose);
449
450                 // Extract the pose from the action
451                 obj->SetPoseByAction(m_tmpaction, m_localframe);
452
453                 // Handle blending between armature actions
454                 if (m_blendin && m_blendframe<m_blendin)
455                 {
456                         IncrementBlending(curtime);
457
458                         // Calculate weight
459                         float weight = 1.f - (m_blendframe/m_blendin);
460
461                         // Blend the poses
462                         obj->BlendInPose(m_blendinpose, weight, ACT_BLEND_BLEND);
463                 }
464
465
466                 // Handle layer blending
467                 if (m_layer_weight >= 0)
468                         obj->BlendInPose(m_blendpose, m_layer_weight, m_blendmode);
469
470                 obj->UpdateTimestep(curtime);
471         }
472         else
473         {
474                 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
475                 BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
476
477                 // Handle shape actions if we have any
478                 if (shape_deformer && shape_deformer->GetKey())
479                 {
480                         Key *key = shape_deformer->GetKey();
481
482                         PointerRNA ptrrna;
483                         RNA_id_pointer_create(&key->id, &ptrrna);
484
485                         animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localframe);
486
487                         // Handle blending between shape actions
488                         if (m_blendin && m_blendframe < m_blendin)
489                         {
490                                 IncrementBlending(curtime);
491
492                                 float weight = 1.f - (m_blendframe/m_blendin);
493
494                                 // We go through and clear out the keyblocks so there isn't any interference
495                                 // from other shape actions
496                                 KeyBlock *kb;
497                                 for (kb=(KeyBlock *)key->block.first; kb; kb=(KeyBlock *)kb->next)
498                                         kb->curval = 0.f;
499
500                                 // Now blend the shape
501                                 BlendShape(key, weight, m_blendinshape);
502                         }
503
504                         // Handle layer blending
505                         if (m_layer_weight >= 0)
506                         {
507                                 obj->GetShape(m_blendshape);
508                                 BlendShape(key, m_layer_weight, m_blendshape);
509                         }
510
511                         obj->SetActiveAction(NULL, 0, curtime);
512                 }
513         }
514
515         BLI_spin_lock(&BL_ActionLock);
516         /* This function is not thread safe because of recursive scene graph transform
517          * updates on children. e.g: If an object and one of its children is animated,
518          * the both can write transform at the same time. A thread lock avoid problems. */
519         m_obj->UpdateIPO(m_localframe, m_ipo_flags & ACT_IPOFLAG_CHILD);
520         BLI_spin_unlock(&BL_ActionLock);
521
522         if (m_done)
523                 ClearControllerList();
524 }
525
526 void BL_Action::InitLock()
527 {
528         BLI_spin_init(&BL_ActionLock);
529 }
530
531 void BL_Action::EndLock()
532 {
533         BLI_spin_end(&BL_ActionLock);
534 }