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