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