enmath3d.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /**
  2. * \defgroup Math3DAPI Math3D library
  3. * @{
  4. */
  5. /**
  6. \brief Vector constructor from components
  7. \param x \p float x component
  8. \param y \p float y component
  9. \param z \p float z component
  10. \return \p vector resulting vector
  11. @code
  12. Print( Vector(1, 2, 3) );
  13. >> <1,2,3>
  14. @endcode
  15. */
  16. proto native vector Vector(float x, float y, float z);
  17. enum ECurveType
  18. {
  19. CatmullRom,
  20. NaturalCubic,
  21. UniformCubic
  22. };
  23. class Math3D
  24. {
  25. private void Math3D() {}
  26. private void ~Math3D() {}
  27. //-----------------------------------------------------------------
  28. proto static vector ClipLine(vector start, vector end, vector norm, float d);
  29. /**
  30. \brief Tests whether ray is intersecting sphere.
  31. \param raybase \p vector Start of ray
  32. \param raycos \p vector End of ray
  33. \param center \p vector Center of sphere
  34. \param radius \p float Radius of sphere
  35. \return \p float -1 when not intersecting, else the fraction of ray
  36. */
  37. proto static float IntersectRaySphere(vector raybase, vector raycos, vector center, float radius);
  38. /**
  39. \brief Tests whether ray is intersecting axis aligned box.
  40. \param start \p vector Start of ray
  41. \param end \p vector End of ray
  42. \param mins \p vector Minimums of bound box
  43. \param maxs \p vector Maximums of bound box
  44. \return \p float -1 when not intersecting, else the fraction of ray
  45. */
  46. proto static float IntersectRayBox(vector start, vector end, vector mins, vector maxs);
  47. /**
  48. \brief Tests whether sphere is intersecting axis aligned box.
  49. \param origin \p vector Origin of sphere
  50. \param radius \p float Radius of sphere
  51. \param mins \p vector Minimums of bound box
  52. \param maxs \p vector Maximums of bound box
  53. \return \p bool True when intersects
  54. */
  55. proto static bool IntersectSphereBox(vector origin, float radius, vector mins, vector maxs);
  56. /**
  57. \brief Tests whether sphere is intersecting cone.
  58. \param origin \p vector Origin of sphere
  59. \param radius \p float Radius of sphere
  60. \param conepos \p vector Position of top of cone
  61. \param axis \p vector Orientation of cone in direction from top to bottom
  62. \param angle \p float Angle of cone in radians
  63. \return \p bool True when sphere is intersecting cone
  64. */
  65. proto static bool IntersectSphereCone(vector origin, float radius, vector conepos, vector axis, float angle);
  66. /**
  67. \brief Tests whether sphere is fully inside cone.
  68. \param origin \p vector Origin of sphere
  69. \param radius \p float Radius of sphere
  70. \param conepos \p vector Position of top of cone
  71. \param axis \p vector Orientation of cone in direction from top to bottom
  72. \param angle \p float Angle of cone in radians
  73. \return \p bool True when sphere is fully inside cone
  74. */
  75. proto static bool IntersectWholeSphereCone(vector origin, float radius, vector conepos, vector axis, float angle);
  76. /**
  77. \brief Tests whether cylinder is intersecting oriented box.
  78. \param mins \p vector Minimums of bound box
  79. \param maxs \p vector Maximums of bound box
  80. \param obbMat \p vector Transform of box
  81. \param cylMat \p vector Transform of cylinder
  82. \param cylinderRadius \p float Radius of cylinder
  83. \param cylinderHeight \p float Height of cylinder
  84. \return \p bool True when cylinder is intersecting oriented box
  85. */
  86. proto static bool IntersectCylinderOBB(vector mins, vector maxs, vector obbMat[4], vector cylMat[4], float cylinderRadius, float cylinderHeight);
  87. /**
  88. \brief Tests whether ray is intersecting cylinder.
  89. \param rayStart \p vector Start of ray
  90. \param rayEnd \p vector End of ray
  91. \param center \p vector Center of cylinder
  92. \param radius \p float Radius of cylinder
  93. \param height \p float Height of cylinder
  94. \return \p bool True when ray is intersecting cylinder
  95. */
  96. proto static bool IntersectRayCylinder(vector rayStart, vector rayEnd, vector center, float radius, float height);
  97. /**
  98. \brief Tests whether ray is intersecting plane.
  99. \param rayStart \p vector Start of ray
  100. \param rayEnd \p vector End of ray
  101. \param planeNormal \p vector Normal of the plane
  102. \param planeDist \p float Length of the plane
  103. \param intersection \p vector Intersection point of the plane, only valid when return is 3
  104. \return \p int 1 when behind, 2 when in front and 3 when intersecting the plane
  105. */
  106. proto static int IntersectRayPlane(vector rayStart, vector rayEnd, vector planeNormal, float planeDist, out vector intersection);
  107. /**
  108. \brief Creates rotation matrix from angles
  109. \param ang \p vector which contains angles
  110. \param[out] mat \p vector created rotation matrix
  111. @code
  112. vector mat[3];
  113. YawPitchRollMatrix( "70 15 45", mat );
  114. Print( mat );
  115. >> <0.330366,0.0885213,-0.939693>,<0.458809,0.854988,0.241845>,<0.824835,-0.511037,0.241845>
  116. @endcode
  117. */
  118. proto static void YawPitchRollMatrix(vector ang, out vector mat[3]);
  119. /**
  120. \brief Creates rotation matrix from direction and up vector
  121. \param dir \p vector direction vector
  122. \param up \p vector up vector
  123. \param[out] mat \p vector[4] created rotation matrix
  124. @code
  125. vector mat[4];
  126. vector dir = "1 0 1";
  127. vector up = "0 1 0";
  128. DirectionAndUpMatrix( dir, up, mat );
  129. Print( mat );
  130. >> <0.707107,0,-0.707107>,<0,1,0>,<0.707107,0,0.707107>,<0,0,0>
  131. @endcode
  132. */
  133. proto static void DirectionAndUpMatrix(vector dir, vector up, out vector mat[4]);
  134. /**
  135. \brief Transforms matrix
  136. \param mat0 \p vector[4] first matrix
  137. \param mat1 \p vector[4] second matrix
  138. \param[out] res \p vector[4] result of first and second matrix multiplication
  139. @code
  140. vector mat0[4] = { "2 0 0 0", "0 3 0 0", "0 1 0 0", "0 0 0 1" }; // scale matrix
  141. vector mat1[4] = { "1 0 0 0", "0 1 0 0", "0 1 0 0", "2 4 1 3" }; // translation matrix
  142. vector res[4];
  143. Math3D.MatrixMultiply4(mat0, mat1, res)
  144. Print( res );
  145. >> <2,0,0>,<0,3,0>,<0,3,0>,<4,13,0>
  146. @endcode
  147. */
  148. proto static void MatrixMultiply4(vector mat0[4], vector mat1[4], out vector res[4]);
  149. /**
  150. \brief Transforms rotation matrix
  151. \param mat0 \p vector[3] first matrix
  152. \param mat1 \p vector[3] second matrix
  153. \param[out] res \p vector[3] result of first and second matrix multiplication
  154. @code
  155. vector mat0[3] = { "1.5 2.5 0", "0.1 1.3 0", "0 0 1" }; // rotation matrix
  156. vector mat1[3] = { "1 0.4 0", "0 1 0", "0 1.3 2.7" }; // rotation matrix
  157. vector res[3];
  158. Math3D.MatrixMultiply3(mat0, mat1, res)
  159. Print( res );
  160. >> <1.54,3.02,0>,<0.1,1.3,0>,<0.13,1.69,2.7>
  161. @endcode
  162. */
  163. proto static void MatrixMultiply3(vector mat0[3], vector mat1[3], out vector res[3]);
  164. /**
  165. \brief Invert-transforms matrix
  166. \param mat0 \p vector[4] first matrix
  167. \param mat1 \p vector[4] second matrix
  168. \param[out] res \p vector[4] inverse result of first and second matrix multiplication
  169. @code
  170. vector mat0[4] = { "2 0 0", "0 3 0", "0 0 1", "0 0 0" }; // scale matrix
  171. vector mat1[4] = { "1 0 0", "0 1 0", "0 0 1", "2 4 1" }; // translation matrix
  172. vector res[4];
  173. Math3D.MatrixInvMultiply4(mat0, mat1, res)
  174. Print( res );
  175. >> <2,0,0>,<0,3,1>,<0,3,1>,<4,12,4>
  176. @endcode
  177. */
  178. proto static void MatrixInvMultiply4(vector mat0[4], vector mat1[4], out vector res[4]);
  179. /**
  180. \brief Invert-transforms rotation matrix
  181. \param mat0 \p vector[3] first matrix
  182. \param mat1 \p vector[3] second matrix
  183. \param[out] res \p vector[3] result of first and second matrix multiplication
  184. @code
  185. vector mat0[3] = { "1.5 2.5 0", "0.1 1.3 0", "0 0 1" }; // rotation matrix
  186. vector mat1[3] = { "1 0.4 0", "0 1 0", "0 1.3 2.7" }; // rotation matrix
  187. vector res[3];
  188. Math3D.MatrixInvMultiply3(mat0, mat1, res)
  189. Print( res );
  190. >> <2.5,0.62,0>,<2.5,1.3,0>,<3.25,1.69,2.7>
  191. @endcode
  192. */
  193. proto static void MatrixInvMultiply3(vector mat0[3], vector mat1[3], out vector res[3]);
  194. /**
  195. \brief Inverses a matrix
  196. \param[it] mat \p matrix which should be inversed
  197. */
  198. proto static void MatrixInverse4(vector mat[4]);
  199. /**
  200. \brief Inverses a matrix
  201. \param[it] mat \p matrix which should be inversed
  202. */
  203. proto static void MatrixInverse3(vector mat[3]);
  204. /**
  205. \brief Orthogonalizes matrix
  206. \param[it] mat \p matrix which should be orthogonalized
  207. */
  208. proto static void MatrixOrthogonalize4(vector mat[4]);
  209. /**
  210. \brief Orthogonalizes matrix
  211. \param[it] mat \p matrix which should be orthogonalized
  212. */
  213. proto static void MatrixOrthogonalize3(vector mat[3]);
  214. /**
  215. \brief Creates identity matrix
  216. \param[out] mat \p created identity matrix
  217. @code
  218. vector mat[4];
  219. Math3D.MatrixIdentity4( mat );
  220. Print( mat );
  221. >> <1,0,0>,<0,1,0>,<0,0,1>,<0,0,0>
  222. @endcode
  223. */
  224. static void MatrixIdentity4(out vector mat[4])
  225. {
  226. mat[0] = "1 0 0";
  227. mat[1] = "0 1 0";
  228. mat[2] = "0 0 1";
  229. mat[3] = vector.Zero;
  230. }
  231. /**
  232. \brief Creates identity matrix
  233. \param[out] mat \p created identity matrix
  234. @code
  235. vector mat[3];
  236. Math3D.MatrixIdentity3( mat );
  237. Print( mat );
  238. >> <1,0,0>,<0,1,0>,<0,0,1>
  239. @endcode
  240. */
  241. static void MatrixIdentity3(out vector mat[3])
  242. {
  243. mat[0] = "1 0 0";
  244. mat[1] = "0 1 0";
  245. mat[2] = "0 0 1";
  246. }
  247. /**
  248. \brief Creates scale matrix
  249. \param scale \p scale coeficient
  250. \param[out] mat \p created scale matrix
  251. @code
  252. vector mat[3];
  253. Math3D.ScaleMatrix( 2.5, mat );
  254. Print( mat );
  255. >> <2.5,0,0>,<0,2.5,0>,<0,0,2.5>
  256. @endcode
  257. */
  258. static void ScaleMatrix(float scale, out vector mat[3])
  259. {
  260. vector v0, v1, v2;
  261. v0[0] = scale;
  262. v1[1] = scale;
  263. v2[2] = scale;
  264. mat[0] = v0;
  265. mat[1] = v1;
  266. mat[2] = v2;
  267. }
  268. /**
  269. \brief Creates identity quaternion
  270. \param[out] q \p float[4] created identity quaternion
  271. @code
  272. float q[4];
  273. Math3D.QuatIdentity( q );
  274. Print( q );
  275. >> {0,0,0,1}
  276. @endcode
  277. */
  278. static void QuatIdentity(out float q[4])
  279. {
  280. q[0] = 0;
  281. q[1] = 0;
  282. q[2] = 0;
  283. q[3] = 1;
  284. }
  285. /**
  286. \brief Copies quaternion
  287. \param s \p float[4] quaternion to copy
  288. \param[out] d \p float[4] created quaternion copy
  289. @code
  290. float s[4] = { 2, 3, 4, 1 };
  291. float d[4];
  292. Math3D.QuatCopy( s, d );
  293. Print( d );
  294. >> {2,3,4,1}
  295. @endcode
  296. */
  297. static void QuatCopy(float s[4], out float d[4])
  298. {
  299. d[0] = s[0];
  300. d[1] = s[1];
  301. d[2] = s[2];
  302. d[3] = s[3];
  303. }
  304. /**
  305. \brief Converts rotation matrix to quaternion
  306. \param mat \p vector[3] rotation matrix
  307. \param[out] d \p float[4] created quaternion copy
  308. @code
  309. vector mat[3];
  310. vector rot = "70 15 45";
  311. rot.RotationMatrixFromAngles( mat );
  312. float d[4];
  313. Math3D.MatrixToQuat( mat, d );
  314. Print( d );
  315. >> {0.241626,0.566299,-0.118838,0.778973}
  316. @endcode
  317. */
  318. proto static void MatrixToQuat(vector mat[3], out float d[4]);
  319. //! Converts quaternion to rotation matrix
  320. proto static void QuatToMatrix(float q[4], out vector mat[3]);
  321. /**
  322. \brief Returns angles of rotation matrix
  323. \param mat \p vector[3] rotation matrix
  324. \return \p vector roll, pitch, yaw angles
  325. @code
  326. vector mat[3];
  327. Math3D.RollPitchYawMatrix( "70 15 45", mat );
  328. vector ang = Math3D.MatrixToAngles( mat );
  329. Print( ang );
  330. >> <70,15,-45>
  331. @endcode
  332. */
  333. proto static vector MatrixToAngles(vector mat[3]);
  334. /**
  335. \brief Linear interpolation between q1 and q2 with weight 'frac' (0...1)
  336. \param[out] qout \p float[4] result quaternion
  337. \param q1 \p float[4] first quaternion
  338. \param q2 \p float[4] second quaternion
  339. \param frac \p float interpolation weight
  340. @code
  341. float q1[4] = { 1, 1, 1, 1 };
  342. float q2[4] = { 2, 2, 2, 1 };
  343. float qout[4];
  344. Math3D.QuatLerp( qout, q1, q2, 0.5 );
  345. Print( qout );
  346. >> {1.5,1.5,1.5,1}
  347. @endcode
  348. */
  349. proto static void QuatLerp(out float qout[4], float q1[4], float q2[4], float frac);
  350. /**
  351. \brief Multiplies quaternions
  352. \param[out] qout \p float[4] result quaternion
  353. \param q1 \p float[4] first quaternion
  354. \param q2 \p float[4] second quaternion
  355. @code
  356. float q1[4] = { 1, 2, 3, 1 };
  357. float q2[4] = { 2, 2, 2, 1 };
  358. float qout[4];
  359. Math3D.QuatMultiply( qout, q1, q2 );
  360. Print( qout );
  361. >> {2,4,6,1}
  362. @endcode
  363. */
  364. proto static void QuatMultiply(out float qout[4], float q1[4], float q2[4]);
  365. //! Returns Angles vector from quaternion
  366. proto static vector QuatToAngles(float q[4]);
  367. /**
  368. \brief Returns 1, when bounding boxes intersects
  369. \param mins1 \p vector minimum point of first bounding box
  370. \param maxs1 \p vector maximum point of first bounding box
  371. \param mins2 \p vector minimum point of second bounding box
  372. \param maxs2 \p vector maximum point of second bounding box
  373. \return \p int 1 if boundig boxes intersects, otherwise 0
  374. @code
  375. vector mins1 = "1 1 1";
  376. vector maxs1 = "3 3 3";
  377. vector mins2 = "2 2 2";
  378. vector maxs2 = "4 4 4";
  379. Print( Math3D.CheckBoundBox(mins1, maxs1, mins2, maxs2) );
  380. >> 1
  381. @endcode
  382. */
  383. proto static int CheckBoundBox(vector mins1, vector maxs1, vector mins2, vector maxs2);
  384. /**
  385. \brief Returns randon normalized direction
  386. \return \p vector
  387. @code
  388. Print( Math3D.GetRandomDir() );
  389. >>vector ret = 0x0000000007c1a1c0 {<0.422565,0,-0.906333>}
  390. @endcode
  391. */
  392. static vector GetRandomDir()
  393. {
  394. float x = Math.RandomFloatInclusive(-1, 1);
  395. float y = Math.RandomFloatInclusive(-1, 1);
  396. float z = Math.RandomFloatInclusive(-1, 1);
  397. return Vector(x, y, z).Normalized();
  398. }
  399. /**
  400. \brief Computes curve
  401. \return \p vector
  402. @code
  403. auto points = new array<vector>();
  404. points.Insert( Vector( 0, 0, 0) );
  405. points.Insert( Vector( 5, 0, 0) );
  406. points.Insert( Vector( 8, 3, 0) );
  407. points.Insert( Vector( 6, 1, 0) );
  408. float t = 0.5;
  409. vector result = Math3D.Curve(ECurveType.CatmullRom, t, points);
  410. @endcode
  411. */
  412. proto static native vector Curve(ECurveType type, float param, notnull array<vector> points);
  413. /**
  414. \brief Point on line beg .. end nearest to pos
  415. \return \p vector
  416. */
  417. proto static vector NearestPoint(vector beg, vector end, vector pos);
  418. /**
  419. \brief Angle that a target is from the direction of an origin
  420. \return \p float Angle in radians
  421. */
  422. proto static float AngleFromPosition(vector origin, vector originDir, vector target);
  423. /**
  424. \brief Calculates the points of a right 2D cone in 3D space
  425. \param origin \p vector Origin of cone
  426. \param length \p float Length of the cone
  427. \param halfAngle \p float Half of the angle of the cone in radians
  428. \param angleOffset \p float Angle offset of the cone in radians (handy for rotating it along with something in the world)
  429. \param[out] leftPoint \p vector Left point of the cone
  430. \param[out] rightPoint \p vector Right point of the cone
  431. */
  432. proto static void ConePoints(vector origin, float length, float halfAngle, float angleOffset, out vector leftPoint, out vector rightPoint);
  433. };
  434. //@}