BGE API cleanup: motion actuator. Apply patch from Moguri.
[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_PyMath.h" // For PyVecTo - should this include be put in PyObjectPlus?
35 #include "KX_IPhysicsController.h"
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 /* ------------------------------------------------------------------------- */
42 /* Native functions                                                          */
43 /* ------------------------------------------------------------------------- */
44
45 KX_ObjectActuator::
46 KX_ObjectActuator(
47         SCA_IObject* gameobj,
48         const MT_Vector3& force,
49         const MT_Vector3& torque,
50         const MT_Vector3& dloc,
51         const MT_Vector3& drot,
52         const MT_Vector3& linV,
53         const MT_Vector3& angV,
54         const short damping,
55         const KX_LocalFlags& flag,
56         PyTypeObject* T
57 ) : 
58         SCA_IActuator(gameobj,T),
59         m_force(force),
60         m_torque(torque),
61         m_dloc(dloc),
62         m_drot(drot),
63         m_linear_velocity(linV),
64         m_angular_velocity(angV),
65         m_linear_length2(0.0),
66         m_current_linear_factor(0.0),
67         m_current_angular_factor(0.0),
68         m_damping(damping),
69         m_previous_error(0.0,0.0,0.0),
70         m_error_accumulator(0.0,0.0,0.0),
71         m_bitLocalFlag (flag),
72         m_active_combined_velocity (false),
73         m_linear_damping_active(false),
74         m_angular_damping_active(false)
75 {
76         if (m_bitLocalFlag.ServoControl)
77         {
78                 // in servo motion, the force is local if the target velocity is local
79                 m_bitLocalFlag.Force = m_bitLocalFlag.LinearVelocity;
80
81                 m_pid = m_torque;
82         }
83
84         UpdateFuzzyFlags();
85 }
86
87 bool KX_ObjectActuator::Update()
88 {
89         
90         bool bNegativeEvent = IsNegativeEvent();
91         RemoveAllEvents();
92                 
93         KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent()); 
94
95         if (bNegativeEvent) {
96                 // If we previously set the linear velocity we now have to inform
97                 // the physics controller that we no longer wish to apply it and that
98                 // it should reconcile the externally set velocity with it's 
99                 // own velocity.
100                 if (m_active_combined_velocity) {
101                         if (parent)
102                                 parent->ResolveCombinedVelocities(
103                                                 m_linear_velocity,
104                                                 m_angular_velocity,
105                                                 (m_bitLocalFlag.LinearVelocity) != 0,
106                                                 (m_bitLocalFlag.AngularVelocity) != 0
107                                         );
108                         m_active_combined_velocity = false;
109                 } 
110                 m_linear_damping_active = false;
111                 m_angular_damping_active = false;
112                 m_error_accumulator.setValue(0.0,0.0,0.0);
113                 m_previous_error.setValue(0.0,0.0,0.0);
114                 return false; 
115
116         } else if (parent)
117         {
118                 if (m_bitLocalFlag.ServoControl) 
119                 {
120                         // In this mode, we try to reach a target speed using force
121                         // As we don't know the friction, we must implement a generic 
122                         // servo control to achieve the speed in a configurable
123                         // v = current velocity
124                         // V = target velocity
125                         // e = V-v = speed error
126                         // dt = time interval since previous update
127                         // I = sum(e(t)*dt)
128                         // dv = e(t) - e(t-1)
129                         // KP, KD, KI : coefficient
130                         // F = KP*e+KI*I+KD*dv
131                         MT_Scalar mass = parent->GetMass();
132                         if (mass < MT_EPSILON)
133                                 return false;
134                         MT_Vector3 v = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
135                         MT_Vector3 e = m_linear_velocity - v;
136                         MT_Vector3 dv = e - m_previous_error;
137                         MT_Vector3 I = m_error_accumulator + e;
138
139                         m_force = m_pid.x()*e+m_pid.y()*I+m_pid.z()*dv;
140                         // to automatically adapt the PID coefficient to mass;
141                         m_force *= mass;
142                         if (m_bitLocalFlag.Torque) 
143                         {
144                                 if (m_force[0] > m_dloc[0])
145                                 {
146                                         m_force[0] = m_dloc[0];
147                                         I[0] = m_error_accumulator[0];
148                                 } else if (m_force[0] < m_drot[0])
149                                 {
150                                         m_force[0] = m_drot[0];
151                                         I[0] = m_error_accumulator[0];
152                                 }
153                         }
154                         if (m_bitLocalFlag.DLoc) 
155                         {
156                                 if (m_force[1] > m_dloc[1])
157                                 {
158                                         m_force[1] = m_dloc[1];
159                                         I[1] = m_error_accumulator[1];
160                                 } else if (m_force[1] < m_drot[1])
161                                 {
162                                         m_force[1] = m_drot[1];
163                                         I[1] = m_error_accumulator[1];
164                                 }
165                         }
166                         if (m_bitLocalFlag.DRot) 
167                         {
168                                 if (m_force[2] > m_dloc[2])
169                                 {
170                                         m_force[2] = m_dloc[2];
171                                         I[2] = m_error_accumulator[2];
172                                 } else if (m_force[2] < m_drot[2])
173                                 {
174                                         m_force[2] = m_drot[2];
175                                         I[2] = m_error_accumulator[2];
176                                 }
177                         }
178                         m_previous_error = e;
179                         m_error_accumulator = I;
180                         parent->ApplyForce(m_force,(m_bitLocalFlag.LinearVelocity) != 0);
181                 } else
182                 {
183                         if (!m_bitLocalFlag.ZeroForce)
184                         {
185                                 parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
186                         }
187                         if (!m_bitLocalFlag.ZeroTorque)
188                         {
189                                 parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
190                         }
191                         if (!m_bitLocalFlag.ZeroDLoc)
192                         {
193                                 parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
194                         }
195                         if (!m_bitLocalFlag.ZeroDRot)
196                         {
197                                 parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
198                         }
199                         if (!m_bitLocalFlag.ZeroLinearVelocity)
200                         {
201                                 if (m_bitLocalFlag.AddOrSetLinV) {
202                                         parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
203                                 } else {
204                                         m_active_combined_velocity = true;
205                                         if (m_damping > 0) {
206                                                 MT_Vector3 linV;
207                                                 if (!m_linear_damping_active) {
208                                                         // delta and the start speed (depends on the existing speed in that direction)
209                                                         linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
210                                                         // keep only the projection along the desired direction
211                                                         m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2;
212                                                         m_linear_damping_active = true;
213                                                 }
214                                                 if (m_current_linear_factor < 1.0)
215                                                         m_current_linear_factor += 1.0/m_damping;
216                                                 if (m_current_linear_factor > 1.0)
217                                                         m_current_linear_factor = 1.0;
218                                                 linV = m_current_linear_factor * m_linear_velocity;
219                                                 parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0);
220                                         } else {
221                                                 parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
222                                         }
223                                 }
224                         }
225                         if (!m_bitLocalFlag.ZeroAngularVelocity)
226                         {
227                                 m_active_combined_velocity = true;
228                                 if (m_damping > 0) {
229                                         MT_Vector3 angV;
230                                         if (!m_angular_damping_active) {
231                                                 // delta and the start speed (depends on the existing speed in that direction)
232                                                 angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
233                                                 // keep only the projection along the desired direction
234                                                 m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2;
235                                                 m_angular_damping_active = true;
236                                         }
237                                         if (m_current_angular_factor < 1.0)
238                                                 m_current_angular_factor += 1.0/m_damping;
239                                         if (m_current_angular_factor > 1.0)
240                                                 m_current_angular_factor = 1.0;
241                                         angV = m_current_angular_factor * m_angular_velocity;
242                                         parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0);
243                                 } else {
244                                         parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
245                                 }
246                         }
247                 }
248                 
249         }
250         return true;
251 }
252
253
254
255 CValue* KX_ObjectActuator::GetReplica()
256 {
257         KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName());
258         replica->ProcessReplica();
259
260         return replica;
261 }
262
263
264
265 /* some 'standard' utilities... */
266 bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
267 {
268         bool res = false;
269         res = (type > KX_OBJECT_ACT_NODEF) && (type < KX_OBJECT_ACT_MAX);
270         return res;
271 }
272
273
274
275 /* ------------------------------------------------------------------------- */
276 /* Python functions                                                          */
277 /* ------------------------------------------------------------------------- */
278
279 /* Integration hooks ------------------------------------------------------- */
280 PyTypeObject KX_ObjectActuator::Type = {
281 #if (PY_VERSION_HEX >= 0x02060000)
282         PyVarObject_HEAD_INIT(NULL, 0)
283 #else
284         /* python 2.5 and below */
285         PyObject_HEAD_INIT( NULL )  /* required py macro */
286         0,                          /* ob_size */
287 #endif
288         "KX_ObjectActuator",
289         sizeof(PyObjectPlus_Proxy),
290         0,
291         py_base_dealloc,
292         0,
293         0,
294         0,
295         0,
296         py_base_repr,
297         0,0,0,0,0,0,
298         py_base_getattro,
299         py_base_setattro,
300         0,0,0,0,0,0,0,0,0,
301         Methods
302 };
303
304 PyParentObject KX_ObjectActuator::Parents[] = {
305         &KX_ObjectActuator::Type,
306         &SCA_IActuator::Type,
307         &SCA_ILogicBrick::Type,
308         &CValue::Type,
309         NULL
310 };
311
312 PyMethodDef KX_ObjectActuator::Methods[] = {
313         // Deprecated ----->
314         {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_NOARGS},
315         {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
316         {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_NOARGS},
317         {"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS},
318         {"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_NOARGS},
319         {"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS},
320         {"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_NOARGS},
321         {"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS},
322         {"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_NOARGS},
323         {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
324         {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_NOARGS},
325         {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
326         {"setDamping", (PyCFunction) KX_ObjectActuator::sPySetDamping, METH_VARARGS},
327         {"getDamping", (PyCFunction) KX_ObjectActuator::sPyGetDamping, METH_NOARGS},
328         {"setForceLimitX", (PyCFunction) KX_ObjectActuator::sPySetForceLimitX, METH_VARARGS},
329         {"getForceLimitX", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitX, METH_NOARGS},
330         {"setForceLimitY", (PyCFunction) KX_ObjectActuator::sPySetForceLimitY, METH_VARARGS},
331         {"getForceLimitY", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitY, METH_NOARGS},
332         {"setForceLimitZ", (PyCFunction) KX_ObjectActuator::sPySetForceLimitZ, METH_VARARGS},
333         {"getForceLimitZ", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitZ, METH_NOARGS},
334         {"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_NOARGS},
335         {"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS},
336
337         // <----- Deprecated
338
339         {NULL,NULL} //Sentinel
340 };
341
342 PyAttributeDef KX_ObjectActuator::Attributes[] = {
343         KX_PYATTRIBUTE_VECTOR_RW_CHECK("force", -1000, 1000, false, KX_ObjectActuator, m_force, PyUpdateFuzzyFlags),
344         KX_PYATTRIBUTE_BOOL_RW("useLocalForce", KX_ObjectActuator, m_bitLocalFlag.Force),
345         KX_PYATTRIBUTE_VECTOR_RW_CHECK("torque", -1000, 1000, false, KX_ObjectActuator, m_torque, PyUpdateFuzzyFlags),
346         KX_PYATTRIBUTE_BOOL_RW("useLocalTorque", KX_ObjectActuator, m_bitLocalFlag.Torque),
347         KX_PYATTRIBUTE_VECTOR_RW_CHECK("dLoc", -1000, 1000, false, KX_ObjectActuator, m_dloc, PyUpdateFuzzyFlags),
348         KX_PYATTRIBUTE_BOOL_RW("useLocalDLoc", KX_ObjectActuator, m_bitLocalFlag.DLoc),
349         KX_PYATTRIBUTE_VECTOR_RW_CHECK("dRot", -1000, 1000, false, KX_ObjectActuator, m_drot, PyUpdateFuzzyFlags),
350         KX_PYATTRIBUTE_BOOL_RW("useLocalDRot", KX_ObjectActuator, m_bitLocalFlag.DRot),
351         KX_PYATTRIBUTE_VECTOR_RW_CHECK("linV", -1000, 1000, false, KX_ObjectActuator, m_linear_velocity, PyUpdateFuzzyFlags),
352         KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity),
353         KX_PYATTRIBUTE_VECTOR_RW_CHECK("angV", -1000, 1000, false, KX_ObjectActuator, m_angular_velocity, PyUpdateFuzzyFlags),
354         KX_PYATTRIBUTE_BOOL_RW("useLocalAngV", KX_ObjectActuator, m_bitLocalFlag.AngularVelocity),
355         KX_PYATTRIBUTE_SHORT_RW("damping", 0, 1000, false, KX_ObjectActuator, m_damping),
356         KX_PYATTRIBUTE_RW_FUNCTION("forceLimitX", KX_ObjectActuator, pyattr_get_forceLimitX, pyattr_set_forceLimitX),
357         KX_PYATTRIBUTE_RW_FUNCTION("forceLimitY", KX_ObjectActuator, pyattr_get_forceLimitY, pyattr_set_forceLimitY),
358         KX_PYATTRIBUTE_RW_FUNCTION("forceLimitZ", KX_ObjectActuator, pyattr_get_forceLimitZ, pyattr_set_forceLimitZ),
359         KX_PYATTRIBUTE_VECTOR_RW_CHECK("pid", -100, 200, true, KX_ObjectActuator, m_pid, PyCheckPid),
360         { NULL }        //Sentinel
361 };
362
363 PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) {
364         py_getattro_up(SCA_IActuator);
365 }
366
367
368 PyObject* KX_ObjectActuator::py_getattro_dict() {
369         py_getattro_dict_up(SCA_IActuator);
370 }
371
372 int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value)
373 {
374         py_setattro_up(SCA_IActuator);
375 }
376
377 /* Attribute get/set functions */
378
379 PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
380 {
381         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
382         PyObject *retVal = PyList_New(3);
383
384         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[0]));
385         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[0]));
386         PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.Torque));
387         
388         return retVal;
389 }
390
391 int KX_ObjectActuator::pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
392 {
393         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
394
395         PyObject* seq = PySequence_Fast(value, "");
396         if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
397         {
398                 self->m_drot[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
399                 self->m_dloc[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
400                 self->m_bitLocalFlag.Torque = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
401
402                 if (!PyErr_Occurred())
403                 {
404                         Py_DECREF(seq);
405                         return PY_SET_ATTR_SUCCESS;
406                 }
407         }
408
409         Py_XDECREF(seq);
410
411         PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
412         return PY_SET_ATTR_FAIL;
413 }
414
415 PyObject* KX_ObjectActuator::pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
416 {
417         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
418         PyObject *retVal = PyList_New(3);
419
420         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[1]));
421         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[1]));
422         PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DLoc));
423         
424         return retVal;
425 }
426
427 int     KX_ObjectActuator::pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
428 {
429         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
430
431         PyObject* seq = PySequence_Fast(value, "");
432         if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
433         {
434                 self->m_drot[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
435                 self->m_dloc[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
436                 self->m_bitLocalFlag.DLoc = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
437
438                 if (!PyErr_Occurred())
439                 {
440                         Py_DECREF(seq);
441                         return PY_SET_ATTR_SUCCESS;
442                 }
443         }
444
445         Py_XDECREF(seq);
446
447         PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
448         return PY_SET_ATTR_FAIL;
449 }
450
451 PyObject* KX_ObjectActuator::pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
452 {
453         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
454         PyObject *retVal = PyList_New(3);
455
456         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[2]));
457         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[2]));
458         PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DRot));
459         
460         return retVal;
461 }
462
463 int     KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
464 {
465         KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
466
467         PyObject* seq = PySequence_Fast(value, "");
468         if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
469         {
470                 self->m_drot[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
471                 self->m_dloc[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
472                 self->m_bitLocalFlag.DRot = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
473
474                 if (!PyErr_Occurred())
475                 {
476                         Py_DECREF(seq);
477                         return PY_SET_ATTR_SUCCESS;
478                 }
479         }
480
481         Py_XDECREF(seq);
482
483         PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
484         return PY_SET_ATTR_FAIL;
485 }
486
487 /* 1. set ------------------------------------------------------------------ */
488 /* Removed! */
489
490 /* 2. getForce                                                               */
491 PyObject* KX_ObjectActuator::PyGetForce()
492 {
493         ShowDeprecationWarning("getForce()", "the force and the useLocalForce properties");
494         PyObject *retVal = PyList_New(4);
495
496         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_force[0]));
497         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_force[1]));
498         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_force[2]));
499         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
500         
501         return retVal;
502 }
503 /* 3. setForce                                                               */
504 PyObject* KX_ObjectActuator::PySetForce(PyObject* args)
505 {
506         ShowDeprecationWarning("setForce()", "the force and the useLocalForce properties");
507         float vecArg[3];
508         int bToggle = 0;
509         if (!PyArg_ParseTuple(args, "fffi:setForce", &vecArg[0], &vecArg[1], 
510                                                   &vecArg[2], &bToggle)) {
511                 return NULL;
512         }
513         m_force.setValue(vecArg);
514         m_bitLocalFlag.Force = PyArgToBool(bToggle);
515         UpdateFuzzyFlags();
516         Py_RETURN_NONE;
517 }
518
519 /* 4. getTorque                                                              */
520 PyObject* KX_ObjectActuator::PyGetTorque()
521 {
522         ShowDeprecationWarning("getTorque()", "the torque and the useLocalTorque properties");
523         PyObject *retVal = PyList_New(4);
524
525         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0]));
526         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_torque[1]));
527         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_torque[2]));
528         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
529         
530         return retVal;
531 }
532 /* 5. setTorque                                                              */
533 PyObject* KX_ObjectActuator::PySetTorque(PyObject* args)
534 {
535         ShowDeprecationWarning("setTorque()", "the torque and the useLocalTorque properties");
536         float vecArg[3];
537         int bToggle = 0;
538         if (!PyArg_ParseTuple(args, "fffi:setTorque", &vecArg[0], &vecArg[1], 
539                                                   &vecArg[2], &bToggle)) {
540                 return NULL;
541         }
542         m_torque.setValue(vecArg);
543         m_bitLocalFlag.Torque = PyArgToBool(bToggle);
544         UpdateFuzzyFlags();
545         Py_RETURN_NONE;
546 }
547
548 /* 6. getDLoc                                                                */
549 PyObject* KX_ObjectActuator::PyGetDLoc()
550 {
551         ShowDeprecationWarning("getDLoc()", "the dLoc and the useLocalDLoc properties");
552         PyObject *retVal = PyList_New(4);
553
554         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
555         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
556         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
557         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
558         
559         return retVal;
560 }
561 /* 7. setDLoc                                                                */
562 PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args)
563 {
564         ShowDeprecationWarning("setDLoc()", "the dLoc and the useLocalDLoc properties");
565         float vecArg[3];
566         int bToggle = 0;
567         if(!PyArg_ParseTuple(args, "fffi:setDLoc", &vecArg[0], &vecArg[1], 
568                                                  &vecArg[2], &bToggle)) {
569                 return NULL;
570         }
571         m_dloc.setValue(vecArg);
572         m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
573         UpdateFuzzyFlags();
574         Py_RETURN_NONE;
575 }
576
577 /* 8. getDRot                                                                */
578 PyObject* KX_ObjectActuator::PyGetDRot()
579 {
580         ShowDeprecationWarning("getDRot()", "the dRot and the useLocalDRot properties");
581         PyObject *retVal = PyList_New(4);
582
583         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0]));
584         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_drot[1]));
585         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_drot[2]));
586         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
587         
588         return retVal;
589 }
590 /* 9. setDRot                                                                */
591 PyObject* KX_ObjectActuator::PySetDRot(PyObject* args)
592 {
593         ShowDeprecationWarning("setDRot()", "the dRot and the useLocalDRot properties");
594         float vecArg[3];
595         int bToggle = 0;
596         if (!PyArg_ParseTuple(args, "fffi:setDRot", &vecArg[0], &vecArg[1], 
597                                                   &vecArg[2], &bToggle)) {
598                 return NULL;
599         }
600         m_drot.setValue(vecArg);
601         m_bitLocalFlag.DRot = PyArgToBool(bToggle);
602         UpdateFuzzyFlags();
603         Py_RETURN_NONE;
604 }
605
606 /* 10. getLinearVelocity                                                 */
607 PyObject* KX_ObjectActuator::PyGetLinearVelocity() {
608         ShowDeprecationWarning("getLinearVelocity()", "the linV and the useLocalLinV properties");
609         PyObject *retVal = PyList_New(4);
610
611         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
612         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
613         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
614         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
615         
616         return retVal;
617 }
618
619 /* 11. setLinearVelocity                                                 */
620 PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) {
621         ShowDeprecationWarning("setLinearVelocity()", "the linV and the useLocalLinV properties");
622         float vecArg[3];
623         int bToggle = 0;
624         if (!PyArg_ParseTuple(args, "fffi:setLinearVelocity", &vecArg[0], &vecArg[1], 
625                                                   &vecArg[2], &bToggle)) {
626                 return NULL;
627         }
628         m_linear_velocity.setValue(vecArg);
629         m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
630         UpdateFuzzyFlags();
631         Py_RETURN_NONE;
632 }
633
634
635 /* 12. getAngularVelocity                                                */
636 PyObject* KX_ObjectActuator::PyGetAngularVelocity() {
637         ShowDeprecationWarning("getAngularVelocity()", "the angV and the useLocalAngV properties");
638         PyObject *retVal = PyList_New(4);
639
640         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
641         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
642         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
643         PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
644         
645         return retVal;
646 }
647 /* 13. setAngularVelocity                                                */
648 PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) {
649         ShowDeprecationWarning("setAngularVelocity()", "the angV and the useLocalAngV properties");
650         float vecArg[3];
651         int bToggle = 0;
652         if (!PyArg_ParseTuple(args, "fffi:setAngularVelocity", &vecArg[0], &vecArg[1], 
653                                                   &vecArg[2], &bToggle)) {
654                 return NULL;
655         }
656         m_angular_velocity.setValue(vecArg);
657         m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
658         UpdateFuzzyFlags();
659         Py_RETURN_NONE;
660 }
661
662 /* 13. setDamping                                                */
663 PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) {
664         ShowDeprecationWarning("setDamping()", "the damping property");
665         int damping = 0;
666         if (!PyArg_ParseTuple(args, "i:setDamping", &damping) || damping < 0 || damping > 1000) {
667                 return NULL;
668         }
669         m_damping = damping;
670         Py_RETURN_NONE;
671 }
672
673 /* 13. getVelocityDamping                                                */
674 PyObject* KX_ObjectActuator::PyGetDamping() {
675         ShowDeprecationWarning("getDamping()", "the damping property");
676         return Py_BuildValue("i",m_damping);
677 }
678 /* 6. getForceLimitX                                                                */
679 PyObject* KX_ObjectActuator::PyGetForceLimitX()
680 {
681         ShowDeprecationWarning("getForceLimitX()", "the forceLimitX property");
682         PyObject *retVal = PyList_New(3);
683
684         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0]));
685         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[0]));
686         PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque));
687         
688         return retVal;
689 }
690 /* 7. setForceLimitX                                                         */
691 PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args)
692 {
693         ShowDeprecationWarning("setForceLimitX()", "the forceLimitX property");
694         float vecArg[2];
695         int bToggle = 0;
696         if(!PyArg_ParseTuple(args, "ffi:setForceLimitX", &vecArg[0], &vecArg[1], &bToggle)) {
697                 return NULL;
698         }
699         m_drot[0] = vecArg[0];
700         m_dloc[0] = vecArg[1];
701         m_bitLocalFlag.Torque = PyArgToBool(bToggle);
702         Py_RETURN_NONE;
703 }
704
705 /* 6. getForceLimitY                                                                */
706 PyObject* KX_ObjectActuator::PyGetForceLimitY()
707 {
708         ShowDeprecationWarning("getForceLimitY()", "the forceLimitY property");
709         PyObject *retVal = PyList_New(3);
710
711         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[1]));
712         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
713         PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc));
714         
715         return retVal;
716 }
717 /* 7. setForceLimitY                                                                */
718 PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args)
719 {
720         ShowDeprecationWarning("setForceLimitY()", "the forceLimitY property");
721         float vecArg[2];
722         int bToggle = 0;
723         if(!PyArg_ParseTuple(args, "ffi:setForceLimitY", &vecArg[0], &vecArg[1], &bToggle)) {
724                 return NULL;
725         }
726         m_drot[1] = vecArg[0];
727         m_dloc[1] = vecArg[1];
728         m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
729         Py_RETURN_NONE;
730 }
731
732 /* 6. getForceLimitZ                                                                */
733 PyObject* KX_ObjectActuator::PyGetForceLimitZ()
734 {
735         ShowDeprecationWarning("getForceLimitZ()", "the forceLimitZ property");
736         PyObject *retVal = PyList_New(3);
737
738         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[2]));
739         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[2]));
740         PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot));
741         
742         return retVal;
743 }
744 /* 7. setForceLimitZ                                                                */
745 PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args)
746 {
747         ShowDeprecationWarning("setForceLimitZ()", "the forceLimitZ property");
748         float vecArg[2];
749         int bToggle = 0;
750         if(!PyArg_ParseTuple(args, "ffi:setForceLimitZ", &vecArg[0], &vecArg[1], &bToggle)) {
751                 return NULL;
752         }
753         m_drot[2] = vecArg[0];
754         m_dloc[2] = vecArg[1];
755         m_bitLocalFlag.DRot = PyArgToBool(bToggle);
756         Py_RETURN_NONE;
757 }
758
759 /* 4. getPID                                                              */
760 PyObject* KX_ObjectActuator::PyGetPID()
761 {
762         ShowDeprecationWarning("getPID()", "the pid property");
763         PyObject *retVal = PyList_New(3);
764
765         PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_pid[0]));
766         PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_pid[1]));
767         PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_pid[2]));
768         
769         return retVal;
770 }
771 /* 5. setPID                                                              */
772 PyObject* KX_ObjectActuator::PySetPID(PyObject* args)
773 {
774         ShowDeprecationWarning("setPID()", "the pid property");
775         float vecArg[3];
776         if (!PyArg_ParseTuple(args, "fff:setPID", &vecArg[0], &vecArg[1], &vecArg[2])) {
777                 return NULL;
778         }
779         m_pid.setValue(vecArg);
780         Py_RETURN_NONE;
781 }
782
783
784
785
786
787 /* eof */