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