Simple game engine with complete export to scripting language
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

441 lines
10 KiB

  1. #include "ScriptSystem_Math.h"
  2. #include "Utilities/MersenneTwister.h"
  3. #include <cmath>
  4. namespace BlueCore
  5. {
  6. static MTRand mtrand;
  7. //------------------------------------------------------------------------------
  8. static SQInteger _sin(HSQUIRRELVM v)
  9. {
  10. SQFloat f;
  11. sq_getfloat (v, 2, &f );
  12. sq_pushfloat (v, ( SQFloat ) sin (f ) );
  13. return 1;
  14. }
  15. //------------------------------------------------------------------------------
  16. static SQInteger _cos(HSQUIRRELVM v)
  17. {
  18. SQFloat f;
  19. sq_getfloat (v, 2, &f );
  20. sq_pushfloat (v, ( SQFloat ) cos (f ) );
  21. return 1;
  22. }
  23. //------------------------------------------------------------------------------
  24. static SQInteger _tan(HSQUIRRELVM v)
  25. {
  26. SQFloat f;
  27. sq_getfloat (v, 2, &f );
  28. sq_pushfloat (v, ( SQFloat ) tan (f ) );
  29. return 1;
  30. }
  31. //------------------------------------------------------------------------------
  32. static SQInteger _sqrt(HSQUIRRELVM v)
  33. {
  34. SQFloat f;
  35. sq_getfloat (v, 2, &f );
  36. sq_pushfloat (v, ( SQFloat ) sqrt (f ) );
  37. return 1;
  38. }
  39. //------------------------------------------------------------------------------
  40. static SQInteger _trunc(HSQUIRRELVM v)
  41. {
  42. SQFloat f;
  43. sq_getfloat (v, 2, &f );
  44. sq_pushfloat (v, ( SQFloat ) f - fmod(f, 1.0) );
  45. return 1;
  46. }
  47. //------------------------------------------------------------------------------
  48. static SQInteger _floor(HSQUIRRELVM v)
  49. {
  50. SQFloat f;
  51. sq_getfloat (v, 2, &f );
  52. sq_pushfloat (v, ( SQFloat ) floor (f ) );
  53. return 1;
  54. }
  55. //------------------------------------------------------------------------------
  56. static SQInteger _ceil(HSQUIRRELVM v)
  57. {
  58. SQFloat f;
  59. sq_getfloat (v, 2, &f );
  60. sq_pushfloat (v, ( SQFloat ) ceil (f ) );
  61. return 1;
  62. }
  63. //------------------------------------------------------------------------------
  64. static SQInteger _rand(HSQUIRRELVM v)
  65. {
  66. sq_pushfloat (v, mtrand.rand() );
  67. return 1;
  68. }
  69. //------------------------------------------------------------------------------
  70. static SQInteger _seed_rand(HSQUIRRELVM v)
  71. {
  72. SQInteger seed;
  73. sq_getinteger(v, 2, &seed );
  74. mtrand.seed(seed );
  75. return 0;
  76. }
  77. //------------------------------------------------------------------------------
  78. static void _setup_basic_math (HSQUIRRELVM vm)
  79. {
  80. sq_pushroottable (vm);
  81. sq_pushstring (vm, "sin", -1);
  82. sq_newclosure (vm, _sin, 0);
  83. sq_setparamscheck (vm, 2, ".n");
  84. sq_newslot (vm, -3, false);
  85. sq_pushstring (vm, "cos", -1);
  86. sq_newclosure (vm, _cos, 0);
  87. sq_setparamscheck (vm, 2, ".n");
  88. sq_newslot (vm, -3, false);
  89. sq_pushstring (vm, "tan", -1);
  90. sq_newclosure (vm, _tan, 0);
  91. sq_setparamscheck (vm, 2, ".n");
  92. sq_newslot (vm, -3, false);
  93. sq_pushstring (vm, "sqrt", -1);
  94. sq_newclosure (vm, _sqrt, 0);
  95. sq_setparamscheck (vm, 2, ".n");
  96. sq_newslot (vm, -3, false);
  97. sq_pushstring (vm, "trunc", -1);
  98. sq_newclosure (vm, _trunc, 0);
  99. sq_setparamscheck (vm, 2, ".n");
  100. sq_newslot (vm, -3, false);
  101. sq_pushstring (vm, "floor", -1);
  102. sq_newclosure (vm, _floor, 0);
  103. sq_setparamscheck (vm, 2, ".n");
  104. sq_newslot (vm, -3, false);
  105. sq_pushstring (vm, "ceil", -1);
  106. sq_newclosure (vm, _ceil, 0);
  107. sq_setparamscheck (vm, 2, ".n");
  108. sq_newslot (vm, -3, false);
  109. sq_pushstring (vm, "rand", -1);
  110. sq_newclosure (vm, _rand, 0);
  111. sq_setparamscheck (vm, 1, ".");
  112. sq_newslot (vm, -3, false);
  113. sq_pushstring (vm, "seed_rand", -1);
  114. sq_newclosure (vm, _seed_rand, 0);
  115. sq_setparamscheck (vm, 2, ".n");
  116. sq_newslot (vm, -3, false);
  117. // pop the root table
  118. sq_pop (vm, 1);
  119. }
  120. //------------------------------------------------------------------------------
  121. static SQInteger _vector__add ( HSQUIRRELVM v )
  122. {
  123. SQFloat ax, ay, az;
  124. SQFloat bx = 0.0, by = 0.0, bz = 0.0;
  125. _getvectorvalues ( v, 1, ax, ay, az );
  126. _getvectorvalues ( v, 2, bx, by, bz );
  127. _pushvector ( v, ax + bx, ay + by, az + bz );
  128. return 1;
  129. }
  130. //------------------------------------------------------------------------------
  131. static SQInteger _vector__sub ( HSQUIRRELVM v )
  132. {
  133. SQFloat ax, ay, az;
  134. SQFloat bx = 0.0, by = 0.0, bz = 0.0;
  135. _getvectorvalues ( v, 1, ax, ay, az );
  136. _getvectorvalues ( v, 2, bx, by, bz );
  137. _pushvector ( v, ax - bx, ay - by, az - bz );
  138. return 1;
  139. }
  140. //------------------------------------------------------------------------------
  141. static SQInteger _vector__mul ( HSQUIRRELVM v )
  142. {
  143. SQFloat x, y, z, f;
  144. _getvectorvalues ( v, 1, x, y, z );
  145. sq_getfloat ( v, 2, &f );
  146. _pushvector ( v, x*f, y*f, z*f );
  147. return 1;
  148. }
  149. //------------------------------------------------------------------------------
  150. static SQInteger _vector__div ( HSQUIRRELVM v )
  151. {
  152. SQFloat x, y, z, f;
  153. _getvectorvalues ( v, 1, x, y, z );
  154. sq_getfloat ( v, 2, &f );
  155. _pushvector ( v, x / f, y / f, y / f );
  156. return 1;
  157. }
  158. //------------------------------------------------------------------------------
  159. static SQInteger _vector_length ( HSQUIRRELVM v )
  160. {
  161. SQFloat x, y, z;
  162. _getvectorvalues ( v, 1, x, y, z );
  163. sq_pushfloat ( v, std::sqrt ( x*x + y*y + z*z ) );
  164. return 1;
  165. }
  166. //------------------------------------------------------------------------------
  167. static SQInteger _vector_normalize ( HSQUIRRELVM v )
  168. {
  169. SQFloat x, y, z;
  170. _getvectorvalues ( v, 1, x, y, z );
  171. SQFloat l = 1 / std::sqrt ( x * x + y * y + z * z );
  172. _setvectorvalues ( v, 1, x*l, y*l, z*l );
  173. return 0;
  174. }
  175. //------------------------------------------------------------------------------
  176. static SQInteger _vector_constructor ( HSQUIRRELVM v )
  177. {
  178. SQFloat x = 0.0;
  179. SQFloat y = 0.0;
  180. SQFloat z = 0.0;
  181. SQInteger argc = sq_gettop ( v );
  182. if ( argc > 1 )
  183. sq_getfloat ( v, 2, &x );
  184. if ( argc > 2 )
  185. sq_getfloat ( v, 3, &y );
  186. if ( argc > 3 )
  187. sq_getfloat ( v, 4, &z );
  188. _setvectorvalues ( v, 1, x, y, z );
  189. return 0;
  190. }
  191. //------------------------------------------------------------------------------
  192. static void _register_vector_class( HSQUIRRELVM _vm )
  193. {
  194. sq_pushroottable ( _vm );
  195. // push class
  196. sq_pushstring ( _vm, "Vector", -1 );
  197. if ( SQ_SUCCEEDED ( sq_newclass ( _vm, SQFalse ) ) )
  198. {
  199. // register variables
  200. sq_pushstring ( _vm, "x", -1 );
  201. sq_pushfloat ( _vm, 0.0 );
  202. sq_newslot ( _vm, -3, false );
  203. sq_pushstring ( _vm, "y", -1 );
  204. sq_pushfloat ( _vm, 0.0 );
  205. sq_newslot ( _vm, -3, false );
  206. sq_pushstring ( _vm, "z", -1 );
  207. sq_pushfloat ( _vm, 0.0 );
  208. sq_newslot ( _vm, -3, false );
  209. // register constructor
  210. sq_pushstring ( _vm, "constructor", -1 );
  211. sq_newclosure ( _vm, _vector_constructor, 0 );
  212. sq_newslot ( _vm, -3, false );
  213. // register _add
  214. sq_pushstring ( _vm, "_add", -1 );
  215. sq_newclosure ( _vm, _vector__add, 0 );
  216. sq_newslot ( _vm, -3, false );
  217. // register _sub
  218. sq_pushstring ( _vm, "_sub", -1 );
  219. sq_newclosure ( _vm, _vector__sub, 0 );
  220. sq_newslot ( _vm, -3, false );
  221. // register _mul
  222. sq_pushstring ( _vm, "_mul", -1 );
  223. sq_newclosure ( _vm, _vector__mul, 0 );
  224. sq_newslot ( _vm, -3, false );
  225. // register _div
  226. sq_pushstring ( _vm, "_div", -1 );
  227. sq_newclosure ( _vm, _vector__div, 0 );
  228. sq_newslot ( _vm, -3, false );
  229. // register length
  230. sq_pushstring ( _vm, "length", -1 );
  231. sq_newclosure ( _vm, _vector_length, 0 );
  232. sq_newslot ( _vm, -3, false );
  233. // register normalize
  234. sq_pushstring ( _vm, "normalize", -1 );
  235. sq_newclosure ( _vm, _vector_normalize, 0 );
  236. sq_newslot ( _vm, -3, false );
  237. // create_vector class
  238. sq_newslot ( _vm, -3, false );
  239. }
  240. sq_poptop ( _vm );
  241. }
  242. //------------------------------------------------------------------------------
  243. static SQInteger _quaternion_constructor ( HSQUIRRELVM v )
  244. {
  245. SQFloat w = 0.0;
  246. SQFloat x = 0.0;
  247. SQFloat y = 0.0;
  248. SQFloat z = 0.0;
  249. SQInteger argc = sq_gettop ( v );
  250. if ( argc > 1 )
  251. sq_getfloat ( v, 2, &w );
  252. if ( argc > 2 )
  253. sq_getfloat ( v, 3, &x );
  254. if ( argc > 3 )
  255. sq_getfloat ( v, 4, &y );
  256. if ( argc > 4 )
  257. sq_getfloat ( v, 5, &z );
  258. _setquaternionvalues ( v, 1, w, x, y, z );
  259. return 0;
  260. }
  261. //------------------------------------------------------------------------------
  262. static SQInteger _quaternion_apply ( HSQUIRRELVM vm )
  263. {
  264. SQFloat qw, qx, qy, qz;
  265. SQFloat vx, vy, vz;
  266. _getquaternionvalues ( vm, 1, qw, qx, qy, qz );
  267. _getvectorvalues ( vm, 2, vx, vy, vz );
  268. SQFloat xx = qx*qx, xy = qx*qy, xz = qx*qz, xw = qx*qw,
  269. yy = qy*qy, yz = qy*qz, yw = qy*qw,
  270. zz = qz*qz, zw = qz*qw;
  271. SQFloat rx = 2.0 * (vx * (0.5 - yy - zz) + vy * (xy - zw) + vz * (xz + yw));
  272. SQFloat ry = 2.0 * (vx * (xy + zw) + vy * (0.5 - xx - zz) + vz * (yz - xw));
  273. SQFloat rz = 2.0 * (vx * (xz - yw) + vy * (yz + xw) + vz * (0.5 - xx - yy));
  274. _pushvector ( vm, rx, ry, rz );
  275. return 1;
  276. }
  277. //------------------------------------------------------------------------------
  278. static SQInteger _quaternion_applyinversed ( HSQUIRRELVM vm )
  279. {
  280. SQFloat qw, qx, qy, qz;
  281. SQFloat vx, vy, vz;
  282. _getquaternionvalues ( vm, 1, qw, qx, qy, qz );
  283. _getvectorvalues ( vm, 2, vx, vy, vz );
  284. SQFloat xx = qx*qx, xy = qx*qy, xz = qx*qz, xw = -qx*qw,
  285. yy = qy*qy, yz = qy*qz, yw = -qy*qw,
  286. zz = qz*qz, zw = -qz*qw;
  287. SQFloat rx = 2.0 * (vx * (0.5 - yy - zz) + vy * (xy - zw) + vz * (xz + yw));
  288. SQFloat ry = 2.0 * (vx * (xy + zw) + vy * (0.5 - xx - zz) + vz * (yz - xw));
  289. SQFloat rz = 2.0 * (vx * (xz - yw) + vy * (yz + xw) + vz * (0.5 - xx - yy));
  290. _pushvector ( vm, rx, ry, rz );
  291. return 1;
  292. }
  293. //------------------------------------------------------------------------------
  294. static void _register_quaternion_class (HSQUIRRELVM vm)
  295. {
  296. sq_pushroottable ( vm );
  297. // push class
  298. sq_pushstring ( vm, "Quaternion", -1 );
  299. if ( SQ_SUCCEEDED ( sq_newclass ( vm, SQFalse ) ) )
  300. {
  301. // register variables
  302. sq_pushstring ( vm, "w", -1 );
  303. sq_pushfloat ( vm, 0.0 );
  304. sq_newslot ( vm, -3, false );
  305. sq_pushstring ( vm, "x", -1 );
  306. sq_pushfloat ( vm, 0.0 );
  307. sq_newslot ( vm, -3, false );
  308. sq_pushstring ( vm, "y", -1 );
  309. sq_pushfloat ( vm, 0.0 );
  310. sq_newslot ( vm, -3, false );
  311. sq_pushstring ( vm, "z", -1 );
  312. sq_pushfloat ( vm, 0.0 );
  313. sq_newslot ( vm, -3, false );
  314. // register constructor
  315. sq_pushstring ( vm, "constructor", -1 );
  316. sq_newclosure ( vm, _quaternion_constructor, 0 );
  317. sq_newslot ( vm, -3, false );
  318. sq_pushstring ( vm, "apply", -1 );
  319. sq_newclosure ( vm, _quaternion_apply, 0 );
  320. sq_newslot ( vm, -3, false );
  321. sq_pushstring ( vm, "applyInversed", -1 );
  322. sq_newclosure ( vm, _quaternion_applyinversed, 0 );
  323. sq_newslot ( vm, -3, false );
  324. // create_vector class
  325. sq_newslot ( vm, -3, false );
  326. }
  327. sq_poptop ( vm );
  328. }
  329. //------------------------------------------------------------------------------
  330. void setupScriptSystem_Math (ScriptSystem* scriptsystem)
  331. {
  332. if (scriptsystem == 0)
  333. return;
  334. HSQUIRRELVM vm = scriptsystem->getVM();
  335. if (vm)
  336. {
  337. _setup_basic_math (vm);
  338. _register_vector_class(vm);
  339. _register_quaternion_class(vm);
  340. }
  341. }
  342. } // namespace BlueCore