Added function name to many of the PyArg_ParseTuple calls in gameengine
[blender.git] / source / gameengine / Ketsji / KX_ObjectActuator.cpp
1 /**
2  * Do translation/rotation actions
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL 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.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #include "KX_ObjectActuator.h"
33 #include "KX_GameObject.h"
34 #include "KX_IPhysicsController.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 /* ------------------------------------------------------------------------- */
41 /* Native functions                                                          */
42 /* ------------------------------------------------------------------------- */
43
44 KX_ObjectActuator::
45 KX_ObjectActuator(
46         SCA_IObject* gameobj,
47         const MT_Vector3& force,
48         const MT_Vector3& torque,
49         const MT_Vector3& dloc,
50         const MT_Vector3& drot,
51         const MT_Vector3& linV,
52         const MT_Vector3& angV,
53         const short damping,
54         const KX_LocalFlags& flag,
55         PyTypeObject* T
56 ) : 
57         SCA_IActuator(gameobj,T),
58         m_force(force),
59         m_torque(torque),
60         m_dloc(dloc),
61         m_drot(drot),
62         m_linear_velocity(linV),
63         m_angular_velocity(angV),
64         m_linear_length2(0.0),
65         m_current_linear_factor(0.0),
66         m_current_angular_factor(0.0),
67         m_damping(damping),
68         m_previous_error(0.0,0.0,0.0),
69         m_error_accumulator(0.0,0.0,0.0),
70         m_bitLocalFlag (flag),
71         m_active_combined_velocity (false),
72         m_linear_damping_active(false),
73         m_angular_damping_active(false)
74 {
75         if (m_bitLocalFlag.ServoControl)
76         {
77                 // in servo motion, the force is local if the target velocity is local
78                 m_bitLocalFlag.Force = m_bitLocalFlag.LinearVelocity;
79         }
80         UpdateFuzzyFlags();
81 }
82
83 bool KX_ObjectActuator::Update()
84 {
85         
86         bool bNegativeEvent = IsNegativeEvent();
87         RemoveAllEvents();
88                 
89         KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent()); 
90
91         if (bNegativeEvent) {
92                 // If we previously set the linear velocity we now have to inform
93                 // the physics controller that we no longer wish to apply it and that
94                 // it should reconcile the externally set velocity with it's 
95                 // own velocity.
96                 if (m_active_combined_velocity) {
97                         if (parent)
98                                 parent->ResolveCombinedVelocities(
99                                                 m_linear_velocity,
100                                                 m_angular_velocity,
101                                                 (m_bitLocalFlag.LinearVelocity) != 0,
102                                                 (m_bitLocalFlag.AngularVelocity) != 0
103                                         );
104                         m_active_combined_velocity = false;
105                 } 
106                 m_linear_damping_active = false;
107                 m_angular_damping_active = false;
108                 m_error_accumulator.setValue(0.0,0.0,0.0);
109                 m_previous_error.setValue(0.0,0.0,0.0);
110                 return false; 
111
112         } else if (parent)
113         {
114                 if (m_bitLocalFlag.ServoControl) 
115                 {
116                         // In this mode, we try to reach a target speed using force
117                         // As we don't know the friction, we must implement a generic 
118                         // servo control to achieve the speed in a configurable
119                         // v = current velocity
120                         // V = target velocity
121                         // e = V-v = speed error
122                         // dt = time interval since previous update
123                         // I = sum(e(t)*dt)
124                         // dv = e(t) - e(t-1)
125                         // KP, KD, KI : coefficient
126                         // F = KP*e+KI*I+KD*dv
127                         MT_Scalar mass = parent->GetMass();
128                         if (mass < MT_EPSILON)
129                                 return false;
130                         MT_Vector3 v = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
131                         MT_Vector3 e = m_linear_velocity - v;
132                         MT_Vector3 dv = e - m_previous_error;
133                         MT_Vector3 I = m_error_accumulator + e;
134
135                         m_force = m_torque.x()*e+m_torque.y()*I+m_torque.z()*dv;
136                         // to automatically adapt the PID coefficient to mass;
137                         m_force *= mass;
138                         if (m_bitLocalFlag.Torque) 
139                         {
140                                 if (m_force[0] > m_dloc[0])
141                                 {
142                                         m_force[0] = m_dloc[0];
143                                         I[0] = m_error_accumulator[0];
144                                 } else if (m_force[0] < m_drot[0])
145                                 {
146                                         m_force[0] = m_drot[0];
147                                         I[0] = m_error_accumulator[0];
148                                 }
149                         }
150                         if (m_bitLocalFlag.DLoc) 
151                         {
152                                 if (m_force[1] > m_dloc[1])
153                                 {
154                                         m_force[1] = m_dloc[1];
155                                         I[1] = m_error_accumulator[1];
156                                 } else if (m_force[1] < m_drot[1])
157                                 {
158                                         m_force[1] = m_drot[1];
159                                         I[1] = m_error_accumulator[1];
160                                 }
161                         }
162                         if (m_bitLocalFlag.DRot) 
163                         {
164                                 if (m_force[2] > m_dloc[2])
165                                 {
166                                         m_force[2] = m_dloc[2];
167                                         I[2] = m_error_accumulator[2];
168                                 } else if (m_force[2] < m_drot[2])
169                                 {
170                                         m_force[2] = m_drot[2];
171                                         I[2] = m_error_accumulator[2];
172                                 }
173                         }
174                         m_previous_error = e;
175                         m_error_accumulator = I;
176                         parent->ApplyForce(m_force,(m_bitLocalFlag.LinearVelocity) != 0);
177                 } else
178                 {
179                         if (!m_bitLocalFlag.ZeroForce)
180                         {
181                                 parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
182                         }
183                         if (!m_bitLocalFlag.ZeroTorque)
184                         {
185                                 parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
186                         }
187                         if (!m_bitLocalFlag.ZeroDLoc)
188                         {
189                                 parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
190                         }
191                         if (!m_bitLocalFlag.ZeroDRot)
192                         {
193                                 parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
194                         }
195                         if (!m_bitLocalFlag.ZeroLinearVelocity)
196                         {
197                                 if (m_bitLocalFlag.AddOrSetLinV) {
198                                         parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
199                                 } else {
200                                         m_active_combined_velocity = true;
201                                         if (m_damping > 0) {
202                                                 MT_Vector3 linV;
203                                                 if (!m_linear_damping_active) {
204                                                         // delta and the start speed (depends on the existing speed in that direction)
205                                                         linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
206                                                         // keep only the projection along the desired direction
207                                                         m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2;
208                                                         m_linear_damping_active = true;
209                                                 }
210                                                 if (m_current_linear_factor < 1.0)
211                                                         m_current_linear_factor += 1.0/m_damping;
212                                                 if (m_current_linear_factor > 1.0)
213                                                         m_current_linear_factor = 1.0;
214                                                 linV = m_current_linear_factor * m_linear_velocity;
215                                                 parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0);
216                                         } else {
217                                                 parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
218                                         }
219                                 }
220                         }
221                         if (!m_bitLocalFlag.ZeroAngularVelocity)
222                         {
223                                 m_active_combined_velocity = true;
224                                 if (m_damping > 0) {
225                                         MT_Vector3 angV;
226                                         if (!m_angular_damping_active) {
227                                                 // delta and the start speed (depends on the existing speed in that direction)
228                                                 angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
229                                                 // keep only the projection along the desired direction
230                                                 m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2;
231                                                 m_angular_damping_active = true;
232                                         }
233                                         if (m_current_angular_factor < 1.0)
234                                                 m_current_angular_factor += 1.0/m_damping;
235                                         if (m_current_angular_factor > 1.0)
236                                                 m_current_angular_factor = 1.0;
237                                         angV = m_current_angular_factor * m_angular_velocity;
238                                         parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0);
239                                 } else {
240                                         parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
241                                 }
242                         }
243                 }
244                 
245         }
246         return true;
247 }
248
249
250
251 CValue* KX_ObjectActuator::GetReplica()
252 {
253         KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName());
254         replica->ProcessReplica();
255
256         // this will copy properties and so on...
257         CValue::AddDataToReplica(replica);
258
259         return replica;
260 }
261
262
263
264 /* some 'standard' utilities... */
265 bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
266 {
267         bool res = false;
268         res = (type > KX_OBJECT_ACT_NODEF) && (type < KX_OBJECT_ACT_MAX);
269         return res;
270 }
271
272
273
274 /* ------------------------------------------------------------------------- */
275 /* Python functions                                                          */
276 /* ------------------------------------------------------------------------- */
277
278 /* Integration hooks ------------------------------------------------------- */
279 PyTypeObject KX_ObjectActuator::Type = {
280         PyObject_HEAD_INIT(NULL)
281         0,
282         "KX_ObjectActuator",
283         sizeof(KX_ObjectActuator),
284         0,
285         PyDestructor,
286         0,
287         0,
288         0,
289         0,
290         py_base_repr,
291         0,0,0,0,0,0,
292         py_base_getattro,
293         py_base_setattro,
294         0,0,0,0,0,0,0,0,0,
295         Methods
296 };
297
298 PyParentObject KX_ObjectActuator::Parents[] = {
299         &KX_ObjectActuator::Type,
300         &SCA_IActuator::Type,
301         &SCA_ILogicBrick::Type,
302         &CValue::Type,
303         NULL
304 };
305
306 PyMethodDef KX_ObjectActuator::Methods[] = {
307         {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_NOARGS},
308         {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
309         {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_NOARGS},
310         {"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS},
311         {"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_NOARGS},
312         {"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS},
313         {"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_NOARGS},
314         {"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS},
315         {"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_NOARGS},
316         {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
317         {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_NOARGS},
318         {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
319         {"setDamping", (PyCFunction) KX_ObjectActuator::sPySetDamping, METH_VARARGS},
320         {"getDamping", (PyCFunction) KX_ObjectActuator::sPyGetDamping, METH_NOARGS},
321         {"setForceLimitX", (PyCFunction) KX_ObjectActuator::sPySetForceLimitX, METH_VARARGS},
322         {"getForceLimitX", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitX, METH_NOARGS},
323         {"setForceLimitY", (PyCFunction) KX_ObjectActuator::sPySetForceLimitY, METH_VARARGS},
324         {"getForceLimitY", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitY, METH_NOARGS},
325         {"setForceLimitZ", (PyCFunction) KX_ObjectActuator::sPySetForceLimitZ, METH_VARARGS},
326         {"getForceLimitZ", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitZ, METH_NOARGS},
327         {"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_NOARGS},
328         {"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS},
329
330
331
332         {NULL,NULL} //Sentinel
333 };
334
335 PyAttributeDef KX_ObjectActuator::Attributes[] = {
336         { NULL }        //Sentinel
337 };
338
339 PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) {
340         py_getattro_up(SCA_IActuator);
341 };
342
343 /* 1. set ------------------------------------------------------------------ */
344 /* Removed! */
345
346 /* 2. getForce                                                               */
347 PyObject* KX_ObjectActuator::PyGetForce(PyObject* self)
348 {
349         PyObject *retVal = PyList_New(4);
350
351         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0]));
352         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1]));
353         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2]));
354         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
355         
356         return retVal;
357 }
358 /* 3. setForce                                                               */
359 PyObject* KX_ObjectActuator::PySetForce(PyObject* self, 
360                                                                                 PyObject* args, 
361                                                                                 PyObject* kwds)
362 {
363         float vecArg[3];
364         int bToggle = 0;
365         if (!PyArg_ParseTuple(args, "fffi:setForce", &vecArg[0], &vecArg[1], 
366                                                   &vecArg[2], &bToggle)) {
367                 return NULL;
368         }
369         m_force.setValue(vecArg);
370         m_bitLocalFlag.Force = PyArgToBool(bToggle);
371         UpdateFuzzyFlags();
372         Py_RETURN_NONE;
373 }
374
375 /* 4. getTorque                                                              */
376 PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self)
377 {
378         PyObject *retVal = PyList_New(4);
379
380         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
381         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
382         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
383         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
384         
385         return retVal;
386 }
387 /* 5. setTorque                                                              */
388 PyObject* KX_ObjectActuator::PySetTorque(PyObject* self, 
389                                                                                  PyObject* args, 
390                                                                                  PyObject* kwds)
391 {
392         float vecArg[3];
393         int bToggle = 0;
394         if (!PyArg_ParseTuple(args, "fffi:setTorque", &vecArg[0], &vecArg[1], 
395                                                   &vecArg[2], &bToggle)) {
396                 return NULL;
397         }
398         m_torque.setValue(vecArg);
399         m_bitLocalFlag.Torque = PyArgToBool(bToggle);
400         UpdateFuzzyFlags();
401         Py_RETURN_NONE;
402 }
403
404 /* 6. getDLoc                                                                */
405 PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self)
406 {
407         PyObject *retVal = PyList_New(4);
408
409         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
410         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
411         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
412         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
413         
414         return retVal;
415 }
416 /* 7. setDLoc                                                                */
417 PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self, 
418                                                                            PyObject* args, 
419                                                                            PyObject* kwds)
420 {
421         float vecArg[3];
422         int bToggle = 0;
423         if(!PyArg_ParseTuple(args, "fffi:setDLoc", &vecArg[0], &vecArg[1], 
424                                                  &vecArg[2], &bToggle)) {
425                 return NULL;
426         }
427         m_dloc.setValue(vecArg);
428         m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
429         UpdateFuzzyFlags();
430         Py_RETURN_NONE;
431 }
432
433 /* 8. getDRot                                                                */
434 PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self)
435 {
436         PyObject *retVal = PyList_New(4);
437
438         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
439         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1]));
440         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2]));
441         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
442         
443         return retVal;
444 }
445 /* 9. setDRot                                                                */
446 PyObject* KX_ObjectActuator::PySetDRot(PyObject* self, 
447                                                                            PyObject* args, 
448                                                                            PyObject* kwds)
449 {
450         float vecArg[3];
451         int bToggle = 0;
452         if (!PyArg_ParseTuple(args, "fffi:setDRot", &vecArg[0], &vecArg[1], 
453                                                   &vecArg[2], &bToggle)) {
454                 return NULL;
455         }
456         m_drot.setValue(vecArg);
457         m_bitLocalFlag.DRot = PyArgToBool(bToggle);
458         UpdateFuzzyFlags();
459         Py_RETURN_NONE;
460 }
461
462 /* 10. getLinearVelocity                                                 */
463 PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self) {
464         PyObject *retVal = PyList_New(4);
465
466         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
467         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
468         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
469         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
470         
471         return retVal;
472 }
473
474 /* 11. setLinearVelocity                                                 */
475 PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self, 
476                                                                                                  PyObject* args, 
477                                                                                                  PyObject* kwds) {
478         float vecArg[3];
479         int bToggle = 0;
480         if (!PyArg_ParseTuple(args, "fffi:setLinearVelocity", &vecArg[0], &vecArg[1], 
481                                                   &vecArg[2], &bToggle)) {
482                 return NULL;
483         }
484         m_linear_velocity.setValue(vecArg);
485         m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
486         UpdateFuzzyFlags();
487         Py_RETURN_NONE;
488 }
489
490
491 /* 12. getAngularVelocity                                                */
492 PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self) {
493         PyObject *retVal = PyList_New(4);
494
495         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
496         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
497         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
498         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
499         
500         return retVal;
501 }
502 /* 13. setAngularVelocity                                                */
503 PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self, 
504                                                                                                   PyObject* args, 
505                                                                                                   PyObject* kwds) {
506         float vecArg[3];
507         int bToggle = 0;
508         if (!PyArg_ParseTuple(args, "fffi:setAngularVelocity", &vecArg[0], &vecArg[1], 
509                                                   &vecArg[2], &bToggle)) {
510                 return NULL;
511         }
512         m_angular_velocity.setValue(vecArg);
513         m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
514         UpdateFuzzyFlags();
515         Py_RETURN_NONE;
516 }
517
518 /* 13. setDamping                                                */
519 PyObject* KX_ObjectActuator::PySetDamping(PyObject* self, 
520                                                                                   PyObject* args, 
521                                                                                   PyObject* kwds) {
522         int damping = 0;
523         if (!PyArg_ParseTuple(args, "i:setDamping", &damping) || damping < 0 || damping > 1000) {
524                 return NULL;
525         }
526         m_damping = damping;
527         Py_RETURN_NONE;
528 }
529
530 /* 13. getVelocityDamping                                                */
531 PyObject* KX_ObjectActuator::PyGetDamping(PyObject* self) {
532         return Py_BuildValue("i",m_damping);
533 }
534 /* 6. getForceLimitX                                                                */
535 PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self)
536 {
537         PyObject *retVal = PyList_New(3);
538
539         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
540         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[0]));
541         PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque));
542         
543         return retVal;
544 }
545 /* 7. setForceLimitX                                                         */
546 PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self, 
547                                                                                           PyObject* args, 
548                                                                                           PyObject* kwds)
549 {
550         float vecArg[2];
551         int bToggle = 0;
552         if(!PyArg_ParseTuple(args, "ffi:setForceLimitX", &vecArg[0], &vecArg[1], &bToggle)) {
553                 return NULL;
554         }
555         m_drot[0] = vecArg[0];
556         m_dloc[0] = vecArg[1];
557         m_bitLocalFlag.Torque = PyArgToBool(bToggle);
558         Py_RETURN_NONE;
559 }
560
561 /* 6. getForceLimitY                                                                */
562 PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self)
563 {
564         PyObject *retVal = PyList_New(3);
565
566         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[1]));
567         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
568         PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc));
569         
570         return retVal;
571 }
572 /* 7. setForceLimitY                                                                */
573 PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self, 
574                                                                                           PyObject* args, 
575                                                                                           PyObject* kwds)
576 {
577         float vecArg[2];
578         int bToggle = 0;
579         if(!PyArg_ParseTuple(args, "ffi:setForceLimitY", &vecArg[0], &vecArg[1], &bToggle)) {
580                 return NULL;
581         }
582         m_drot[1] = vecArg[0];
583         m_dloc[1] = vecArg[1];
584         m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
585         Py_RETURN_NONE;
586 }
587
588 /* 6. getForceLimitZ                                                                */
589 PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self)
590 {
591         PyObject *retVal = PyList_New(3);
592
593         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[2]));
594         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[2]));
595         PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot));
596         
597         return retVal;
598 }
599 /* 7. setForceLimitZ                                                                */
600 PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self, 
601                                                                                           PyObject* args, 
602                                                                                           PyObject* kwds)
603 {
604         float vecArg[2];
605         int bToggle = 0;
606         if(!PyArg_ParseTuple(args, "ffi:setForceLimitZ", &vecArg[0], &vecArg[1], &bToggle)) {
607                 return NULL;
608         }
609         m_drot[2] = vecArg[0];
610         m_dloc[2] = vecArg[1];
611         m_bitLocalFlag.DRot = PyArgToBool(bToggle);
612         Py_RETURN_NONE;
613 }
614
615 /* 4. getPID                                                              */
616 PyObject* KX_ObjectActuator::PyGetPID(PyObject* self)
617 {
618         PyObject *retVal = PyList_New(3);
619
620         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
621         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
622         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
623         
624         return retVal;
625 }
626 /* 5. setPID                                                              */
627 PyObject* KX_ObjectActuator::PySetPID(PyObject* self, 
628                                                                           PyObject* args, 
629                                                                           PyObject* kwds)
630 {
631         float vecArg[3];
632         if (!PyArg_ParseTuple(args, "fff:setPID", &vecArg[0], &vecArg[1], &vecArg[2])) {
633                 return NULL;
634         }
635         m_torque.setValue(vecArg);
636         Py_RETURN_NONE;
637 }
638
639
640
641
642
643 /* eof */