wrap_Physics.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /**
  2. * Copyright (c) 2006-2017 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "wrap_Physics.h"
  22. #include "wrap_World.h"
  23. #include "wrap_Contact.h"
  24. #include "wrap_Body.h"
  25. #include "wrap_Fixture.h"
  26. #include "wrap_Shape.h"
  27. #include "wrap_CircleShape.h"
  28. #include "wrap_PolygonShape.h"
  29. #include "wrap_EdgeShape.h"
  30. #include "wrap_ChainShape.h"
  31. #include "wrap_Joint.h"
  32. #include "wrap_MouseJoint.h"
  33. #include "wrap_DistanceJoint.h"
  34. #include "wrap_PrismaticJoint.h"
  35. #include "wrap_RevoluteJoint.h"
  36. #include "wrap_PulleyJoint.h"
  37. #include "wrap_GearJoint.h"
  38. #include "wrap_FrictionJoint.h"
  39. #include "wrap_WeldJoint.h"
  40. #include "wrap_WheelJoint.h"
  41. #include "wrap_RopeJoint.h"
  42. #include "wrap_MotorJoint.h"
  43. namespace love
  44. {
  45. namespace physics
  46. {
  47. namespace box2d
  48. {
  49. #define instance() (Module::getInstance<Physics>(Module::M_PHYSICS))
  50. int w_newWorld(lua_State *L)
  51. {
  52. float gx = (float)luaL_optnumber(L, 1, 0);
  53. float gy = (float)luaL_optnumber(L, 2, 0);
  54. bool sleep = luax_optboolean(L, 3, true);
  55. World *w;
  56. luax_catchexcept(L, [&](){ w = instance()->newWorld(gx, gy, sleep); });
  57. luax_pushtype(L, w);
  58. w->release();
  59. return 1;
  60. }
  61. int w_newBody(lua_State *L)
  62. {
  63. World *world = luax_checkworld(L, 1);
  64. float x = (float)luaL_optnumber(L, 2, 0.0);
  65. float y = (float)luaL_optnumber(L, 3, 0.0);
  66. Body::Type btype = Body::BODY_STATIC;
  67. const char *typestr = lua_isnoneornil(L, 4) ? 0 : lua_tostring(L, 4);
  68. if (typestr && !Body::getConstant(typestr, btype))
  69. return luaL_error(L, "Invalid Body type: %s", typestr);
  70. Body *body;
  71. luax_catchexcept(L, [&](){ body = instance()->newBody(world, x, y, btype); });
  72. luax_pushtype(L, body);
  73. body->release();
  74. return 1;
  75. }
  76. int w_newFixture(lua_State *L)
  77. {
  78. Body *body = luax_checkbody(L, 1);
  79. Shape *shape = luax_checkshape(L, 2);
  80. float density = (float)luaL_optnumber(L, 3, 1.0f);
  81. Fixture *fixture;
  82. luax_catchexcept(L, [&](){ fixture = instance()->newFixture(body, shape, density); });
  83. luax_pushtype(L, fixture);
  84. fixture->release();
  85. return 1;
  86. }
  87. int w_newCircleShape(lua_State *L)
  88. {
  89. int top = lua_gettop(L);
  90. if (top == 1)
  91. {
  92. float radius = (float)luaL_checknumber(L, 1);
  93. CircleShape *shape;
  94. luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(radius); });
  95. luax_pushtype(L, shape);
  96. shape->release();
  97. return 1;
  98. }
  99. else if (top == 3)
  100. {
  101. float x = (float)luaL_checknumber(L, 1);
  102. float y = (float)luaL_checknumber(L, 2);
  103. float radius = (float)luaL_checknumber(L, 3);
  104. CircleShape *shape;
  105. luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(x, y, radius); });
  106. luax_pushtype(L, shape);
  107. shape->release();
  108. return 1;
  109. }
  110. else
  111. return luaL_error(L, "Incorrect number of parameters");
  112. }
  113. int w_newRectangleShape(lua_State *L)
  114. {
  115. int top = lua_gettop(L);
  116. if (top == 2)
  117. {
  118. float w = (float)luaL_checknumber(L, 1);
  119. float h = (float)luaL_checknumber(L, 2);
  120. PolygonShape *shape;
  121. luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(w, h); });
  122. luax_pushtype(L, shape);
  123. shape->release();
  124. return 1;
  125. }
  126. else if (top == 4 || top == 5)
  127. {
  128. float x = (float)luaL_checknumber(L, 1);
  129. float y = (float)luaL_checknumber(L, 2);
  130. float w = (float)luaL_checknumber(L, 3);
  131. float h = (float)luaL_checknumber(L, 4);
  132. float angle = (float)luaL_optnumber(L, 5, 0);
  133. PolygonShape *shape;
  134. luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(x, y, w, h, angle); });
  135. luax_pushtype(L, shape);
  136. shape->release();
  137. return 1;
  138. }
  139. else
  140. return luaL_error(L, "Incorrect number of parameters");
  141. }
  142. int w_newEdgeShape(lua_State *L)
  143. {
  144. float x1 = (float)luaL_checknumber(L, 1);
  145. float y1 = (float)luaL_checknumber(L, 2);
  146. float x2 = (float)luaL_checknumber(L, 3);
  147. float y2 = (float)luaL_checknumber(L, 4);
  148. EdgeShape *shape;
  149. luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(x1, y1, x2, y2); });
  150. luax_pushtype(L, shape);
  151. shape->release();
  152. return 1;
  153. }
  154. int w_newPolygonShape(lua_State *L)
  155. {
  156. int ret = 0;
  157. luax_catchexcept(L, [&](){ ret = instance()->newPolygonShape(L); });
  158. return ret;
  159. }
  160. int w_newChainShape(lua_State *L)
  161. {
  162. int ret = 0;
  163. luax_catchexcept(L, [&](){ ret = instance()->newChainShape(L); });
  164. return ret;
  165. }
  166. int w_newDistanceJoint(lua_State *L)
  167. {
  168. Body *body1 = luax_checkbody(L, 1);
  169. Body *body2 = luax_checkbody(L, 2);
  170. float x1 = (float)luaL_checknumber(L, 3);
  171. float y1 = (float)luaL_checknumber(L, 4);
  172. float x2 = (float)luaL_checknumber(L, 5);
  173. float y2 = (float)luaL_checknumber(L, 6);
  174. bool collideConnected = luax_optboolean(L, 7, false);
  175. DistanceJoint *j;
  176. luax_catchexcept(L, [&]() {
  177. j = instance()->newDistanceJoint(body1, body2, x1, y1, x2, y2, collideConnected);
  178. });
  179. luax_pushtype(L, j);
  180. j->release();
  181. return 1;
  182. }
  183. int w_newMouseJoint(lua_State *L)
  184. {
  185. Body *body = luax_checkbody(L, 1);
  186. float x = (float)luaL_checknumber(L, 2);
  187. float y = (float)luaL_checknumber(L, 3);
  188. MouseJoint *j;
  189. luax_catchexcept(L, [&](){ j = instance()->newMouseJoint(body, x, y); });
  190. luax_pushtype(L, j);
  191. j->release();
  192. return 1;
  193. }
  194. int w_newRevoluteJoint(lua_State *L)
  195. {
  196. Body *body1 = luax_checkbody(L, 1);
  197. Body *body2 = luax_checkbody(L, 2);
  198. float xA = (float)luaL_checknumber(L, 3);
  199. float yA = (float)luaL_checknumber(L, 4);
  200. float xB, yB;
  201. bool collideConnected;
  202. if (lua_gettop(L) >= 6)
  203. {
  204. xB = (float)luaL_checknumber(L, 5);
  205. yB = (float)luaL_checknumber(L, 6);
  206. collideConnected = luax_optboolean(L, 7, false);
  207. }
  208. else
  209. {
  210. xB = xA;
  211. yB = yA;
  212. collideConnected = luax_optboolean(L, 5, false);
  213. }
  214. RevoluteJoint *j;
  215. luax_catchexcept(L, [&]() {
  216. if (lua_gettop(L) >= 8)
  217. {
  218. float referenceAngle = (float)luaL_checknumber(L, 8);
  219. j = instance()->newRevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle);
  220. }
  221. else
  222. j = instance()->newRevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected);
  223. });
  224. luax_pushtype(L, j);
  225. j->release();
  226. return 1;
  227. }
  228. int w_newPrismaticJoint(lua_State *L)
  229. {
  230. Body *body1 = luax_checkbody(L, 1);
  231. Body *body2 = luax_checkbody(L, 2);
  232. float xA = (float)luaL_checknumber(L, 3);
  233. float yA = (float)luaL_checknumber(L, 4);
  234. float xB, yB, ax, ay;
  235. bool collideConnected;
  236. if (lua_gettop(L) >= 8)
  237. {
  238. xB = (float)luaL_checknumber(L, 5);
  239. yB = (float)luaL_checknumber(L, 6);
  240. ax = (float)luaL_checknumber(L, 7);
  241. ay = (float)luaL_checknumber(L, 8);
  242. collideConnected = luax_optboolean(L, 9, false);
  243. }
  244. else
  245. {
  246. xB = xA;
  247. yB = yA;
  248. ax = (float)luaL_checknumber(L, 5);
  249. ay = (float)luaL_checknumber(L, 6);
  250. collideConnected = luax_optboolean(L, 7, false);
  251. }
  252. PrismaticJoint *j;
  253. luax_catchexcept(L, [&]() {
  254. if (lua_gettop(L) >= 10)
  255. {
  256. float referenceAngle = (float)luaL_checknumber(L, 10);
  257. j = instance()->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected, referenceAngle);
  258. }
  259. else
  260. j = instance()->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);
  261. });
  262. luax_pushtype(L, j);
  263. j->release();
  264. return 1;
  265. }
  266. int w_newPulleyJoint(lua_State *L)
  267. {
  268. Body *body1 = luax_checkbody(L, 1);
  269. Body *body2 = luax_checkbody(L, 2);
  270. float gx1 = (float)luaL_checknumber(L, 3);
  271. float gy1 = (float)luaL_checknumber(L, 4);
  272. float gx2 = (float)luaL_checknumber(L, 5);
  273. float gy2 = (float)luaL_checknumber(L, 6);
  274. float x1 = (float)luaL_checknumber(L, 7);
  275. float y1 = (float)luaL_checknumber(L, 8);
  276. float x2 = (float)luaL_checknumber(L, 9);
  277. float y2 = (float)luaL_checknumber(L, 10);
  278. float ratio = (float)luaL_optnumber(L, 11, 1.0);
  279. bool collideConnected = luax_optboolean(L, 12, true); // PulleyJoints default to colliding connected bodies, see b2PulleyJoint.h
  280. PulleyJoint *j;
  281. luax_catchexcept(L, [&]() {
  282. j = instance()->newPulleyJoint(body1, body2, b2Vec2(gx1,gy1), b2Vec2(gx2,gy2), b2Vec2(x1,y1), b2Vec2(x2,y2), ratio, collideConnected);
  283. });
  284. luax_pushtype(L, j);
  285. j->release();
  286. return 1;
  287. }
  288. int w_newGearJoint(lua_State *L)
  289. {
  290. Joint *joint1 = luax_checkjoint(L, 1);
  291. Joint *joint2 = luax_checkjoint(L, 2);
  292. float ratio = (float)luaL_optnumber(L, 3, 1.0);
  293. bool collideConnected = luax_optboolean(L, 4, false);
  294. GearJoint *j;
  295. luax_catchexcept(L, [&]() {
  296. j = instance()->newGearJoint(joint1, joint2, ratio, collideConnected);
  297. });
  298. luax_pushtype(L, j);
  299. j->release();
  300. return 1;
  301. }
  302. int w_newFrictionJoint(lua_State *L)
  303. {
  304. Body *body1 = luax_checkbody(L, 1);
  305. Body *body2 = luax_checkbody(L, 2);
  306. float xA = (float)luaL_checknumber(L, 3);
  307. float yA = (float)luaL_checknumber(L, 4);
  308. float xB, yB;
  309. bool collideConnected;
  310. if (lua_gettop(L) >= 6)
  311. {
  312. xB = (float)luaL_checknumber(L, 5);
  313. yB = (float)luaL_checknumber(L, 6);
  314. collideConnected = luax_optboolean(L, 7, false);
  315. }
  316. else
  317. {
  318. xB = xA;
  319. yB = yA;
  320. collideConnected = luax_optboolean(L, 5, false);
  321. }
  322. FrictionJoint *j;
  323. luax_catchexcept(L, [&]() {
  324. j = instance()->newFrictionJoint(body1, body2, xA, yA, xB, yB, collideConnected);
  325. });
  326. luax_pushtype(L, j);
  327. j->release();
  328. return 1;
  329. }
  330. int w_newWeldJoint(lua_State *L)
  331. {
  332. Body *body1 = luax_checkbody(L, 1);
  333. Body *body2 = luax_checkbody(L, 2);
  334. float xA = (float)luaL_checknumber(L, 3);
  335. float yA = (float)luaL_checknumber(L, 4);
  336. float xB, yB;
  337. bool collideConnected;
  338. if (lua_gettop(L) >= 6)
  339. {
  340. xB = (float)luaL_checknumber(L, 5);
  341. yB = (float)luaL_checknumber(L, 6);
  342. collideConnected = luax_optboolean(L, 7, false);
  343. }
  344. else
  345. {
  346. xB = xA;
  347. yB = yA;
  348. collideConnected = luax_optboolean(L, 5, false);
  349. }
  350. WeldJoint *j;
  351. luax_catchexcept(L, [&]() {
  352. if (lua_gettop(L) >= 8)
  353. {
  354. float referenceAngle = (float)luaL_checknumber(L, 8);
  355. j = instance()->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle);
  356. }
  357. else
  358. j = instance()->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected);
  359. });
  360. luax_pushtype(L, j);
  361. j->release();
  362. return 1;
  363. }
  364. int w_newWheelJoint(lua_State *L)
  365. {
  366. Body *body1 = luax_checkbody(L, 1);
  367. Body *body2 = luax_checkbody(L, 2);
  368. float xA = (float)luaL_checknumber(L, 3);
  369. float yA = (float)luaL_checknumber(L, 4);
  370. float xB, yB, ax, ay;
  371. bool collideConnected;
  372. if (lua_gettop(L) >= 8)
  373. {
  374. xB = (float)luaL_checknumber(L, 5);
  375. yB = (float)luaL_checknumber(L, 6);
  376. ax = (float)luaL_checknumber(L, 7);
  377. ay = (float)luaL_checknumber(L, 8);
  378. collideConnected = luax_optboolean(L, 9, false);
  379. }
  380. else
  381. {
  382. xB = xA;
  383. yB = yA;
  384. ax = (float)luaL_checknumber(L, 5);
  385. ay = (float)luaL_checknumber(L, 6);
  386. collideConnected = luax_optboolean(L, 7, false);
  387. }
  388. WheelJoint *j;
  389. luax_catchexcept(L, [&]() {
  390. j = instance()->newWheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);
  391. });
  392. luax_pushtype(L, j);
  393. j->release();
  394. return 1;
  395. }
  396. int w_newRopeJoint(lua_State *L)
  397. {
  398. Body *body1 = luax_checkbody(L, 1);
  399. Body *body2 = luax_checkbody(L, 2);
  400. float x1 = (float)luaL_checknumber(L, 3);
  401. float y1 = (float)luaL_checknumber(L, 4);
  402. float x2 = (float)luaL_checknumber(L, 5);
  403. float y2 = (float)luaL_checknumber(L, 6);
  404. float maxLength = (float)luaL_checknumber(L, 7);
  405. bool collideConnected = luax_optboolean(L, 8, false);
  406. RopeJoint *j;
  407. luax_catchexcept(L, [&]() {
  408. j = instance()->newRopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected);
  409. });
  410. luax_pushtype(L, j);
  411. j->release();
  412. return 1;
  413. }
  414. int w_newMotorJoint(lua_State *L)
  415. {
  416. Body *body1 = luax_checkbody(L, 1);
  417. Body *body2 = luax_checkbody(L, 2);
  418. MotorJoint *j = 0;
  419. if (!lua_isnoneornil(L, 3))
  420. {
  421. float correctionFactor = (float)luaL_checknumber(L, 3);
  422. bool collideConnected = luax_optboolean(L, 4, false);
  423. luax_catchexcept(L, [&]() {
  424. j = instance()->newMotorJoint(body1, body2, correctionFactor, collideConnected);
  425. });
  426. }
  427. else
  428. {
  429. luax_catchexcept(L, [&](){ j = instance()->newMotorJoint(body1, body2); });
  430. }
  431. luax_pushtype(L, j);
  432. j->release();
  433. return 1;
  434. }
  435. int w_getDistance(lua_State *L)
  436. {
  437. return instance()->getDistance(L);
  438. }
  439. int w_setMeter(lua_State *L)
  440. {
  441. int arg1 = (int) luaL_checknumber(L, 1);
  442. luax_catchexcept(L, [&](){ Physics::setMeter(arg1); });
  443. return 0;
  444. }
  445. int w_getMeter(lua_State *L)
  446. {
  447. lua_pushinteger(L, Physics::getMeter());
  448. return 1;
  449. }
  450. // List of functions to wrap.
  451. static const luaL_Reg functions[] =
  452. {
  453. { "newWorld", w_newWorld },
  454. { "newBody", w_newBody },
  455. { "newFixture", w_newFixture },
  456. { "newCircleShape", w_newCircleShape },
  457. { "newRectangleShape", w_newRectangleShape },
  458. { "newPolygonShape", w_newPolygonShape },
  459. { "newEdgeShape", w_newEdgeShape },
  460. { "newChainShape", w_newChainShape },
  461. { "newDistanceJoint", w_newDistanceJoint },
  462. { "newMouseJoint", w_newMouseJoint },
  463. { "newRevoluteJoint", w_newRevoluteJoint },
  464. { "newPrismaticJoint", w_newPrismaticJoint },
  465. { "newPulleyJoint", w_newPulleyJoint },
  466. { "newGearJoint", w_newGearJoint },
  467. { "newFrictionJoint", w_newFrictionJoint },
  468. { "newWeldJoint", w_newWeldJoint },
  469. { "newWheelJoint", w_newWheelJoint },
  470. { "newRopeJoint", w_newRopeJoint },
  471. { "newMotorJoint", w_newMotorJoint },
  472. { "getDistance", w_getDistance },
  473. { "getMeter", w_getMeter },
  474. { "setMeter", w_setMeter },
  475. { 0, 0 },
  476. };
  477. static const lua_CFunction types[] =
  478. {
  479. luaopen_world,
  480. luaopen_contact,
  481. luaopen_body,
  482. luaopen_fixture,
  483. luaopen_shape,
  484. luaopen_circleshape,
  485. luaopen_polygonshape,
  486. luaopen_edgeshape,
  487. luaopen_chainshape,
  488. luaopen_joint,
  489. luaopen_mousejoint,
  490. luaopen_distancejoint,
  491. luaopen_prismaticjoint,
  492. luaopen_revolutejoint,
  493. luaopen_pulleyjoint,
  494. luaopen_gearjoint,
  495. luaopen_frictionjoint,
  496. luaopen_weldjoint,
  497. luaopen_wheeljoint,
  498. luaopen_ropejoint,
  499. luaopen_motorjoint,
  500. 0
  501. };
  502. extern "C" int luaopen_love_physics(lua_State *L)
  503. {
  504. Physics *instance = instance();
  505. if (instance == nullptr)
  506. {
  507. luax_catchexcept(L, [&](){ instance = new Physics(); });
  508. }
  509. else
  510. instance->retain();
  511. WrappedModule w;
  512. w.module = instance;
  513. w.name = "physics";
  514. w.type = &Module::type;
  515. w.functions = functions;
  516. w.types = types;
  517. return luax_register_module(L, w);
  518. }
  519. } // box2d
  520. } // physics
  521. } // love