Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[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         PyVarObject_HEAD_INIT(NULL, 0)
415         "BL_ShapeActionActuator",
416         sizeof(PyObjectPlus_Proxy),
417         0,
418         py_base_dealloc,
419         0,
420         0,
421         0,
422         0,
423         py_base_repr,
424         0,0,0,0,0,0,0,0,0,
425         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
426         0,0,0,0,0,0,0,
427         Methods,
428         0,
429         0,
430         &SCA_IActuator::Type,
431         0,0,0,0,0,0,
432         py_base_new
433 };
434
435
436 PyMethodDef BL_ShapeActionActuator::Methods[] = {
437         {"setAction", (PyCFunction) BL_ShapeActionActuator::sPySetAction, METH_VARARGS, (const char *)SetAction_doc},
438         {"setStart", (PyCFunction) BL_ShapeActionActuator::sPySetStart, METH_VARARGS, (const char *)SetStart_doc},
439         {"setEnd", (PyCFunction) BL_ShapeActionActuator::sPySetEnd, METH_VARARGS, (const char *)SetEnd_doc},
440         {"setBlendin", (PyCFunction) BL_ShapeActionActuator::sPySetBlendin, METH_VARARGS, (const char *)SetBlendin_doc},
441         {"setPriority", (PyCFunction) BL_ShapeActionActuator::sPySetPriority, METH_VARARGS, (const char *)SetPriority_doc},
442         {"setFrame", (PyCFunction) BL_ShapeActionActuator::sPySetFrame, METH_VARARGS, (const char *)SetFrame_doc},
443         {"setProperty", (PyCFunction) BL_ShapeActionActuator::sPySetProperty, METH_VARARGS, (const char *)SetProperty_doc},
444         {"setFrameProperty", (PyCFunction) BL_ShapeActionActuator::sPySetFrameProperty, METH_VARARGS, (const char *)SetFrameProperty_doc},
445         {"setBlendtime", (PyCFunction) BL_ShapeActionActuator::sPySetBlendtime, METH_VARARGS, (const char *)SetBlendtime_doc},
446
447         {"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_NOARGS, (const char *)GetAction_doc},
448         {"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_NOARGS, (const char *)GetStart_doc},
449         {"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_NOARGS, (const char *)GetEnd_doc},
450         {"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_NOARGS, (const char *)GetBlendin_doc},
451         {"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_NOARGS, (const char *)GetPriority_doc},
452         {"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_NOARGS, (const char *)GetFrame_doc},
453         {"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_NOARGS, (const char *)GetProperty_doc},
454         {"getFrameProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetFrameProperty, METH_NOARGS, (const char *)GetFrameProperty_doc},
455         {"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_NOARGS, (const char *)GetType_doc},  
456         {"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_NOARGS, (const char *)SetType_doc},
457         {NULL,NULL} //Sentinel
458 };
459
460 PyAttributeDef BL_ShapeActionActuator::Attributes[] = {
461         KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ShapeActionActuator, m_startframe),
462         KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ShapeActionActuator, m_endframe),
463         KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendin),
464         KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ShapeActionActuator, pyattr_get_action, pyattr_set_action),
465         KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ShapeActionActuator, m_priority),
466         KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ShapeActionActuator, m_localtime, CheckFrame),
467         KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ShapeActionActuator, m_propname),
468         KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ShapeActionActuator, m_framepropname),
469         KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendframe, CheckBlendTime),
470         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType),
471         { NULL }        //Sentinel
472 };
473
474 /*     setStart                                                              */
475 const char BL_ShapeActionActuator::GetAction_doc[] = 
476 "getAction()\n"
477 "\tReturns a string containing the name of the current action.\n";
478
479 PyObject* BL_ShapeActionActuator::PyGetAction() {
480         ShowDeprecationWarning("getAction()", "the action property");
481         if (m_action){
482                 return PyUnicode_FromString(m_action->id.name+2);
483         }
484         Py_RETURN_NONE;
485 }
486
487 /*     getProperty                                                             */
488 const char BL_ShapeActionActuator::GetProperty_doc[] = 
489 "getProperty()\n"
490 "\tReturns the name of the property to be used in FromProp mode.\n";
491
492 PyObject* BL_ShapeActionActuator::PyGetProperty() {
493         ShowDeprecationWarning("getProperty()", "the property property");
494         PyObject *result;
495         
496         result = Py_BuildValue("s", (const char *)m_propname);
497         
498         return result;
499 }
500
501 /*     getFrame                                                              */
502 const char BL_ShapeActionActuator::GetFrame_doc[] = 
503 "getFrame()\n"
504 "\tReturns the current frame number.\n";
505
506 PyObject* BL_ShapeActionActuator::PyGetFrame() {
507         ShowDeprecationWarning("getFrame()", "the frame property");
508         PyObject *result;
509         
510         result = Py_BuildValue("f", m_localtime);
511         
512         return result;
513 }
514
515 /*     getEnd                                                                */
516 const char BL_ShapeActionActuator::GetEnd_doc[] = 
517 "getEnd()\n"
518 "\tReturns the last frame of the action.\n";
519
520 PyObject* BL_ShapeActionActuator::PyGetEnd() {
521         ShowDeprecationWarning("getEnd()", "the end property");
522         PyObject *result;
523         
524         result = Py_BuildValue("f", m_endframe);
525         
526         return result;
527 }
528
529 /*     getStart                                                              */
530 const char BL_ShapeActionActuator::GetStart_doc[] = 
531 "getStart()\n"
532 "\tReturns the starting frame of the action.\n";
533
534 PyObject* BL_ShapeActionActuator::PyGetStart() {
535         ShowDeprecationWarning("getStart()", "the start property");
536         PyObject *result;
537         
538         result = Py_BuildValue("f", m_startframe);
539         
540         return result;
541 }
542
543 /*     getBlendin                                                            */
544 const char BL_ShapeActionActuator::GetBlendin_doc[] = 
545 "getBlendin()\n"
546 "\tReturns the number of interpolation animation frames to be\n"
547 "\tgenerated when this actuator is triggered.\n";
548
549 PyObject* BL_ShapeActionActuator::PyGetBlendin() {
550         ShowDeprecationWarning("getBlendin()", "the blendin property");
551         PyObject *result;
552         
553         result = Py_BuildValue("f", m_blendin);
554         
555         return result;
556 }
557
558 /*     getPriority                                                           */
559 const char BL_ShapeActionActuator::GetPriority_doc[] = 
560 "getPriority()\n"
561 "\tReturns the priority for this actuator.  Actuators with lower\n"
562 "\tPriority numbers will override actuators with higher numbers.\n";
563
564 PyObject* BL_ShapeActionActuator::PyGetPriority() {
565         ShowDeprecationWarning("getPriority()", "the priority property");
566         PyObject *result;
567         
568         result = Py_BuildValue("i", m_priority);
569         
570         return result;
571 }
572
573 /*     setAction                                                             */
574 const char BL_ShapeActionActuator::SetAction_doc[] = 
575 "setAction(action, (reset))\n"
576 "\t - action    : The name of the action to set as the current action.\n"
577 "\t               Should be an action with Shape channels.\n"
578 "\t - reset     : Optional parameter indicating whether to reset the\n"
579 "\t               blend timer or not.  A value of 1 indicates that the\n"
580 "\t               timer should be reset.  A value of 0 will leave it\n"
581 "\t               unchanged.  If reset is not specified, the timer will"
582 "\t                   be reset.\n";
583
584 PyObject* BL_ShapeActionActuator::PySetAction(PyObject* args) {
585         ShowDeprecationWarning("setAction()", "the action property");
586         char *string;
587         int     reset = 1;
588
589         if (PyArg_ParseTuple(args,"s|i:setAction",&string, &reset))
590         {
591                 bAction *action;
592                 
593                 action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string));
594                 
595                 if (!action){
596                         /* NOTE!  Throw an exception or something */
597                         //                      printf ("setAction failed: Action not found\n", string);
598                 }
599                 else{
600                         m_action=action;
601                         if (reset)
602                                 m_blendframe = 0.f;
603                 }
604         }
605         else {
606                 return NULL;
607         }
608         
609         Py_RETURN_NONE;
610 }
611
612 /*     setStart                                                              */
613 const char BL_ShapeActionActuator::SetStart_doc[] = 
614 "setStart(start)\n"
615 "\t - start     : Specifies the starting frame of the animation.\n";
616
617 PyObject* BL_ShapeActionActuator::PySetStart(PyObject* args) {
618         ShowDeprecationWarning("setStart()", "the start property");
619         float start;
620         
621         if (PyArg_ParseTuple(args,"f:setStart",&start))
622         {
623                 m_startframe = start;
624         }
625         else {
626                 return NULL;
627         }
628         
629         Py_RETURN_NONE;
630 }
631
632 /*     setEnd                                                                */
633 const char BL_ShapeActionActuator::SetEnd_doc[] = 
634 "setEnd(end)\n"
635 "\t - end       : Specifies the ending frame of the animation.\n";
636
637 PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* args) {
638         ShowDeprecationWarning("setEnd()", "the end property");
639         float end;
640         
641         if (PyArg_ParseTuple(args,"f:setEnd",&end))
642         {
643                 m_endframe = end;
644         }
645         else {
646                 return NULL;
647         }
648         
649         Py_RETURN_NONE;
650 }
651
652 /*     setBlendin                                                            */
653 const char BL_ShapeActionActuator::SetBlendin_doc[] = 
654 "setBlendin(blendin)\n"
655 "\t - blendin   : Specifies the number of frames of animation to generate\n"
656 "\t               when making transitions between actions.\n";
657
658 PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* args) {
659         ShowDeprecationWarning("setBlendin()", "the blendin property");
660         float blendin;
661         
662         if (PyArg_ParseTuple(args,"f:setBlendin",&blendin))
663         {
664                 m_blendin = blendin;
665         }
666         else {
667                 return NULL;
668         }
669         
670         Py_RETURN_NONE;
671 }
672
673 /*     setBlendtime                                                          */
674 const char BL_ShapeActionActuator::SetBlendtime_doc[] = 
675 "setBlendtime(blendtime)\n"
676 "\t - blendtime : Allows the script to directly modify the internal timer\n"
677 "\t               used when generating transitions between actions.  This\n"
678 "\t               parameter must be in the range from 0.0 to 1.0.\n";
679
680 PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* args) {
681         ShowDeprecationWarning("setBlendtime()", "the blendTime property");
682         float blendframe;
683         
684         if (PyArg_ParseTuple(args,"f:setBlendtime",&blendframe))
685         {
686                 m_blendframe = blendframe * m_blendin;
687                 if (m_blendframe<0.f)
688                         m_blendframe = 0.f;
689                 if (m_blendframe>m_blendin)
690                         m_blendframe = m_blendin;
691         }
692         else {
693                 return NULL;
694         }
695         
696         Py_RETURN_NONE;
697 }
698
699 /*     setPriority                                                           */
700 const char BL_ShapeActionActuator::SetPriority_doc[] = 
701 "setPriority(priority)\n"
702 "\t - priority  : Specifies the new priority.  Actuators will lower\n"
703 "\t               priority numbers will override actuators with higher\n"
704 "\t               numbers.\n";
705
706 PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* args) {
707         ShowDeprecationWarning("setPriority()", "the priority property");
708         int priority;
709         
710         if (PyArg_ParseTuple(args,"i:setPriority",&priority))
711         {
712                 m_priority = priority;
713         }
714         else {
715                 return NULL;
716         }
717         
718         Py_RETURN_NONE;
719 }
720
721 /*     getProperty                                                             */
722 const char BL_ShapeActionActuator::GetFrameProperty_doc[] = 
723 "getFrameProperty()\n"
724 "\tReturns the name of the property, that is set to the current frame number.\n";
725
726 PyObject* BL_ShapeActionActuator::PyGetFrameProperty() {
727         ShowDeprecationWarning("getFrameProperty()", "the frameProperty property");
728         PyObject *result;
729         
730         result = Py_BuildValue("s", (const char *)m_framepropname);
731         
732         return result;
733 }
734
735
736 /*     setFrame                                                              */
737 const char BL_ShapeActionActuator::SetFrame_doc[] = 
738 "setFrame(frame)\n"
739 "\t - frame     : Specifies the new current frame for the animation\n";
740
741 PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* args) {
742         ShowDeprecationWarning("setFrame()", "the frame property");
743         float frame;
744         
745         if (PyArg_ParseTuple(args,"f:setFrame",&frame))
746         {
747                 m_localtime = frame;
748                 if (m_localtime<m_startframe)
749                         m_localtime=m_startframe;
750                 else if (m_localtime>m_endframe)
751                         m_localtime=m_endframe;
752         }
753         else {
754                 return NULL;
755         }
756         
757         Py_RETURN_NONE;
758 }
759
760 /*     setProperty                                                           */
761 const char BL_ShapeActionActuator::SetProperty_doc[] = 
762 "setProperty(prop)\n"
763 "\t - prop      : A string specifying the property name to be used in\n"
764 "\t               FromProp playback mode.\n";
765
766 PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* args) {
767         ShowDeprecationWarning("setProperty()", "the property property");
768         char *string;
769         
770         if (PyArg_ParseTuple(args,"s:setProperty",&string))
771         {
772                 m_propname = string;
773         }
774         else {
775                 return NULL;
776         }
777         
778         Py_RETURN_NONE;
779 }
780
781 /*     setFrameProperty                                                          */
782 const char BL_ShapeActionActuator::SetFrameProperty_doc[] = 
783 "setFrameProperty(prop)\n"
784 "\t - prop      : A string specifying the property of the frame set up update.\n";
785
786 PyObject* BL_ShapeActionActuator::PySetFrameProperty(PyObject* args) {
787         ShowDeprecationWarning("setFrameProperty()", "the frameProperty property");
788         char *string;
789         
790         if (PyArg_ParseTuple(args,"s:setFrameProperty",&string))
791         {
792                 m_framepropname = string;
793         }
794         else {
795                 return NULL;
796         }
797         
798         Py_RETURN_NONE;
799 }
800
801 /* getType */
802 const char BL_ShapeActionActuator::GetType_doc[] =
803 "getType()\n"
804 "\tReturns the operation mode of the actuator.\n";
805 PyObject* BL_ShapeActionActuator::PyGetType() {
806         ShowDeprecationWarning("getType()", "the type property");
807     return Py_BuildValue("h", m_playtype);
808 }
809
810 /* setType */
811 const char BL_ShapeActionActuator::SetType_doc[] =
812 "setType(mode)\n"
813 "\t - mode: Play (0), Flipper (2), LoopStop (3), LoopEnd (4) or Property (6)\n"
814 "\tSet the operation mode of the actuator.\n";
815 PyObject* BL_ShapeActionActuator::PySetType(PyObject* args) {
816         ShowDeprecationWarning("setType()", "the type property");
817         short typeArg;
818                                                                                                              
819     if (!PyArg_ParseTuple(args, "h:setType", &typeArg)) {
820         return NULL;
821     }
822
823         switch (typeArg) {
824         case ACT_ACTION_PLAY:
825         case ACT_ACTION_FLIPPER:
826         case ACT_ACTION_LOOP_STOP:
827         case ACT_ACTION_LOOP_END:
828         case ACT_ACTION_FROM_PROP:
829                 m_playtype = typeArg;
830                 break;
831         default:
832                 printf("Invalid type for action actuator: %d\n", typeArg); /* error */
833     }
834         
835     Py_RETURN_NONE;
836 }
837
838 PyObject* BL_ShapeActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
839 {
840         BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
841         return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : "");
842 }
843
844 int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
845 {
846         BL_ShapeActionActuator* self= static_cast<BL_ShapeActionActuator*>(self_v);
847         /* exact copy of BL_ActionActuator's function from here down */
848         if (!PyUnicode_Check(value))
849         {
850                 PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action");
851                 return PY_SET_ATTR_FAIL;
852         }
853
854         bAction *action= NULL;
855         STR_String val = _PyUnicode_AsString(value);
856         
857         if (val != "")
858         {
859                 action= (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(val);
860                 if (action==NULL)
861                 {
862                         PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, action not found!");
863                         return PY_SET_ATTR_FAIL;
864                 }
865         }
866         
867         self->SetAction(action);
868         return PY_SET_ATTR_SUCCESS;
869
870 }