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