lua_math.cpp 26 KB

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