BGE Py API using python3 c/api calls. include bpy_compat.h to support py2.x
[blender.git] / source / gameengine / Converter / BL_ShapeActionActuator.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_ShapeActionActuator.h"
38 #include "BL_ShapeDeformer.h"
39 #include "KX_GameObject.h"
40 #include "STR_HashedString.h"
41 #include "DNA_nla_types.h"
42 #include "DNA_action_types.h"
43 #include "DNA_scene_types.h"
44 #include "BKE_action.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
54 #ifdef HAVE_CONFIG_H
55 #include <config.h>
56 #endif
57
58 BL_ShapeActionActuator::~BL_ShapeActionActuator()
59 {
60 }
61
62 void BL_ShapeActionActuator::ProcessReplica()
63 {
64         SCA_IActuator::ProcessReplica();
65         m_localtime=m_startframe;
66         m_lastUpdate=-1;
67 }
68
69 void BL_ShapeActionActuator::SetBlendTime (float newtime)
70 {
71         m_blendframe = newtime;
72 }
73
74 CValue* BL_ShapeActionActuator::GetReplica() 
75 {
76         BL_ShapeActionActuator* replica = new BL_ShapeActionActuator(*this);//m_float,GetName());
77         replica->ProcessReplica();
78         return replica;
79 }
80
81 bool BL_ShapeActionActuator::ClampLocalTime()
82 {
83         if (m_startframe < m_endframe)  {
84                 if (m_localtime < m_startframe)
85                 {
86                         m_localtime = m_startframe;
87                         return true;
88                 } 
89                 else if (m_localtime > m_endframe)
90                 {
91                         m_localtime = m_endframe;
92                         return true;
93                 }
94         } else {
95                 if (m_localtime > m_startframe)
96                 {
97                         m_localtime = m_startframe;
98                         return true;
99                 }
100                 else if (m_localtime < m_endframe)
101                 {
102                         m_localtime = m_endframe;
103                         return true;
104                 }
105         }
106         return false;
107 }
108
109 void BL_ShapeActionActuator::SetStartTime(float curtime)
110 {
111         float direction = m_startframe < m_endframe ? 1.0 : -1.0;
112         
113         if (!(m_flag & ACT_FLAG_REVERSE))
114                 m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate();
115         else
116                 m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate();
117 }
118
119 void BL_ShapeActionActuator::SetLocalTime(float curtime)
120 {
121         float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate();
122         
123         if (m_endframe < m_startframe)
124                 delta_time = -delta_time;
125
126         if (!(m_flag & ACT_FLAG_REVERSE))
127                 m_localtime = m_startframe + delta_time;
128         else
129                 m_localtime = m_endframe - delta_time;
130 }
131
132 void BL_ShapeActionActuator::BlendShape(Key* key, float srcweight)
133 {
134         vector<float>::const_iterator it;
135         float dstweight;
136         KeyBlock *kb;
137         
138         dstweight = 1.0F - srcweight;
139
140         for (it=m_blendshape.begin(), kb = (KeyBlock*)key->block.first; 
141                  kb && it != m_blendshape.end(); 
142                  kb = (KeyBlock*)kb->next, it++) {
143                 kb->curval = kb->curval * dstweight + (*it) * srcweight;
144         }
145 }
146
147 bool BL_ShapeActionActuator::Update(double curtime, bool frame)
148 {
149         bool bNegativeEvent = false;
150         bool bPositiveEvent = false;
151         bool keepgoing = true;
152         bool wrap = false;
153         bool apply=true;
154         int     priority;
155         float newweight;
156
157         curtime -= KX_KetsjiEngine::GetSuspendedDelta();
158         
159         // result = true if animation has to be continued, false if animation stops
160         // maybe there are events for us in the queue !
161         if (frame)
162         {
163                 bNegativeEvent = m_negevent;
164                 bPositiveEvent = m_posevent;
165                 RemoveAllEvents();
166                 
167                 if (bPositiveEvent)
168                         m_flag |= ACT_FLAG_ACTIVE;
169                 
170                 if (bNegativeEvent)
171                 {
172                         if (!(m_flag & ACT_FLAG_ACTIVE))
173                                 return false;
174                         m_flag &= ~ACT_FLAG_ACTIVE;
175                 }
176         }
177         
178         /*      This action can only be attached to a deform object */
179         BL_DeformableGameObject *obj = (BL_DeformableGameObject*)GetParent();
180         float length = m_endframe - m_startframe;
181         
182         priority = m_priority;
183         
184         /* Determine pre-incrementation behaviour and set appropriate flags */
185         switch (m_playtype){
186         case ACT_ACTION_MOTION:
187                 if (bNegativeEvent){
188                         keepgoing=false;
189                         apply=false;
190                 };
191                 break;
192         case ACT_ACTION_FROM_PROP:
193                 if (bNegativeEvent){
194                         apply=false;
195                         keepgoing=false;
196                 }
197                 break;
198         case ACT_ACTION_LOOP_END:
199                 if (bPositiveEvent){
200                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
201                                 m_flag &= ~ACT_FLAG_KEYUP;
202                                 m_flag &= ~ACT_FLAG_REVERSE;
203                                 m_flag |= ACT_FLAG_LOCKINPUT;
204                                 m_localtime = m_startframe;
205                                 m_starttime = curtime;
206                         }
207                 }
208                 if (bNegativeEvent){
209                         m_flag |= ACT_FLAG_KEYUP;
210                 }
211                 break;
212         case ACT_ACTION_LOOP_STOP:
213                 if (bPositiveEvent){
214                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
215                                 m_flag &= ~ACT_FLAG_REVERSE;
216                                 m_flag &= ~ACT_FLAG_KEYUP;
217                                 m_flag |= ACT_FLAG_LOCKINPUT;
218                                 SetStartTime(curtime);
219                         }
220                 }
221                 if (bNegativeEvent){
222                         m_flag |= ACT_FLAG_KEYUP;
223                         m_flag &= ~ACT_FLAG_LOCKINPUT;
224                         keepgoing=false;
225                         apply=false;
226                 }
227                 break;
228         case ACT_ACTION_FLIPPER:
229                 if (bPositiveEvent){
230                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
231                                 m_flag &= ~ACT_FLAG_REVERSE;
232                                 m_flag |= ACT_FLAG_LOCKINPUT;
233                                 SetStartTime(curtime);
234                         }
235                 }
236                 else if (bNegativeEvent){
237                         m_flag |= ACT_FLAG_REVERSE;
238                         m_flag &= ~ACT_FLAG_LOCKINPUT;
239                         SetStartTime(curtime);
240                 }
241                 break;
242         case ACT_ACTION_PLAY:
243                 if (bPositiveEvent){
244                         if (!(m_flag & ACT_FLAG_LOCKINPUT)){
245                                 m_flag &= ~ACT_FLAG_REVERSE;
246                                 m_localtime = m_starttime;
247                                 m_starttime = curtime;
248                                 m_flag |= ACT_FLAG_LOCKINPUT;
249                         }
250                 }
251                 break;
252         default:
253                 break;
254         }
255         
256         /* Perform increment */
257         if (keepgoing){
258                 if (m_playtype == ACT_ACTION_MOTION){
259                         MT_Point3       newpos;
260                         MT_Point3       deltapos;
261                         
262                         newpos = obj->NodeGetWorldPosition();
263                         
264                         /* Find displacement */
265                         deltapos = newpos-m_lastpos;
266                         m_localtime += (length/m_stridelength) * deltapos.length();
267                         m_lastpos = newpos;
268                 }
269                 else{
270                         SetLocalTime(curtime);
271                 }
272         }
273         
274         /* Check if a wrapping response is needed */
275         if (length){
276                 if (m_localtime < m_startframe || m_localtime > m_endframe)
277                 {
278                         m_localtime = m_startframe + fmod(m_localtime, length);
279                         wrap = true;
280                 }
281         }
282         else
283                 m_localtime = m_startframe;
284         
285         /* Perform post-increment tasks */
286         switch (m_playtype){
287         case ACT_ACTION_FROM_PROP:
288                 {
289                         CValue* propval = GetParent()->GetProperty(m_propname);
290                         if (propval)
291                                 m_localtime = propval->GetNumber();
292                         
293                         if (bNegativeEvent){
294                                 keepgoing=false;
295                         }
296                 }
297                 break;
298         case ACT_ACTION_MOTION:
299                 break;
300         case ACT_ACTION_LOOP_STOP:
301                 break;
302         case ACT_ACTION_FLIPPER:
303                 if (wrap){
304                         if (!(m_flag & ACT_FLAG_REVERSE)){
305                                 m_localtime=m_endframe;
306                                 //keepgoing = false;
307                         }
308                         else {
309                                 m_localtime=m_startframe;
310                                 keepgoing = false;
311                         }
312                 }
313                 break;
314         case ACT_ACTION_LOOP_END:
315                 if (wrap){
316                         if (m_flag & ACT_FLAG_KEYUP){
317                                 keepgoing = false;
318                                 m_localtime = m_endframe;
319                                 m_flag &= ~ACT_FLAG_LOCKINPUT;
320                         }
321                         SetStartTime(curtime);
322                 }
323                 break;
324         case ACT_ACTION_PLAY:
325                 if (wrap){
326                         m_localtime = m_endframe;
327                         keepgoing = false;
328                         m_flag &= ~ACT_FLAG_LOCKINPUT;
329                 }
330                 break;
331         default:
332                 keepgoing = false;
333                 break;
334         }
335         
336         /* Set the property if its defined */
337         if (m_framepropname[0] != '\0') {
338                 CValue* propowner = GetParent();
339                 CValue* oldprop = propowner->GetProperty(m_framepropname);
340                 CValue* newval = new CFloatValue(m_localtime);
341                 if (oldprop) {
342                         oldprop->SetValue(newval);
343                 } else {
344                         propowner->SetProperty(m_framepropname, newval);
345                 }
346                 newval->Release();
347         }
348         
349         if (bNegativeEvent)
350                 m_blendframe=0.0f;
351         
352         /* Apply the pose if necessary*/
353         if (apply) {
354
355                 /* Priority test */
356                 if (obj->SetActiveAction(this, priority, curtime)){
357                         Key *key = obj->GetKey();
358
359                         if (!key) {
360                                 // this could happen if the mesh was changed in the middle of an action
361                                 // and the new mesh has no key, stop the action
362                                 keepgoing = false;
363                         }
364                         else {
365                                 ListBase tchanbase= {NULL, NULL};
366                         
367                                 if (m_blendin && m_blendframe==0.0f){
368                                         // this is the start of the blending, remember the startup shape
369                                         obj->GetShape(m_blendshape);
370                                         m_blendstart = curtime;
371                                 }
372                                 // only interested in shape channel
373                                 // XXX extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime);
374                 
375                                 if (0) { // XXX !execute_ipochannels(&tchanbase)) {
376                                         // no update, this is possible if action does not match the keys, stop the action
377                                         keepgoing = false;
378                                 } 
379                                 else {
380                                         // the key have changed, apply blending if needed
381                                         if (m_blendin && (m_blendframe<m_blendin)){
382                                                 newweight = (m_blendframe/(float)m_blendin);
383
384                                                 BlendShape(key, 1.0f - newweight);
385
386                                                 /* Increment current blending percentage */
387                                                 m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
388                                                 if (m_blendframe>m_blendin)
389                                                         m_blendframe = m_blendin;
390                                         }
391                                         m_lastUpdate = m_localtime;
392                                 }
393                                 BLI_freelistN(&tchanbase);
394                         }
395                 }
396                 else{
397                         m_blendframe = 0.0f;
398                 }
399         }
400         
401         if (!keepgoing){
402                 m_blendframe = 0.0f;
403         }
404         return keepgoing;
405 };
406
407 /* ------------------------------------------------------------------------- */
408 /* Python functions                                                          */
409 /* ------------------------------------------------------------------------- */
410
411 /* Integration hooks ------------------------------------------------------- */
412
413 PyTypeObject BL_ShapeActionActuator::Type = {
414 #if (PY_VERSION_HEX >= 0x02060000)
415         PyVarObject_HEAD_INIT(NULL, 0)
416 #else
417         /* python 2.5 and below */
418         PyObject_HEAD_INIT( NULL )  /* required py macro */
419         0,                          /* ob_size */
420 #endif
421                 "BL_ShapeActionActuator",
422                 sizeof(PyObjectPlus_Proxy),
423                 0,
424                 py_base_dealloc,
425                 0,
426                 0,
427                 0,
428                 0,
429                 py_base_repr,
430                 0,0,0,0,0,0,
431                 NULL, //py_base_getattro,
432                 NULL, //py_base_setattro,
433                 0,
434                 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
435                 0,0,0,0,0,0,0,
436                 Methods,
437                 0,
438                 0,
439                 &SCA_IActuator::Type
440 };
441
442
443 PyMethodDef BL_ShapeActionActuator::Methods[] = {
444         {"setAction", (PyCFunction) BL_ShapeActionActuator::sPySetAction, METH_VARARGS, (PY_METHODCHAR)SetAction_doc},
445         {"setStart", (PyCFunction) BL_ShapeActionActuator::sPySetStart, METH_VARARGS, (PY_METHODCHAR)SetStart_doc},
446         {"setEnd", (PyCFunction) BL_ShapeActionActuator::sPySetEnd, METH_VARARGS, (PY_METHODCHAR)SetEnd_doc},
447         {"setBlendin", (PyCFunction) BL_ShapeActionActuator::sPySetBlendin, METH_VARARGS, (PY_METHODCHAR)SetBlendin_doc},
448         {"setPriority", (PyCFunction) BL_ShapeActionActuator::sPySetPriority, METH_VARARGS, (PY_METHODCHAR)SetPriority_doc},
449         {"setFrame", (PyCFunction) BL_ShapeActionActuator::sPySetFrame, METH_VARARGS, (PY_METHODCHAR)SetFrame_doc},
450         {"setProperty", (PyCFunction) BL_ShapeActionActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
451         {"setFrameProperty", (PyCFunction) BL_ShapeActionActuator::sPySetFrameProperty, METH_VARARGS, (PY_METHODCHAR)SetFrameProperty_doc},
452         {"setBlendtime", (PyCFunction) BL_ShapeActionActuator::sPySetBlendtime, METH_VARARGS, (PY_METHODCHAR)SetBlendtime_doc},
453
454         {"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_NOARGS, (PY_METHODCHAR)GetAction_doc},
455         {"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_NOARGS, (PY_METHODCHAR)GetStart_doc},
456         {"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_NOARGS, (PY_METHODCHAR)GetEnd_doc},
457         {"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_NOARGS, (PY_METHODCHAR)GetBlendin_doc},
458         {"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_NOARGS, (PY_METHODCHAR)GetPriority_doc},
459         {"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_NOARGS, (PY_METHODCHAR)GetFrame_doc},
460         {"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_NOARGS, (PY_METHODCHAR)GetProperty_doc},
461         {"getFrameProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetFrameProperty, METH_NOARGS, (PY_METHODCHAR)GetFrameProperty_doc},
462         {"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_NOARGS, (PY_METHODCHAR)GetType_doc}, 
463         {"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_NOARGS, (PY_METHODCHAR)SetType_doc},
464         {NULL,NULL} //Sentinel
465 };
466
467 PyAttributeDef BL_ShapeActionActuator::Attributes[] = {
468         KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ShapeActionActuator, m_startframe),
469         KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ShapeActionActuator, m_endframe),
470         KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendin),
471         KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ShapeActionActuator, pyattr_get_action, pyattr_set_action),
472         KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ShapeActionActuator, m_priority),
473         KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ShapeActionActuator, m_localtime, CheckFrame),
474         KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ShapeActionActuator, m_propname),
475         KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ShapeActionActuator, m_framepropname),
476         KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendframe, CheckBlendTime),
477         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType),
478         { NULL }        //Sentinel
479 };
480
481 /*     setStart                                                              */
482 const char BL_ShapeActionActuator::GetAction_doc[] = 
483 "getAction()\n"
484 "\tReturns a string containing the name of the current action.\n";
485
486 PyObject* BL_ShapeActionActuator::PyGetAction() {
487         ShowDeprecationWarning("getAction()", "the action property");
488         if (m_action){
489                 return PyUnicode_FromString(m_action->id.name+2);
490         }
491         Py_RETURN_NONE;
492 }
493
494 /*     getProperty                                                             */
495 const char BL_ShapeActionActuator::GetProperty_doc[] = 
496 "getProperty()\n"
497 "\tReturns the name of the property to be used in FromProp mode.\n";
498
499 PyObject* BL_ShapeActionActuator::PyGetProperty() {
500         ShowDeprecationWarning("getProperty()", "the property property");
501         PyObject *result;
502         
503         result = Py_BuildValue("s", (const char *)m_propname);
504         
505         return result;
506 }
507
508 /*     getFrame                                                              */
509 const char BL_ShapeActionActuator::GetFrame_doc[] = 
510 "getFrame()\n"
511 "\tReturns the current frame number.\n";
512
513 PyObject* BL_ShapeActionActuator::PyGetFrame() {
514         ShowDeprecationWarning("getFrame()", "the frame property");
515         PyObject *result;
516         
517         result = Py_BuildValue("f", m_localtime);
518         
519         return result;
520 }
521
522 /*     getEnd                                                                */
523 const char BL_ShapeActionActuator::GetEnd_doc[] = 
524 "getEnd()\n"
525 "\tReturns the last frame of the action.\n";
526
527 PyObject* BL_ShapeActionActuator::PyGetEnd() {
528         ShowDeprecationWarning("getEnd()", "the end property");
529         PyObject *result;
530         
531         result = Py_BuildValue("f", m_endframe);
532         
533         return result;
534 }
535
536 /*     getStart                                                              */
537 const char BL_ShapeActionActuator::GetStart_doc[] = 
538 "getStart()\n"
539 "\tReturns the starting frame of the action.\n";
540
541 PyObject* BL_ShapeActionActuator::PyGetStart() {
542         ShowDeprecationWarning("getStart()", "the start property");
543         PyObject *result;
544         
545         result = Py_BuildValue("f", m_startframe);
546         
547         return result;
548 }
549
550 /*     getBlendin                                                            */
551 const char BL_ShapeActionActuator::GetBlendin_doc[] = 
552 "getBlendin()\n"
553 "\tReturns the number of interpolation animation frames to be\n"
554 "\tgenerated when this actuator is triggered.\n";
555
556 PyObject* BL_ShapeActionActuator::PyGetBlendin() {
557         ShowDeprecationWarning("getBlendin()", "the blendin property");
558         PyObject *result;
559         
560         result = Py_BuildValue("f", m_blendin);
561         
562         return result;
563 }
564
565 /*     getPriority                                                           */
566 const char BL_ShapeActionActuator::GetPriority_doc[] = 
567 "getPriority()\n"
568 "\tReturns the priority for this actuator.  Actuators with lower\n"
569 "\tPriority numbers will override actuators with higher numbers.\n";
570
571 PyObject* BL_ShapeActionActuator::PyGetPriority() {
572         ShowDeprecationWarning("getPriority()", "the priority property");
573         PyObject *result;
574         
575         result = Py_BuildValue("i", m_priority);
576         
577         return result;
578 }
579
580 /*     setAction                                                             */
581 const char BL_ShapeActionActuator::SetAction_doc[] = 
582 "setAction(action, (reset))\n"
583 "\t - action    : The name of the action to set as the current action.\n"
584 "\t               Should be an action with Shape channels.\n"
585 "\t - reset     : Optional parameter indicating whether to reset the\n"
586 "\t               blend timer or not.  A value of 1 indicates that the\n"
587 "\t               timer should be reset.  A value of 0 will leave it\n"
588 "\t               unchanged.  If reset is not specified, the timer will"
589 "\t                   be reset.\n";
590
591 PyObject* BL_ShapeActionActuator::PySetAction(PyObject* args) {
592         ShowDeprecationWarning("setAction()", "the action property");
593         char *string;
594         int     reset = 1;
595
596         if (PyArg_ParseTuple(args,"s|i:setAction",&string, &reset))
597         {
598                 bAction *action;
599                 
600                 action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string));
601                 
602                 if (!action){
603                         /* NOTE!  Throw an exception or something */
604                         //                      printf ("setAction failed: Action not found\n", string);
605                 }
606                 else{
607                         m_action=action;
608                         if (reset)
609                                 m_blendframe = 0.f;
610                 }
611         }
612         else {
613                 return NULL;
614         }
615         
616         Py_RETURN_NONE;
617 }
618
619 /*     setStart                                                              */
620 const char BL_ShapeActionActuator::SetStart_doc[] = 
621 "setStart(start)\n"
622 "\t - start     : Specifies the starting frame of the animation.\n";
623
624 PyObject* BL_ShapeActionActuator::PySetStart(PyObject* args) {
625         ShowDeprecationWarning("setStart()", "the start property");
626         float start;
627         
628         if (PyArg_ParseTuple(args,"f:setStart",&start))
629         {
630                 m_startframe = start;
631         }
632         else {
633                 return NULL;
634         }
635         
636         Py_RETURN_NONE;
637 }
638
639 /*     setEnd                                                                */
640 const char BL_ShapeActionActuator::SetEnd_doc[] = 
641 "setEnd(end)\n"
642 "\t - end       : Specifies the ending frame of the animation.\n";
643
644 PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* args) {
645         ShowDeprecationWarning("setEnd()", "the end property");
646         float end;
647         
648         if (PyArg_ParseTuple(args,"f:setEnd",&end))
649         {
650                 m_endframe = end;
651         }
652         else {
653                 return NULL;
654         }
655         
656         Py_RETURN_NONE;
657 }
658
659 /*     setBlendin                                                            */
660 const char BL_ShapeActionActuator::SetBlendin_doc[] = 
661 "setBlendin(blendin)\n"
662 "\t - blendin   : Specifies the number of frames of animation to generate\n"
663 "\t               when making transitions between actions.\n";
664
665 PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* args) {
666         ShowDeprecationWarning("setBlendin()", "the blendin property");
667         float blendin;
668         
669         if (PyArg_ParseTuple(args,"f:setBlendin",&blendin))
670         {
671                 m_blendin = blendin;
672         }
673         else {
674                 return NULL;
675         }
676         
677         Py_RETURN_NONE;
678 }
679
680 /*     setBlendtime                                                          */
681 const char BL_ShapeActionActuator::SetBlendtime_doc[] = 
682 "setBlendtime(blendtime)\n"
683 "\t - blendtime : Allows the script to directly modify the internal timer\n"
684 "\t               used when generating transitions between actions.  This\n"
685 "\t               parameter must be in the range from 0.0 to 1.0.\n";
686
687 PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* args) {
688         ShowDeprecationWarning("setBlendtime()", "the blendTime property");
689         float blendframe;
690         
691         if (PyArg_ParseTuple(args,"f:setBlendtime",&blendframe))
692         {
693                 m_blendframe = blendframe * m_blendin;
694                 if (m_blendframe<0.f)
695                         m_blendframe = 0.f;
696                 if (m_blendframe>m_blendin)
697                         m_blendframe = m_blendin;
698         }
699         else {
700                 return NULL;
701         }
702         
703         Py_RETURN_NONE;
704 }
705
706 /*     setPriority                                                           */
707 const char BL_ShapeActionActuator::SetPriority_doc[] = 
708 "setPriority(priority)\n"
709 "\t - priority  : Specifies the new priority.  Actuators will lower\n"
710 "\t               priority numbers will override actuators with higher\n"
711 "\t               numbers.\n";
712
713 PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* args) {
714         ShowDeprecationWarning("setPriority()", "the priority property");
715         int priority;
716         
717         if (PyArg_ParseTuple(args,"i:setPriority",&priority))
718         {
719                 m_priority = priority;
720         }
721         else {
722                 return NULL;
723         }
724         
725         Py_RETURN_NONE;
726 }
727
728 /*     getProperty                                                             */
729 const char BL_ShapeActionActuator::GetFrameProperty_doc[] = 
730 "getFrameProperty()\n"
731 "\tReturns the name of the property, that is set to the current frame number.\n";
732
733 PyObject* BL_ShapeActionActuator::PyGetFrameProperty() {
734         ShowDeprecationWarning("getFrameProperty()", "the frameProperty property");
735         PyObject *result;
736         
737         result = Py_BuildValue("s", (const char *)m_framepropname);
738         
739         return result;
740 }
741
742
743 /*     setFrame                                                              */
744 const char BL_ShapeActionActuator::SetFrame_doc[] = 
745 "setFrame(frame)\n"
746 "\t - frame     : Specifies the new current frame for the animation\n";
747
748 PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* args) {
749         ShowDeprecationWarning("setFrame()", "the frame property");
750         float frame;
751         
752         if (PyArg_ParseTuple(args,"f:setFrame",&frame))
753         {
754                 m_localtime = frame;
755                 if (m_localtime<m_startframe)
756                         m_localtime=m_startframe;
757                 else if (m_localtime>m_endframe)
758                         m_localtime=m_endframe;
759         }
760         else {
761                 return NULL;
762         }
763         
764         Py_RETURN_NONE;
765 }
766
767 /*     setProperty                                                           */
768 const char BL_ShapeActionActuator::SetProperty_doc[] = 
769 "setProperty(prop)\n"
770 "\t - prop      : A string specifying the property name to be used in\n"
771 "\t               FromProp playback mode.\n";
772
773 PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* args) {
774         ShowDeprecationWarning("setProperty()", "the property property");
775         char *string;
776         
777         if (PyArg_ParseTuple(args,"s:setProperty",&string))
778         {
779                 m_propname = string;
780         }
781         else {
782                 return NULL;
783         }
784         
785         Py_RETURN_NONE;
786 }
787
788 /*     setFrameProperty                                                          */
789 const char BL_ShapeActionActuator::SetFrameProperty_doc[] = 
790 "setFrameProperty(prop)\n"
791 "\t - prop      : A string specifying the property of the frame set up update.\n";
792
793 PyObject* BL_ShapeActionActuator::PySetFrameProperty(PyObject* args) {
794         ShowDeprecationWarning("setFrameProperty()", "the frameProperty property");
795         char *string;
796         
797         if (PyArg_ParseTuple(args,"s:setFrameProperty",&string))
798         {
799                 m_framepropname = string;
800         }
801         else {
802                 return NULL;
803         }
804         
805         Py_RETURN_NONE;
806 }
807
808 /* getType */
809 const char BL_ShapeActionActuator::GetType_doc[] =
810 "getType()\n"
811 "\tReturns the operation mode of the actuator.\n";
812 PyObject* BL_ShapeActionActuator::PyGetType() {
813         ShowDeprecationWarning("getType()", "the type property");
814     return Py_BuildValue("h", m_playtype);
815 }
816
817 /* setType */
818 const char BL_ShapeActionActuator::SetType_doc[] =
819 "setType(mode)\n"
820 "\t - mode: Play (0), Flipper (2), LoopStop (3), LoopEnd (4) or Property (6)\n"
821 "\tSet the operation mode of the actuator.\n";
822 PyObject* BL_ShapeActionActuator::PySetType(PyObject* args) {
823         ShowDeprecationWarning("setType()", "the type property");
824         short typeArg;
825                                                                                                              
826     if (!PyArg_ParseTuple(args, "h:setType", &typeArg)) {
827         return NULL;
828     }
829
830         switch (typeArg) {
831         case ACT_ACTION_PLAY:
832         case ACT_ACTION_FLIPPER:
833         case ACT_ACTION_LOOP_STOP:
834         case ACT_ACTION_LOOP_END:
835         case ACT_ACTION_FROM_PROP:
836                 m_playtype = typeArg;
837                 break;
838         default:
839                 printf("Invalid type for action actuator: %d\n", typeArg); /* error */
840     }
841         
842     Py_RETURN_NONE;
843 }
844
845 PyObject* BL_ShapeActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
846 {
847         BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
848         return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : "");
849 }
850
851 int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
852 {
853         BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
854         /* exact copy of BL_ActionActuator's function from here down */
855         if (!PyUnicode_Check(value))
856         {
857                 PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action");
858                 return PY_SET_ATTR_FAIL;
859         }
860
861         bAction *action= NULL;
862         STR_String val = _PyUnicode_AsString(value);
863         
864         if (val != "")
865         {
866                 action= (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(val);
867                 if (action==NULL)
868                 {
869                         PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, action not found!");
870                         return PY_SET_ATTR_FAIL;
871                 }
872         }
873         
874         self->SetAction(action);
875         return PY_SET_ATTR_SUCCESS;
876
877 }