Simple game engine with complete export to scripting language
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScriptSystem_RigidBody.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. #include "RigidBodySimulation.h"
  2. #include "ScriptSystem_Math.h"
  3. namespace BlueCore
  4. {
  5. //------------------------------------------------------------------------------
  6. static weak_ptr<RigidBodySimulation> gRigidBodySimulation;
  7. //------------------------------------------------------------------------------
  8. static SQInteger _rigidbody_getposition(HSQUIRRELVM v)
  9. {
  10. RigidBody *body = 0;
  11. Vector3 position;
  12. if (sq_gettop(v) == 1)
  13. {
  14. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  15. }
  16. if (body)
  17. {
  18. position = body->getPosition();
  19. _pushvector(v, position.x, position.y, position.z);
  20. return 1;
  21. }
  22. return 0;
  23. }
  24. //------------------------------------------------------------------------------
  25. static SQInteger _rigidbody_getrotation(HSQUIRRELVM v)
  26. {
  27. RigidBody *body = 0;
  28. Quaternion q;
  29. if (sq_gettop(v) == 1)
  30. {
  31. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  32. }
  33. if (body)
  34. {
  35. q = body->getOrientation();
  36. _pushquaternion(v, q.w, q.x, q.y, q.z);
  37. return 1;
  38. }
  39. return 0;
  40. }
  41. //------------------------------------------------------------------------------
  42. static SQInteger _rigidbody_getangularvelocity(HSQUIRRELVM v)
  43. {
  44. RigidBody *body = 0;
  45. Vector3 velocity;
  46. if (sq_gettop(v) == 1)
  47. {
  48. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  49. }
  50. if (body)
  51. {
  52. velocity = body->getAngularVelocity();
  53. _pushvector(v, velocity.x, velocity.y, velocity.z);
  54. return 1;
  55. }
  56. return 0;
  57. }
  58. //------------------------------------------------------------------------------
  59. static SQInteger _rigidbody_getlinearvelocity(HSQUIRRELVM v)
  60. {
  61. RigidBody *body = 0;
  62. Vector3 velocity;
  63. if (sq_gettop(v) == 1)
  64. {
  65. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  66. }
  67. if (body)
  68. {
  69. velocity = body->getLinearVelocity();
  70. _pushvector(v, velocity.x, velocity.y, velocity.z);
  71. return 1;
  72. }
  73. return 0;
  74. }
  75. //------------------------------------------------------------------------------
  76. static SQInteger _rigidbody_setposition(HSQUIRRELVM v)
  77. {
  78. RigidBody *body = 0;
  79. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  80. if (body)
  81. {
  82. Vector3 position;
  83. int argc = sq_gettop(v);
  84. if (argc == 2)
  85. {
  86. _getvectorvalues(v, 2, position.x, position.y, position.z);
  87. }
  88. else if (argc == 4)
  89. {
  90. sq_getfloat(v, 2, &position.x);
  91. sq_getfloat(v, 3, &position.y);
  92. sq_getfloat(v, 4, &position.z);
  93. }
  94. body->setPosition(position);
  95. }
  96. return 0;
  97. }
  98. //------------------------------------------------------------------------------
  99. static SQInteger _rigidbody_setlinearvelocity(HSQUIRRELVM v)
  100. {
  101. RigidBody *body = 0;
  102. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  103. if (body)
  104. {
  105. Vector3 velocity;
  106. int argc = sq_gettop(v);
  107. if (argc == 2)
  108. {
  109. _getvectorvalues(v, 2, velocity.x, velocity.y, velocity.z);
  110. }
  111. else if (argc == 4)
  112. {
  113. sq_getfloat(v, 2, &velocity.x);
  114. sq_getfloat(v, 3, &velocity.y);
  115. sq_getfloat(v, 4, &velocity.z);
  116. }
  117. body->setLinearVelocity(velocity);
  118. }
  119. return 0;
  120. }
  121. //------------------------------------------------------------------------------
  122. static SQInteger _rigidbody_setrotation(HSQUIRRELVM v)
  123. {
  124. RigidBody *body = 0;
  125. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  126. if (body)
  127. {
  128. Quaternion q;
  129. int argc = sq_gettop(v);
  130. if (argc == 2)
  131. {
  132. _getquaternionvalues(v, 2, q.w, q.x, q.y, q.z);
  133. }
  134. else if (argc == 5)
  135. {
  136. sq_getfloat(v, 2, &q.w);
  137. sq_getfloat(v, 3, &q.x);
  138. sq_getfloat(v, 4, &q.y);
  139. sq_getfloat(v, 5, &q.z);
  140. }
  141. body->setOrientation(q);
  142. }
  143. return 0;
  144. }
  145. //------------------------------------------------------------------------------
  146. static SQInteger _rigidbody_applylocalforce(HSQUIRRELVM v)
  147. {
  148. RigidBody *body = 0;
  149. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  150. if (body)
  151. {
  152. int argc = sq_gettop(v);
  153. if (argc == 2)
  154. {
  155. Vector3 force;
  156. _getvectorvalues(v, 2, force.x, force.y, force.z);
  157. body->applyLocalForce(force);
  158. }
  159. else if (argc == 3)
  160. {
  161. Vector3 force, point;
  162. _getvectorvalues(v, 2, force.x, force.y, force.z);
  163. _getvectorvalues(v, 3, point.x, point.y, point.z);
  164. body->applyLocalForce(force, point);
  165. }
  166. }
  167. return 0;
  168. }
  169. //------------------------------------------------------------------------------
  170. static SQInteger _rigidbody_applyglobalforce(HSQUIRRELVM v)
  171. {
  172. RigidBody *body = 0;
  173. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  174. if (body)
  175. {
  176. int argc = sq_gettop(v);
  177. if (argc == 2)
  178. {
  179. Vector3 force;
  180. _getvectorvalues(v, 2, force.x, force.y, force.z);
  181. body->applyGlobalForce(force);
  182. }
  183. else if (argc == 3)
  184. {
  185. Vector3 force, point;
  186. _getvectorvalues(v, 2, force.x, force.y, force.z);
  187. _getvectorvalues(v, 3, point.x, point.y, point.z);
  188. body->applyGlobalForce(force, point);
  189. }
  190. }
  191. return 0;
  192. }
  193. //------------------------------------------------------------------------------
  194. static SQInteger _rigidbody_addcollisionmesh(HSQUIRRELVM v)
  195. {
  196. SQInteger argc = sq_gettop(v);
  197. if (argc < 3)
  198. {
  199. sq_pushinteger(v, 0);
  200. return 1;
  201. }
  202. RigidBody *body = 0;
  203. const SQChar *meshname = 0;
  204. SQFloat density = 1.0;
  205. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  206. sq_getstring(v, 2, &meshname);
  207. sq_getfloat(v, 3, &density);
  208. if (body)
  209. {
  210. sq_pushinteger(v, body->addCollisionMesh(meshname, density) );
  211. }
  212. else
  213. sq_pushinteger(v, 0);
  214. return 1;
  215. }
  216. //------------------------------------------------------------------------------
  217. static SQInteger _rigidbody_setcollisionmeshposition(HSQUIRRELVM v)
  218. {
  219. int argc = sq_gettop(v);
  220. // need at least geom + vector
  221. if (argc < 3)
  222. return 0;
  223. RigidBody *body = 0;
  224. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  225. if (body)
  226. {
  227. SQInteger geom = 0;
  228. sq_getinteger(v, 2, &geom);
  229. Vector3 position;
  230. if (argc == 3)
  231. {
  232. _getvectorvalues(v, 3, position.x, position.y, position.z);
  233. }
  234. else if (argc == 5)
  235. {
  236. sq_getfloat(v, 3, &position.x);
  237. sq_getfloat(v, 4, &position.y);
  238. sq_getfloat(v, 5, &position.z);
  239. }
  240. body->setCollisionMeshPosition(geom, position);
  241. }
  242. return 0;
  243. }
  244. //------------------------------------------------------------------------------
  245. static SQInteger _rigidbody_disablecollisionmesh(HSQUIRRELVM v)
  246. {
  247. int argc = sq_gettop(v);
  248. // need at least geom
  249. if (argc < 2)
  250. return 0;
  251. RigidBody *body = 0;
  252. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  253. if (body)
  254. {
  255. SQInteger geom = 0;
  256. sq_getinteger(v, 2, &geom);
  257. body->disableCollisionMesh(geom);
  258. }
  259. return 0;
  260. }
  261. //------------------------------------------------------------------------------
  262. static SQInteger _rigidbody_enablecollisionmesh(HSQUIRRELVM v)
  263. {
  264. int argc = sq_gettop(v);
  265. // need at least geom
  266. if (argc < 2)
  267. return 0;
  268. RigidBody *body = 0;
  269. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  270. if (body)
  271. {
  272. SQInteger geom = 0;
  273. sq_getinteger(v, 2, &geom);
  274. body->enableCollisionMesh(geom);
  275. }
  276. return 0;
  277. }
  278. //------------------------------------------------------------------------------
  279. static SQInteger _rigidbody_setcollisionmeshrotation(HSQUIRRELVM v)
  280. {
  281. int argc = sq_gettop(v);
  282. // need at least geom + quaternion
  283. if (argc < 3)
  284. return 0;
  285. RigidBody *body = 0;
  286. sq_getinstanceup(v, 1, ( void ** ) &body, 0);
  287. if (body)
  288. {
  289. SQInteger geom = 0;
  290. sq_getinteger(v, 2, &geom);
  291. Quaternion rotation;
  292. if (argc == 3)
  293. {
  294. _getquaternionvalues(v, 3, rotation.w, rotation.x, rotation.y,
  295. rotation.z);
  296. }
  297. else if (argc == 4)
  298. {
  299. Vector3 axis;
  300. SQFloat angle;
  301. _getvectorvalues(v, 3, axis.x, axis.y, axis.z);
  302. sq_getfloat(v, 5, &angle);
  303. rotation = Quaternion(axis, angle);
  304. }
  305. else if (argc == 5)
  306. {
  307. SQFloat h, a, b;
  308. sq_getfloat(v, 3, &h);
  309. sq_getfloat(v, 4, &a);
  310. sq_getfloat(v, 5, &b);
  311. rotation = Quaternion(h, a, b);
  312. }
  313. body->setCollisionMeshRotation(geom, rotation);
  314. }
  315. return 0;
  316. }
  317. //------------------------------------------------------------------------------
  318. static SQInteger _rigidbody_releasehook(SQUserPointer p, SQInteger size)
  319. {
  320. if (gRigidBodySimulation.valid())
  321. {
  322. RigidBody *self = ( RigidBody* ) p;
  323. gRigidBodySimulation->deleteRigidBody(self);
  324. }
  325. return 1;
  326. }
  327. //------------------------------------------------------------------------------
  328. static SQInteger _rigidbody_constructor(HSQUIRRELVM v)
  329. {
  330. RigidBody *body = gRigidBodySimulation->createRigidBody();
  331. if (SQ_FAILED(sq_setinstanceup(v, 1, body) ) )
  332. {
  333. gRigidBodySimulation->deleteRigidBody(body);
  334. return 0;
  335. }
  336. HSQOBJECT obj;
  337. sq_getstackobj(v, 2, &obj);
  338. body->setCollisionHandler(obj);
  339. sq_setreleasehook(v, 1, _rigidbody_releasehook);
  340. return 0;
  341. }
  342. //------------------------------------------------------------------------------
  343. void setupScriptSystem_RigidBody(ScriptSystem *scriptsystem,
  344. RigidBodySimulation *simulation)
  345. {
  346. gRigidBodySimulation = simulation;
  347. HSQUIRRELVM vm = scriptsystem->getVM();
  348. sq_pushroottable(vm);
  349. sq_pushstring(vm, "RigidBody", -1);
  350. if (SQ_SUCCEEDED(sq_newclass(vm, SQFalse) ) )
  351. {
  352. // register rigidbody functions
  353. sq_pushstring(vm, "constructor", -1);
  354. sq_newclosure(vm, _rigidbody_constructor, 0);
  355. sq_newslot(vm, -3, false);
  356. sq_pushstring(vm, "setPosition", -1);
  357. sq_newclosure(vm, _rigidbody_setposition, 0);
  358. //sq_setparamscheck( vm, 2, "xx" );
  359. sq_newslot(vm, -3, false);
  360. sq_pushstring(vm, "getPosition", -1);
  361. sq_newclosure(vm, _rigidbody_getposition, 0);
  362. sq_setparamscheck(vm, 1, "x");
  363. sq_newslot(vm, -3, false);
  364. sq_pushstring(vm, "setRotation", -1);
  365. sq_newclosure(vm, _rigidbody_setrotation, 0);
  366. //sq_setparamscheck( vm, 2, "xx" );
  367. sq_newslot(vm, -3, false);
  368. sq_pushstring(vm, "getRotation", -1);
  369. sq_newclosure(vm, _rigidbody_getrotation, 0);
  370. sq_setparamscheck(vm, 1, "x");
  371. sq_newslot(vm, -3, false);
  372. sq_pushstring(vm, "getLinearVelocity", -1);
  373. sq_newclosure(vm, _rigidbody_getlinearvelocity, 0);
  374. sq_setparamscheck(vm, 1, "x");
  375. sq_newslot(vm, -3, false);
  376. sq_pushstring(vm, "setLinearVelocity", -1);
  377. sq_newclosure(vm, _rigidbody_setlinearvelocity, 0);
  378. sq_newslot(vm, -3, false);
  379. sq_pushstring(vm, "getAngularVelocity", -1);
  380. sq_newclosure(vm, _rigidbody_getangularvelocity, 0);
  381. sq_setparamscheck(vm, 1, "x");
  382. sq_newslot(vm, -3, false);
  383. sq_pushstring(vm, "applyLocalForce", -1);
  384. sq_newclosure(vm, _rigidbody_applylocalforce, 0);
  385. //sq_setparamscheck (vm, 3, "xxx");
  386. sq_newslot(vm, -3, false);
  387. sq_pushstring(vm, "applyGlobalForce", -1);
  388. sq_newclosure(vm, _rigidbody_applyglobalforce, 0);
  389. sq_setparamscheck(vm, 3, "xxx");
  390. sq_newslot(vm, -3, false);
  391. sq_pushstring(vm, "addCollisionMesh", -1);
  392. sq_newclosure(vm, _rigidbody_addcollisionmesh, 0);
  393. sq_setparamscheck(vm, 3, "xsn");
  394. sq_newslot(vm, -3, false);
  395. sq_pushstring(vm, "setCollisionMeshPosition", -1);
  396. sq_newclosure(vm, _rigidbody_setcollisionmeshposition, 0);
  397. sq_newslot(vm, -3, false);
  398. sq_pushstring(vm, "setCollisionMeshRotation", -1);
  399. sq_newclosure(vm, _rigidbody_setcollisionmeshrotation, 0);
  400. sq_newslot(vm, -3, false);
  401. sq_pushstring(vm, "getCollisionMeshPosition", -1);
  402. sq_newclosure(vm, _rigidbody_setcollisionmeshposition, 0);
  403. sq_newslot(vm, -3, false);
  404. sq_pushstring(vm, "getCollisionMeshRotation", -1);
  405. sq_newclosure(vm, _rigidbody_setcollisionmeshrotation, 0);
  406. sq_newslot(vm, -3, false);
  407. sq_pushstring(vm, "disableCollisionMesh", -1);
  408. sq_newclosure(vm, _rigidbody_disablecollisionmesh, 0);
  409. sq_newslot(vm, -3, false);
  410. sq_pushstring(vm, "enableCollisionMesh", -1);
  411. sq_newclosure(vm, _rigidbody_enablecollisionmesh, 0);
  412. sq_newslot(vm, -3, false);
  413. sq_newslot(vm, -3, false);
  414. }
  415. sq_poptop(vm);
  416. }
  417. } // namespace BlueCore