Initial revision
[blender.git] / source / gameengine / Ketsji / KX_ObjectActuator.cpp
1 /**
2  * Do translation/rotation actions
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 #include "KX_ObjectActuator.h"
36 #include "KX_GameObject.h"
37 #include "KX_IPhysicsController.h"
38
39
40 /* ------------------------------------------------------------------------- */
41 /* Native functions                                                          */
42 /* ------------------------------------------------------------------------- */
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 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_active_combined_velocity (false),
65         m_bitLocalFlag (flag)
66 {
67 }
68
69 bool KX_ObjectActuator::Update(double curtime,double deltatime)
70 {
71         
72         bool bNegativeEvent = IsNegativeEvent();
73         RemoveAllEvents();
74                 
75         KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent()); 
76
77         if (bNegativeEvent) {
78                 // If we previously set the linear velocity we now have to inform
79                 // the physics controller that we no longer wish to apply it and that
80                 // it should reconcile the externally set velocity with it's 
81                 // own velocity.
82                 if (m_active_combined_velocity) {
83                         //if (parent->GetSumoObject()) {
84                                 //parent->GetPhysicsController()->ResolveCombinedVelocities(
85                                 //      m_linear_velocity,
86                                 //      m_angular_velocity,
87                                 //      (m_bitLocalFlag.LinearVelocity) != 0,
88                                 //      (m_bitLocalFlag.AngularVelocity) != 0
89                                 //);
90                                 m_active_combined_velocity = false;
91                         //}
92                         return false;
93                 } else {
94                         return false; 
95                 }
96
97         } else 
98         if (parent)
99         {
100                 /* Probably better to use some flags, so these MT_zero tests can be  */
101                 /* skipped.                                                          */
102                 if (!MT_fuzzyZero(m_force))
103                 {
104                         parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
105                 }
106                 if (!MT_fuzzyZero(m_torque))
107                 {
108                         parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
109                 }
110                 if (!MT_fuzzyZero(m_dloc))
111                 {
112                         parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
113                 }
114                 if (!MT_fuzzyZero(m_drot))
115                 {
116                         parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
117                 }
118                 if (!MT_fuzzyZero(m_linear_velocity))
119                 {
120                         if (m_bitLocalFlag.AddOrSetLinV) {
121                                 parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
122                         } else {
123                                 m_active_combined_velocity = true;
124                                 parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
125                         }
126                 }
127                 if (!MT_fuzzyZero(m_angular_velocity))
128                 {
129                         parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
130                         m_active_combined_velocity = true;
131                 }
132                 
133         }
134         return true;
135 }
136
137
138
139 CValue* KX_ObjectActuator::GetReplica()
140 {
141         KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName());
142         replica->ProcessReplica();
143
144         // this will copy properties and so on...
145         CValue::AddDataToReplica(replica);
146
147         return replica;
148 }
149
150
151
152 /* some 'standard' utilities... */
153 bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
154 {
155         bool res = false;
156         res = (type > KX_OBJECT_ACT_NODEF) && (type < KX_OBJECT_ACT_MAX);
157         return res;
158 }
159
160
161
162 /* ------------------------------------------------------------------------- */
163 /* Python functions                                                          */
164 /* ------------------------------------------------------------------------- */
165
166 /* Integration hooks ------------------------------------------------------- */
167 PyTypeObject KX_ObjectActuator::Type = {
168         PyObject_HEAD_INIT(&PyType_Type)
169         0,
170         "KX_ObjectActuator",
171         sizeof(KX_ObjectActuator),
172         0,
173         PyDestructor,
174         0,
175         __getattr,
176         __setattr,
177         0, //&MyPyCompare,
178         __repr,
179         0, //&cvalue_as_number,
180         0,
181         0,
182         0,
183         0
184 };
185
186 PyParentObject KX_ObjectActuator::Parents[] = {
187         &KX_ObjectActuator::Type,
188         &SCA_IActuator::Type,
189         &SCA_ILogicBrick::Type,
190         &CValue::Type,
191         NULL
192 };
193
194 PyMethodDef KX_ObjectActuator::Methods[] = {
195         {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_VARARGS},
196         {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
197         {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_VARARGS},
198         {"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS},
199         {"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_VARARGS},
200         {"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS},
201         {"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_VARARGS},
202         {"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS},
203         {"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_VARARGS},
204         {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
205         {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS},
206         {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
207
208
209         {NULL,NULL} //Sentinel
210 };
211
212 PyObject* KX_ObjectActuator::_getattr(char* attr) {
213         _getattr_up(SCA_IActuator);
214 };
215
216 /* 1. set ------------------------------------------------------------------ */
217 /* Removed! */
218
219 /* 2. getForce                                                               */
220 PyObject* KX_ObjectActuator::PyGetForce(PyObject* self, 
221                                                                                 PyObject* args, 
222                                                                                 PyObject* kwds)
223 {
224         PyObject *retVal = PyList_New(4);
225
226         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0]));
227         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1]));
228         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2]));
229         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
230         
231         return retVal;
232 }
233 /* 3. setForce                                                               */
234 PyObject* KX_ObjectActuator::PySetForce(PyObject* self, 
235                                                                                 PyObject* args, 
236                                                                                 PyObject* kwds)
237 {
238         float vecArg[3];
239         int bToggle = 0;
240         if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
241                                                   &vecArg[2], &bToggle)) {
242                 return NULL;
243         }
244         m_force.setValue(vecArg);
245         m_bitLocalFlag.Force = PyArgToBool(bToggle);
246         Py_Return;
247 }
248
249 /* 4. getTorque                                                              */
250 PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self, 
251                                                                                  PyObject* args, 
252                                                                                  PyObject* kwds)
253 {
254         PyObject *retVal = PyList_New(4);
255
256         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
257         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
258         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
259         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
260         
261         return retVal;
262 }
263 /* 5. setTorque                                                              */
264 PyObject* KX_ObjectActuator::PySetTorque(PyObject* self, 
265                                                                                  PyObject* args, 
266                                                                                  PyObject* kwds)
267 {
268         float vecArg[3];
269         int bToggle = 0;
270         if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
271                                                   &vecArg[2], &bToggle)) {
272                 return NULL;
273         }
274         m_torque.setValue(vecArg);
275         m_bitLocalFlag.Torque = PyArgToBool(bToggle);
276         Py_Return;
277 }
278
279 /* 6. getDLoc                                                                */
280 PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self, 
281                                                                            PyObject* args, 
282                                                                            PyObject* kwds)
283 {
284         PyObject *retVal = PyList_New(4);
285
286         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
287         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
288         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
289         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
290         
291         return retVal;
292 }
293 /* 7. setDLoc                                                                */
294 PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self, 
295                                                                            PyObject* args, 
296                                                                            PyObject* kwds)
297 {
298         float vecArg[3];
299         int bToggle = 0;
300         if(!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
301                                                  &vecArg[2], &bToggle)) {
302                 return NULL;
303         }
304         m_dloc.setValue(vecArg);
305         m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
306         Py_Return;
307 }
308
309 /* 8. getDRot                                                                */
310 PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self, 
311                                                                            PyObject* args, 
312                                                                            PyObject* kwds)
313 {
314         PyObject *retVal = PyList_New(4);
315
316         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
317         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1]));
318         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2]));
319         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
320         
321         return retVal;
322 }
323 /* 9. setDRot                                                                */
324 PyObject* KX_ObjectActuator::PySetDRot(PyObject* self, 
325                                                                            PyObject* args, 
326                                                                            PyObject* kwds)
327 {
328         float vecArg[3];
329         int bToggle = 0;
330         if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
331                                                   &vecArg[2], &bToggle)) {
332                 return NULL;
333         }
334         m_drot.setValue(vecArg);
335         m_bitLocalFlag.DRot = PyArgToBool(bToggle);
336         Py_Return;
337 }
338
339 /* 10. getLinearVelocity                                                 */
340 PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self, 
341                                                                                                  PyObject* args, 
342                                                                                                  PyObject* kwds) {
343         PyObject *retVal = PyList_New(4);
344
345         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
346         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
347         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
348         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
349         
350         return retVal;
351 }
352
353 /* 11. setLinearVelocity                                                 */
354 PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self, 
355                                                                                                  PyObject* args, 
356                                                                                                  PyObject* kwds) {
357         float vecArg[3];
358         int bToggle = 0;
359         if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
360                                                   &vecArg[2], &bToggle)) {
361                 return NULL;
362         }
363         m_linear_velocity.setValue(vecArg);
364         m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
365         Py_Return;
366 }
367
368
369 /* 12. getAngularVelocity                                                */
370 PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self, 
371                                                                                                   PyObject* args, 
372                                                                                                   PyObject* kwds) {
373         PyObject *retVal = PyList_New(4);
374
375         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
376         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
377         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
378         PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
379         
380         return retVal;
381 }
382 /* 13. setAngularVelocity                                                */
383 PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self, 
384                                                                                                   PyObject* args, 
385                                                                                                   PyObject* kwds) {
386         float vecArg[3];
387         int bToggle = 0;
388         if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
389                                                   &vecArg[2], &bToggle)) {
390                 return NULL;
391         }
392         m_angular_velocity.setValue(vecArg);
393         m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
394         Py_Return;
395 }
396
397
398
399
400 /* eof */