/src/lipsofsuna/extension/math/script-quaternion.c

https://gitlab.com/xenodora/lipsofsuna · C · 321 lines · 251 code · 45 blank · 25 comment · 8 complexity · 18e9b95633650769eafe0e6b8c74cbd9 MD5 · raw file

  1. /* Lips of Suna
  2. * Copyright© 2007-2014 Lips of Suna development team.
  3. *
  4. * Lips of Suna is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as
  6. * published by the Free Software Foundation, either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * Lips of Suna is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with Lips of Suna. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /**
  18. * \addtogroup LIExt Extension
  19. * @{
  20. * \addtogroup LIExtQuaternion Quaternion
  21. * @{
  22. */
  23. #include "lipsofsuna/script.h"
  24. static void Quaternion_new (LIScrArgs* args)
  25. {
  26. LIMatQuaternion quat = { 0.0f, 0.0f, 0.0f, 1.0f };
  27. liscr_args_geti_float (args, 0, &quat.x);
  28. liscr_args_geti_float (args, 1, &quat.y);
  29. liscr_args_geti_float (args, 2, &quat.z);
  30. liscr_args_geti_float (args, 3, &quat.w);
  31. liscr_args_seti_quaternion (args, &quat);
  32. }
  33. static void Quaternion_new_from_axis (LIScrArgs* args)
  34. {
  35. float angle = 0.0f;
  36. LIMatVector axis = { 0.0f, 1.0f, 0.0f };
  37. LIMatQuaternion quat;
  38. liscr_args_geti_float (args, 0, &axis.x);
  39. liscr_args_geti_float (args, 1, &axis.y);
  40. liscr_args_geti_float (args, 2, &axis.z);
  41. liscr_args_geti_float (args, 3, &angle);
  42. quat = limat_quaternion_rotation (angle, axis);
  43. liscr_args_seti_quaternion (args, &quat);
  44. }
  45. static void Quaternion_new_from_dir (LIScrArgs* args)
  46. {
  47. LIMatVector dir = { 0.0f, 0.0f, -1.0f };
  48. LIMatVector up = { 0.0f, 1.0f, 0.0f };
  49. LIMatQuaternion quat;
  50. liscr_args_geti_float (args, 0, &dir.x);
  51. liscr_args_geti_float (args, 1, &dir.y);
  52. liscr_args_geti_float (args, 2, &dir.z);
  53. liscr_args_geti_float (args, 3, &up.x);
  54. liscr_args_geti_float (args, 4, &up.y);
  55. liscr_args_geti_float (args, 5, &up.z);
  56. quat = limat_quaternion_look (dir, up);
  57. quat = limat_quaternion_conjugate (quat);
  58. liscr_args_seti_quaternion (args, &quat);
  59. }
  60. static void Quaternion_new_from_euler (LIScrArgs* args)
  61. {
  62. float euler[3] = { 0.0f, 0.0f, 0.0f };
  63. LIMatQuaternion quat;
  64. liscr_args_geti_float (args, 0, euler + 0);
  65. liscr_args_geti_float (args, 1, euler + 1);
  66. liscr_args_geti_float (args, 2, euler + 2);
  67. quat = limat_quaternion_euler (euler[0], euler[1], euler[2]);
  68. quat = limat_quaternion_validate (quat);
  69. quat = limat_quaternion_normalize (quat);
  70. liscr_args_seti_quaternion (args, &quat);
  71. }
  72. static void Quaternion_new_from_vectors (LIScrArgs* args)
  73. {
  74. LIMatQuaternion quat;
  75. LIMatVector v1 = { 0.0f, 0.0f, 0.0f };
  76. LIMatVector v2 = { 0.0f, 0.0f, 0.0f };
  77. liscr_args_geti_float (args, 0, &v1.x);
  78. liscr_args_geti_float (args, 1, &v1.y);
  79. liscr_args_geti_float (args, 2, &v1.z);
  80. liscr_args_geti_float (args, 3, &v2.x);
  81. liscr_args_geti_float (args, 4, &v2.y);
  82. liscr_args_geti_float (args, 5, &v2.z);
  83. quat = limat_quaternion_init_vectors (v1, v2);
  84. quat = limat_quaternion_validate (quat);
  85. quat = limat_quaternion_normalize (quat);
  86. liscr_args_seti_quaternion (args, &quat);
  87. }
  88. static void Quaternion_add (LIScrArgs* args)
  89. {
  90. LIMatQuaternion tmp;
  91. LIScrData* b;
  92. if (!liscr_args_geti_data (args, 0, LISCR_SCRIPT_QUATERNION, &b))
  93. return;
  94. tmp = limat_quaternion_add (*((LIMatQuaternion*) args->self), *((LIMatQuaternion*) liscr_data_get_data (b)));
  95. liscr_args_seti_quaternion (args, &tmp);
  96. }
  97. static void Quaternion_sub (LIScrArgs* args)
  98. {
  99. LIMatQuaternion tmp;
  100. LIScrData* b;
  101. if (!liscr_args_geti_data (args, 0, LISCR_SCRIPT_QUATERNION, &b))
  102. return;
  103. tmp = limat_quaternion_subtract (*((LIMatQuaternion*) args->self), *((LIMatQuaternion*) liscr_data_get_data (b)));
  104. liscr_args_seti_quaternion (args, &tmp);
  105. }
  106. static void Quaternion_tostring (LIScrArgs* args)
  107. {
  108. char buffer[256];
  109. LIMatQuaternion* self;
  110. self = args->self;
  111. snprintf (buffer, 256, "Quaternion(%g,%g,%g,%g)", self->x, self->y, self->z, self->w);
  112. liscr_args_seti_string (args, buffer);
  113. }
  114. static void Quaternion_concat (LIScrArgs* args)
  115. {
  116. LIMatQuaternion* self;
  117. LIMatQuaternion quat;
  118. if (!liscr_args_geti_quaternion (args, 0, &quat))
  119. return;
  120. self = args->self;
  121. *self = limat_quaternion_multiply (*self, quat);
  122. *self = limat_quaternion_validate (*self);
  123. }
  124. static void Quaternion_multiply (LIScrArgs* args)
  125. {
  126. float s;
  127. LIMatQuaternion* self;
  128. if (!liscr_args_geti_float (args, 0, &s))
  129. return;
  130. self = args->self;
  131. *self = limat_quaternion_init (self->x * s, self->y * s, self->z * s, self->w * s);
  132. }
  133. static void Quaternion_nlerp (LIScrArgs* args)
  134. {
  135. float val;
  136. LIMatQuaternion* self;
  137. LIMatQuaternion q2;
  138. if (liscr_args_geti_quaternion(args, 0, &q2) &&
  139. liscr_args_geti_float (args, 1, &val))
  140. {
  141. self = args->self;
  142. q2 = limat_quaternion_get_nearest (q2, *self);
  143. *self = limat_quaternion_nlerp (*self, q2, val);
  144. }
  145. }
  146. static void Quaternion_normalize (LIScrArgs* args)
  147. {
  148. LIMatQuaternion tmp;
  149. tmp = limat_quaternion_normalize (*((LIMatQuaternion*) args->self));
  150. liscr_args_seti_quaternion (args, &tmp);
  151. }
  152. static void Quaternion_set_axis (LIScrArgs* args)
  153. {
  154. float angle;
  155. LIMatQuaternion* self;
  156. LIMatVector axis;
  157. if (liscr_args_geti_vector (args, 0, &axis) &&
  158. liscr_args_geti_float (args, 1, &angle))
  159. {
  160. self = args->self;
  161. *self = limat_quaternion_rotation (angle, axis);
  162. }
  163. }
  164. static void Quaternion_get_conjugate (LIScrArgs* args)
  165. {
  166. LIMatQuaternion* data;
  167. LIMatQuaternion tmp;
  168. data = args->self;
  169. tmp = limat_quaternion_conjugate (*data);
  170. liscr_args_seti_quaternion (args, &tmp);
  171. }
  172. static void Quaternion_set_dir (LIScrArgs* args)
  173. {
  174. LIMatQuaternion* self;
  175. LIMatVector v1;
  176. LIMatVector v2;
  177. if (liscr_args_geti_vector (args, 0, &v1) &&
  178. liscr_args_geti_vector (args, 1, &v2))
  179. {
  180. self = args->self;
  181. *self = limat_quaternion_look (v1, v2);
  182. *self = limat_quaternion_conjugate (*self);
  183. }
  184. }
  185. static void Quaternion_get_euler (LIScrArgs* args)
  186. {
  187. float e[3];
  188. LIMatQuaternion* data;
  189. data = args->self;
  190. limat_quaternion_get_euler (*data, e + 0, e + 1, e + 2);
  191. liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE);
  192. liscr_args_seti_float (args, limat_number_validate (e[0]));
  193. liscr_args_seti_float (args, limat_number_validate (e[1]));
  194. liscr_args_seti_float (args, limat_number_validate (e[2]));
  195. }
  196. static void Quaternion_set_euler (LIScrArgs* args)
  197. {
  198. float e[3];
  199. LIMatQuaternion* self;
  200. if (liscr_args_geti_float (args, 0, e + 0) &&
  201. liscr_args_geti_float (args, 1, e + 1) &&
  202. liscr_args_geti_float (args, 2, e + 2))
  203. {
  204. self = args->self;
  205. *self = limat_quaternion_euler (e[0], e[1], e[2]);
  206. }
  207. }
  208. static void Quaternion_get_length (LIScrArgs* args)
  209. {
  210. liscr_args_seti_float (args, limat_quaternion_get_length (*((LIMatQuaternion*) args->self)));
  211. }
  212. static void Quaternion_get_w (LIScrArgs* args)
  213. {
  214. liscr_args_seti_float (args, ((LIMatQuaternion*) args->self)->w);
  215. }
  216. static void Quaternion_set_w (LIScrArgs* args)
  217. {
  218. liscr_args_geti_float (args, 0, &((LIMatQuaternion*) args->self)->w);
  219. }
  220. static void Quaternion_get_x (LIScrArgs* args)
  221. {
  222. liscr_args_seti_float (args, ((LIMatQuaternion*) args->self)->x);
  223. }
  224. static void Quaternion_set_x (LIScrArgs* args)
  225. {
  226. liscr_args_geti_float (args, 0, &((LIMatQuaternion*) args->self)->x);
  227. }
  228. static void Quaternion_get_y (LIScrArgs* args)
  229. {
  230. liscr_args_seti_float (args, ((LIMatQuaternion*) args->self)->y);
  231. }
  232. static void Quaternion_set_y (LIScrArgs* args)
  233. {
  234. liscr_args_geti_float (args, 0, &((LIMatQuaternion*) args->self)->y);
  235. }
  236. static void Quaternion_get_z (LIScrArgs* args)
  237. {
  238. liscr_args_seti_float (args, ((LIMatQuaternion*) args->self)->z);
  239. }
  240. static void Quaternion_set_z (LIScrArgs* args)
  241. {
  242. liscr_args_geti_float (args, 0, &((LIMatQuaternion*) args->self)->z);
  243. }
  244. /*****************************************************************************/
  245. void liext_script_quaternion (
  246. LIScrScript* self)
  247. {
  248. liscr_script_insert_cfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_new", Quaternion_new);
  249. liscr_script_insert_cfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_new_from_axis", Quaternion_new_from_axis);
  250. liscr_script_insert_cfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_new_from_dir", Quaternion_new_from_dir);
  251. liscr_script_insert_cfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_new_from_euler", Quaternion_new_from_euler);
  252. liscr_script_insert_cfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_new_from_vectors", Quaternion_new_from_vectors);
  253. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_add", Quaternion_add);
  254. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_concat", Quaternion_concat);
  255. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_multiply", Quaternion_multiply);
  256. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_sub", Quaternion_sub);
  257. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_tostring", Quaternion_tostring);
  258. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_nlerp", Quaternion_nlerp);
  259. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_normalize", Quaternion_normalize);
  260. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_axis", Quaternion_set_axis);
  261. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_conjugate", Quaternion_get_conjugate);
  262. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_dir", Quaternion_set_dir);
  263. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_euler", Quaternion_get_euler);
  264. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_euler", Quaternion_set_euler);
  265. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_length", Quaternion_get_length);
  266. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_x", Quaternion_get_x);
  267. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_x", Quaternion_set_x);
  268. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_y", Quaternion_get_y);
  269. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_y", Quaternion_set_y);
  270. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_z", Quaternion_get_z);
  271. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_z", Quaternion_set_z);
  272. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_get_w", Quaternion_get_w);
  273. liscr_script_insert_mfunc (self, LISCR_SCRIPT_QUATERNION, "quaternion_set_w", Quaternion_set_w);
  274. }
  275. /** @} */
  276. /** @} */