BGE API cleanup: action actuator.
[blender.git] / source / gameengine / Converter / BL_ActionActuator.cpp
1 /**
2 * $Id$
3 *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28 */
29
30 #if defined (__sgi)
31 #include <math.h>
32 #else
33 #include <cmath>
34 #endif
35
36 #include "SCA_LogicManager.h"
37 #include "BL_ActionActuator.h"
38 #include "BL_ArmatureObject.h"
39 #include "BL_SkinDeformer.h"
40 #include "KX_GameObject.h"
41 #include "STR_HashedString.h"
42 #include "DNA_action_types.h"
43 #include "DNA_nla_types.h"
44 #include "DNA_actuator_types.h"
45 #include "BKE_action.h"
46 #include "DNA_armature_types.h"
47 #include "MEM_guardedalloc.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_arithb.h"
50 #include "MT_Matrix4x4.h"
51 #include "BKE_utildefines.h"
52 #include "FloatValue.h"
53 #include "PyObjectPlus.h"
54
55 #include "blendef.h"
56
57 #ifdef HAVE_CONFIG_H
58 #include <config.h>
59 #endif
60
61 BL_ActionActuator::~BL_ActionActuator()
62 {
63         if (m_pose)
64                 game_free_pose(m_pose);
65         if (m_userpose)
66                 game_free_pose(m_userpose);
67         if (m_blendpose)
68                 game_free_pose(m_blendpose);
69 }
70
71 void BL_ActionActuator::ProcessReplica(){
72 //      bPose *oldpose = m_pose;
73 //      bPose *oldbpose = m_blendpose;
74         
75         m_pose = NULL;
76         m_blendpose = NULL;
77         m_localtime=m_startframe;
78         m_lastUpdate=-1;
79         
80 }
81
82 void BL_ActionActuator::SetBlendTime (float newtime){
83         m_blendframe = newtime;
84 }
85
86 CValue* BL_ActionActuator::GetReplica() {
87         BL_ActionActuator* replica = new BL_ActionActuator(*this);//m_float,GetName());
88         replica->ProcessReplica();
89         
90         // this will copy properties and so on...
91         CValue::AddDataToReplica(replica);
92         return replica;
93 }
94
95 bool BL_ActionActuator::ClampLocalTime()
96 {
97         if (m_startframe < m_endframe)
98         {
99                 if (m_localtime < m_startframe)
100                 {
101                         m_localtime = m_startframe;
102                         return true;
103                 } 
104                 else if (m_localtime > m_endframe)
105                 {
106                         m_localtime = m_endframe;
107                         return true;
108                 }
109         } else {
110                 if (m_localtime > m_startframe)
111                 {
112                         m_localtime = m_startframe;
113                         return true;
114                 }
115                 else if (m_localtime < m_endframe)
116                 {
117                         m_localtime = m_endframe;
118                         return true;
119                 }
120         }
121         return false;
122 }
123
124 void BL_ActionActuator::SetStartTime(float curtime)
125 {
126         float direction = m_startframe < m_endframe ? 1.0 : -1.0;
127         
128         if (!(m_flag & ACT_FLAG_REVERSE))
129                 m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate();
130         else
131                 m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate();
132 }
133
134 void BL_ActionActuator::SetLocalTime(float curtime)
135 {
136         float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate();
137         
138         if (m_endframe < m_startframe)
139                 delta_time = -delta_time;
140
141         if (!(m_flag & ACT_FLAG_REVERSE))
142                 m_localtime = m_startframe + delta_time;
143         else
144                 m_localtime = m_endframe - delta_time;
145 }
146
147
148 bool BL_ActionActuator::Update(double curtime, bool frame)
149 {
150         bool bNegativeEvent = false;
151         bool bPositiveEvent = false;
152         bool keepgoing = true;
153         bool wrap = false;
154         bool apply=true;
155         int     priority;
156         float newweight;
157
158         curtime -= KX_KetsjiEngine::GetSuspendedDelta();
159         
160         // result = true if animation has to be continued, false if animation stops
161         // maybe there are events for us in the queue !
162         if (frame)
163         {
164                 for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
165                 {
166                         if ((*i)->GetNumber() == 0.0f)
167                                 bNegativeEvent = true;
168                         else
169                                 bPositiveEvent= true;
170                         (*i)->Release();
171                 
172                 }
173                 m_events.clear();
174                 
175                 if (bPositiveEvent)
176                         m_flag |= ACT_FLAG_ACTIVE;
177                 
178                 if (bNegativeEvent)
179                 {
180                         // dont continue where we left off when restarting
181                         if (m_end_reset) {
182                                 m_flag &= ~ACT_FLAG_LOCKINPUT;
183                         }
184                         
185                         if (!(m_flag & ACT_FLAG_ACTIVE))
186                                 return false;
187                         m_flag &= ~ACT_FLAG_ACTIVE;
188                 }
189         }
190         
191         /*      We know that action actuators have been discarded from all non armature objects:
192         if we're being called, we're attached to a BL_ArmatureObject */
193         BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
194         float length = m_endframe - m_startframe;
195         
196         priority = m_priority;
197         
198         /* Determine pre-incrementation behaviour and set appropriate flags */
199         switch (m_playtype){
200         case ACT_ACTION_MOTION:
201                 if (bNegativeEvent){
202                         keepgoing=false;
203                         apply=false;
204                 };
205                 break;
206         case ACT_ACTION_FROM_PROP:
207                 if (bNegativeEvent){
208                         apply=false;
209                         keepgoing=false;
210                 }
211                 break;
212         case ACT_ACTION_LOOP_END:
213                 if (bPositiveEvent){
214                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
215                                 m_flag &= ~ACT_FLAG_KEYUP;
216                                 m_flag &= ~ACT_FLAG_REVERSE;
217                                 m_flag |= ACT_FLAG_LOCKINPUT;
218                                 m_localtime = m_startframe;
219                                 m_starttime = curtime;
220                         }
221                 }
222                 if (bNegativeEvent){
223                         m_flag |= ACT_FLAG_KEYUP;
224                 }
225                 break;
226         case ACT_ACTION_LOOP_STOP:
227                 if (bPositiveEvent){
228                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
229                                 m_flag &= ~ACT_FLAG_REVERSE;
230                                 m_flag &= ~ACT_FLAG_KEYUP;
231                                 m_flag |= ACT_FLAG_LOCKINPUT;
232                                 SetStartTime(curtime);
233                         }
234                 }
235                 if (bNegativeEvent){
236                         m_flag |= ACT_FLAG_KEYUP;
237                         m_flag &= ~ACT_FLAG_LOCKINPUT;
238                         keepgoing=false;
239                         apply=false;
240                 }
241                 break;
242         case ACT_ACTION_FLIPPER:
243                 if (bPositiveEvent){
244                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
245                                 m_flag &= ~ACT_FLAG_REVERSE;
246                                 m_flag |= ACT_FLAG_LOCKINPUT;
247                                 SetStartTime(curtime);
248                         }
249                 }
250                 else if (bNegativeEvent){
251                         m_flag |= ACT_FLAG_REVERSE;
252                         m_flag &= ~ACT_FLAG_LOCKINPUT;
253                         SetStartTime(curtime);
254                 }
255                 break;
256         case ACT_ACTION_PLAY:
257                 if (bPositiveEvent){
258                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
259                                 m_flag &= ~ACT_FLAG_REVERSE;
260                                 m_localtime = m_starttime;
261                                 m_starttime = curtime;
262                                 m_flag |= ACT_FLAG_LOCKINPUT;
263                         }
264                 }
265                 break;
266         default:
267                 break;
268         }
269         
270         /* Perform increment */
271         if (keepgoing){
272                 if (m_playtype == ACT_ACTION_MOTION){
273                         MT_Point3       newpos;
274                         MT_Point3       deltapos;
275                         
276                         newpos = obj->NodeGetWorldPosition();
277                         
278                         /* Find displacement */
279                         deltapos = newpos-m_lastpos;
280                         m_localtime += (length/m_stridelength) * deltapos.length();
281                         m_lastpos = newpos;
282                 }
283                 else{
284                         SetLocalTime(curtime);
285                 }
286         }
287         
288         /* Check if a wrapping response is needed */
289         if (length){
290                 if (m_localtime < m_startframe || m_localtime > m_endframe)
291                 {
292                         m_localtime = m_startframe + fmod(m_localtime, length);
293                         wrap = true;
294                 }
295         }
296         else
297                 m_localtime = m_startframe;
298         
299         /* Perform post-increment tasks */
300         switch (m_playtype){
301         case ACT_ACTION_FROM_PROP:
302                 {
303                         CValue* propval = GetParent()->GetProperty(m_propname);
304                         if (propval)
305                                 m_localtime = propval->GetNumber();
306                         
307                         if (bNegativeEvent){
308                                 keepgoing=false;
309                         }
310                 }
311                 break;
312         case ACT_ACTION_MOTION:
313                 break;
314         case ACT_ACTION_LOOP_STOP:
315                 break;
316         case ACT_ACTION_FLIPPER:
317                 if (wrap){
318                         if (!(m_flag & ACT_FLAG_REVERSE)){
319                                 m_localtime=m_endframe;
320                                 //keepgoing = false;
321                         }
322                         else {
323                                 m_localtime=m_startframe;
324                                 keepgoing = false;
325                         }
326                 }
327                 break;
328         case ACT_ACTION_LOOP_END:
329                 if (wrap){
330                         if (m_flag & ACT_FLAG_KEYUP){
331                                 keepgoing = false;
332                                 m_localtime = m_endframe;
333                                 m_flag &= ~ACT_FLAG_LOCKINPUT;
334                         }
335                         SetStartTime(curtime);
336                 }
337                 break;
338         case ACT_ACTION_PLAY:
339                 if (wrap){
340                         m_localtime = m_endframe;
341                         keepgoing = false;
342                         m_flag &= ~ACT_FLAG_LOCKINPUT;
343                 }
344                 break;
345         default:
346                 keepgoing = false;
347                 break;
348         }
349         
350         /* Set the property if its defined */
351         if (m_framepropname[0] != '\0') {
352                 CValue* propowner = GetParent();
353                 CValue* oldprop = propowner->GetProperty(m_framepropname);
354                 CValue* newval = new CFloatValue(m_localtime);
355                 if (oldprop) {
356                         oldprop->SetValue(newval);
357                 } else {
358                         propowner->SetProperty(m_framepropname, newval);
359                 }
360                 newval->Release();
361         }
362         
363         if (bNegativeEvent)
364                 m_blendframe=0.0;
365         
366         /* Apply the pose if necessary*/
367         if (apply){
368
369                 /* Priority test */
370                 if (obj->SetActiveAction(this, priority, curtime)){
371                         
372                         /* Get the underlying pose from the armature */
373                         obj->GetPose(&m_pose);
374                         
375                         /* Override the necessary channels with ones from the action */
376                         extract_pose_from_action(m_pose, m_action, m_localtime);
377
378                         /* Perform the user override (if any) */
379                         if (m_userpose){
380                                 extract_pose_from_pose(m_pose, m_userpose);
381 //                              clear_pose(m_userpose);
382                                 MEM_freeN(m_userpose);
383                                 m_userpose = NULL;
384                         }
385 #if 1
386                         /* Handle blending */
387                         if (m_blendin && (m_blendframe<m_blendin)){
388                                 /* If this is the start of a blending sequence... */
389                                 if ((m_blendframe==0.0) || (!m_blendpose)){
390                                         obj->GetMRDPose(&m_blendpose);
391                                         m_blendstart = curtime;
392                                 }
393                                 
394                                 /* Find percentages */
395                                 newweight = (m_blendframe/(float)m_blendin);
396                                 blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
397
398                                 /* Increment current blending percentage */
399                                 m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
400                                 if (m_blendframe>m_blendin)
401                                         m_blendframe = m_blendin;
402                                 
403                         }
404 #endif
405                         m_lastUpdate = m_localtime;
406                         obj->SetPose (m_pose);
407                 }
408                 else{
409                         m_blendframe = 0.0;
410                 }
411         }
412         
413         if (!keepgoing){
414                 m_blendframe = 0.0;
415         }
416         return keepgoing;
417 };
418
419 /* ------------------------------------------------------------------------- */
420 /* Python functions                                                          */
421 /* ------------------------------------------------------------------------- */
422
423 /*     setStart                                                              */
424 const char BL_ActionActuator::GetAction_doc[] = 
425 "getAction()\n"
426 "\tReturns a string containing the name of the current action.\n";
427
428 PyObject* BL_ActionActuator::PyGetAction(PyObject* self, 
429                                                                                  PyObject* args, 
430                                                                                  PyObject* kwds) {
431         ShowDeprecationWarning("getAction()", "the action property");
432
433         if (m_action){
434                 return PyString_FromString(m_action->id.name+2);
435         }
436         Py_RETURN_NONE;
437 }
438
439 /*     getProperty                                                             */
440 const char BL_ActionActuator::GetProperty_doc[] = 
441 "getProperty()\n"
442 "\tReturns the name of the property to be used in FromProp mode.\n";
443
444 PyObject* BL_ActionActuator::PyGetProperty(PyObject* self, 
445                                                                                    PyObject* args, 
446                                                                                    PyObject* kwds) {
447         ShowDeprecationWarning("getProperty()", "the property property");
448
449         PyObject *result;
450         
451         result = Py_BuildValue("s", (const char *)m_propname);
452         
453         return result;
454 }
455
456 /*     getProperty                                                             */
457 const char BL_ActionActuator::GetFrameProperty_doc[] = 
458 "getFrameProperty()\n"
459 "\tReturns the name of the property, that is set to the current frame number.\n";
460
461 PyObject* BL_ActionActuator::PyGetFrameProperty(PyObject* self, 
462                                                                                    PyObject* args, 
463                                                                                    PyObject* kwds) {
464         ShowDeprecationWarning("getFrameProperty()", "the frameProperty property");
465
466         PyObject *result;
467         
468         result = Py_BuildValue("s", (const char *)m_framepropname);
469         
470         return result;
471 }
472
473 /*     getFrame                                                              */
474 const char BL_ActionActuator::GetFrame_doc[] = 
475 "getFrame()\n"
476 "\tReturns the current frame number.\n";
477
478 PyObject* BL_ActionActuator::PyGetFrame(PyObject* self, 
479                                                                                 PyObject* args, 
480                                                                                 PyObject* kwds) {
481         ShowDeprecationWarning("getFrame()", "the frame property");
482
483         PyObject *result;
484         
485         result = Py_BuildValue("f", m_localtime);
486         
487         return result;
488 }
489
490 /*     getEnd                                                                */
491 const char BL_ActionActuator::GetEnd_doc[] = 
492 "getEnd()\n"
493 "\tReturns the last frame of the action.\n";
494
495 PyObject* BL_ActionActuator::PyGetEnd(PyObject* self, 
496                                                                           PyObject* args, 
497                                                                           PyObject* kwds) {
498         ShowDeprecationWarning("getEnd()", "the end property");
499
500         PyObject *result;
501         
502         result = Py_BuildValue("f", m_endframe);
503         
504         return result;
505 }
506
507 /*     getStart                                                              */
508 const char BL_ActionActuator::GetStart_doc[] = 
509 "getStart()\n"
510 "\tReturns the starting frame of the action.\n";
511
512 PyObject* BL_ActionActuator::PyGetStart(PyObject* self, 
513                                                                                 PyObject* args, 
514                                                                                 PyObject* kwds) {
515         ShowDeprecationWarning("getStart()", "the start property");
516
517         PyObject *result;
518         
519         result = Py_BuildValue("f", m_startframe);
520         
521         return result;
522 }
523
524 /*     getBlendin                                                            */
525 const char BL_ActionActuator::GetBlendin_doc[] = 
526 "getBlendin()\n"
527 "\tReturns the number of interpolation animation frames to be\n"
528 "\tgenerated when this actuator is triggered.\n";
529
530 PyObject* BL_ActionActuator::PyGetBlendin(PyObject* self, 
531                                                                                   PyObject* args, 
532                                                                                   PyObject* kwds) {
533         ShowDeprecationWarning("getBlendin()", "the blendin property");
534
535         PyObject *result;
536         
537         result = Py_BuildValue("f", m_blendin);
538         
539         return result;
540 }
541
542 /*     getPriority                                                           */
543 const char BL_ActionActuator::GetPriority_doc[] = 
544 "getPriority()\n"
545 "\tReturns the priority for this actuator.  Actuators with lower\n"
546 "\tPriority numbers will override actuators with higher numbers.\n";
547
548 PyObject* BL_ActionActuator::PyGetPriority(PyObject* self, 
549                                                                                    PyObject* args, 
550                                                                                    PyObject* kwds) {
551         ShowDeprecationWarning("getPriority()", "the priority property");
552
553         PyObject *result;
554         
555         result = Py_BuildValue("i", m_priority);
556         
557         return result;
558 }
559
560 /*     setAction                                                             */
561 const char BL_ActionActuator::SetAction_doc[] = 
562 "setAction(action, (reset))\n"
563 "\t - action    : The name of the action to set as the current action.\n"
564 "\t - reset     : Optional parameter indicating whether to reset the\n"
565 "\t               blend timer or not.  A value of 1 indicates that the\n"
566 "\t               timer should be reset.  A value of 0 will leave it\n"
567 "\t               unchanged.  If reset is not specified, the timer will"
568 "\t                   be reset.\n";
569
570 PyObject* BL_ActionActuator::PySetAction(PyObject* self, 
571                                                                                  PyObject* args, 
572                                                                                  PyObject* kwds) {
573         ShowDeprecationWarning("setAction()", "the action property");
574
575         char *string;
576         int     reset = 1;
577
578         if (PyArg_ParseTuple(args,"s|i",&string, &reset))
579         {
580                 bAction *action;
581                 
582                 action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string));
583                 
584                 if (!action){
585                         /* NOTE!  Throw an exception or something */
586                         //                      printf ("setAction failed: Action not found\n", string);
587                 }
588                 else{
589                         m_action=action;
590                         if (reset)
591                                 m_blendframe = 0;
592                 }
593         }
594         else {
595                 return NULL;
596         }
597         
598         Py_RETURN_NONE;
599 }
600
601 /*     setStart                                                              */
602 const char BL_ActionActuator::SetStart_doc[] = 
603 "setStart(start)\n"
604 "\t - start     : Specifies the starting frame of the animation.\n";
605
606 PyObject* BL_ActionActuator::PySetStart(PyObject* self, 
607                                                                                 PyObject* args, 
608                                                                                 PyObject* kwds) {
609         ShowDeprecationWarning("setStart()", "the start property");
610
611         float start;
612         
613         if (PyArg_ParseTuple(args,"f",&start))
614         {
615                 m_startframe = start;
616         }
617         else {
618                 return NULL;
619         }
620         
621         Py_RETURN_NONE;
622 }
623
624 /*     setEnd                                                                */
625 const char BL_ActionActuator::SetEnd_doc[] = 
626 "setEnd(end)\n"
627 "\t - end       : Specifies the ending frame of the animation.\n";
628
629 PyObject* BL_ActionActuator::PySetEnd(PyObject* self, 
630                                                                           PyObject* args, 
631                                                                           PyObject* kwds) {
632         ShowDeprecationWarning("setEnd()", "the end property");
633
634         float end;
635         
636         if (PyArg_ParseTuple(args,"f",&end))
637         {
638                 m_endframe = end;
639         }
640         else {
641                 return NULL;
642         }
643         
644         Py_RETURN_NONE;
645 }
646
647 /*     setBlendin                                                            */
648 const char BL_ActionActuator::SetBlendin_doc[] = 
649 "setBlendin(blendin)\n"
650 "\t - blendin   : Specifies the number of frames of animation to generate\n"
651 "\t               when making transitions between actions.\n";
652
653 PyObject* BL_ActionActuator::PySetBlendin(PyObject* self, 
654                                                                                   PyObject* args, 
655                                                                                   PyObject* kwds) {
656         ShowDeprecationWarning("setBlendin()", "the blendin property");
657
658         float blendin;
659         
660         if (PyArg_ParseTuple(args,"f",&blendin))
661         {
662                 m_blendin = blendin;
663         }
664         else {
665                 return NULL;
666         }
667         
668         Py_RETURN_NONE;
669 }
670
671 /*     setBlendtime                                                          */
672 const char BL_ActionActuator::SetBlendtime_doc[] = 
673 "setBlendtime(blendtime)\n"
674 "\t - blendtime : Allows the script to directly modify the internal timer\n"
675 "\t               used when generating transitions between actions.  This\n"
676 "\t               parameter must be in the range from 0.0 to 1.0.\n";
677
678 PyObject* BL_ActionActuator::PySetBlendtime(PyObject* self, 
679                                                                                   PyObject* args, 
680                                                                                   PyObject* kwds) {
681         ShowDeprecationWarning("setBlendtime()", "the blendtime property");
682
683         float blendframe;
684         
685         if (PyArg_ParseTuple(args,"f",&blendframe))
686         {
687                 m_blendframe = blendframe * m_blendin;
688                 if (m_blendframe<0)
689                         m_blendframe = 0;
690                 if (m_blendframe>m_blendin)
691                         m_blendframe = m_blendin;
692         }
693         else {
694                 return NULL;
695         }
696         
697         Py_RETURN_NONE;
698 }
699
700 /*     setPriority                                                           */
701 const char BL_ActionActuator::SetPriority_doc[] = 
702 "setPriority(priority)\n"
703 "\t - priority  : Specifies the new priority.  Actuators will lower\n"
704 "\t               priority numbers will override actuators with higher\n"
705 "\t               numbers.\n";
706
707 PyObject* BL_ActionActuator::PySetPriority(PyObject* self, 
708                                                                                    PyObject* args, 
709                                                                                    PyObject* kwds) {
710         ShowDeprecationWarning("setPriority()", "the priority property");
711
712         int priority;
713         
714         if (PyArg_ParseTuple(args,"i",&priority))
715         {
716                 m_priority = priority;
717         }
718         else {
719                 return NULL;
720         }
721         
722         Py_RETURN_NONE;
723 }
724
725 /*     setFrame                                                              */
726 const char BL_ActionActuator::SetFrame_doc[] = 
727 "setFrame(frame)\n"
728 "\t - frame     : Specifies the new current frame for the animation\n";
729
730 PyObject* BL_ActionActuator::PySetFrame(PyObject* self, 
731                                                                                 PyObject* args, 
732                                                                                 PyObject* kwds) {
733         ShowDeprecationWarning("setFrame()", "the frame property");
734
735         float frame;
736         
737         if (PyArg_ParseTuple(args,"f",&frame))
738         {
739                 m_localtime = frame;
740                 if (m_localtime<m_startframe)
741                         m_localtime=m_startframe;
742                 else if (m_localtime>m_endframe)
743                         m_localtime=m_endframe;
744         }
745         else {
746                 return NULL;
747         }
748         
749         Py_RETURN_NONE;
750 }
751
752 /*     setProperty                                                           */
753 const char BL_ActionActuator::SetProperty_doc[] = 
754 "setProperty(prop)\n"
755 "\t - prop      : A string specifying the property name to be used in\n"
756 "\t               FromProp playback mode.\n";
757
758 PyObject* BL_ActionActuator::PySetProperty(PyObject* self, 
759                                                                                    PyObject* args, 
760                                                                                    PyObject* kwds) {
761         ShowDeprecationWarning("setProperty()", "the property property");
762
763         char *string;
764         
765         if (PyArg_ParseTuple(args,"s",&string))
766         {
767                 m_propname = string;
768         }
769         else {
770                 return NULL;
771         }
772         
773         Py_RETURN_NONE;
774 }
775
776 /*     setFrameProperty                                                          */
777 const char BL_ActionActuator::SetFrameProperty_doc[] = 
778 "setFrameProperty(prop)\n"
779 "\t - prop      : A string specifying the property of the frame set up update.\n";
780
781 PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* self, 
782                                                                                    PyObject* args, 
783                                                                                    PyObject* kwds) {
784         ShowDeprecationWarning("setFrameProperty()", "the frameProperty property");
785
786         char *string;
787         
788         if (PyArg_ParseTuple(args,"s",&string))
789         {
790                 m_framepropname = string;
791         }
792         else {
793                 return NULL;
794         }
795         
796         Py_RETURN_NONE;
797 }
798
799 /*
800 PyObject* BL_ActionActuator::PyGetChannel(PyObject* self, 
801                                                                                    PyObject* args, 
802                                                                                    PyObject* kwds) {
803         char *string;
804         
805         if (PyArg_ParseTuple(args,"s",&string))
806         {
807                 m_propname = string;
808         }
809         else {
810                 return NULL;
811         }
812         
813         Py_RETURN_NONE;
814 }
815 */
816
817 /* getType */
818 const char BL_ActionActuator::GetType_doc[] =
819 "getType()\n"
820 "\tReturns the operation mode of the actuator.\n";
821 PyObject* BL_ActionActuator::PyGetType(PyObject* self,
822                                        PyObject* args, 
823                                        PyObject* kwds) {
824         ShowDeprecationWarning("getType()", "the type property");
825
826     return Py_BuildValue("h", m_playtype);
827 }
828
829 /* setType */
830 const char BL_ActionActuator::SetType_doc[] =
831 "setType(mode)\n"
832 "\t - mode: Play (0), Flipper (2), LoopStop (3), LoopEnd (4) or Property (6)\n"
833 "\tSet the operation mode of the actuator.\n";
834 PyObject* BL_ActionActuator::PySetType(PyObject* self,
835                                        PyObject* args,
836                                        PyObject* kwds) {
837         ShowDeprecationWarning("setType()", "the type property");
838
839         short typeArg;
840                                                                                                              
841     if (!PyArg_ParseTuple(args, "h", &typeArg)) {
842         return NULL;
843     }
844
845         switch (typeArg) {
846         case KX_ACT_ACTION_PLAY:
847         case KX_ACT_ACTION_FLIPPER:
848         case KX_ACT_ACTION_LOOPSTOP:
849         case KX_ACT_ACTION_LOOPEND:
850         case KX_ACT_ACTION_PROPERTY:
851                 m_playtype = typeArg;
852                 break;
853         default:
854                 printf("Invalid type for action actuator: %d\n", typeArg); /* error */
855     }
856         Py_RETURN_NONE;
857 }
858
859 PyObject* BL_ActionActuator::PyGetContinue(PyObject* self) {
860         ShowDeprecationWarning("getContinue()", "the continue property");
861
862     return PyInt_FromLong((long)(m_end_reset==0));
863 }
864
865 PyObject* BL_ActionActuator::PySetContinue(PyObject* self, PyObject* value) {
866         ShowDeprecationWarning("setContinue()", "the continue property");
867
868         int param = PyObject_IsTrue( value );
869         
870         if( param == -1 ) {
871                 PyErr_SetString( PyExc_TypeError, "expected True/False or 0/1" );
872                 return NULL;
873         }
874
875         if (param) {
876                 m_end_reset = 0;
877         } else {
878                 m_end_reset = 1;
879         }
880     Py_RETURN_NONE;
881 }
882
883 //<-----Deprecated
884
885 /*     setChannel                                                         */
886 KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel,
887 "setChannel(channel, matrix)\n"
888 "\t - channel   : A string specifying the name of the bone channel.\n"
889 "\t - matrix    : A 4x4 matrix specifying the overriding transformation\n"
890 "\t               as an offset from the bone's rest position.\n")
891 {
892         float matrix[4][4];
893         char *string;
894         PyObject* pylist;
895         bool    error = false;
896         int row,col;
897         int     mode = 0;       /* 0 for bone space, 1 for armature/world space */
898         
899         if (!PyArg_ParseTuple(args,"sO|i", &string, &pylist, &mode))
900                 return NULL;
901         
902         if (pylist->ob_type == &CListValue::Type)
903         {
904                 CListValue* listval = (CListValue*) pylist;
905                 if (listval->GetCount() == 4)
906                 {
907                         for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
908                         {
909                                 CListValue* vecval = (CListValue*)listval->GetValue(row);
910                                 for (col=0;col<4;col++)
911                                 {
912                                         matrix[row][col] = vecval->GetValue(col)->GetNumber();
913                                         
914                                 }
915                         }
916                 }
917                 else
918                 {
919                         error = true;
920                 }
921         }
922         else
923         {
924                 // assert the list is long enough...
925                 int numitems = PyList_Size(pylist);
926                 if (numitems == 4)
927                 {
928                         for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
929                         {
930                                 
931                                 PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector4 list
932                                 for (col=0;col<4;col++)
933                                 {
934                                         matrix[row][col] =  PyFloat_AsDouble(PyList_GetItem(veclist,col));
935                                         
936                                 }
937                         }
938                 }
939                 else
940                 {
941                         error = true;
942                 }
943         }
944         
945         if (!error)
946         {
947
948 /*      DO IT HERE */
949                 bPoseChannel *pchan= verify_pose_channel(m_userpose, string);
950
951                 Mat4ToQuat(matrix, pchan->quat);
952                 Mat4ToSize(matrix, pchan->size);
953                 VECCOPY (pchan->loc, matrix[3]);
954                 
955                 pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE;
956
957                 if (!m_userpose){
958                         m_userpose = (bPose*)MEM_callocN(sizeof(bPose), "userPose");
959                 }
960         }
961         
962         Py_RETURN_NONE;
963 }
964
965 /* ------------------------------------------------------------------------- */
966 /* Python Integration Hooks                                                                      */
967 /* ------------------------------------------------------------------------- */
968
969 PyTypeObject BL_ActionActuator::Type = {
970         PyObject_HEAD_INIT(&PyType_Type)
971                 0,
972                 "BL_ActionActuator",
973                 sizeof(BL_ActionActuator),
974                 0,
975                 PyDestructor,
976                 0,
977                 __getattr,
978                 __setattr,
979                 0, //&MyPyCompare,
980                 __repr,
981                 0, //&cvalue_as_number,
982                 0,
983                 0,
984                 0,
985                 0
986 };
987
988 PyParentObject BL_ActionActuator::Parents[] = {
989         &BL_ActionActuator::Type,
990                 &SCA_IActuator::Type,
991                 &SCA_ILogicBrick::Type,
992                 &CValue::Type,
993                 NULL
994 };
995
996 PyMethodDef BL_ActionActuator::Methods[] = {
997         //Deprecated ----->
998         {"setAction", (PyCFunction) BL_ActionActuator::sPySetAction, METH_VARARGS, (PY_METHODCHAR)SetAction_doc},
999         {"setStart", (PyCFunction) BL_ActionActuator::sPySetStart, METH_VARARGS, (PY_METHODCHAR)SetStart_doc},
1000         {"setEnd", (PyCFunction) BL_ActionActuator::sPySetEnd, METH_VARARGS, (PY_METHODCHAR)SetEnd_doc},
1001         {"setBlendin", (PyCFunction) BL_ActionActuator::sPySetBlendin, METH_VARARGS, (PY_METHODCHAR)SetBlendin_doc},
1002         {"setPriority", (PyCFunction) BL_ActionActuator::sPySetPriority, METH_VARARGS, (PY_METHODCHAR)SetPriority_doc},
1003         {"setFrame", (PyCFunction) BL_ActionActuator::sPySetFrame, METH_VARARGS, (PY_METHODCHAR)SetFrame_doc},
1004         {"setProperty", (PyCFunction) BL_ActionActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
1005         {"setFrameProperty", (PyCFunction) BL_ActionActuator::sPySetFrameProperty, METH_VARARGS, (PY_METHODCHAR)SetFrameProperty_doc},
1006         {"setBlendtime", (PyCFunction) BL_ActionActuator::sPySetBlendtime, METH_VARARGS, (PY_METHODCHAR)SetBlendtime_doc},
1007
1008         {"getAction", (PyCFunction) BL_ActionActuator::sPyGetAction, METH_VARARGS, (PY_METHODCHAR)GetAction_doc},
1009         {"getStart", (PyCFunction) BL_ActionActuator::sPyGetStart, METH_VARARGS, (PY_METHODCHAR)GetStart_doc},
1010         {"getEnd", (PyCFunction) BL_ActionActuator::sPyGetEnd, METH_VARARGS, (PY_METHODCHAR)GetEnd_doc},
1011         {"getBlendin", (PyCFunction) BL_ActionActuator::sPyGetBlendin, METH_VARARGS, (PY_METHODCHAR)GetBlendin_doc},
1012         {"getPriority", (PyCFunction) BL_ActionActuator::sPyGetPriority, METH_VARARGS, (PY_METHODCHAR)GetPriority_doc},
1013         {"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, (PY_METHODCHAR)GetFrame_doc},
1014         {"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
1015         {"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, (PY_METHODCHAR)GetFrameProperty_doc},
1016 //      {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS},
1017         {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, (PY_METHODCHAR)GetType_doc},
1018         {"setType", (PyCFunction) BL_ActionActuator::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
1019         {"getContinue", (PyCFunction) BL_ActionActuator::sPyGetContinue, METH_NOARGS, 0},       
1020         {"setContinue", (PyCFunction) BL_ActionActuator::sPySetContinue, METH_O, 0},
1021         //<------
1022         KX_PYMETHODTABLE(BL_ActionActuator, setChannel),
1023         {NULL,NULL} //Sentinel
1024 };
1025
1026 PyAttributeDef BL_ActionActuator::Attributes[] = {
1027         KX_PYATTRIBUTE_FLOAT_RW("start", 0, MAXFRAMEF, BL_ActionActuator, m_startframe),
1028         KX_PYATTRIBUTE_FLOAT_RW("end", 0, MAXFRAMEF, BL_ActionActuator, m_endframe),
1029         KX_PYATTRIBUTE_FLOAT_RW("blendin", 0, MAXFRAMEF, BL_ActionActuator, m_blendin),
1030         KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ActionActuator, m_priority),
1031         KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ActionActuator, m_localtime, CheckFrame),
1032         KX_PYATTRIBUTE_STRING_RW("property", 0, 31, false, BL_ActionActuator, m_propname),
1033         KX_PYATTRIBUTE_STRING_RW("frameProperty", 0, 31, false, BL_ActionActuator, m_framepropname),
1034         KX_PYATTRIBUTE_BOOL_RW("continue", BL_ActionActuator, m_end_reset),
1035         KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime),
1036         KX_PYATTRIBUTE_ENUM_RW_CHECK("type",0,100,false,BL_ActionActuator,m_playtype,CheckType),
1037         { NULL }        //Sentinel
1038 };
1039
1040 PyObject* BL_ActionActuator::_getattr(const STR_String& attr) {
1041         if (attr == "action")
1042                 return PyString_FromString(m_action->id.name+2);
1043         PyObject* object = _getattr_self(Attributes, this, attr);
1044         if (object != NULL)
1045                 return object;
1046         _getattr_up(SCA_IActuator);
1047 }
1048
1049 int BL_ActionActuator::_setattr(const STR_String& attr, PyObject* value) {
1050         if (attr == "action")
1051         {
1052                 if (!PyString_Check(value))
1053                 {
1054                         PyErr_SetString(PyExc_ValueError, "expected a string");
1055                         return 1;
1056                 }
1057
1058                 STR_String val = PyString_AsString(value);
1059                 
1060                 if (val == "")
1061                 {
1062                         m_action = NULL;
1063                         return 0;
1064                 }
1065
1066                 bAction *action;
1067                 
1068                 action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(val);
1069                 
1070
1071                 if (!action)
1072                 {
1073                         PyErr_SetString(PyExc_ValueError, "action not found!");
1074                         return 1;
1075                 }
1076
1077                 m_action = action;
1078                 return 0;
1079         }
1080         int ret = _setattr_self(Attributes, this, attr, value);
1081         if (ret >= 0)
1082                 return ret;
1083         return SCA_IActuator::_setattr(attr, value);
1084 }