Making the C++ stuff work for the MipsPro 7.3 compiler.
[blender-staging.git] / source / gameengine / Ketsji / KX_IpoActuator.cpp
1 /**
2  * Do Ipo stuff
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #if defined (__sgi)
36 #include <math.h>
37 #else
38 #include <cmath>
39 #endif
40  
41 #include "KX_IpoActuator.h"
42 #include "KX_GameObject.h"
43
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif
47
48 #include "KX_KetsjiEngine.h"
49
50 /* ------------------------------------------------------------------------- */
51 /* Type strings                                                              */
52 /* ------------------------------------------------------------------------- */
53
54 STR_String KX_IpoActuator::S_KX_ACT_IPO_PLAY_STRING      = "Play";
55 STR_String KX_IpoActuator::S_KX_ACT_IPO_PINGPONG_STRING  = "PingPong";
56 STR_String KX_IpoActuator::S_KX_ACT_IPO_FLIPPER_STRING   = "Flipper";
57 STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPSTOP_STRING  = "LoopStop";
58 STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPEND_STRING   = "LoopEnd";
59 STR_String KX_IpoActuator::S_KX_ACT_IPO_KEY2KEY_STRING   = "Key2key";
60 STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp";
61
62 /* ------------------------------------------------------------------------- */
63 /* Native functions                                                          */
64 /* ------------------------------------------------------------------------- */
65 /** Another poltergeist? This seems to be a very transient class... */
66 class CIpoAction : public CAction
67 {
68         float           m_curtime;
69         bool            m_resurse;
70         KX_GameObject* m_gameobj;
71         bool        m_ipo_as_force;
72         bool        m_force_ipo_local;
73
74 public:
75         CIpoAction(KX_GameObject* gameobj,
76                 float curtime,
77                 bool recurse, 
78                 bool ipo_as_force,
79                 bool force_ipo_local) :
80           m_curtime(curtime) ,
81           m_resurse(recurse),
82           m_gameobj(gameobj),
83           m_ipo_as_force(ipo_as_force),
84           m_force_ipo_local(force_ipo_local) 
85           {
86                   /* intentionally empty */
87           };
88
89         virtual void Execute() const
90         {
91                 m_gameobj->UpdateIPO(
92                         m_curtime, 
93                         m_resurse, 
94                         m_ipo_as_force, 
95                         m_force_ipo_local);
96         };
97
98 };
99
100 KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
101                                                            const STR_String& propname,
102                                                            float starttime,
103                                                            float endtime,
104                                                            bool recurse,
105                                                            int acttype,
106                                                            bool ipo_as_force,
107                                                            bool force_ipo_local,
108                                                            PyTypeObject* T) 
109         : SCA_IActuator(gameobj,T),
110         m_bNegativeEvent(false),
111         m_startframe (starttime),
112         m_endframe(endtime),
113         m_recurse(recurse),
114         m_localtime(starttime),
115         m_starttime(-1.0),
116         m_direction(1),
117         m_propname(propname),
118         m_ipo_as_force(ipo_as_force),
119         m_force_ipo_local(force_ipo_local),
120         m_type((IpoActType)acttype)
121 {
122         // intentionally empty
123 }
124
125 void KX_IpoActuator::SetStart(float starttime) 
126
127         m_startframe=starttime;
128 }
129
130 void KX_IpoActuator::SetEnd(float endtime) 
131
132         m_endframe=endtime;
133 }
134
135 bool KX_IpoActuator::ClampLocalTime()
136 {
137         if (m_startframe < m_endframe)
138         {
139                 if (m_localtime < m_startframe)
140                 {
141                         m_localtime = m_startframe;
142                         return true;
143                 } 
144                 else if (m_localtime > m_endframe)
145                 {
146                         m_localtime = m_endframe;
147                         return true;
148                 }
149         } else {
150                 if (m_localtime > m_startframe)
151                 {
152                         m_localtime = m_startframe;
153                         return true;
154                 }
155                 else if (m_localtime < m_endframe)
156                 {
157                         m_localtime = m_endframe;
158                         return true;
159                 }
160         }
161         return false;
162 }
163
164 void KX_IpoActuator::SetStartTime(float curtime)
165 {
166         float direction = m_startframe < m_endframe ? 1.0 : -1.0;
167         
168         if (m_direction > 0)
169                 m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_FIXED_FRAME_PER_SEC;
170         else
171                 m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_FIXED_FRAME_PER_SEC;
172 }
173
174 void KX_IpoActuator::SetLocalTime(float curtime)
175 {
176         float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC;
177         
178         if (m_endframe < m_startframe)
179                 delta_time = -delta_time;
180
181         if (m_direction > 0)
182                 m_localtime = m_startframe + delta_time;
183         else
184                 m_localtime = m_endframe - delta_time;
185 }
186
187 bool KX_IpoActuator::Update(double curtime, bool frame)
188 {
189         // result = true if animation has to be continued, false if animation stops
190         // maybe there are events for us in the queue !
191         bool bNegativeEvent = false;
192         int numevents = m_events.size();
193
194         for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
195         {
196                 i--;
197                 if ((*i)->GetNumber() == 0.0f)
198                         bNegativeEvent = true;
199                 
200                 (*i)->Release();
201                 m_events.pop_back();
202         }
203
204         if (bNegativeEvent)
205         {
206                 RemoveAllEvents();
207         }
208         
209
210         double  start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0);
211
212         bool result=true;
213         if (m_starttime < 0.0)
214                 m_starttime = curtime;
215         
216         switch (m_type)
217         {
218                 
219         case KX_ACT_IPO_PLAY:
220         {
221                 // Check if playing forwards.  result = ! finished
222                 if (start_smaller_then_end > 0.0)
223                         result = (m_localtime < m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
224                 else
225                         result = (m_localtime > m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
226                 
227                 if (result)
228                 {
229                         SetLocalTime(curtime);
230                 
231                         /* Perform clamping */
232                         ClampLocalTime();
233                         
234                         CIpoAction ipoaction(
235                                 (KX_GameObject*)GetParent(), 
236                                 m_localtime, 
237                                 m_recurse, 
238                                 m_ipo_as_force,
239                                 m_force_ipo_local);
240                         GetParent()->Execute(ipoaction);
241                 } else
242                 {
243                         m_localtime=m_startframe;
244                         m_starttime=curtime;
245                         m_direction=1;
246                 }
247                 break;
248         }
249         case KX_ACT_IPO_PINGPONG:
250         {
251                 result = true;
252                 if (bNegativeEvent && ((m_localtime == m_startframe )|| (m_localtime == m_endframe)))
253                         result = false;
254                 else
255                         SetLocalTime(curtime);
256                         
257                 if (ClampLocalTime())
258                 {
259                         result = false;
260                         m_direction = -m_direction;
261                 }
262                 
263                 CIpoAction ipoaction(
264                         (KX_GameObject*) GetParent(),
265                         m_localtime,
266                         m_recurse, 
267                         m_ipo_as_force,
268                         m_force_ipo_local);
269                 GetParent()->Execute(ipoaction);
270                 break;
271         }
272         case KX_ACT_IPO_FLIPPER:
273         {
274                 result = true;
275                 if (numevents)
276                 {
277                         if (bNegativeEvent)
278                                 m_direction = -1;
279                         else
280                                 m_direction = 1;
281                         SetStartTime(curtime);
282                 }
283                 
284                 SetLocalTime(curtime);
285                 
286                 if (ClampLocalTime() && m_localtime == m_startframe)
287                         result = false;
288                         
289                 CIpoAction ipoaction(
290                         (KX_GameObject*) GetParent(),
291                         m_localtime,
292                         m_recurse,
293                         m_ipo_as_force,
294                         m_force_ipo_local);
295                 GetParent()->Execute(ipoaction);
296                 break;
297         }
298
299         case KX_ACT_IPO_LOOPSTOP:
300         {
301                 if (numevents)
302                 {
303                         if (bNegativeEvent)
304                         {
305                                 result = false;
306                                 m_bNegativeEvent = false;
307                                 numevents = 0;
308                         }
309                         SetStartTime(curtime);
310                 } // fall through to loopend, and quit the ipo animation immediatly 
311         }
312         case KX_ACT_IPO_LOOPEND:
313         {
314                 if (numevents){
315                         if (bNegativeEvent){
316                                 m_bNegativeEvent = true;
317                         }
318                 }
319                 
320                 if (bNegativeEvent && m_localtime == m_startframe){
321                         result = false;
322                 } 
323                 else
324                 {
325                         if (m_localtime*start_smaller_then_end < m_endframe*start_smaller_then_end)
326                         {
327                                 SetLocalTime(curtime);
328                         }
329                         else{
330                                 if (!m_bNegativeEvent){
331                                         /* Perform wraparound */
332                                         SetLocalTime(curtime);
333                                         m_localtime = m_startframe + fmod(m_localtime, m_startframe - m_endframe);
334                                         SetStartTime(curtime);
335                                 }
336                                 else
337                                 {       
338                                         /* Perform clamping */
339                                         m_localtime=m_endframe;
340                                         result = false;
341                                         m_bNegativeEvent = false;
342                                 }
343                         }
344                 }
345                 
346                 CIpoAction ipoaction(
347                         (KX_GameObject*) GetParent(),
348                         m_localtime,
349                         m_recurse,
350                         m_ipo_as_force,
351                         m_force_ipo_local);
352                 GetParent()->Execute(ipoaction);
353                 break;
354         }
355         
356         case KX_ACT_IPO_KEY2KEY:
357         {
358                 // not implemented yet
359                 result = false;
360                 break;
361         }
362         
363         case KX_ACT_IPO_FROM_PROP:
364         {
365                 result = !bNegativeEvent;
366
367                 CValue* propval = GetParent()->GetProperty(m_propname);
368                 if (propval)
369                 {
370                         float target = propval->GetNumber(); 
371                         float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC;
372                         if (target > m_localtime)
373                         {
374                                 m_localtime += delta_time;
375                                 if (m_localtime > target)
376                                         m_localtime = target;
377                         }
378                         else
379                         {
380                                 m_localtime -= delta_time;
381                                 if (m_localtime < target)
382                                         m_localtime = target;
383                         }
384         
385                         CIpoAction ipoaction(
386                                 (KX_GameObject*) GetParent(),
387                                 m_localtime,
388                                 m_recurse,
389                                 m_ipo_as_force,
390                                 m_force_ipo_local);
391                         GetParent()->Execute(ipoaction);
392
393                 } else
394                 {
395                         result = false;
396                 }
397                 break;
398         }
399                 
400         default:
401                 result = false;
402         }
403         
404         if (!result && m_type != KX_ACT_IPO_LOOPSTOP)
405                 m_starttime = -1.0;
406
407         return result;
408 }
409
410 KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) {
411         IpoActType res = KX_ACT_IPO_NODEF;
412
413         if (modename == S_KX_ACT_IPO_PLAY_STRING) { 
414                 res = KX_ACT_IPO_PLAY;
415         } else if (modename == S_KX_ACT_IPO_PINGPONG_STRING) {
416                 res = KX_ACT_IPO_PINGPONG;
417         } else if (modename == S_KX_ACT_IPO_FLIPPER_STRING) {
418                 res = KX_ACT_IPO_FLIPPER;
419         } else if (modename == S_KX_ACT_IPO_LOOPSTOP_STRING) {
420                 res = KX_ACT_IPO_LOOPSTOP;
421         } else if (modename == S_KX_ACT_IPO_LOOPEND_STRING) {
422                 res = KX_ACT_IPO_LOOPEND;
423         } else if (modename == S_KX_ACT_IPO_KEY2KEY_STRING) {
424                 res = KX_ACT_IPO_KEY2KEY;
425         } else if (modename == S_KX_ACT_IPO_FROM_PROP_STRING) {
426                 res = KX_ACT_IPO_FROM_PROP;
427         }
428
429         return res;
430 }
431
432 /* ------------------------------------------------------------------------- */
433 /* Python functions                                                          */
434 /* ------------------------------------------------------------------------- */
435
436
437
438 /* Integration hooks ------------------------------------------------------- */
439 PyTypeObject KX_IpoActuator::Type = {
440         PyObject_HEAD_INIT(&PyType_Type)
441         0,
442         "KX_IpoActuator",
443         sizeof(KX_IpoActuator),
444         0,
445         PyDestructor,
446         0,
447         __getattr,
448         __setattr,
449         0, //&MyPyCompare,
450         __repr,
451         0, //&cvalue_as_number,
452         0,
453         0,
454         0,
455         0
456 };
457
458 PyParentObject KX_IpoActuator::Parents[] = {
459         &KX_IpoActuator::Type,
460         &SCA_IActuator::Type,
461         &SCA_ILogicBrick::Type,
462         &CValue::Type,
463         NULL
464 };
465
466 PyMethodDef KX_IpoActuator::Methods[] = {
467         {"set", (PyCFunction) KX_IpoActuator::sPySet, 
468                 METH_VARARGS, Set_doc},
469         {"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty, 
470                 METH_VARARGS, SetProperty_doc},
471         {"setStart", (PyCFunction) KX_IpoActuator::sPySetStart, 
472                 METH_VARARGS, SetStart_doc},
473         {"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart, 
474                 METH_VARARGS, GetStart_doc},
475         {"setEnd", (PyCFunction) KX_IpoActuator::sPySetEnd, 
476                 METH_VARARGS, SetEnd_doc},
477         {"getEnd", (PyCFunction) KX_IpoActuator::sPyGetEnd, 
478                 METH_VARARGS, GetEnd_doc},
479         {"setIpoAsForce", (PyCFunction) KX_IpoActuator::sPySetIpoAsForce, 
480                 METH_VARARGS, SetIpoAsForce_doc},
481         {"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce, 
482                 METH_VARARGS, GetIpoAsForce_doc},
483         {"setType", (PyCFunction) KX_IpoActuator::sPySetType, 
484                 METH_VARARGS, SetType_doc},
485         {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, 
486                 METH_VARARGS, GetType_doc},     
487         {"setForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPySetForceIpoActsLocal,
488                 METH_VARARGS, SetForceIpoActsLocal_doc},
489         {"getForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPyGetForceIpoActsLocal,
490                 METH_VARARGS, GetForceIpoActsLocal_doc},
491         {NULL,NULL} //Sentinel
492 };
493
494 PyObject* KX_IpoActuator::_getattr(const STR_String& attr) {
495         _getattr_up(SCA_IActuator);
496 }
497
498
499
500 /* set --------------------------------------------------------------------- */
501 char KX_IpoActuator::Set_doc[] = 
502 "set(mode, startframe, endframe, force?)\n"
503 "\t - mode:       Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
504 "\t - startframe: first frame to use (int)\n"
505 "\t - endframe  : last frame to use (int)\n"
506 "\t - force?    : interpret this ipo as a force? (KX_TRUE, KX_FALSE)"
507 "\tSet the properties of the actuator.\n";
508 PyObject* KX_IpoActuator::PySet(PyObject* self, 
509                                                                 PyObject* args, 
510                                                                 PyObject* kwds) {
511         /* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND                 */
512         /* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe,            */
513         /* arg4 = force toggle                                                   */
514         char* mode;
515         int forceToggle;
516         IpoActType modenum;
517         int startFrame, stopFrame;
518         if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame, 
519                                                  &stopFrame, &forceToggle)) {
520                 return NULL;
521         }
522         modenum = string2mode(mode);
523         
524         switch (modenum) {
525         case KX_ACT_IPO_PLAY:
526         case KX_ACT_IPO_PINGPONG:
527         case KX_ACT_IPO_FLIPPER:
528         case KX_ACT_IPO_LOOPSTOP:
529         case KX_ACT_IPO_LOOPEND:
530                 m_type         = modenum;
531                 m_startframe    = startFrame;
532                 m_endframe      = stopFrame;
533                 m_ipo_as_force = PyArgToBool(forceToggle);
534                 break;
535         default:
536                 ; /* error */
537         }
538
539         Py_Return;
540 }
541
542 /* set property  ----------------------------------------------------------- */
543 char KX_IpoActuator::SetProperty_doc[] = 
544 "setProperty(propname)\n"
545 "\t - propname: name of the property (string)\n"
546 "\tSet the property to be used in FromProp mode.\n";
547 PyObject* KX_IpoActuator::PySetProperty(PyObject* self, 
548                                                                                 PyObject* args, 
549                                                                                 PyObject* kwds) {
550         /* mode is implicit here, but not supported yet... */
551         /* args: property */
552         char *propertyName;
553         if(!PyArg_ParseTuple(args, "s", &propertyName)) {
554                 return NULL;
555         }
556
557         m_propname = propertyName;
558         
559         Py_Return;
560 }
561
562 /* 4. setStart:                                                              */
563 char KX_IpoActuator::SetStart_doc[] = 
564 "setStart(frame)\n"
565 "\t - frame: first frame to use (int)\n"
566 "\tSet the frame from which the ipo starts playing.\n";
567 PyObject* KX_IpoActuator::PySetStart(PyObject* self, 
568                                                                          PyObject* args, 
569                                                                          PyObject* kwds) {
570         float startArg;
571         if(!PyArg_ParseTuple(args, "f", &startArg)) {
572                 return NULL;            
573         }
574         
575         m_startframe = startArg;
576
577         Py_Return;
578 }
579 /* 5. getStart:                                                              */
580 char KX_IpoActuator::GetStart_doc[] = 
581 "getStart()\n"
582 "\tReturns the frame from which the ipo starts playing.\n";
583 PyObject* KX_IpoActuator::PyGetStart(PyObject* self, 
584                                                                          PyObject* args, 
585                                                                          PyObject* kwds) {
586         return PyFloat_FromDouble(m_startframe);
587 }
588
589 /* 6. setEnd:                                                                */
590 char KX_IpoActuator::SetEnd_doc[] = 
591 "setEnd(frame)\n"
592 "\t - frame: last frame to use (int)\n"
593 "\tSet the frame at which the ipo stops playing.\n";
594 PyObject* KX_IpoActuator::PySetEnd(PyObject* self, 
595                                                                    PyObject* args, 
596                                                                    PyObject* kwds) {
597         float endArg;
598         if(!PyArg_ParseTuple(args, "f", &endArg)) {
599                 return NULL;            
600         }
601         
602         m_endframe = endArg;
603
604         Py_Return;
605 }
606 /* 7. getEnd:                                                                */
607 char KX_IpoActuator::GetEnd_doc[] = 
608 "getEnd()\n"
609 "\tReturns the frame at which the ipo stops playing.\n";
610 PyObject* KX_IpoActuator::PyGetEnd(PyObject* self, 
611                                                                    PyObject* args, 
612                                                                    PyObject* kwds) {
613         return PyFloat_FromDouble(m_endframe);
614 }
615
616 /* 6. setIpoAsForce:                                                           */
617 char KX_IpoActuator::SetIpoAsForce_doc[] = 
618 "setIpoAsForce(force?)\n"
619 "\t - force?    : interpret this ipo as a force? (KX_TRUE, KX_FALSE)\n"
620 "\tSet whether to interpret the ipo as a force rather than a displacement.\n";
621 PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self, 
622                                                                                   PyObject* args, 
623                                                                                   PyObject* kwds) { 
624         int boolArg;
625         
626         if (!PyArg_ParseTuple(args, "i", &boolArg)) {
627                 return NULL;
628         }
629
630         m_ipo_as_force = PyArgToBool(boolArg);
631         
632         Py_Return;      
633 }
634 /* 7. getIpoAsForce:                                                         */
635 char KX_IpoActuator::GetIpoAsForce_doc[] = 
636 "getIpoAsForce()\n"
637 "\tReturns whether to interpret the ipo as a force rather than a displacement.\n";
638 PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self, 
639                                                                                   PyObject* args, 
640                                                                                   PyObject* kwds) {
641         return BoolToPyArg(m_ipo_as_force);
642 }
643
644 /* 8. setType:                                                               */
645 char KX_IpoActuator::SetType_doc[] = 
646 "setType(mode)\n"
647 "\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
648 "\tSet the operation mode of the actuator.\n";
649 PyObject* KX_IpoActuator::PySetType(PyObject* self, 
650                                                                         PyObject* args, 
651                                                                         PyObject* kwds) {
652         int typeArg;
653         
654         if (!PyArg_ParseTuple(args, "i", &typeArg)) {
655                 return NULL;
656         }
657         
658         if ( (typeArg > KX_ACT_IPO_NODEF) 
659                  && (typeArg < KX_ACT_IPO_KEY2KEY) ) {
660                 m_type = (IpoActType) typeArg;
661         }
662         
663         Py_Return;
664 }
665 /* 9. getType:                                                               */
666 char KX_IpoActuator::GetType_doc[] = 
667 "getType()\n"
668 "\tReturns the operation mode of the actuator.\n";
669 PyObject* KX_IpoActuator::PyGetType(PyObject* self, 
670                                                                         PyObject* args, 
671                                                                         PyObject* kwds) {
672         return PyInt_FromLong(m_type);
673 }
674
675 /* 10. setForceIpoActsLocal:                                                 */
676 char KX_IpoActuator::SetForceIpoActsLocal_doc[] = 
677 "setForceIpoActsLocal(local?)\n"
678 "\t - local?    : Apply the ipo-as-force in the object's local\n"
679 "\t               coordinates? (KX_TRUE, KX_FALSE)\n"
680 "\tSet whether to apply the force in the object's local\n"
681 "\tcoordinates rather than the world global coordinates.\n";
682 PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self, 
683                                                                                          PyObject* args, 
684                                                                                      PyObject* kwds) { 
685         int boolArg;
686         
687         if (!PyArg_ParseTuple(args, "i", &boolArg)) {
688                 return NULL;
689         }
690
691         m_force_ipo_local = PyArgToBool(boolArg);
692         
693         Py_Return;      
694 }
695 /* 11. getForceIpoActsLocal:                                                */
696 char KX_IpoActuator::GetForceIpoActsLocal_doc[] = 
697 "getForceIpoActsLocal()\n"
698 "\tReturn whether to apply the force in the object's local\n"
699 "\tcoordinates rather than the world global coordinates.\n";
700 PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self, 
701                                                                                          PyObject* args, 
702                                                                                          PyObject* kwds) {
703         return BoolToPyArg(m_force_ipo_local);
704 }
705
706
707 /* eof */