lua_math.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "math_utils.h"
  6. #include "math_types.h"
  7. #include "vector3.h"
  8. #include "matrix4x4.h"
  9. #include "quaternion.h"
  10. #include "color4.h"
  11. #include "intersection.h"
  12. #include "lua_stack.h"
  13. #include "lua_environment.h"
  14. namespace crown
  15. {
  16. static int math_ray_plane_intersection(lua_State* L)
  17. {
  18. LuaStack stack(L);
  19. Plane p;
  20. p.n = stack.get_vector3(3);
  21. p.d = stack.get_float(4);
  22. stack.push_float(ray_plane_intersection(stack.get_vector3(1), stack.get_vector3(2), p));
  23. return 1;
  24. }
  25. static int math_ray_sphere_intersection(lua_State* L)
  26. {
  27. LuaStack stack(L);
  28. Sphere s;
  29. s.c = stack.get_vector3(3);
  30. s.r = stack.get_float(4);
  31. stack.push_float(ray_sphere_intersection(stack.get_vector3(1), stack.get_vector3(2), s));
  32. return 1;
  33. }
  34. static int math_ray_obb_intersection(lua_State* L)
  35. {
  36. LuaStack stack(L);
  37. stack.push_float(ray_obb_intersection(stack.get_vector3(1)
  38. , stack.get_vector3(2)
  39. , stack.get_matrix4x4(3)
  40. , stack.get_vector3(4)));
  41. return 1;
  42. }
  43. static int vector3_new(lua_State* L)
  44. {
  45. LuaStack stack(L);
  46. stack.push_vector3(vector3(stack.get_float(1), stack.get_float(2), stack.get_float(3)));
  47. return 1;
  48. }
  49. static int vector3_ctor(lua_State* L)
  50. {
  51. LuaStack stack(L);
  52. stack.remove(1); // Remove table
  53. return vector3_new(L);
  54. }
  55. static int vector3_x(lua_State* L)
  56. {
  57. LuaStack stack(L);
  58. stack.push_float(stack.get_vector3(1).x);
  59. return 1;
  60. }
  61. static int vector3_y(lua_State* L)
  62. {
  63. LuaStack stack(L);
  64. stack.push_float(stack.get_vector3(1).y);
  65. return 1;
  66. }
  67. static int vector3_z(lua_State* L)
  68. {
  69. LuaStack stack(L);
  70. stack.push_float(stack.get_vector3(1).z);
  71. return 1;
  72. }
  73. static int vector3_set_x(lua_State* L)
  74. {
  75. LuaStack stack(L);
  76. stack.get_vector3(1).x = stack.get_float(2);
  77. return 0;
  78. }
  79. static int vector3_set_y(lua_State* L)
  80. {
  81. LuaStack stack(L);
  82. stack.get_vector3(1).y = stack.get_float(2);
  83. return 0;
  84. }
  85. static int vector3_set_z(lua_State* L)
  86. {
  87. LuaStack stack(L);
  88. stack.get_vector3(1).z = stack.get_float(2);
  89. return 0;
  90. }
  91. static int vector3_values(lua_State* L)
  92. {
  93. LuaStack stack(L);
  94. Vector3& a = stack.get_vector3(1);
  95. stack.push_float(a.x);
  96. stack.push_float(a.y);
  97. stack.push_float(a.z);
  98. return 3;
  99. }
  100. static int vector3_add(lua_State* L)
  101. {
  102. LuaStack stack(L);
  103. stack.push_vector3(stack.get_vector3(1) + stack.get_vector3(2));
  104. return 1;
  105. }
  106. static int vector3_subtract(lua_State* L)
  107. {
  108. LuaStack stack(L);
  109. stack.push_vector3(stack.get_vector3(1) - stack.get_vector3(2));
  110. return 1;
  111. }
  112. static int vector3_multiply(lua_State* L)
  113. {
  114. LuaStack stack(L);
  115. stack.push_vector3(stack.get_vector3(1) * stack.get_float(2));
  116. return 1;
  117. }
  118. static int vector3_divide(lua_State* L)
  119. {
  120. LuaStack stack(L);
  121. stack.push_vector3(stack.get_vector3(1) / stack.get_float(2));
  122. return 1;
  123. }
  124. static int vector3_dot(lua_State* L)
  125. {
  126. LuaStack stack(L);
  127. stack.push_float(dot(stack.get_vector3(1), stack.get_vector3(2)));
  128. return 1;
  129. }
  130. static int vector3_cross(lua_State* L)
  131. {
  132. LuaStack stack(L);
  133. stack.push_vector3(cross(stack.get_vector3(1), stack.get_vector3(2)));
  134. return 1;
  135. }
  136. static int vector3_equal(lua_State* L)
  137. {
  138. LuaStack stack(L);
  139. stack.push_bool(stack.get_vector3(1) == stack.get_vector3(2));
  140. return 1;
  141. }
  142. static int vector3_length(lua_State* L)
  143. {
  144. LuaStack stack(L);
  145. stack.push_float(length(stack.get_vector3(1)));
  146. return 1;
  147. }
  148. static int vector3_squared_length(lua_State* L)
  149. {
  150. LuaStack stack(L);
  151. stack.push_float(squared_length(stack.get_vector3(1)));
  152. return 1;
  153. }
  154. static int vector3_set_length(lua_State* L)
  155. {
  156. LuaStack stack(L);
  157. set_length(stack.get_vector3(1), stack.get_float(2));
  158. return 0;
  159. }
  160. static int vector3_normalize(lua_State* L)
  161. {
  162. LuaStack stack(L);
  163. stack.push_vector3(normalize(stack.get_vector3(1)));
  164. return 1;
  165. }
  166. static int vector3_distance(lua_State* L)
  167. {
  168. LuaStack stack(L);
  169. stack.push_float(distance(stack.get_vector3(1), stack.get_vector3(2)));
  170. return 1;
  171. }
  172. static int vector3_angle(lua_State* L)
  173. {
  174. LuaStack stack(L);
  175. stack.push_float(angle(stack.get_vector3(1), stack.get_vector3(2)));
  176. return 1;
  177. }
  178. static int vector3_max(lua_State* L)
  179. {
  180. LuaStack stack(L);
  181. stack.push_vector3(max(stack.get_vector3(1), stack.get_vector3(2)));
  182. return 1;
  183. }
  184. static int vector3_min(lua_State* L)
  185. {
  186. LuaStack stack(L);
  187. stack.push_vector3(min(stack.get_vector3(1), stack.get_vector3(2)));
  188. return 1;
  189. }
  190. static int vector3_forward(lua_State* L)
  191. {
  192. LuaStack stack(L);
  193. stack.push_vector3(VECTOR3_FORWARD);
  194. return 1;
  195. }
  196. static int vector3_backward(lua_State* L)
  197. {
  198. LuaStack stack(L);
  199. stack.push_vector3(VECTOR3_BACKWARD);
  200. return 1;
  201. }
  202. static int vector3_left(lua_State* L)
  203. {
  204. LuaStack stack(L);
  205. stack.push_vector3(VECTOR3_LEFT);
  206. return 1;
  207. }
  208. static int vector3_right(lua_State* L)
  209. {
  210. LuaStack stack(L);
  211. stack.push_vector3(VECTOR3_RIGHT);
  212. return 1;
  213. }
  214. static int vector3_up(lua_State* L)
  215. {
  216. LuaStack stack(L);
  217. stack.push_vector3(VECTOR3_UP);
  218. return 1;
  219. }
  220. static int vector3_down(lua_State* L)
  221. {
  222. LuaStack stack(L);
  223. stack.push_vector3(VECTOR3_DOWN);
  224. return 1;
  225. }
  226. static int vector3_zero(lua_State* L)
  227. {
  228. LuaStack stack(L);
  229. stack.push_vector3(VECTOR3_ZERO);
  230. return 1;
  231. }
  232. static int vector2_new(lua_State* L)
  233. {
  234. LuaStack stack(L);
  235. stack.push_vector2(vector2(stack.get_float(1), stack.get_float(2)));
  236. return 1;
  237. }
  238. static int vector2_ctor(lua_State* L)
  239. {
  240. LuaStack stack(L);
  241. stack.remove(1); // Remove table
  242. return vector2_new(L);
  243. }
  244. static int vector3box_new(lua_State* L)
  245. {
  246. LuaStack stack(L);
  247. if (stack.num_args() == 0)
  248. stack.push_vector3box(Vector3());
  249. else if (stack.num_args() == 1)
  250. stack.push_vector3box(stack.get_vector3(1));
  251. else
  252. stack.push_vector3box(vector3(stack.get_float(1)
  253. , stack.get_float(2)
  254. , stack.get_float(3)));
  255. return 1;
  256. }
  257. static int vector3box_ctor(lua_State* L)
  258. {
  259. LuaStack stack(L);
  260. stack.remove(1); // Remove table
  261. return vector3box_new(L);
  262. }
  263. static int vector3box_store(lua_State* L)
  264. {
  265. LuaStack stack(L);
  266. Vector3& v = stack.get_vector3box(1);
  267. if (stack.num_args() == 2)
  268. v = stack.get_vector3(2);
  269. else
  270. v = vector3(stack.get_float(2)
  271. , stack.get_float(3)
  272. , stack.get_float(4));
  273. return 0;
  274. }
  275. static int vector3box_unbox(lua_State* L)
  276. {
  277. LuaStack stack(L);
  278. stack.push_vector3(stack.get_vector3box(1));
  279. return 1;
  280. }
  281. static int vector3box_get_value(lua_State* L)
  282. {
  283. LuaStack stack(L);
  284. Vector3& v = stack.get_vector3box(1);
  285. const char* s = stack.get_string(2);
  286. switch (s[0])
  287. {
  288. case 'x': stack.push_float(v.x); return 1;
  289. case 'y': stack.push_float(v.y); return 1;
  290. case 'z': stack.push_float(v.z); return 1;
  291. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  292. }
  293. return 0;
  294. }
  295. static int vector3box_set_value(lua_State* L)
  296. {
  297. LuaStack stack(L);
  298. Vector3& v = stack.get_vector3box(1);
  299. const char* s = stack.get_string(2);
  300. const float value = stack.get_float(3);
  301. switch (s[0])
  302. {
  303. case 'x': v.x = value; break;
  304. case 'y': v.y = value; break;
  305. case 'z': v.z = value; break;
  306. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  307. }
  308. return 0;
  309. }
  310. static int vector3box_tostring(lua_State* L)
  311. {
  312. LuaStack stack(L);
  313. Vector3& v = stack.get_vector3box(1);
  314. stack.push_fstring("Vector3Box (%p)", &v);
  315. return 1;
  316. }
  317. static int matrix4x4_new(lua_State* L)
  318. {
  319. LuaStack stack(L);
  320. stack.push_matrix4x4(matrix4x4(stack.get_float(1)
  321. , stack.get_float(2)
  322. , stack.get_float(3)
  323. , stack.get_float(4)
  324. , stack.get_float(5)
  325. , stack.get_float(6)
  326. , stack.get_float(7)
  327. , stack.get_float(8)
  328. , stack.get_float(9)
  329. , stack.get_float(10)
  330. , stack.get_float(11)
  331. , stack.get_float(12)
  332. , stack.get_float(13)
  333. , stack.get_float(14)
  334. , stack.get_float(15)
  335. , stack.get_float(16)));
  336. return 1;
  337. }
  338. static int matrix4x4_ctor(lua_State* L)
  339. {
  340. LuaStack stack(L);
  341. stack.remove(1); // Remove table
  342. return matrix4x4_new(L);
  343. }
  344. static int matrix4x4_from_quaternion(lua_State* L)
  345. {
  346. LuaStack stack(L);
  347. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), vector3(0, 0, 0)));
  348. return 1;
  349. }
  350. static int matrix4x4_from_translation(lua_State* L)
  351. {
  352. LuaStack stack(L);
  353. stack.push_matrix4x4(matrix4x4(QUATERNION_IDENTITY, stack.get_vector3(1)));
  354. return 1;
  355. }
  356. static int matrix4x4_from_quaternion_translation(lua_State* L)
  357. {
  358. LuaStack stack(L);
  359. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), stack.get_vector3(2)));
  360. return 1;
  361. }
  362. static int matrix4x4_from_axes(lua_State* L)
  363. {
  364. LuaStack stack(L);
  365. stack.push_matrix4x4(matrix4x4(stack.get_vector3(1), stack.get_vector3(2), stack.get_vector3(3), stack.get_vector3(4)));
  366. return 1;
  367. }
  368. static int matrix4x4_add(lua_State* L)
  369. {
  370. LuaStack stack(L);
  371. stack.push_matrix4x4(stack.get_matrix4x4(1) + stack.get_matrix4x4(2));
  372. return 1;
  373. }
  374. static int matrix4x4_subtract(lua_State* L)
  375. {
  376. LuaStack stack(L);
  377. stack.push_matrix4x4(stack.get_matrix4x4(1) - stack.get_matrix4x4(2));
  378. return 1;
  379. }
  380. static int matrix4x4_multiply(lua_State* L)
  381. {
  382. LuaStack stack(L);
  383. stack.push_matrix4x4(stack.get_matrix4x4(1) * stack.get_matrix4x4(2));
  384. return 1;
  385. }
  386. static int matrix4x4_transpose(lua_State* L)
  387. {
  388. LuaStack stack(L);
  389. stack.push_matrix4x4(transpose(stack.get_matrix4x4(1)));
  390. return 1;
  391. }
  392. static int matrix4x4_determinant(lua_State* L)
  393. {
  394. LuaStack stack(L);
  395. stack.push_float(determinant(stack.get_matrix4x4(1)));
  396. return 1;
  397. }
  398. static int matrix4x4_invert(lua_State* L)
  399. {
  400. LuaStack stack(L);
  401. stack.push_matrix4x4(invert(stack.get_matrix4x4(1)));
  402. return 1;
  403. }
  404. static int matrix4x4_x(lua_State* L)
  405. {
  406. LuaStack stack(L);
  407. stack.push_vector3(x(stack.get_matrix4x4(1)));
  408. return 1;
  409. }
  410. static int matrix4x4_y(lua_State* L)
  411. {
  412. LuaStack stack(L);
  413. stack.push_vector3(y(stack.get_matrix4x4(1)));
  414. return 1;
  415. }
  416. static int matrix4x4_z(lua_State* L)
  417. {
  418. LuaStack stack(L);
  419. stack.push_vector3(z(stack.get_matrix4x4(1)));
  420. return 1;
  421. }
  422. static int matrix4x4_set_x(lua_State* L)
  423. {
  424. LuaStack stack(L);
  425. set_x(stack.get_matrix4x4(1), stack.get_vector3(2));
  426. return 0;
  427. }
  428. static int matrix4x4_set_y(lua_State* L)
  429. {
  430. LuaStack stack(L);
  431. set_y(stack.get_matrix4x4(1), stack.get_vector3(2));
  432. return 0;
  433. }
  434. static int matrix4x4_set_z(lua_State* L)
  435. {
  436. LuaStack stack(L);
  437. set_z(stack.get_matrix4x4(1), stack.get_vector3(2));
  438. return 0;
  439. }
  440. static int matrix4x4_translation(lua_State* L)
  441. {
  442. LuaStack stack(L);
  443. stack.push_vector3(translation(stack.get_matrix4x4(1)));
  444. return 1;
  445. }
  446. static int matrix4x4_set_translation(lua_State* L)
  447. {
  448. LuaStack stack(L);
  449. set_translation(stack.get_matrix4x4(1), stack.get_vector3(2));
  450. return 0;
  451. }
  452. static int matrix4x4_rotation(lua_State* L)
  453. {
  454. LuaStack stack(L);
  455. stack.push_quaternion(rotation(stack.get_matrix4x4(1)));
  456. return 1;
  457. }
  458. static int matrix4x4_set_rotation(lua_State* L)
  459. {
  460. LuaStack stack(L);
  461. set_rotation(stack.get_matrix4x4(1), stack.get_quaternion(2));
  462. return 0;
  463. }
  464. static int matrix4x4_identity(lua_State* L)
  465. {
  466. LuaStack stack(L);
  467. stack.push_matrix4x4(MATRIX4X4_IDENTITY);
  468. return 1;
  469. }
  470. static int matrix4x4_to_string(lua_State* L)
  471. {
  472. LuaStack stack(L);
  473. Matrix4x4& a = stack.get_matrix4x4(1);
  474. stack.push_fstring("%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n",
  475. a.x.x, a.x.y, a.x.z, a.y.w, a.y.x, a.y.y, a.y.z, a.y.w, a.z.x, a.z.y, a.z.z, a.z.w, a.t.x, a.t.y, a.t.z, a.t.w);
  476. return 1;
  477. }
  478. static int matrix4x4box_new(lua_State* L)
  479. {
  480. LuaStack stack(L);
  481. stack.push_matrix4x4box(stack.get_matrix4x4(1));
  482. return 1;
  483. }
  484. static int matrix4x4box_ctor(lua_State* L)
  485. {
  486. LuaStack stack(L);
  487. stack.remove(1); // Remove table
  488. return matrix4x4box_new(L);
  489. }
  490. static int matrix4x4box_store(lua_State* L)
  491. {
  492. LuaStack stack(L);
  493. stack.get_matrix4x4box(1) = stack.get_matrix4x4(2);
  494. return 0;
  495. }
  496. static int matrix4x4box_unbox(lua_State* L)
  497. {
  498. LuaStack stack(L);
  499. stack.push_matrix4x4(stack.get_matrix4x4box(1));
  500. return 1;
  501. }
  502. static int matrix4x4box_tostring(lua_State* L)
  503. {
  504. LuaStack stack(L);
  505. Matrix4x4& m = stack.get_matrix4x4box(1);
  506. stack.push_fstring("Matrix4x4Box (%p)", &m);
  507. return 1;
  508. }
  509. static int quaternion_new(lua_State* L)
  510. {
  511. LuaStack stack(L);
  512. stack.push_quaternion(quaternion(stack.get_vector3(1), stack.get_float(2)));
  513. return 1;
  514. }
  515. static int quaternion_ctor(lua_State* L)
  516. {
  517. LuaStack stack(L);
  518. stack.remove(1); // Remove table
  519. return quaternion_new(L);
  520. }
  521. static int quaternion_negate(lua_State* L)
  522. {
  523. LuaStack stack(L);
  524. stack.push_quaternion(-stack.get_quaternion(1));
  525. return 1;
  526. }
  527. static int quaternion_identity(lua_State* L)
  528. {
  529. LuaStack stack(L);
  530. stack.push_quaternion(QUATERNION_IDENTITY);
  531. return 1;
  532. }
  533. static int quaternion_length(lua_State* L)
  534. {
  535. LuaStack stack(L);
  536. stack.push_float(length(stack.get_quaternion(1)));
  537. return 1;
  538. }
  539. static int quaternion_normalize(lua_State* L)
  540. {
  541. LuaStack stack(L);
  542. stack.push_quaternion(normalize(stack.get_quaternion(1)));
  543. return 1;
  544. }
  545. static int quaternion_conjugate(lua_State* L)
  546. {
  547. LuaStack stack(L);
  548. stack.push_quaternion(conjugate(stack.get_quaternion(1)));
  549. return 1;
  550. }
  551. static int quaternion_inverse(lua_State* L)
  552. {
  553. LuaStack stack(L);
  554. stack.push_quaternion(inverse(stack.get_quaternion(1)));
  555. return 1;
  556. }
  557. static int quaternion_multiply(lua_State* L)
  558. {
  559. LuaStack stack(L);
  560. stack.push_quaternion(stack.get_quaternion(1) * stack.get_quaternion(2));
  561. return 1;
  562. }
  563. static int quaternion_multiply_by_scalar(lua_State* L)
  564. {
  565. LuaStack stack(L);
  566. stack.push_quaternion(stack.get_quaternion(1) * stack.get_float(2));
  567. return 1;
  568. }
  569. static int quaternion_power(lua_State* L)
  570. {
  571. LuaStack stack(L);
  572. stack.push_quaternion(power(stack.get_quaternion(1), stack.get_float(2)));
  573. return 1;
  574. }
  575. static int quaternion_elements(lua_State* L)
  576. {
  577. LuaStack stack(L);
  578. const Quaternion& q = stack.get_quaternion(1);
  579. stack.push_float(q.x);
  580. stack.push_float(q.y);
  581. stack.push_float(q.z);
  582. stack.push_float(q.w);
  583. return 4;
  584. }
  585. static int quaternion_look(lua_State* L)
  586. {
  587. LuaStack stack(L);
  588. const Vector3 up = stack.num_args() == 2 ? stack.get_vector3(2) : VECTOR3_YAXIS;
  589. stack.push_quaternion(look(stack.get_vector3(1), up));
  590. return 1;
  591. }
  592. static int quaternion_right(lua_State* L)
  593. {
  594. LuaStack stack(L);
  595. stack.push_vector3(right(stack.get_quaternion(1)));
  596. return 1;
  597. }
  598. static int quaternion_up(lua_State* L)
  599. {
  600. LuaStack stack(L);
  601. stack.push_vector3(up(stack.get_quaternion(1)));
  602. return 1;
  603. }
  604. static int quaternion_forward(lua_State* L)
  605. {
  606. LuaStack stack(L);
  607. stack.push_vector3(forward(stack.get_quaternion(1)));
  608. return 1;
  609. }
  610. static int quaternionbox_new(lua_State* L)
  611. {
  612. LuaStack stack(L);
  613. if (stack.num_args() == 1)
  614. stack.push_quaternionbox(stack.get_quaternion(1));
  615. else
  616. stack.push_quaternionbox(quaternion(stack.get_float(1)
  617. , stack.get_float(2)
  618. , stack.get_float(3)
  619. , stack.get_float(4)));
  620. return 1;
  621. }
  622. static int quaternionbox_ctor(lua_State* L)
  623. {
  624. LuaStack stack(L);
  625. stack.remove(1); // Remove table
  626. return quaternionbox_new(L);
  627. }
  628. static int quaternionbox_store(lua_State* L)
  629. {
  630. LuaStack stack(L);
  631. Quaternion& q = stack.get_quaternionbox(1);
  632. if (stack.num_args() == 2)
  633. q = stack.get_quaternion(2);
  634. else
  635. q = quaternion(stack.get_float(2)
  636. , stack.get_float(3)
  637. , stack.get_float(4)
  638. , stack.get_float(5));
  639. return 0;
  640. }
  641. static int quaternionbox_unbox(lua_State* L)
  642. {
  643. LuaStack stack(L);
  644. Quaternion& q = stack.get_quaternionbox(1);
  645. stack.push_quaternion(q);
  646. return 1;
  647. }
  648. static int quaternionbox_tostring(lua_State* L)
  649. {
  650. LuaStack stack(L);
  651. Quaternion& q = stack.get_quaternionbox(1);
  652. stack.push_fstring("QuaternionBox (%p)", &q);
  653. return 1;
  654. }
  655. static int color4_new(lua_State* L)
  656. {
  657. LuaStack stack(L);
  658. stack.push_quaternion(quaternion(stack.get_float(1)
  659. , stack.get_float(2)
  660. , stack.get_float(3)
  661. , stack.get_float(4)));
  662. return 1;
  663. }
  664. static int color4_ctor(lua_State* L)
  665. {
  666. LuaStack stack(L);
  667. stack.remove(1); // Remove table
  668. return color4_new(L);
  669. }
  670. static int lightuserdata_add(lua_State* L)
  671. {
  672. LuaStack stack(L);
  673. const Vector3& a = stack.get_vector3(1);
  674. const Vector3& b = stack.get_vector3(2);
  675. stack.push_vector3(a + b);
  676. return 1;
  677. }
  678. static int lightuserdata_sub(lua_State* L)
  679. {
  680. LuaStack stack(L);
  681. const Vector3& a = stack.get_vector3(1);
  682. const Vector3& b = stack.get_vector3(2);
  683. stack.push_vector3(a - b);
  684. return 1;
  685. }
  686. static int lightuserdata_mul(lua_State* L)
  687. {
  688. LuaStack stack(L);
  689. const Vector3& a = stack.get_vector3(1);
  690. const float b = stack.get_float(2);
  691. stack.push_vector3(a * b);
  692. return 1;
  693. }
  694. static int lightuserdata_div(lua_State* L)
  695. {
  696. LuaStack stack(L);
  697. const Vector3& a = stack.get_vector3(1);
  698. const float b = stack.get_float(2);
  699. stack.push_vector3(a / b);
  700. return 1;
  701. }
  702. static int lightuserdata_unm(lua_State* L)
  703. {
  704. LuaStack stack(L);
  705. stack.push_vector3(-stack.get_vector3(1));
  706. return 1;
  707. }
  708. static int lightuserdata_index(lua_State* L)
  709. {
  710. LuaStack stack(L);
  711. Vector3& v = stack.get_vector3(1);
  712. const char* s = stack.get_string(2);
  713. switch (s[0])
  714. {
  715. case 'x': stack.push_float(v.x); return 1;
  716. case 'y': stack.push_float(v.y); return 1;
  717. case 'z': stack.push_float(v.z); return 1;
  718. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  719. }
  720. return 0;
  721. }
  722. static int lightuserdata_newindex(lua_State* L)
  723. {
  724. LuaStack stack(L);
  725. Vector3& v = stack.get_vector3(1);
  726. const char* s = stack.get_string(2);
  727. const float value = stack.get_float(3);
  728. switch (s[0])
  729. {
  730. case 'x': v.x = value; break;
  731. case 'y': v.y = value; break;
  732. case 'z': v.z = value; break;
  733. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  734. }
  735. return 0;
  736. }
  737. void load_math(LuaEnvironment& env)
  738. {
  739. env.load_module_function("Math", "ray_plane_intersection", math_ray_plane_intersection);
  740. env.load_module_function("Math", "ray_sphere_intersection", math_ray_sphere_intersection);
  741. env.load_module_function("Math", "ray_obb_intersection", math_ray_obb_intersection);
  742. env.load_module_function("Vector3", "new", vector3_new);
  743. env.load_module_function("Vector3", "x", vector3_x);
  744. env.load_module_function("Vector3", "y", vector3_y);
  745. env.load_module_function("Vector3", "z", vector3_z);
  746. env.load_module_function("Vector3", "set_x", vector3_set_x);
  747. env.load_module_function("Vector3", "set_y", vector3_set_y);
  748. env.load_module_function("Vector3", "set_z", vector3_set_z);
  749. env.load_module_function("Vector3", "values", vector3_values);
  750. env.load_module_function("Vector3", "add", vector3_add);
  751. env.load_module_function("Vector3", "subtract", vector3_subtract);
  752. env.load_module_function("Vector3", "multiply", vector3_multiply);
  753. env.load_module_function("Vector3", "divide", vector3_divide);
  754. env.load_module_function("Vector3", "dot", vector3_dot);
  755. env.load_module_function("Vector3", "cross", vector3_cross);
  756. env.load_module_function("Vector3", "equal", vector3_equal);
  757. env.load_module_function("Vector3", "length", vector3_length);
  758. env.load_module_function("Vector3", "squared_length", vector3_squared_length);
  759. env.load_module_function("Vector3", "set_length", vector3_set_length);
  760. env.load_module_function("Vector3", "normalize", vector3_normalize);
  761. env.load_module_function("Vector3", "distance", vector3_distance);
  762. env.load_module_function("Vector3", "angle", vector3_angle);
  763. env.load_module_function("Vector3", "max", vector3_max);
  764. env.load_module_function("Vector3", "min", vector3_min);
  765. env.load_module_function("Vector3", "forward", vector3_forward);
  766. env.load_module_function("Vector3", "backward", vector3_backward);
  767. env.load_module_function("Vector3", "left", vector3_left);
  768. env.load_module_function("Vector3", "right", vector3_right);
  769. env.load_module_function("Vector3", "up", vector3_up);
  770. env.load_module_function("Vector3", "down", vector3_down);
  771. env.load_module_function("Vector3", "zero", vector3_zero);
  772. env.load_module_constructor("Vector3", vector3_ctor);
  773. env.load_module_function("Vector2", "new", vector2_new);
  774. env.load_module_constructor("Vector2", vector2_ctor);
  775. env.load_module_function("Vector3Box", "new", vector3box_new);
  776. env.load_module_function("Vector3Box", "store", vector3box_store);
  777. env.load_module_function("Vector3Box", "unbox", vector3box_unbox);
  778. env.load_module_function("Vector3Box", "__index", vector3box_get_value);
  779. env.load_module_function("Vector3Box", "__newindex", vector3box_set_value);
  780. env.load_module_function("Vector3Box", "__tostring", vector3box_tostring);
  781. env.load_module_constructor("Vector3Box", vector3box_ctor);
  782. env.load_module_function("Matrix4x4", "new", matrix4x4_new);
  783. env.load_module_function("Matrix4x4", "from_quaternion", matrix4x4_from_quaternion);
  784. env.load_module_function("Matrix4x4", "from_translation", matrix4x4_from_translation);
  785. env.load_module_function("Matrix4x4", "from_quaternion_translation", matrix4x4_from_quaternion_translation);
  786. env.load_module_function("Matrix4x4", "from_axes", matrix4x4_from_axes);
  787. env.load_module_function("Matrix4x4", "add", matrix4x4_add);
  788. env.load_module_function("Matrix4x4", "subtract", matrix4x4_subtract);
  789. env.load_module_function("Matrix4x4", "multiply", matrix4x4_multiply);
  790. env.load_module_function("Matrix4x4", "transpose", matrix4x4_transpose);
  791. env.load_module_function("Matrix4x4", "determinant", matrix4x4_determinant);
  792. env.load_module_function("Matrix4x4", "invert", matrix4x4_invert);
  793. env.load_module_function("Matrix4x4", "x", matrix4x4_x);
  794. env.load_module_function("Matrix4x4", "y", matrix4x4_y);
  795. env.load_module_function("Matrix4x4", "z", matrix4x4_z);
  796. env.load_module_function("Matrix4x4", "set_x", matrix4x4_set_x);
  797. env.load_module_function("Matrix4x4", "set_y", matrix4x4_set_y);
  798. env.load_module_function("Matrix4x4", "set_z", matrix4x4_set_z);
  799. env.load_module_function("Matrix4x4", "translation", matrix4x4_translation);
  800. env.load_module_function("Matrix4x4", "set_translation", matrix4x4_set_translation);
  801. env.load_module_function("Matrix4x4", "rotation", matrix4x4_rotation);
  802. env.load_module_function("Matrix4x4", "set_rotation", matrix4x4_set_rotation);
  803. env.load_module_function("Matrix4x4", "identity", matrix4x4_identity);
  804. env.load_module_function("Matrix4x4", "to_string", matrix4x4_to_string);
  805. env.load_module_constructor("Matrix4x4", matrix4x4_ctor);
  806. env.load_module_function("Matrix4x4Box", "new", matrix4x4box_new);
  807. env.load_module_function("Matrix4x4Box", "store", matrix4x4box_store);
  808. env.load_module_function("Matrix4x4Box", "unbox", matrix4x4box_unbox);
  809. env.load_module_function("Matrix4x4Box", "__tostring", matrix4x4box_tostring);
  810. env.load_module_constructor("Matrix4x4Box", matrix4x4box_ctor);
  811. env.load_module_function("Quaternion", "new", quaternion_new);
  812. env.load_module_function("Quaternion", "negate", quaternion_negate);
  813. env.load_module_function("Quaternion", "identity", quaternion_identity);
  814. env.load_module_function("Quaternion", "multiply", quaternion_multiply);
  815. env.load_module_function("Quaternion", "multiply_by_scalar", quaternion_multiply_by_scalar);
  816. env.load_module_function("Quaternion", "length", quaternion_length);
  817. env.load_module_function("Quaternion", "normalize", quaternion_normalize);
  818. env.load_module_function("Quaternion", "conjugate", quaternion_conjugate);
  819. env.load_module_function("Quaternion", "inverse", quaternion_inverse);
  820. env.load_module_function("Quaternion", "power", quaternion_power);
  821. env.load_module_function("Quaternion", "elements", quaternion_elements);
  822. env.load_module_function("Quaternion", "look", quaternion_look);
  823. env.load_module_function("Quaternion", "right", quaternion_right);
  824. env.load_module_function("Quaternion", "up", quaternion_up);
  825. env.load_module_function("Quaternion", "forward", quaternion_forward);
  826. env.load_module_constructor("Quaternion", quaternion_ctor);
  827. env.load_module_function("QuaternionBox", "new", quaternionbox_new);
  828. env.load_module_function("QuaternionBox", "store", quaternionbox_store);
  829. env.load_module_function("QuaternionBox", "unbox", quaternionbox_unbox);
  830. env.load_module_function("QuaternionBox", "__tostring", quaternionbox_tostring);
  831. env.load_module_constructor("QuaternionBox", quaternionbox_ctor);
  832. env.load_module_function("Color4", "new", color4_new);
  833. env.load_module_constructor("Color4", color4_ctor);
  834. env.load_module_function("Lightuserdata_mt", "__add", lightuserdata_add);
  835. env.load_module_function("Lightuserdata_mt", "__sub", lightuserdata_sub);
  836. env.load_module_function("Lightuserdata_mt", "__mul", lightuserdata_mul);
  837. env.load_module_function("Lightuserdata_mt", "__div", lightuserdata_div);
  838. env.load_module_function("Lightuserdata_mt", "__unm", lightuserdata_unm);
  839. env.load_module_function("Lightuserdata_mt", "__index", lightuserdata_index);
  840. env.load_module_function("Lightuserdata_mt", "__newindex", lightuserdata_newindex);
  841. }
  842. } // namespace crown