lua_math.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  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 vector3_to_string(lua_State* L)
  256. {
  257. LuaStack stack(L);
  258. const Vector3 v = stack.get_vector3(1);
  259. char buf[32];
  260. snprintf(buf, sizeof(buf), "%.4f %.4f %.4f", v.x, v.y, v.z);
  261. stack.push_string(buf);
  262. return 1;
  263. }
  264. static int vector2_new(lua_State* L)
  265. {
  266. LuaStack stack(L);
  267. stack.push_vector2(vector2(stack.get_float(1), stack.get_float(2)));
  268. return 1;
  269. }
  270. static int vector2_ctor(lua_State* L)
  271. {
  272. LuaStack stack(L);
  273. stack.remove(1); // Remove table
  274. return vector2_new(L);
  275. }
  276. static int vector3box_new(lua_State* L)
  277. {
  278. LuaStack stack(L);
  279. if (stack.num_args() == 0)
  280. stack.push_vector3box(Vector3());
  281. else if (stack.num_args() == 1)
  282. stack.push_vector3box(stack.get_vector3(1));
  283. else
  284. stack.push_vector3box(vector3(stack.get_float(1)
  285. , stack.get_float(2)
  286. , stack.get_float(3)));
  287. return 1;
  288. }
  289. static int vector3box_ctor(lua_State* L)
  290. {
  291. LuaStack stack(L);
  292. stack.remove(1); // Remove table
  293. return vector3box_new(L);
  294. }
  295. static int vector3box_store(lua_State* L)
  296. {
  297. LuaStack stack(L);
  298. Vector3& v = stack.get_vector3box(1);
  299. if (stack.num_args() == 2)
  300. v = stack.get_vector3(2);
  301. else
  302. v = vector3(stack.get_float(2)
  303. , stack.get_float(3)
  304. , stack.get_float(4));
  305. return 0;
  306. }
  307. static int vector3box_unbox(lua_State* L)
  308. {
  309. LuaStack stack(L);
  310. stack.push_vector3(stack.get_vector3box(1));
  311. return 1;
  312. }
  313. static int vector3box_get_value(lua_State* L)
  314. {
  315. LuaStack stack(L);
  316. Vector3& v = stack.get_vector3box(1);
  317. const char* s = stack.get_string(2);
  318. switch (s[0])
  319. {
  320. case 'x': stack.push_float(v.x); return 1;
  321. case 'y': stack.push_float(v.y); return 1;
  322. case 'z': stack.push_float(v.z); return 1;
  323. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  324. }
  325. return 0;
  326. }
  327. static int vector3box_set_value(lua_State* L)
  328. {
  329. LuaStack stack(L);
  330. Vector3& v = stack.get_vector3box(1);
  331. const char* s = stack.get_string(2);
  332. const float value = stack.get_float(3);
  333. switch (s[0])
  334. {
  335. case 'x': v.x = value; break;
  336. case 'y': v.y = value; break;
  337. case 'z': v.z = value; break;
  338. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  339. }
  340. return 0;
  341. }
  342. static int vector3box_tostring(lua_State* L)
  343. {
  344. LuaStack stack(L);
  345. Vector3& v = stack.get_vector3box(1);
  346. stack.push_fstring("Vector3Box (%p)", &v);
  347. return 1;
  348. }
  349. static int matrix4x4_new(lua_State* L)
  350. {
  351. LuaStack stack(L);
  352. stack.push_matrix4x4(matrix4x4(stack.get_float(1)
  353. , stack.get_float(2)
  354. , stack.get_float(3)
  355. , stack.get_float(4)
  356. , stack.get_float(5)
  357. , stack.get_float(6)
  358. , stack.get_float(7)
  359. , stack.get_float(8)
  360. , stack.get_float(9)
  361. , stack.get_float(10)
  362. , stack.get_float(11)
  363. , stack.get_float(12)
  364. , stack.get_float(13)
  365. , stack.get_float(14)
  366. , stack.get_float(15)
  367. , stack.get_float(16)));
  368. return 1;
  369. }
  370. static int matrix4x4_ctor(lua_State* L)
  371. {
  372. LuaStack stack(L);
  373. stack.remove(1); // Remove table
  374. return matrix4x4_new(L);
  375. }
  376. static int matrix4x4_from_quaternion(lua_State* L)
  377. {
  378. LuaStack stack(L);
  379. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), vector3(0, 0, 0)));
  380. return 1;
  381. }
  382. static int matrix4x4_from_translation(lua_State* L)
  383. {
  384. LuaStack stack(L);
  385. stack.push_matrix4x4(matrix4x4(QUATERNION_IDENTITY, stack.get_vector3(1)));
  386. return 1;
  387. }
  388. static int matrix4x4_from_quaternion_translation(lua_State* L)
  389. {
  390. LuaStack stack(L);
  391. stack.push_matrix4x4(matrix4x4(stack.get_quaternion(1), stack.get_vector3(2)));
  392. return 1;
  393. }
  394. static int matrix4x4_from_axes(lua_State* L)
  395. {
  396. LuaStack stack(L);
  397. stack.push_matrix4x4(matrix4x4(stack.get_vector3(1), stack.get_vector3(2), stack.get_vector3(3), stack.get_vector3(4)));
  398. return 1;
  399. }
  400. static int matrix4x4_copy(lua_State* L)
  401. {
  402. LuaStack stack(L);
  403. stack.push_matrix4x4(stack.get_matrix4x4(1));
  404. return 1;
  405. }
  406. static int matrix4x4_add(lua_State* L)
  407. {
  408. LuaStack stack(L);
  409. stack.push_matrix4x4(stack.get_matrix4x4(1) + stack.get_matrix4x4(2));
  410. return 1;
  411. }
  412. static int matrix4x4_subtract(lua_State* L)
  413. {
  414. LuaStack stack(L);
  415. stack.push_matrix4x4(stack.get_matrix4x4(1) - stack.get_matrix4x4(2));
  416. return 1;
  417. }
  418. static int matrix4x4_multiply(lua_State* L)
  419. {
  420. LuaStack stack(L);
  421. stack.push_matrix4x4(stack.get_matrix4x4(1) * stack.get_matrix4x4(2));
  422. return 1;
  423. }
  424. static int matrix4x4_transpose(lua_State* L)
  425. {
  426. LuaStack stack(L);
  427. stack.push_matrix4x4(transpose(stack.get_matrix4x4(1)));
  428. return 1;
  429. }
  430. static int matrix4x4_determinant(lua_State* L)
  431. {
  432. LuaStack stack(L);
  433. stack.push_float(determinant(stack.get_matrix4x4(1)));
  434. return 1;
  435. }
  436. static int matrix4x4_invert(lua_State* L)
  437. {
  438. LuaStack stack(L);
  439. stack.push_matrix4x4(invert(stack.get_matrix4x4(1)));
  440. return 1;
  441. }
  442. static int matrix4x4_x(lua_State* L)
  443. {
  444. LuaStack stack(L);
  445. stack.push_vector3(x(stack.get_matrix4x4(1)));
  446. return 1;
  447. }
  448. static int matrix4x4_y(lua_State* L)
  449. {
  450. LuaStack stack(L);
  451. stack.push_vector3(y(stack.get_matrix4x4(1)));
  452. return 1;
  453. }
  454. static int matrix4x4_z(lua_State* L)
  455. {
  456. LuaStack stack(L);
  457. stack.push_vector3(z(stack.get_matrix4x4(1)));
  458. return 1;
  459. }
  460. static int matrix4x4_set_x(lua_State* L)
  461. {
  462. LuaStack stack(L);
  463. set_x(stack.get_matrix4x4(1), stack.get_vector3(2));
  464. return 0;
  465. }
  466. static int matrix4x4_set_y(lua_State* L)
  467. {
  468. LuaStack stack(L);
  469. set_y(stack.get_matrix4x4(1), stack.get_vector3(2));
  470. return 0;
  471. }
  472. static int matrix4x4_set_z(lua_State* L)
  473. {
  474. LuaStack stack(L);
  475. set_z(stack.get_matrix4x4(1), stack.get_vector3(2));
  476. return 0;
  477. }
  478. static int matrix4x4_translation(lua_State* L)
  479. {
  480. LuaStack stack(L);
  481. stack.push_vector3(translation(stack.get_matrix4x4(1)));
  482. return 1;
  483. }
  484. static int matrix4x4_set_translation(lua_State* L)
  485. {
  486. LuaStack stack(L);
  487. set_translation(stack.get_matrix4x4(1), stack.get_vector3(2));
  488. return 0;
  489. }
  490. static int matrix4x4_rotation(lua_State* L)
  491. {
  492. LuaStack stack(L);
  493. stack.push_quaternion(rotation(stack.get_matrix4x4(1)));
  494. return 1;
  495. }
  496. static int matrix4x4_set_rotation(lua_State* L)
  497. {
  498. LuaStack stack(L);
  499. set_rotation(stack.get_matrix4x4(1), stack.get_quaternion(2));
  500. return 0;
  501. }
  502. static int matrix4x4_identity(lua_State* L)
  503. {
  504. LuaStack stack(L);
  505. stack.push_matrix4x4(MATRIX4X4_IDENTITY);
  506. return 1;
  507. }
  508. static int matrix4x4_transform(lua_State* L)
  509. {
  510. LuaStack stack(L);
  511. stack.push_vector3(stack.get_vector3(2) * stack.get_matrix4x4(1));
  512. return 1;
  513. }
  514. static int matrix4x4_to_string(lua_State* L)
  515. {
  516. LuaStack stack(L);
  517. Matrix4x4& a = stack.get_matrix4x4(1);
  518. char buf[256];
  519. snprintf(buf, sizeof(buf),
  520. "%.4f, %.4f, %.4f, %.4f\n"
  521. "%.4f, %.4f, %.4f, %.4f\n"
  522. "%.4f, %.4f, %.4f, %.4f\n"
  523. "%.4f, %.4f, %.4f, %.4f"
  524. , a.x.x, a.x.y, a.x.z, a.y.w
  525. , a.y.x, a.y.y, a.y.z, a.y.w
  526. , a.z.x, a.z.y, a.z.z, a.z.w
  527. , a.t.x, a.t.y, a.t.z, a.t.w
  528. );
  529. stack.push_string(buf);
  530. return 1;
  531. }
  532. static int matrix4x4box_new(lua_State* L)
  533. {
  534. LuaStack stack(L);
  535. stack.push_matrix4x4box(stack.get_matrix4x4(1));
  536. return 1;
  537. }
  538. static int matrix4x4box_ctor(lua_State* L)
  539. {
  540. LuaStack stack(L);
  541. stack.remove(1); // Remove table
  542. return matrix4x4box_new(L);
  543. }
  544. static int matrix4x4box_store(lua_State* L)
  545. {
  546. LuaStack stack(L);
  547. stack.get_matrix4x4box(1) = stack.get_matrix4x4(2);
  548. return 0;
  549. }
  550. static int matrix4x4box_unbox(lua_State* L)
  551. {
  552. LuaStack stack(L);
  553. stack.push_matrix4x4(stack.get_matrix4x4box(1));
  554. return 1;
  555. }
  556. static int matrix4x4box_tostring(lua_State* L)
  557. {
  558. LuaStack stack(L);
  559. Matrix4x4& m = stack.get_matrix4x4box(1);
  560. stack.push_fstring("Matrix4x4Box (%p)", &m);
  561. return 1;
  562. }
  563. static int quaternion_new(lua_State* L)
  564. {
  565. LuaStack stack(L);
  566. stack.push_quaternion(quaternion(stack.get_vector3(1), stack.get_float(2)));
  567. return 1;
  568. }
  569. static int quaternion_ctor(lua_State* L)
  570. {
  571. LuaStack stack(L);
  572. stack.remove(1); // Remove table
  573. return quaternion_new(L);
  574. }
  575. static int quaternion_negate(lua_State* L)
  576. {
  577. LuaStack stack(L);
  578. stack.push_quaternion(-stack.get_quaternion(1));
  579. return 1;
  580. }
  581. static int quaternion_identity(lua_State* L)
  582. {
  583. LuaStack stack(L);
  584. stack.push_quaternion(QUATERNION_IDENTITY);
  585. return 1;
  586. }
  587. static int quaternion_length(lua_State* L)
  588. {
  589. LuaStack stack(L);
  590. stack.push_float(length(stack.get_quaternion(1)));
  591. return 1;
  592. }
  593. static int quaternion_normalize(lua_State* L)
  594. {
  595. LuaStack stack(L);
  596. stack.push_quaternion(normalize(stack.get_quaternion(1)));
  597. return 1;
  598. }
  599. static int quaternion_conjugate(lua_State* L)
  600. {
  601. LuaStack stack(L);
  602. stack.push_quaternion(conjugate(stack.get_quaternion(1)));
  603. return 1;
  604. }
  605. static int quaternion_inverse(lua_State* L)
  606. {
  607. LuaStack stack(L);
  608. stack.push_quaternion(inverse(stack.get_quaternion(1)));
  609. return 1;
  610. }
  611. static int quaternion_multiply(lua_State* L)
  612. {
  613. LuaStack stack(L);
  614. stack.push_quaternion(stack.get_quaternion(1) * stack.get_quaternion(2));
  615. return 1;
  616. }
  617. static int quaternion_multiply_by_scalar(lua_State* L)
  618. {
  619. LuaStack stack(L);
  620. stack.push_quaternion(stack.get_quaternion(1) * stack.get_float(2));
  621. return 1;
  622. }
  623. static int quaternion_power(lua_State* L)
  624. {
  625. LuaStack stack(L);
  626. stack.push_quaternion(power(stack.get_quaternion(1), stack.get_float(2)));
  627. return 1;
  628. }
  629. static int quaternion_elements(lua_State* L)
  630. {
  631. LuaStack stack(L);
  632. const Quaternion& q = stack.get_quaternion(1);
  633. stack.push_float(q.x);
  634. stack.push_float(q.y);
  635. stack.push_float(q.z);
  636. stack.push_float(q.w);
  637. return 4;
  638. }
  639. static int quaternion_look(lua_State* L)
  640. {
  641. LuaStack stack(L);
  642. const Vector3 up = stack.num_args() == 2 ? stack.get_vector3(2) : VECTOR3_YAXIS;
  643. stack.push_quaternion(look(stack.get_vector3(1), up));
  644. return 1;
  645. }
  646. static int quaternion_right(lua_State* L)
  647. {
  648. LuaStack stack(L);
  649. stack.push_vector3(right(stack.get_quaternion(1)));
  650. return 1;
  651. }
  652. static int quaternion_up(lua_State* L)
  653. {
  654. LuaStack stack(L);
  655. stack.push_vector3(up(stack.get_quaternion(1)));
  656. return 1;
  657. }
  658. static int quaternion_forward(lua_State* L)
  659. {
  660. LuaStack stack(L);
  661. stack.push_vector3(forward(stack.get_quaternion(1)));
  662. return 1;
  663. }
  664. static int quaternionbox_new(lua_State* L)
  665. {
  666. LuaStack stack(L);
  667. if (stack.num_args() == 1)
  668. stack.push_quaternionbox(stack.get_quaternion(1));
  669. else
  670. stack.push_quaternionbox(quaternion(stack.get_float(1)
  671. , stack.get_float(2)
  672. , stack.get_float(3)
  673. , stack.get_float(4)));
  674. return 1;
  675. }
  676. static int quaternionbox_ctor(lua_State* L)
  677. {
  678. LuaStack stack(L);
  679. stack.remove(1); // Remove table
  680. return quaternionbox_new(L);
  681. }
  682. static int quaternionbox_store(lua_State* L)
  683. {
  684. LuaStack stack(L);
  685. Quaternion& q = stack.get_quaternionbox(1);
  686. if (stack.num_args() == 2)
  687. q = stack.get_quaternion(2);
  688. else
  689. q = quaternion(stack.get_float(2)
  690. , stack.get_float(3)
  691. , stack.get_float(4)
  692. , stack.get_float(5));
  693. return 0;
  694. }
  695. static int quaternionbox_unbox(lua_State* L)
  696. {
  697. LuaStack stack(L);
  698. Quaternion& q = stack.get_quaternionbox(1);
  699. stack.push_quaternion(q);
  700. return 1;
  701. }
  702. static int quaternionbox_tostring(lua_State* L)
  703. {
  704. LuaStack stack(L);
  705. Quaternion& q = stack.get_quaternionbox(1);
  706. stack.push_fstring("QuaternionBox (%p)", &q);
  707. return 1;
  708. }
  709. static int color4_new(lua_State* L)
  710. {
  711. LuaStack stack(L);
  712. stack.push_quaternion(quaternion(stack.get_float(1)
  713. , stack.get_float(2)
  714. , stack.get_float(3)
  715. , stack.get_float(4)));
  716. return 1;
  717. }
  718. static int color4_ctor(lua_State* L)
  719. {
  720. LuaStack stack(L);
  721. stack.remove(1); // Remove table
  722. return color4_new(L);
  723. }
  724. static int lightuserdata_add(lua_State* L)
  725. {
  726. LuaStack stack(L);
  727. const Vector3& a = stack.get_vector3(1);
  728. const Vector3& b = stack.get_vector3(2);
  729. stack.push_vector3(a + b);
  730. return 1;
  731. }
  732. static int lightuserdata_sub(lua_State* L)
  733. {
  734. LuaStack stack(L);
  735. const Vector3& a = stack.get_vector3(1);
  736. const Vector3& b = stack.get_vector3(2);
  737. stack.push_vector3(a - b);
  738. return 1;
  739. }
  740. static int lightuserdata_mul(lua_State* L)
  741. {
  742. LuaStack stack(L);
  743. const int i = stack.is_number(1) ? 1 : 2;
  744. stack.push_vector3(stack.get_float(i) * stack.get_vector3(3-i));
  745. return 1;
  746. }
  747. static int lightuserdata_div(lua_State* L)
  748. {
  749. LuaStack stack(L);
  750. const Vector3& a = stack.get_vector3(1);
  751. const float b = stack.get_float(2);
  752. stack.push_vector3(a / b);
  753. return 1;
  754. }
  755. static int lightuserdata_unm(lua_State* L)
  756. {
  757. LuaStack stack(L);
  758. stack.push_vector3(-stack.get_vector3(1));
  759. return 1;
  760. }
  761. static int lightuserdata_index(lua_State* L)
  762. {
  763. LuaStack stack(L);
  764. Vector3& v = stack.get_vector3(1);
  765. const char* s = stack.get_string(2);
  766. switch (s[0])
  767. {
  768. case 'x': stack.push_float(v.x); return 1;
  769. case 'y': stack.push_float(v.y); return 1;
  770. case 'z': stack.push_float(v.z); return 1;
  771. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  772. }
  773. return 0;
  774. }
  775. static int lightuserdata_newindex(lua_State* L)
  776. {
  777. LuaStack stack(L);
  778. Vector3& v = stack.get_vector3(1);
  779. const char* s = stack.get_string(2);
  780. const float value = stack.get_float(3);
  781. switch (s[0])
  782. {
  783. case 'x': v.x = value; break;
  784. case 'y': v.y = value; break;
  785. case 'z': v.z = value; break;
  786. default: LUA_ASSERT(false, stack, "Bad index: '%c'", s[0]); break;
  787. }
  788. return 0;
  789. }
  790. void load_math(LuaEnvironment& env)
  791. {
  792. env.load_module_function("Math", "ray_plane_intersection", math_ray_plane_intersection);
  793. env.load_module_function("Math", "ray_disc_intersection", math_ray_disc_intersection);
  794. env.load_module_function("Math", "ray_sphere_intersection", math_ray_sphere_intersection);
  795. env.load_module_function("Math", "ray_obb_intersection", math_ray_obb_intersection);
  796. env.load_module_function("Vector3", "new", vector3_new);
  797. env.load_module_function("Vector3", "x", vector3_x);
  798. env.load_module_function("Vector3", "y", vector3_y);
  799. env.load_module_function("Vector3", "z", vector3_z);
  800. env.load_module_function("Vector3", "set_x", vector3_set_x);
  801. env.load_module_function("Vector3", "set_y", vector3_set_y);
  802. env.load_module_function("Vector3", "set_z", vector3_set_z);
  803. env.load_module_function("Vector3", "values", vector3_values);
  804. env.load_module_function("Vector3", "add", vector3_add);
  805. env.load_module_function("Vector3", "subtract", vector3_subtract);
  806. env.load_module_function("Vector3", "multiply", vector3_multiply);
  807. env.load_module_function("Vector3", "divide", vector3_divide);
  808. env.load_module_function("Vector3", "dot", vector3_dot);
  809. env.load_module_function("Vector3", "cross", vector3_cross);
  810. env.load_module_function("Vector3", "equal", vector3_equal);
  811. env.load_module_function("Vector3", "length", vector3_length);
  812. env.load_module_function("Vector3", "squared_length", vector3_squared_length);
  813. env.load_module_function("Vector3", "set_length", vector3_set_length);
  814. env.load_module_function("Vector3", "normalize", vector3_normalize);
  815. env.load_module_function("Vector3", "distance", vector3_distance);
  816. env.load_module_function("Vector3", "angle", vector3_angle);
  817. env.load_module_function("Vector3", "max", vector3_max);
  818. env.load_module_function("Vector3", "min", vector3_min);
  819. env.load_module_function("Vector3", "forward", vector3_forward);
  820. env.load_module_function("Vector3", "backward", vector3_backward);
  821. env.load_module_function("Vector3", "left", vector3_left);
  822. env.load_module_function("Vector3", "right", vector3_right);
  823. env.load_module_function("Vector3", "up", vector3_up);
  824. env.load_module_function("Vector3", "down", vector3_down);
  825. env.load_module_function("Vector3", "zero", vector3_zero);
  826. env.load_module_function("Vector3", "to_string", vector3_to_string);
  827. env.load_module_constructor("Vector3", vector3_ctor);
  828. env.load_module_function("Vector2", "new", vector2_new);
  829. env.load_module_constructor("Vector2", vector2_ctor);
  830. env.load_module_function("Vector3Box", "new", vector3box_new);
  831. env.load_module_function("Vector3Box", "store", vector3box_store);
  832. env.load_module_function("Vector3Box", "unbox", vector3box_unbox);
  833. env.load_module_function("Vector3Box", "__index", vector3box_get_value);
  834. env.load_module_function("Vector3Box", "__newindex", vector3box_set_value);
  835. env.load_module_function("Vector3Box", "__tostring", vector3box_tostring);
  836. env.load_module_constructor("Vector3Box", vector3box_ctor);
  837. env.load_module_function("Matrix4x4", "new", matrix4x4_new);
  838. env.load_module_function("Matrix4x4", "from_quaternion", matrix4x4_from_quaternion);
  839. env.load_module_function("Matrix4x4", "from_translation", matrix4x4_from_translation);
  840. env.load_module_function("Matrix4x4", "from_quaternion_translation", matrix4x4_from_quaternion_translation);
  841. env.load_module_function("Matrix4x4", "from_axes", matrix4x4_from_axes);
  842. env.load_module_function("Matrix4x4", "copy", matrix4x4_copy);
  843. env.load_module_function("Matrix4x4", "add", matrix4x4_add);
  844. env.load_module_function("Matrix4x4", "subtract", matrix4x4_subtract);
  845. env.load_module_function("Matrix4x4", "multiply", matrix4x4_multiply);
  846. env.load_module_function("Matrix4x4", "transpose", matrix4x4_transpose);
  847. env.load_module_function("Matrix4x4", "determinant", matrix4x4_determinant);
  848. env.load_module_function("Matrix4x4", "invert", matrix4x4_invert);
  849. env.load_module_function("Matrix4x4", "x", matrix4x4_x);
  850. env.load_module_function("Matrix4x4", "y", matrix4x4_y);
  851. env.load_module_function("Matrix4x4", "z", matrix4x4_z);
  852. env.load_module_function("Matrix4x4", "set_x", matrix4x4_set_x);
  853. env.load_module_function("Matrix4x4", "set_y", matrix4x4_set_y);
  854. env.load_module_function("Matrix4x4", "set_z", matrix4x4_set_z);
  855. env.load_module_function("Matrix4x4", "translation", matrix4x4_translation);
  856. env.load_module_function("Matrix4x4", "set_translation", matrix4x4_set_translation);
  857. env.load_module_function("Matrix4x4", "rotation", matrix4x4_rotation);
  858. env.load_module_function("Matrix4x4", "set_rotation", matrix4x4_set_rotation);
  859. env.load_module_function("Matrix4x4", "identity", matrix4x4_identity);
  860. env.load_module_function("Matrix4x4", "transform", matrix4x4_transform);
  861. env.load_module_function("Matrix4x4", "to_string", matrix4x4_to_string);
  862. env.load_module_constructor("Matrix4x4", matrix4x4_ctor);
  863. env.load_module_function("Matrix4x4Box", "new", matrix4x4box_new);
  864. env.load_module_function("Matrix4x4Box", "store", matrix4x4box_store);
  865. env.load_module_function("Matrix4x4Box", "unbox", matrix4x4box_unbox);
  866. env.load_module_function("Matrix4x4Box", "__tostring", matrix4x4box_tostring);
  867. env.load_module_constructor("Matrix4x4Box", matrix4x4box_ctor);
  868. env.load_module_function("Quaternion", "new", quaternion_new);
  869. env.load_module_function("Quaternion", "negate", quaternion_negate);
  870. env.load_module_function("Quaternion", "identity", quaternion_identity);
  871. env.load_module_function("Quaternion", "multiply", quaternion_multiply);
  872. env.load_module_function("Quaternion", "multiply_by_scalar", quaternion_multiply_by_scalar);
  873. env.load_module_function("Quaternion", "length", quaternion_length);
  874. env.load_module_function("Quaternion", "normalize", quaternion_normalize);
  875. env.load_module_function("Quaternion", "conjugate", quaternion_conjugate);
  876. env.load_module_function("Quaternion", "inverse", quaternion_inverse);
  877. env.load_module_function("Quaternion", "power", quaternion_power);
  878. env.load_module_function("Quaternion", "elements", quaternion_elements);
  879. env.load_module_function("Quaternion", "look", quaternion_look);
  880. env.load_module_function("Quaternion", "right", quaternion_right);
  881. env.load_module_function("Quaternion", "up", quaternion_up);
  882. env.load_module_function("Quaternion", "forward", quaternion_forward);
  883. env.load_module_constructor("Quaternion", quaternion_ctor);
  884. env.load_module_function("QuaternionBox", "new", quaternionbox_new);
  885. env.load_module_function("QuaternionBox", "store", quaternionbox_store);
  886. env.load_module_function("QuaternionBox", "unbox", quaternionbox_unbox);
  887. env.load_module_function("QuaternionBox", "__tostring", quaternionbox_tostring);
  888. env.load_module_constructor("QuaternionBox", quaternionbox_ctor);
  889. env.load_module_function("Color4", "new", color4_new);
  890. env.load_module_constructor("Color4", color4_ctor);
  891. env.load_module_function("Lightuserdata_mt", "__add", lightuserdata_add);
  892. env.load_module_function("Lightuserdata_mt", "__sub", lightuserdata_sub);
  893. env.load_module_function("Lightuserdata_mt", "__mul", lightuserdata_mul);
  894. env.load_module_function("Lightuserdata_mt", "__div", lightuserdata_div);
  895. env.load_module_function("Lightuserdata_mt", "__unm", lightuserdata_unm);
  896. env.load_module_function("Lightuserdata_mt", "__index", lightuserdata_index);
  897. env.load_module_function("Lightuserdata_mt", "__newindex", lightuserdata_newindex);
  898. }
  899. } // namespace crown