2 //metadoc ODEBody copyright Jonathan Wright, 2006
3 //metadoc ODEBody license BSD revised
4 /*metadoc ODEBody description
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");
38 dBodyID
IoMessage_locals_odeBodyIdArgAt_(IoMessage
*self
, void *locals
, int n
)
40 IoObject
*body
= IoMessage_locals_odeBodyArgAt_(self
, locals
, n
);
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
);
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
)));
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
},
104 IoObject_addMethodTable_(self
, methodTable
);
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
;
119 IoODEWorld_addBody(world
, self
);
120 BODYID
= dBodyCreate(IoODEWorld_rawWorldId(world
));
121 dBodySetData(BODYID
, self
);
126 void IoODEBody_free(IoODEBody
*self
)
130 IoODEWorld_removeBody(WORLD
, self
);
131 dBodyDestroy(BODYID
);
133 free(IoObject_dataPointer(self
));
136 void IoODEBody_mark(IoODEBody
*self
)
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
);
158 IoObject
*IoODEBody_bodyFromId(void *state
, dBodyID id
)
162 return ((IoState
*)state
)->ioNil
;
166 return (IoODEBody
*)dBodyGetData(id
);
170 /* ----------------------------------------------------------- */
172 void IoODEBody_worldDestroyed(IoODEBody
*self
)
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
));
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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]);
366 IoObject
*IoODEBody_setRotation(IoODEBody
*self
, IoObject
*locals
, IoMessage
*m
)
368 IoODEBody_assertValidBody(self
, locals
, m
);
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);
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);
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);
384 dBodySetRotation(BODYID
, R
);
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]);
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);