0ba55fe59865a5ea8f52616d5b5b3397d8b3d05b
[blender.git] / source / gameengine / Ketsji / KX_VehicleWrapper.cpp
1
2
3 #include <Python.h>
4 #include "PyObjectPlus.h"
5
6 #include "KX_VehicleWrapper.h"
7 #include "PHY_IPhysicsEnvironment.h"
8 #include "PHY_IVehicle.h"
9 #include "KX_PyMath.h"
10 #include "KX_GameObject.h"
11 #include "KX_MotionState.h"
12
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16
17 KX_VehicleWrapper::KX_VehicleWrapper(
18                                                 PHY_IVehicle* vehicle,
19                                                 PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) :
20                 PyObjectPlus(T),
21                 m_vehicle(vehicle),
22                 m_physenv(physenv)
23 {
24 }
25
26 KX_VehicleWrapper::~KX_VehicleWrapper()
27 {
28         int numMotion = m_motionStates.size();
29         for (int i=0;i<numMotion;i++)
30         {
31                 PHY_IMotionState* motionState = m_motionStates[i];
32                 delete motionState;
33         }
34         m_motionStates.clear();
35 }
36
37
38 PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self, 
39                                                                                         PyObject* args, 
40                                                                                         PyObject* kwds)
41 {
42         
43         PyObject* pylistPos,*pylistDir,*pylistAxleDir;
44         PyObject* wheelGameObject;
45         float suspensionRestLength,wheelRadius;
46         int hasSteering;
47
48         
49         if (PyArg_ParseTuple(args,"OOOOffi:addWheel",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering))
50         {
51                 KX_GameObject *gameOb;
52                 if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false))
53                         return NULL;
54                 
55
56                 if (gameOb->GetSGNode())
57                 {
58                         PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
59
60                         MT_Vector3 attachPos,attachDir,attachAxle;
61                         PyVecTo(pylistPos,attachPos);
62                         PyVecTo(pylistDir,attachDir);
63                         PyVecTo(pylistAxleDir,attachAxle);
64                         PHY__Vector3 aPos,aDir,aAxle;
65                         aPos[0] = attachPos[0];
66                         aPos[1] = attachPos[1];
67                         aPos[2] = attachPos[2];
68                         aDir[0] = attachDir[0];
69                         aDir[1] = attachDir[1];
70                         aDir[2] = attachDir[2];
71                         aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding)
72                         aAxle[1] = -attachAxle[1];
73                         aAxle[2] = -attachAxle[2];
74                         
75                         printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
76                         m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
77                 }
78                 
79         } else {
80                 return NULL;
81         }
82         Py_RETURN_NONE;
83 }
84
85
86
87
88 PyObject* KX_VehicleWrapper::PyGetWheelPosition(PyObject* self, 
89                                                                                         PyObject* args, 
90                                                                                         PyObject* kwds)
91 {
92         
93         int wheelIndex;
94
95         if (PyArg_ParseTuple(args,"i:getWheelPosition",&wheelIndex))
96         {
97                 float position[3];
98                 m_vehicle->GetWheelPosition(wheelIndex,position[0],position[1],position[2]);
99                 MT_Vector3 pos(position[0],position[1],position[2]);
100                 return PyObjectFrom(pos);
101         }
102         return NULL;
103 }
104
105 PyObject* KX_VehicleWrapper::PyGetWheelRotation(PyObject* self, 
106                                                                                         PyObject* args, 
107                                                                                         PyObject* kwds)
108 {
109         int wheelIndex;
110         if (PyArg_ParseTuple(args,"i:getWheelRotation",&wheelIndex))
111         {
112                 return PyFloat_FromDouble(m_vehicle->GetWheelRotation(wheelIndex));
113         }
114         return NULL;
115 }
116
117 PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* self, 
118                                                                                         PyObject* args, 
119                                                                                         PyObject* kwds)
120 {
121         int wheelIndex;
122         if (PyArg_ParseTuple(args,"i:getWheelOrientationQuaternion",&wheelIndex))
123         {
124                 float orn[4];
125                 m_vehicle->GetWheelOrientationQuaternion(wheelIndex,orn[0],orn[1],orn[2],orn[3]);
126                 MT_Quaternion   quatorn(orn[0],orn[1],orn[2],orn[3]);
127                 MT_Matrix3x3 ornmat(quatorn);
128                 return PyObjectFrom(ornmat);
129         }
130         return NULL;
131
132 }
133
134
135 PyObject* KX_VehicleWrapper::PyGetNumWheels(PyObject* self, 
136                                                                                         PyObject* args, 
137                                                                                         PyObject* kwds)
138 {
139         return PyInt_FromLong(m_vehicle->GetNumWheels());
140 }
141
142
143 PyObject* KX_VehicleWrapper::PyGetConstraintId(PyObject* self, 
144                                                                                         PyObject* args, 
145                                                                                         PyObject* kwds)
146 {
147         return PyInt_FromLong(m_vehicle->GetUserConstraintId());
148 }
149
150
151
152 PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* self, 
153                                                                                         PyObject* args, 
154                                                                                         PyObject* kwds)
155 {
156         float force;
157         int wheelIndex;
158
159         if (PyArg_ParseTuple(args,"fi:applyEngineForce",&force,&wheelIndex))
160         {
161                 force *= -1.f;//someone reverse some conventions inside Bullet (axle winding)
162                 m_vehicle->ApplyEngineForce(force,wheelIndex);
163         }
164         else {
165                 return NULL;
166         }
167         Py_RETURN_NONE;
168 }
169
170 PyObject* KX_VehicleWrapper::PySetTyreFriction(PyObject* self, 
171                                                                                         PyObject* args, 
172                                                                                         PyObject* kwds)
173 {
174         float wheelFriction;
175         int wheelIndex;
176
177         if (PyArg_ParseTuple(args,"fi:setTyreFriction",&wheelFriction,&wheelIndex))
178         {
179                 m_vehicle->SetWheelFriction(wheelFriction,wheelIndex);
180         }
181         else {
182                 return NULL;
183         }
184         Py_RETURN_NONE;
185 }
186
187 PyObject* KX_VehicleWrapper::PySetSuspensionStiffness(PyObject* self, 
188                                                                                         PyObject* args, 
189                                                                                         PyObject* kwds)
190 {
191         float suspensionStiffness;
192         int wheelIndex;
193
194         if (PyArg_ParseTuple(args,"fi:setSuspensionStiffness",&suspensionStiffness,&wheelIndex))
195         {
196                 m_vehicle->SetSuspensionStiffness(suspensionStiffness,wheelIndex);
197         }
198         else {
199                 return NULL;
200         }
201         Py_RETURN_NONE;
202 }
203
204 PyObject* KX_VehicleWrapper::PySetSuspensionDamping(PyObject* self, 
205                                                                                         PyObject* args, 
206                                                                                         PyObject* kwds)
207 {
208         float suspensionDamping;
209         int wheelIndex;
210
211         if (PyArg_ParseTuple(args,"fi:setSuspensionDamping",&suspensionDamping,&wheelIndex))
212         {
213                 m_vehicle->SetSuspensionDamping(suspensionDamping,wheelIndex);
214         } else {
215                 return NULL;
216         }
217         Py_RETURN_NONE;
218 }
219
220 PyObject* KX_VehicleWrapper::PySetSuspensionCompression(PyObject* self, 
221                                                                                         PyObject* args, 
222                                                                                         PyObject* kwds)
223 {
224         float suspensionCompression;
225         int wheelIndex;
226
227         if (PyArg_ParseTuple(args,"fi:setSuspensionCompression",&suspensionCompression,&wheelIndex))
228         {
229                 m_vehicle->SetSuspensionCompression(suspensionCompression,wheelIndex);
230         } else {
231                 return NULL;
232         }
233         Py_RETURN_NONE;
234 }
235
236 PyObject* KX_VehicleWrapper::PySetRollInfluence(PyObject* self, 
237                                                                                         PyObject* args, 
238                                                                                         PyObject* kwds)
239 {
240         float rollInfluence;
241         int wheelIndex;
242
243         if (PyArg_ParseTuple(args,"fi:setRollInfluence",&rollInfluence,&wheelIndex))
244         {
245                 m_vehicle->SetRollInfluence(rollInfluence,wheelIndex);
246         }
247         else {
248                 return NULL;
249         }
250         Py_RETURN_NONE;
251 }
252
253
254 PyObject* KX_VehicleWrapper::PyApplyBraking(PyObject* self, 
255                                                                                         PyObject* args, 
256                                                                                         PyObject* kwds)
257 {
258         float braking;
259         int wheelIndex;
260
261         if (PyArg_ParseTuple(args,"fi:applyBraking",&braking,&wheelIndex))
262         {
263                 m_vehicle->ApplyBraking(braking,wheelIndex);
264         }
265         else {
266                 return NULL;
267         }
268         Py_RETURN_NONE;
269 }
270
271
272
273
274 PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* self, 
275                                                                                         PyObject* args, 
276                                                                                         PyObject* kwds)
277 {
278         float steeringValue;
279         int wheelIndex;
280
281         if (PyArg_ParseTuple(args,"fi:setSteeringValue",&steeringValue,&wheelIndex))
282         {
283                 m_vehicle->SetSteeringValue(steeringValue,wheelIndex);
284         }
285         else {
286                 return NULL;
287         }
288         Py_RETURN_NONE;
289 }
290
291
292 PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* self, 
293                                                                                         PyObject* args, 
294                                                                                         PyObject* kwds)
295 {
296         return PyInt_FromLong(m_vehicle->GetUserConstraintType());
297 }
298
299
300
301
302
303 //python specific stuff
304 PyTypeObject KX_VehicleWrapper::Type = {
305         PyObject_HEAD_INIT(NULL)
306                 0,
307                 "KX_VehicleWrapper",
308                 sizeof(KX_VehicleWrapper),
309                 0,
310                 PyDestructor,
311                 0,
312                 0,
313                 0,
314                 0,
315                 py_base_repr,
316                 0,0,0,0,0,0,
317                 py_base_getattro,
318                 py_base_setattro,
319                 0,0,0,0,0,0,0,0,0,
320                 Methods
321 };
322
323 PyParentObject KX_VehicleWrapper::Parents[] = {
324         &KX_VehicleWrapper::Type,
325         &PyObjectPlus::Type,
326         NULL
327 };
328
329 PyObject*       KX_VehicleWrapper::py_getattro(PyObject *attr)
330 {
331         //here you can search for existing data members (like mass,friction etc.)
332         py_getattro_up(PyObjectPlus);
333 }
334
335 int     KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* pyobj)
336 {
337         /* TODO - strange setattr, needs updating */
338         PyTypeObject* type = pyobj->ob_type;
339         int result = 1;
340
341         if (type == &PyList_Type)
342         {
343                 result = 0;
344         }
345         if (type == &PyFloat_Type)
346         {
347                 result = 0;
348
349         }
350         if (type == &PyInt_Type)
351         {
352                 result = 0;
353         }
354         if (type == &PyString_Type)
355         {
356                 result = 0;
357         }
358         if (result)
359                 result = PyObjectPlus::py_setattro(attr,pyobj);
360         return result;
361 };
362
363
364 PyMethodDef KX_VehicleWrapper::Methods[] = {
365         {"addWheel",(PyCFunction) KX_VehicleWrapper::sPyAddWheel, METH_VARARGS},
366         {"getNumWheels",(PyCFunction) KX_VehicleWrapper::sPyGetNumWheels, METH_VARARGS},
367         {"getWheelOrientationQuaternion",(PyCFunction) KX_VehicleWrapper::sPyGetWheelOrientationQuaternion, METH_VARARGS},
368         {"getWheelRotation",(PyCFunction) KX_VehicleWrapper::sPyGetWheelRotation, METH_VARARGS},
369         {"getWheelPosition",(PyCFunction) KX_VehicleWrapper::sPyGetWheelPosition, METH_VARARGS},
370         {"getConstraintId",(PyCFunction) KX_VehicleWrapper::sPyGetConstraintId, METH_VARARGS},
371         {"getConstraintType",(PyCFunction) KX_VehicleWrapper::sPyGetConstraintType, METH_VARARGS},
372         {"setSteeringValue",(PyCFunction) KX_VehicleWrapper::sPySetSteeringValue, METH_VARARGS},
373         {"applyEngineForce",(PyCFunction) KX_VehicleWrapper::sPyApplyEngineForce, METH_VARARGS},
374         {"applyBraking",(PyCFunction) KX_VehicleWrapper::sPyApplyBraking, METH_VARARGS},
375
376         {"setTyreFriction",(PyCFunction) KX_VehicleWrapper::sPySetTyreFriction, METH_VARARGS},
377
378         {"setSuspensionStiffness",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionStiffness, METH_VARARGS},
379
380         {"setSuspensionDamping",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionDamping, METH_VARARGS},
381
382         {"setSuspensionCompression",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionCompression, METH_VARARGS},
383
384         {"setRollInfluence",(PyCFunction) KX_VehicleWrapper::sPySetRollInfluence, METH_VARARGS},
385
386         {NULL,NULL} //Sentinel
387 };
388
389 PyAttributeDef KX_VehicleWrapper::Attributes[] = {
390         { NULL }        //Sentinel
391 };