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