/addons/ODE/source/IoODEBody.c

https://github.com/basuke/io · C · 416 lines · 322 code · 72 blank · 22 comment · 9 complexity · 488168fa7462b011f0618263bbc9053e MD5 · raw file

  1. //metadoc ODEBody copyright Jonathan Wright, 2006
  2. //metadoc ODEBody license BSD revised
  3. //metadoc ODEBody category Physics
  4. /*metadoc ODEBody description
  5. ODEBody binding
  6. */
  7. #include "IoODEBody.h"
  8. #include "IoODEMass.h"
  9. #include "IoState.h"
  10. #include "IoSeq.h"
  11. #include "IoSeq_ode.h"
  12. #include "GLIncludes.h"
  13. #define DATA(self) ((IoODEBodyData *)IoObject_dataPointer(self))
  14. #define BODYID (DATA(self)->bodyId)
  15. #define WORLD (DATA(self)->world)
  16. void IoODEBody_assertValidBody(IoODEBody *self, IoObject *locals, IoMessage *m)
  17. {
  18. IOASSERT(WORLD, "This ODE body belongs to an ODE world which has been freed.");
  19. IOASSERT(BODYID, "ODE World Body cannot be used directly. Clone the world and use the Body on the cloned world.");
  20. }
  21. IoODEBody *IoMessage_locals_odeBodyArgAt_(IoMessage *self, void *locals, int n)
  22. {
  23. IoObject *b = IoMessage_locals_valueArgAt_(self, locals, n);
  24. if (!ISODEBODY(b) && !ISNIL(b))
  25. {
  26. IoMessage_locals_numberArgAt_errorForType_(self, locals, n, "ODEBody");
  27. }
  28. return b;
  29. }
  30. dBodyID IoMessage_locals_odeBodyIdArgAt_(IoMessage *self, void *locals, int n)
  31. {
  32. IoObject *body = IoMessage_locals_odeBodyArgAt_(self, locals, n);
  33. if (ISNIL(body))
  34. {
  35. return 0;
  36. }
  37. else
  38. {
  39. return DATA(body)->bodyId;
  40. }
  41. }
  42. IoTag *IoODEBody_newTag(void *state)
  43. {
  44. IoTag *tag = IoTag_newWithName_("ODEBody");
  45. IoTag_state_(tag, state);
  46. IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoODEBody_free);
  47. IoTag_markFunc_(tag, (IoTagMarkFunc *)IoODEBody_mark);
  48. IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoODEBody_rawClone);
  49. return tag;
  50. }
  51. IoODEBody *IoODEBody_proto(void *state)
  52. {
  53. IoObject *self = IoObject_new(state);
  54. IoObject_tag_(self, IoODEBody_newTag(state));
  55. IoObject_setDataPointer_(self, calloc(1, sizeof(IoODEBodyData)));
  56. BODYID = 0;
  57. WORLD = 0L;
  58. IoState_registerProtoWithFunc_(state, self, IoODEBody_proto);
  59. {
  60. IoMethodTable methodTable[] = {
  61. {"bodyId", IoODEBody_bodyId},
  62. {"world", IoODEBody_world},
  63. {"mass", IoODEBody_mass},
  64. {"setMass", IoODEBody_setMass},
  65. {"position", IoODEBody_position},
  66. {"setPosition", IoODEBody_setPosition},
  67. {"force", IoODEBody_force},
  68. {"setForce", IoODEBody_setForce},
  69. {"addForce", IoODEBody_addForce},
  70. {"addRelForce", IoODEBody_addRelForce},
  71. {"torque", IoODEBody_torque},
  72. {"setTorque", IoODEBody_setTorque},
  73. {"addTorque", IoODEBody_addTorque},
  74. {"addRelTorque", IoODEBody_addRelTorque},
  75. {"linearVelocity", IoODEBody_linearVelocity},
  76. {"setLinearVelocity", IoODEBody_setLinearVelocity},
  77. {"quaternion", IoODEBody_quaternion},
  78. //{"setQuaternion", IoODEBody_setQuaternion},
  79. {"rotation", IoODEBody_rotation},
  80. {"setRotation", IoODEBody_setRotation},
  81. {"glMultMatrix", IoODEBody_glMultMatrix},
  82. {NULL, NULL},
  83. };
  84. IoObject_addMethodTable_(self, methodTable);
  85. }
  86. return self;
  87. }
  88. IoODEBody *IoODEBody_rawClone(IoODEBody *proto)
  89. {
  90. IoObject *self = IoObject_rawClonePrimitive(proto);
  91. IoObject_setDataPointer_(self, calloc(1, sizeof(IoODEBodyData)));
  92. if(DATA(proto)->world)
  93. {
  94. IoODEWorld *world = DATA(proto)->world;
  95. WORLD = world;
  96. IoODEWorld_addBody(world, self);
  97. BODYID = dBodyCreate(IoODEWorld_rawWorldId(world));
  98. dBodySetData(BODYID, self);
  99. }
  100. return self;
  101. }
  102. void IoODEBody_free(IoODEBody *self)
  103. {
  104. if(BODYID && WORLD)
  105. {
  106. IoODEWorld_removeBody(WORLD, self);
  107. dBodyDestroy(BODYID);
  108. }
  109. free(IoObject_dataPointer(self));
  110. }
  111. void IoODEBody_mark(IoODEBody *self)
  112. {
  113. if(WORLD)
  114. {
  115. IoObject_shouldMark((IoObject *)WORLD);
  116. }
  117. }
  118. IoODEBody *IoODEBody_new(void *state)
  119. {
  120. IoODEBody *proto = IoState_protoWithInitFunction_(state, IoODEBody_proto);
  121. return IOCLONE(proto);
  122. }
  123. IoODEBody *IoODEBody_newBodyProtoWithWorld(void *state, IoODEWorld *world)
  124. {
  125. IoODEBody *proto = IoState_protoWithInitFunction_(state, IoODEBody_proto);
  126. IoODEBody *self = IOCLONE(proto);
  127. WORLD = world;
  128. return self;
  129. }
  130. IoObject *IoODEBody_bodyFromId(void *state, dBodyID id)
  131. {
  132. if (id == 0)
  133. {
  134. return ((IoState*)state)->ioNil;
  135. }
  136. else
  137. {
  138. return (IoODEBody*)dBodyGetData(id);
  139. }
  140. }
  141. /* ----------------------------------------------------------- */
  142. void IoODEBody_worldDestroyed(IoODEBody *self)
  143. {
  144. WORLD = 0L;
  145. BODYID = 0;
  146. }
  147. /* ----------------------------------------------------------- */
  148. IoObject *IoODEBody_bodyId(IoODEBody *self, IoObject *locals, IoMessage *m)
  149. {
  150. return IONUMBER((long)BODYID);
  151. }
  152. IoObject *IoODEBody_world(IoODEBody *self, IoObject *locals, IoMessage *m)
  153. {
  154. return WORLD ? WORLD : IONIL(self);
  155. }
  156. IoObject *IoODEBody_mass(IoODEBody *self, IoObject *locals, IoMessage *m)
  157. {
  158. IoODEBody_assertValidBody(self, locals, m);
  159. {
  160. IoODEMass *mass = IoODEMass_new(IOSTATE);
  161. dBodyGetMass(BODYID, IoODEMass_dMassStruct(mass));
  162. return mass;
  163. }
  164. }
  165. IoObject *IoODEBody_setMass(IoODEBody *self, IoObject *locals, IoMessage *m)
  166. {
  167. IoODEBody_assertValidBody(self, locals, m);
  168. {
  169. dMass *mass = IoMessage_locals_odeMassStructArgAt_(m, locals, 0);
  170. dBodySetMass(BODYID, mass);
  171. }
  172. return self;
  173. }
  174. IoObject *IoODEBody_position(IoODEBody *self, IoObject *locals, IoMessage *m)
  175. {
  176. IoODEBody_assertValidBody(self, locals, m);
  177. return IoSeq_newWithODEPoint(IOSTATE, dBodyGetPosition(BODYID));
  178. }
  179. IoObject *IoODEBody_setPosition(IoODEBody *self, IoObject *locals, IoMessage *m)
  180. {
  181. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  182. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  183. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  184. IoODEBody_assertValidBody(self, locals, m);
  185. dBodySetPosition(BODYID, x, y, z);
  186. return self;
  187. }
  188. IoObject *IoODEBody_force(IoODEBody *self, IoObject *locals, IoMessage *m)
  189. {
  190. IoODEBody_assertValidBody(self, locals, m);
  191. return IoSeq_newWithODEPoint(IOSTATE, dBodyGetForce(BODYID));
  192. }
  193. IoObject *IoODEBody_setForce(IoODEBody *self, IoObject *locals, IoMessage *m)
  194. {
  195. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  196. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  197. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  198. IoODEBody_assertValidBody(self, locals, m);
  199. dBodySetForce(BODYID, x, y, z);
  200. return self;
  201. }
  202. IoObject *IoODEBody_addForce(IoODEBody *self, IoObject *locals, IoMessage *m)
  203. {
  204. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  205. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  206. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  207. IoODEBody_assertValidBody(self, locals, m);
  208. dBodyAddForce(BODYID, x, y, z);
  209. return self;
  210. }
  211. IoObject *IoODEBody_addRelForce(IoODEBody *self, IoObject *locals, IoMessage *m)
  212. {
  213. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  214. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  215. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  216. IoODEBody_assertValidBody(self, locals, m);
  217. dBodyAddRelForce(BODYID, x, y, z);
  218. return self;
  219. }
  220. IoObject *IoODEBody_torque(IoODEBody *self, IoObject *locals, IoMessage *m)
  221. {
  222. IoODEBody_assertValidBody(self, locals, m);
  223. return IoSeq_newWithODEPoint(IOSTATE, dBodyGetTorque(BODYID));
  224. }
  225. IoObject *IoODEBody_setTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
  226. {
  227. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  228. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  229. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  230. IoODEBody_assertValidBody(self, locals, m);
  231. dBodySetTorque(BODYID, x, y, z);
  232. return self;
  233. }
  234. IoObject *IoODEBody_addTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
  235. {
  236. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  237. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  238. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  239. IoODEBody_assertValidBody(self, locals, m);
  240. dBodyAddTorque(BODYID, x, y, z);
  241. return self;
  242. }
  243. IoObject *IoODEBody_addRelTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
  244. {
  245. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  246. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  247. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  248. IoODEBody_assertValidBody(self, locals, m);
  249. dBodyAddRelTorque(BODYID, x, y, z);
  250. return self;
  251. }
  252. IoObject *IoODEBody_linearVelocity(IoODEBody *self, IoObject *locals, IoMessage *m)
  253. {
  254. IoODEBody_assertValidBody(self, locals, m);
  255. return IoSeq_newWithODEPoint(IOSTATE, dBodyGetLinearVel(BODYID));
  256. }
  257. IoObject *IoODEBody_setLinearVelocity(IoODEBody *self, IoObject *locals, IoMessage *m)
  258. {
  259. const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
  260. const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
  261. const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);
  262. IoODEBody_assertValidBody(self, locals, m);
  263. dBodySetLinearVel(BODYID, x, y, z);
  264. return self;
  265. }
  266. IoObject *IoODEBody_glMultMatrix(IoODEBody *self, IoObject *locals, IoMessage *m)
  267. {
  268. IoODEBody_assertValidBody(self, locals, m);
  269. {
  270. dBodyID bodyId = BODYID;
  271. const dReal *pos = dBodyGetPosition(bodyId);
  272. const dReal *R = dBodyGetRotation(bodyId);
  273. 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};
  274. glMultMatrixf(matrix);
  275. return self;
  276. }
  277. }
  278. IoObject *IoODEBody_rotation(IoODEBody *self, IoObject *locals, IoMessage *m)
  279. {
  280. IoODEBody_assertValidBody(self, locals, m);
  281. {
  282. const dReal *R = dBodyGetRotation(BODYID);
  283. IoSeq *v = IoSeq_newFloatArrayOfSize_(IOSTATE, 9);
  284. UArray *u = IoSeq_rawUArray(v);
  285. UArray_at_putDouble_(u, 0, R[0]);
  286. UArray_at_putDouble_(u, 1, R[4]);
  287. UArray_at_putDouble_(u, 2, R[8]);
  288. UArray_at_putDouble_(u, 3, R[1]);
  289. UArray_at_putDouble_(u, 4, R[5]);
  290. UArray_at_putDouble_(u, 5, R[9]);
  291. UArray_at_putDouble_(u, 6, R[2]);
  292. UArray_at_putDouble_(u, 7, R[6]);
  293. UArray_at_putDouble_(u, 8, R[10]);
  294. return v;
  295. }
  296. }
  297. IoObject *IoODEBody_setRotation(IoODEBody *self, IoObject *locals, IoMessage *m)
  298. {
  299. IoODEBody_assertValidBody(self, locals, m);
  300. {
  301. dMatrix3 R;
  302. R[0] = IoMessage_locals_doubleArgAt_(m, locals, 0);
  303. R[1] = IoMessage_locals_doubleArgAt_(m, locals, 1);
  304. R[2] = IoMessage_locals_doubleArgAt_(m, locals, 2);
  305. R[3] = 0;
  306. R[4] = IoMessage_locals_doubleArgAt_(m, locals, 3);
  307. R[5] = IoMessage_locals_doubleArgAt_(m, locals, 4);
  308. R[6] = IoMessage_locals_doubleArgAt_(m, locals, 5);
  309. R[7] = 0;
  310. R[8] = IoMessage_locals_doubleArgAt_(m, locals, 6);
  311. R[9] = IoMessage_locals_doubleArgAt_(m, locals, 7);
  312. R[10] = IoMessage_locals_doubleArgAt_(m, locals, 8);
  313. R[11] = 0;
  314. dBodySetRotation(BODYID, R);
  315. return self;
  316. }
  317. }
  318. IoObject *IoODEBody_quaternion(IoODEBody *self, IoObject *locals, IoMessage *m)
  319. {
  320. IoODEBody_assertValidBody(self, locals, m);
  321. {
  322. const dReal *q = dBodyGetQuaternion(BODYID);
  323. IoSeq *v = IoSeq_newFloatArrayOfSize_(IOSTATE, 4);
  324. UArray *u = IoSeq_rawUArray(v);
  325. UArray_at_putDouble_(u, 0, q[0]);
  326. UArray_at_putDouble_(u, 1, q[1]);
  327. UArray_at_putDouble_(u, 2, q[2]);
  328. UArray_at_putDouble_(u, 3, q[3]);
  329. return v;
  330. }
  331. }
  332. /*
  333. IoObject *IoODEBody_setQuaternion(IoODEBody *self, IoObject *locals, IoMessage *m)
  334. {
  335. const double w = IoMessage_locals_doubleArgAt_(m, locals, 0);
  336. const double x = IoMessage_locals_doubleArgAt_(m, locals, 1);
  337. const double y = IoMessage_locals_doubleArgAt_(m, locals, 2);
  338. const double z = IoMessage_locals_doubleArgAt_(m, locals, 3);
  339. IoODEBody_assertValidBody(self, locals, m);
  340. dBodySetQuaternion(BODYID, w, x, y, z);
  341. return self;
  342. }
  343. */