Addons updated to new doc format
[io.git] / addons / ODE / source / IoODEBody.c
blobf9da2fa35daecbf2a64f937cb8d82cc18acb3c88
2 //metadoc ODEBody copyright Jonathan Wright, 2006
3 //metadoc ODEBody license BSD revised
4 /*metadoc ODEBody description
5 ODEBody binding
6 */
8 #include "IoODEBody.h"
9 #include "IoODEMass.h"
10 #include "IoState.h"
11 #include "IoSeq.h"
12 #include "IoVector_ode.h"
13 #include "GLIncludes.h"
15 #define DATA(self) ((IoODEBodyData *)IoObject_dataPointer(self))
16 #define BODYID (DATA(self)->bodyId)
17 #define WORLD (DATA(self)->world)
19 void IoODEBody_assertValidBody(IoODEBody *self, IoObject *locals, IoMessage *m)
21 IOASSERT(WORLD, "This ODE body belongs to an ODE world which has been freed.");
22 IOASSERT(BODYID, "ODE World Body cannot be used directly. Clone the world and use the Body on the cloned world.");
26 IoODEBody *IoMessage_locals_odeBodyArgAt_(IoMessage *self, void *locals, int n)
28 IoObject *b = IoMessage_locals_valueArgAt_(self, locals, n);
30 if (!ISODEBODY(b) && !ISNIL(b))
32 IoMessage_locals_numberArgAt_errorForType_(self, locals, n, "ODEBody");
35 return b;
38 dBodyID IoMessage_locals_odeBodyIdArgAt_(IoMessage *self, void *locals, int n)
40 IoObject *body = IoMessage_locals_odeBodyArgAt_(self, locals, n);
41 if (ISNIL(body))
43 return 0;
45 else
47 return DATA(body)->bodyId;
52 IoTag *IoODEBody_newTag(void *state)
54 IoTag *tag = IoTag_newWithName_("ODEBody");
55 IoTag_state_(tag, state);
56 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoODEBody_free);
57 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoODEBody_mark);
58 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoODEBody_rawClone);
59 return tag;
62 IoODEBody *IoODEBody_proto(void *state)
64 IoObject *self = IoObject_new(state);
65 IoObject_tag_(self, IoODEBody_newTag(state));
67 IoObject_setDataPointer_(self, calloc(1, sizeof(IoODEBodyData)));
69 BODYID = 0;
70 WORLD = 0L;
72 IoState_registerProtoWithFunc_(state, self, IoODEBody_proto);
75 IoMethodTable methodTable[] = {
76 {"bodyId", IoODEBody_bodyId},
77 {"world", IoODEBody_world},
78 {"mass", IoODEBody_mass},
79 {"setMass", IoODEBody_setMass},
80 {"position", IoODEBody_position},
81 {"setPosition", IoODEBody_setPosition},
83 {"force", IoODEBody_force},
84 {"setForce", IoODEBody_setForce},
85 {"addForce", IoODEBody_addForce},
86 {"addRelForce", IoODEBody_addRelForce},
88 {"torque", IoODEBody_torque},
89 {"setTorque", IoODEBody_setTorque},
90 {"addTorque", IoODEBody_addTorque},
91 {"addRelTorque", IoODEBody_addRelTorque},
93 {"linearVelocity", IoODEBody_linearVelocity},
94 {"setLinearVelocity", IoODEBody_setLinearVelocity},
96 {"quaternion", IoODEBody_quaternion},
97 //{"setQuaternion", IoODEBody_setQuaternion},
98 {"rotation", IoODEBody_rotation},
99 {"setRotation", IoODEBody_setRotation},
100 {"glMultMatrix", IoODEBody_glMultMatrix},
102 {NULL, NULL},
104 IoObject_addMethodTable_(self, methodTable);
106 return self;
109 IoODEBody *IoODEBody_rawClone(IoODEBody *proto)
111 IoObject *self = IoObject_rawClonePrimitive(proto);
112 IoObject_setDataPointer_(self, calloc(1, sizeof(IoODEBodyData)));
114 if(DATA(proto)->world)
116 IoODEWorld *world = DATA(proto)->world;
118 WORLD = world;
119 IoODEWorld_addBody(world, self);
120 BODYID = dBodyCreate(IoODEWorld_rawWorldId(world));
121 dBodySetData(BODYID, self);
123 return self;
126 void IoODEBody_free(IoODEBody *self)
128 if(BODYID && WORLD)
130 IoODEWorld_removeBody(WORLD, self);
131 dBodyDestroy(BODYID);
133 free(IoObject_dataPointer(self));
136 void IoODEBody_mark(IoODEBody *self)
138 if(WORLD)
140 IoObject_shouldMark((IoObject *)WORLD);
144 IoODEBody *IoODEBody_new(void *state)
146 IoODEBody *proto = IoState_protoWithInitFunction_(state, IoODEBody_proto);
147 return IOCLONE(proto);
150 IoODEBody *IoODEBody_newBodyProtoWithWorld(void *state, IoODEWorld *world)
152 IoODEBody *proto = IoState_protoWithInitFunction_(state, IoODEBody_proto);
153 IoODEBody *self = IOCLONE(proto);
154 WORLD = world;
155 return self;
158 IoObject *IoODEBody_bodyFromId(void *state, dBodyID id)
160 if (id == 0)
162 return ((IoState*)state)->ioNil;
164 else
166 return (IoODEBody*)dBodyGetData(id);
170 /* ----------------------------------------------------------- */
172 void IoODEBody_worldDestroyed(IoODEBody *self)
174 WORLD = 0L;
175 BODYID = 0;
178 /* ----------------------------------------------------------- */
181 IoObject *IoODEBody_bodyId(IoODEBody *self, IoObject *locals, IoMessage *m)
183 return IONUMBER((long)BODYID);
186 IoObject *IoODEBody_world(IoODEBody *self, IoObject *locals, IoMessage *m)
188 return WORLD ? WORLD : IONIL(self);
191 IoObject *IoODEBody_mass(IoODEBody *self, IoObject *locals, IoMessage *m)
193 IoODEBody_assertValidBody(self, locals, m);
196 IoODEMass *mass = IoODEMass_new(IOSTATE);
197 dBodyGetMass(BODYID, IoODEMass_dMassStruct(mass));
198 return mass;
202 IoObject *IoODEBody_setMass(IoODEBody *self, IoObject *locals, IoMessage *m)
204 IoODEBody_assertValidBody(self, locals, m);
207 dMass *mass = IoMessage_locals_odeMassStructArgAt_(m, locals, 0);
208 dBodySetMass(BODYID, mass);
211 return self;
214 IoObject *IoODEBody_position(IoODEBody *self, IoObject *locals, IoMessage *m)
216 IoODEBody_assertValidBody(self, locals, m);
217 return IoVector_newWithODEPoint(IOSTATE, dBodyGetPosition(BODYID));
220 IoObject *IoODEBody_setPosition(IoODEBody *self, IoObject *locals, IoMessage *m)
222 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
223 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
224 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
226 IoODEBody_assertValidBody(self, locals, m);
227 dBodySetPosition(BODYID, x, y, z);
228 return self;
231 IoObject *IoODEBody_force(IoODEBody *self, IoObject *locals, IoMessage *m)
233 IoODEBody_assertValidBody(self, locals, m);
234 return IoVector_newWithODEPoint(IOSTATE, dBodyGetForce(BODYID));
237 IoObject *IoODEBody_setForce(IoODEBody *self, IoObject *locals, IoMessage *m)
239 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
240 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
241 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
243 IoODEBody_assertValidBody(self, locals, m);
244 dBodySetForce(BODYID, x, y, z);
245 return self;
248 IoObject *IoODEBody_addForce(IoODEBody *self, IoObject *locals, IoMessage *m)
250 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
251 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
252 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
254 IoODEBody_assertValidBody(self, locals, m);
255 dBodyAddForce(BODYID, x, y, z);
256 return self;
259 IoObject *IoODEBody_addRelForce(IoODEBody *self, IoObject *locals, IoMessage *m)
261 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
262 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
263 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
265 IoODEBody_assertValidBody(self, locals, m);
266 dBodyAddRelForce(BODYID, x, y, z);
267 return self;
270 IoObject *IoODEBody_torque(IoODEBody *self, IoObject *locals, IoMessage *m)
272 IoODEBody_assertValidBody(self, locals, m);
273 return IoVector_newWithODEPoint(IOSTATE, dBodyGetTorque(BODYID));
276 IoObject *IoODEBody_setTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
278 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
279 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
280 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
282 IoODEBody_assertValidBody(self, locals, m);
283 dBodySetTorque(BODYID, x, y, z);
284 return self;
287 IoObject *IoODEBody_addTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
289 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
290 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
291 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
293 IoODEBody_assertValidBody(self, locals, m);
294 dBodyAddTorque(BODYID, x, y, z);
295 return self;
298 IoObject *IoODEBody_addRelTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
300 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
301 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
302 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
304 IoODEBody_assertValidBody(self, locals, m);
305 dBodyAddRelTorque(BODYID, x, y, z);
306 return self;
309 IoObject *IoODEBody_linearVelocity(IoODEBody *self, IoObject *locals, IoMessage *m)
311 IoODEBody_assertValidBody(self, locals, m);
312 return IoVector_newWithODEPoint(IOSTATE, dBodyGetLinearVel(BODYID));
315 IoObject *IoODEBody_setLinearVelocity(IoODEBody *self, IoObject *locals, IoMessage *m)
317 const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
318 const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
319 const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
321 IoODEBody_assertValidBody(self, locals, m);
322 dBodySetLinearVel(BODYID, x, y, z);
323 return self;
326 IoObject *IoODEBody_glMultMatrix(IoODEBody *self, IoObject *locals, IoMessage *m)
328 IoODEBody_assertValidBody(self, locals, m);
330 dBodyID bodyId = BODYID;
332 const dReal *pos = dBodyGetPosition(bodyId);
333 const dReal *R = dBodyGetRotation(bodyId);
335 GLfloat matrix[16] = {R[0], R[4], R[8], 0, R[1], R[5], R[9], 0, R[2], R[6], R[10], 0, pos[0], pos[1], pos[2], 1};
336 glMultMatrixf(matrix);
337 return self;
341 IoObject *IoODEBody_rotation(IoODEBody *self, IoObject *locals, IoMessage *m)
343 IoODEBody_assertValidBody(self, locals, m);
345 const dReal *R = dBodyGetRotation(BODYID);
347 IoSeq *v = IoSeq_makeFloatArrayOfSize_(IOSTATE, 9);
348 UArray *u = IoSeq_rawUArray(v);
350 UArray_at_put_(u, 0, R[0]);
351 UArray_at_put_(u, 1, R[4]);
352 UArray_at_put_(u, 2, R[8]);
354 UArray_at_put_(u, 3, R[1]);
355 UArray_at_put_(u, 4, R[5]);
356 UArray_at_put_(u, 5, R[9]);
358 UArray_at_put_(u, 6, R[2]);
359 UArray_at_put_(u, 7, R[6]);
360 UArray_at_put_(u, 8, R[10]);
362 return v;
366 IoObject *IoODEBody_setRotation(IoODEBody *self, IoObject *locals, IoMessage *m)
368 IoODEBody_assertValidBody(self, locals, m);
370 dMatrix3 R;
371 R[0] = IoMessage_locals_doubleArgAt_(m, locals, 0);
372 R[1] = IoMessage_locals_doubleArgAt_(m, locals, 1);
373 R[2] = IoMessage_locals_doubleArgAt_(m, locals, 2);
374 R[3] = 0;
375 R[4] = IoMessage_locals_doubleArgAt_(m, locals, 3);
376 R[5] = IoMessage_locals_doubleArgAt_(m, locals, 4);
377 R[6] = IoMessage_locals_doubleArgAt_(m, locals, 5);
378 R[7] = 0;
379 R[8] = IoMessage_locals_doubleArgAt_(m, locals, 6);
380 R[9] = IoMessage_locals_doubleArgAt_(m, locals, 7);
381 R[10] = IoMessage_locals_doubleArgAt_(m, locals, 8);
382 R[11] = 0;
384 dBodySetRotation(BODYID, R);
385 return self;
389 IoObject *IoODEBody_quaternion(IoODEBody *self, IoObject *locals, IoMessage *m)
391 IoODEBody_assertValidBody(self, locals, m);
393 const dReal *q = dBodyGetQuaternion(BODYID);
394 IoSeq *v = IoSeq_makeFloatArrayOfSize_(IOSTATE, 4);
395 UArray *u = IoSeq_rawUArray(v);
396 UArray_at_put_(u, 0, q[0]);
397 UArray_at_put_(u, 1, q[1]);
398 UArray_at_put_(u, 2, q[2]);
399 UArray_at_put_(u, 3, q[3]);
400 return v;
405 IoObject *IoODEBody_setQuaternion(IoODEBody *self, IoObject *locals, IoMessage *m)
407 const double w = IoMessage_locals_doubleArgAt_(m, locals, 0);
408 const double x = IoMessage_locals_doubleArgAt_(m, locals, 1);
409 const double y = IoMessage_locals_doubleArgAt_(m, locals, 2);
410 const double z = IoMessage_locals_doubleArgAt_(m, locals, 3);
412 IoODEBody_assertValidBody(self, locals, m);
413 dBodySetQuaternion(BODYID, w, x, y, z);
414 return self;