lua_math.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  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_values(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_divide(lua_State* L)
  142. {
  143. LuaStack stack(L);
  144. stack.push_vector3(stack.get_vector3(1) / stack.get_float(2));
  145. return 1;
  146. }
  147. static int vector3_dot(lua_State* L)
  148. {
  149. LuaStack stack(L);
  150. stack.push_float(dot(stack.get_vector3(1), stack.get_vector3(2)));
  151. return 1;
  152. }
  153. static int vector3_cross(lua_State* L)
  154. {
  155. LuaStack stack(L);
  156. stack.push_vector3(cross(stack.get_vector3(1), stack.get_vector3(2)));
  157. return 1;
  158. }
  159. static int vector3_equal(lua_State* L)
  160. {
  161. LuaStack stack(L);
  162. stack.push_bool(stack.get_vector3(1) == stack.get_vector3(2));
  163. return 1;
  164. }
  165. static int vector3_length(lua_State* L)
  166. {
  167. LuaStack stack(L);
  168. stack.push_float(length(stack.get_vector3(1)));
  169. return 1;
  170. }
  171. static int vector3_squared_length(lua_State* L)
  172. {
  173. LuaStack stack(L);
  174. stack.push_float(squared_length(stack.get_vector3(1)));
  175. return 1;
  176. }
  177. static int vector3_set_length(lua_State* L)
  178. {
  179. LuaStack stack(L);
  180. set_length(stack.get_vector3(1), stack.get_float(2));
  181. return 0;
  182. }
  183. static int vector3_normalize(lua_State* L)
  184. {
  185. LuaStack stack(L);
  186. stack.push_vector3(normalize(stack.get_vector3(1)));
  187. return 1;
  188. }
  189. static int vector3_distance(lua_State* L)
  190. {
  191. LuaStack stack(L);
  192. stack.push_float(distance(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_forward(lua_State* L)
  214. {
  215. LuaStack stack(L);
  216. stack.push_vector3(VECTOR3_FORWARD);
  217. return 1;
  218. }
  219. static int vector3_backward(lua_State* L)
  220. {
  221. LuaStack stack(L);
  222. stack.push_vector3(VECTOR3_BACKWARD);
  223. return 1;
  224. }
  225. static int vector3_left(lua_State* L)
  226. {
  227. LuaStack stack(L);
  228. stack.push_vector3(VECTOR3_LEFT);
  229. return 1;
  230. }
  231. static int vector3_right(lua_State* L)
  232. {
  233. LuaStack stack(L);
  234. stack.push_vector3(VECTOR3_RIGHT);
  235. return 1;
  236. }
  237. static int vector3_up(lua_State* L)
  238. {
  239. LuaStack stack(L);
  240. stack.push_vector3(VECTOR3_UP);
  241. return 1;
  242. }
  243. static int vector3_down(lua_State* L)
  244. {
  245. LuaStack stack(L);
  246. stack.push_vector3(VECTOR3_DOWN);
  247. return 1;
  248. }
  249. static int vector3_zero(lua_State* L)
  250. {
  251. LuaStack stack(L);
  252. stack.push_vector3(VECTOR3_ZERO);
  253. return 1;
  254. }
  255. static int vector2_new(lua_State* L)
  256. {
  257. LuaStack stack(L);
  258. stack.push_vector2(vector2(stack.get_float(1), stack.get_float(2)));
  259. return 1;
  260. }
  261. static int vector2_ctor(lua_State* L)
  262. {
  263. LuaStack stack(L);
  264. stack.remove(1); // Remove table
  265. return vector2_new(L);
  266. }
  267. static int vector3box_new(lua_State* L)
  268. {
  269. LuaStack stack(L);
  270. if (stack.num_args() == 0)
  271. stack.push_vector3box(Vector3());
  272. else if (stack.num_args() == 1)
  273. stack.push_vector3box(stack.get_vector3(1));
  274. else
  275. stack.push_vector3box(vector3(stack.get_float(1)
  276. , stack.get_float(2)
  277. , stack.get_float(3)));
  278. return 1;
  279. }
  280. static int vector3box_ctor(lua_State* L)
  281. {
  282. LuaStack stack(L);
  283. stack.remove(1); // Remove table
  284. return vector3box_new(L);
  285. }
  286. static int vector3box_store(lua_State* L)
  287. {
  288. LuaStack stack(L);
  289. Vector3& v = stack.get_vector3box(1);
  290. if (stack.num_args() == 2)
  291. v = stack.get_vector3(2);
  292. else
  293. v = vector3(stack.get_float(2)
  294. , stack.get_float(3)
  295. , stack.get_float(4));
  296. return 0;
  297. }
  298. static int vector3box_unbox(lua_State* L)
  299. {
  300. LuaStack stack(L);
  301. stack.push_vector3(stack.get_vector3box(1));
  302. return 1;
  303. }
  304. static int vector3box_get_value(lua_State* L)
  305. {
  306. LuaStack stack(L);
  307. Vector3& v = stack.get_vector3box(1);
  308. const char* s = stack.get_string(2);
  309. switch (s[0])
  310. {
  311. case 'x': stack.push_float(v.x); return 1;
  312. case 'y': stack.push_float(v.y); return 1;
  313. case 'z': stack.push_float(v.z); return 1;
  314. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  315. }
  316. return 0;
  317. }
  318. static int vector3box_set_value(lua_State* L)
  319. {
  320. LuaStack stack(L);
  321. Vector3& v = stack.get_vector3box(1);
  322. const char* s = stack.get_string(2);
  323. const float value = stack.get_float(3);
  324. switch (s[0])
  325. {
  326. case 'x': v.x = value; break;
  327. case 'y': v.y = value; break;
  328. case 'z': v.z = value; break;
  329. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  330. }
  331. return 0;
  332. }
  333. static int vector3box_tostring(lua_State* L)
  334. {
  335. LuaStack stack(L);
  336. Vector3& v = stack.get_vector3box(1);
  337. stack.push_fstring("Vector3Box (%p)", &v);
  338. return 1;
  339. }
  340. static int matrix4x4_new(lua_State* L)
  341. {
  342. LuaStack stack(L);
  343. stack.push_matrix4x4(matrix4x4(stack.get_float(1)
  344. , stack.get_float(2)
  345. , stack.get_float(3)
  346. , stack.get_float(4)
  347. , stack.get_float(5)
  348. , stack.get_float(6)
  349. , stack.get_float(7)
  350. , stack.get_float(8)
  351. , stack.get_float(9)
  352. , stack.get_float(10)
  353. , stack.get_float(11)
  354. , stack.get_float(12)
  355. , stack.get_float(13)
  356. , stack.get_float(14)
  357. , stack.get_float(15)
  358. , stack.get_float(16)));
  359. return 1;
  360. }
  361. static int matrix4x4_ctor(lua_State* L)
  362. {
  363. LuaStack stack(L);
  364. stack.remove(1); // Remove table
  365. return matrix4x4_new(L);
  366. }
  367. static int matrix4x4_from_quaternion(lua_State* L)
  368. {
  369. LuaStack stack(L);
  370. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), vector3(0, 0, 0)));
  371. return 1;
  372. }
  373. static int matrix4x4_from_translation(lua_State* L)
  374. {
  375. LuaStack stack(L);
  376. stack.push_matrix4x4(matrix4x4(QUATERNION_IDENTITY, stack.get_vector3(1)));
  377. return 1;
  378. }
  379. static int matrix4x4_from_quaternion_translation(lua_State* L)
  380. {
  381. LuaStack stack(L);
  382. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), stack.get_vector3(2)));
  383. return 1;
  384. }
  385. static int matrix4x4_from_axes(lua_State* L)
  386. {
  387. LuaStack stack(L);
  388. stack.push_matrix4x4(matrix4x4(stack.get_vector3(1), stack.get_vector3(2), stack.get_vector3(3), stack.get_vector3(4)));
  389. return 1;
  390. }
  391. static int matrix4x4_add(lua_State* L)
  392. {
  393. LuaStack stack(L);
  394. stack.push_matrix4x4(stack.get_matrix4x4(1) + stack.get_matrix4x4(2));
  395. return 1;
  396. }
  397. static int matrix4x4_subtract(lua_State* L)
  398. {
  399. LuaStack stack(L);
  400. stack.push_matrix4x4(stack.get_matrix4x4(1) - stack.get_matrix4x4(2));
  401. return 1;
  402. }
  403. static int matrix4x4_multiply(lua_State* L)
  404. {
  405. LuaStack stack(L);
  406. stack.push_matrix4x4(stack.get_matrix4x4(1) * stack.get_matrix4x4(2));
  407. return 1;
  408. }
  409. static int matrix4x4_transpose(lua_State* L)
  410. {
  411. LuaStack stack(L);
  412. stack.push_matrix4x4(transpose(stack.get_matrix4x4(1)));
  413. return 1;
  414. }
  415. static int matrix4x4_determinant(lua_State* L)
  416. {
  417. LuaStack stack(L);
  418. stack.push_float(determinant(stack.get_matrix4x4(1)));
  419. return 1;
  420. }
  421. static int matrix4x4_invert(lua_State* L)
  422. {
  423. LuaStack stack(L);
  424. stack.push_matrix4x4(invert(stack.get_matrix4x4(1)));
  425. return 1;
  426. }
  427. static int matrix4x4_x(lua_State* L)
  428. {
  429. LuaStack stack(L);
  430. stack.push_vector3(x(stack.get_matrix4x4(1)));
  431. return 1;
  432. }
  433. static int matrix4x4_y(lua_State* L)
  434. {
  435. LuaStack stack(L);
  436. stack.push_vector3(y(stack.get_matrix4x4(1)));
  437. return 1;
  438. }
  439. static int matrix4x4_z(lua_State* L)
  440. {
  441. LuaStack stack(L);
  442. stack.push_vector3(z(stack.get_matrix4x4(1)));
  443. return 1;
  444. }
  445. static int matrix4x4_set_x(lua_State* L)
  446. {
  447. LuaStack stack(L);
  448. set_x(stack.get_matrix4x4(1), stack.get_vector3(2));
  449. return 0;
  450. }
  451. static int matrix4x4_set_y(lua_State* L)
  452. {
  453. LuaStack stack(L);
  454. set_y(stack.get_matrix4x4(1), stack.get_vector3(2));
  455. return 0;
  456. }
  457. static int matrix4x4_set_z(lua_State* L)
  458. {
  459. LuaStack stack(L);
  460. set_z(stack.get_matrix4x4(1), stack.get_vector3(2));
  461. return 0;
  462. }
  463. static int matrix4x4_translation(lua_State* L)
  464. {
  465. LuaStack stack(L);
  466. stack.push_vector3(translation(stack.get_matrix4x4(1)));
  467. return 1;
  468. }
  469. static int matrix4x4_set_translation(lua_State* L)
  470. {
  471. LuaStack stack(L);
  472. set_translation(stack.get_matrix4x4(1), stack.get_vector3(2));
  473. return 0;
  474. }
  475. static int matrix4x4_rotation(lua_State* L)
  476. {
  477. LuaStack stack(L);
  478. stack.push_quaternion(rotation(stack.get_matrix4x4(1)));
  479. return 1;
  480. }
  481. static int matrix4x4_set_rotation(lua_State* L)
  482. {
  483. LuaStack stack(L);
  484. set_rotation(stack.get_matrix4x4(1), stack.get_quaternion(2));
  485. return 0;
  486. }
  487. static int matrix4x4_identity(lua_State* L)
  488. {
  489. LuaStack stack(L);
  490. stack.push_matrix4x4(MATRIX4X4_IDENTITY);
  491. return 1;
  492. }
  493. static int matrix4x4_transform(lua_State* L)
  494. {
  495. LuaStack stack(L);
  496. stack.push_vector3(stack.get_vector3(2) * stack.get_matrix4x4(1));
  497. return 1;
  498. }
  499. static int matrix4x4_to_string(lua_State* L)
  500. {
  501. LuaStack stack(L);
  502. Matrix4x4& a = stack.get_matrix4x4(1);
  503. stack.push_fstring(
  504. "%.1f, %.1f, %.1f, %.1f\n"
  505. "%.1f, %.1f, %.1f, %.1f\n"
  506. "%.1f, %.1f, %.1f, %.1f\n"
  507. "%.1f, %.1f, %.1f, %.1f\n"
  508. , a.x.x, a.x.y, a.x.z, a.y.w
  509. , a.y.x, a.y.y, a.y.z, a.y.w
  510. , a.z.x, a.z.y, a.z.z, a.z.w
  511. , a.t.x, a.t.y, a.t.z, a.t.w
  512. );
  513. return 1;
  514. }
  515. static int matrix4x4box_new(lua_State* L)
  516. {
  517. LuaStack stack(L);
  518. stack.push_matrix4x4box(stack.get_matrix4x4(1));
  519. return 1;
  520. }
  521. static int matrix4x4box_ctor(lua_State* L)
  522. {
  523. LuaStack stack(L);
  524. stack.remove(1); // Remove table
  525. return matrix4x4box_new(L);
  526. }
  527. static int matrix4x4box_store(lua_State* L)
  528. {
  529. LuaStack stack(L);
  530. stack.get_matrix4x4box(1) = stack.get_matrix4x4(2);
  531. return 0;
  532. }
  533. static int matrix4x4box_unbox(lua_State* L)
  534. {
  535. LuaStack stack(L);
  536. stack.push_matrix4x4(stack.get_matrix4x4box(1));
  537. return 1;
  538. }
  539. static int matrix4x4box_tostring(lua_State* L)
  540. {
  541. LuaStack stack(L);
  542. Matrix4x4& m = stack.get_matrix4x4box(1);
  543. stack.push_fstring("Matrix4x4Box (%p)", &m);
  544. return 1;
  545. }
  546. static int quaternion_new(lua_State* L)
  547. {
  548. LuaStack stack(L);
  549. stack.push_quaternion(quaternion(stack.get_vector3(1), stack.get_float(2)));
  550. return 1;
  551. }
  552. static int quaternion_ctor(lua_State* L)
  553. {
  554. LuaStack stack(L);
  555. stack.remove(1); // Remove table
  556. return quaternion_new(L);
  557. }
  558. static int quaternion_negate(lua_State* L)
  559. {
  560. LuaStack stack(L);
  561. stack.push_quaternion(-stack.get_quaternion(1));
  562. return 1;
  563. }
  564. static int quaternion_identity(lua_State* L)
  565. {
  566. LuaStack stack(L);
  567. stack.push_quaternion(QUATERNION_IDENTITY);
  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 fidx = stack.is_number(1) ? 1 : 2;
  727. stack.push_vector3(stack.get_float(fidx) * stack.get_vector3(3-fidx));
  728. return 1;
  729. }
  730. static int lightuserdata_div(lua_State* L)
  731. {
  732. LuaStack stack(L);
  733. const Vector3& a = stack.get_vector3(1);
  734. const float b = stack.get_float(2);
  735. stack.push_vector3(a / b);
  736. return 1;
  737. }
  738. static int lightuserdata_unm(lua_State* L)
  739. {
  740. LuaStack stack(L);
  741. stack.push_vector3(-stack.get_vector3(1));
  742. return 1;
  743. }
  744. static int lightuserdata_index(lua_State* L)
  745. {
  746. LuaStack stack(L);
  747. Vector3& v = stack.get_vector3(1);
  748. const char* s = stack.get_string(2);
  749. switch (s[0])
  750. {
  751. case 'x': stack.push_float(v.x); return 1;
  752. case 'y': stack.push_float(v.y); return 1;
  753. case 'z': stack.push_float(v.z); return 1;
  754. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  755. }
  756. return 0;
  757. }
  758. static int lightuserdata_newindex(lua_State* L)
  759. {
  760. LuaStack stack(L);
  761. Vector3& v = stack.get_vector3(1);
  762. const char* s = stack.get_string(2);
  763. const float value = stack.get_float(3);
  764. switch (s[0])
  765. {
  766. case 'x': v.x = value; break;
  767. case 'y': v.y = value; break;
  768. case 'z': v.z = value; break;
  769. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  770. }
  771. return 0;
  772. }
  773. void load_math(LuaEnvironment& env)
  774. {
  775. env.load_module_function("Math", "ray_plane_intersection", math_ray_plane_intersection);
  776. env.load_module_function("Math", "ray_disc_intersection", math_ray_disc_intersection);
  777. env.load_module_function("Math", "ray_sphere_intersection", math_ray_sphere_intersection);
  778. env.load_module_function("Math", "ray_obb_intersection", math_ray_obb_intersection);
  779. env.load_module_function("Vector3", "new", vector3_new);
  780. env.load_module_function("Vector3", "x", vector3_x);
  781. env.load_module_function("Vector3", "y", vector3_y);
  782. env.load_module_function("Vector3", "z", vector3_z);
  783. env.load_module_function("Vector3", "set_x", vector3_set_x);
  784. env.load_module_function("Vector3", "set_y", vector3_set_y);
  785. env.load_module_function("Vector3", "set_z", vector3_set_z);
  786. env.load_module_function("Vector3", "values", vector3_values);
  787. env.load_module_function("Vector3", "add", vector3_add);
  788. env.load_module_function("Vector3", "subtract", vector3_subtract);
  789. env.load_module_function("Vector3", "multiply", vector3_multiply);
  790. env.load_module_function("Vector3", "divide", vector3_divide);
  791. env.load_module_function("Vector3", "dot", vector3_dot);
  792. env.load_module_function("Vector3", "cross", vector3_cross);
  793. env.load_module_function("Vector3", "equal", vector3_equal);
  794. env.load_module_function("Vector3", "length", vector3_length);
  795. env.load_module_function("Vector3", "squared_length", vector3_squared_length);
  796. env.load_module_function("Vector3", "set_length", vector3_set_length);
  797. env.load_module_function("Vector3", "normalize", vector3_normalize);
  798. env.load_module_function("Vector3", "distance", vector3_distance);
  799. env.load_module_function("Vector3", "angle", vector3_angle);
  800. env.load_module_function("Vector3", "max", vector3_max);
  801. env.load_module_function("Vector3", "min", vector3_min);
  802. env.load_module_function("Vector3", "forward", vector3_forward);
  803. env.load_module_function("Vector3", "backward", vector3_backward);
  804. env.load_module_function("Vector3", "left", vector3_left);
  805. env.load_module_function("Vector3", "right", vector3_right);
  806. env.load_module_function("Vector3", "up", vector3_up);
  807. env.load_module_function("Vector3", "down", vector3_down);
  808. env.load_module_function("Vector3", "zero", vector3_zero);
  809. env.load_module_constructor("Vector3", vector3_ctor);
  810. env.load_module_function("Vector2", "new", vector2_new);
  811. env.load_module_constructor("Vector2", vector2_ctor);
  812. env.load_module_function("Vector3Box", "new", vector3box_new);
  813. env.load_module_function("Vector3Box", "store", vector3box_store);
  814. env.load_module_function("Vector3Box", "unbox", vector3box_unbox);
  815. env.load_module_function("Vector3Box", "__index", vector3box_get_value);
  816. env.load_module_function("Vector3Box", "__newindex", vector3box_set_value);
  817. env.load_module_function("Vector3Box", "__tostring", vector3box_tostring);
  818. env.load_module_constructor("Vector3Box", vector3box_ctor);
  819. env.load_module_function("Matrix4x4", "new", matrix4x4_new);
  820. env.load_module_function("Matrix4x4", "from_quaternion", matrix4x4_from_quaternion);
  821. env.load_module_function("Matrix4x4", "from_translation", matrix4x4_from_translation);
  822. env.load_module_function("Matrix4x4", "from_quaternion_translation", matrix4x4_from_quaternion_translation);
  823. env.load_module_function("Matrix4x4", "from_axes", matrix4x4_from_axes);
  824. env.load_module_function("Matrix4x4", "add", matrix4x4_add);
  825. env.load_module_function("Matrix4x4", "subtract", matrix4x4_subtract);
  826. env.load_module_function("Matrix4x4", "multiply", matrix4x4_multiply);
  827. env.load_module_function("Matrix4x4", "transpose", matrix4x4_transpose);
  828. env.load_module_function("Matrix4x4", "determinant", matrix4x4_determinant);
  829. env.load_module_function("Matrix4x4", "invert", matrix4x4_invert);
  830. env.load_module_function("Matrix4x4", "x", matrix4x4_x);
  831. env.load_module_function("Matrix4x4", "y", matrix4x4_y);
  832. env.load_module_function("Matrix4x4", "z", matrix4x4_z);
  833. env.load_module_function("Matrix4x4", "set_x", matrix4x4_set_x);
  834. env.load_module_function("Matrix4x4", "set_y", matrix4x4_set_y);
  835. env.load_module_function("Matrix4x4", "set_z", matrix4x4_set_z);
  836. env.load_module_function("Matrix4x4", "translation", matrix4x4_translation);
  837. env.load_module_function("Matrix4x4", "set_translation", matrix4x4_set_translation);
  838. env.load_module_function("Matrix4x4", "rotation", matrix4x4_rotation);
  839. env.load_module_function("Matrix4x4", "set_rotation", matrix4x4_set_rotation);
  840. env.load_module_function("Matrix4x4", "identity", matrix4x4_identity);
  841. env.load_module_function("Matrix4x4", "transform", matrix4x4_transform);
  842. env.load_module_function("Matrix4x4", "to_string", matrix4x4_to_string);
  843. env.load_module_constructor("Matrix4x4", matrix4x4_ctor);
  844. env.load_module_function("Matrix4x4Box", "new", matrix4x4box_new);
  845. env.load_module_function("Matrix4x4Box", "store", matrix4x4box_store);
  846. env.load_module_function("Matrix4x4Box", "unbox", matrix4x4box_unbox);
  847. env.load_module_function("Matrix4x4Box", "__tostring", matrix4x4box_tostring);
  848. env.load_module_constructor("Matrix4x4Box", matrix4x4box_ctor);
  849. env.load_module_function("Quaternion", "new", quaternion_new);
  850. env.load_module_function("Quaternion", "negate", quaternion_negate);
  851. env.load_module_function("Quaternion", "identity", quaternion_identity);
  852. env.load_module_function("Quaternion", "multiply", quaternion_multiply);
  853. env.load_module_function("Quaternion", "multiply_by_scalar", quaternion_multiply_by_scalar);
  854. env.load_module_function("Quaternion", "length", quaternion_length);
  855. env.load_module_function("Quaternion", "normalize", quaternion_normalize);
  856. env.load_module_function("Quaternion", "conjugate", quaternion_conjugate);
  857. env.load_module_function("Quaternion", "inverse", quaternion_inverse);
  858. env.load_module_function("Quaternion", "power", quaternion_power);
  859. env.load_module_function("Quaternion", "elements", quaternion_elements);
  860. env.load_module_function("Quaternion", "look", quaternion_look);
  861. env.load_module_function("Quaternion", "right", quaternion_right);
  862. env.load_module_function("Quaternion", "up", quaternion_up);
  863. env.load_module_function("Quaternion", "forward", quaternion_forward);
  864. env.load_module_constructor("Quaternion", quaternion_ctor);
  865. env.load_module_function("QuaternionBox", "new", quaternionbox_new);
  866. env.load_module_function("QuaternionBox", "store", quaternionbox_store);
  867. env.load_module_function("QuaternionBox", "unbox", quaternionbox_unbox);
  868. env.load_module_function("QuaternionBox", "__tostring", quaternionbox_tostring);
  869. env.load_module_constructor("QuaternionBox", quaternionbox_ctor);
  870. env.load_module_function("Color4", "new", color4_new);
  871. env.load_module_constructor("Color4", color4_ctor);
  872. env.load_module_function("Lightuserdata_mt", "__add", lightuserdata_add);
  873. env.load_module_function("Lightuserdata_mt", "__sub", lightuserdata_sub);
  874. env.load_module_function("Lightuserdata_mt", "__mul", lightuserdata_mul);
  875. env.load_module_function("Lightuserdata_mt", "__div", lightuserdata_div);
  876. env.load_module_function("Lightuserdata_mt", "__unm", lightuserdata_unm);
  877. env.load_module_function("Lightuserdata_mt", "__index", lightuserdata_index);
  878. env.load_module_function("Lightuserdata_mt", "__newindex", lightuserdata_newindex);
  879. }
  880. } // namespace crown