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.

1466 lines
40 KiB

  1. /**********************************************************************************************
  2. *
  3. * raymath v1.2 - Math functions to work with Vector3, Matrix and Quaternions
  4. *
  5. * CONFIGURATION:
  6. *
  7. * #define RAYMATH_IMPLEMENTATION
  8. * Generates the implementation of the library into the included file.
  9. * If not defined, the library is in header only mode and can be included in other headers
  10. * or source files without problems. But only ONE file should hold the implementation.
  11. *
  12. * #define RAYMATH_HEADER_ONLY
  13. * Define static inline functions code, so #include header suffices for use.
  14. * This may use up lots of memory.
  15. *
  16. * #define RAYMATH_STANDALONE
  17. * Avoid raylib.h header inclusion in this file.
  18. * Vector3 and Matrix data types are defined internally in raymath module.
  19. *
  20. *
  21. * LICENSE: zlib/libpng
  22. *
  23. * Copyright (c) 2015-2020 Ramon Santamaria (@raysan5)
  24. *
  25. * This software is provided "as-is", without any express or implied warranty. In no event
  26. * will the authors be held liable for any damages arising from the use of this software.
  27. *
  28. * Permission is granted to anyone to use this software for any purpose, including commercial
  29. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  30. *
  31. * 1. The origin of this software must not be misrepresented; you must not claim that you
  32. * wrote the original software. If you use this software in a product, an acknowledgment
  33. * in the product documentation would be appreciated but is not required.
  34. *
  35. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  36. * as being the original software.
  37. *
  38. * 3. This notice may not be removed or altered from any source distribution.
  39. *
  40. **********************************************************************************************/
  41. #ifndef RAYMATH_H
  42. #define RAYMATH_H
  43. //#define RAYMATH_STANDALONE // NOTE: To use raymath as standalone lib, just uncomment this line
  44. //#define RAYMATH_HEADER_ONLY // NOTE: To compile functions as static inline, uncomment this line
  45. #ifndef RAYMATH_STANDALONE
  46. #include "raylib.h" // Required for structs: Vector3, Matrix
  47. #endif
  48. #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_HEADER_ONLY)
  49. #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_HEADER_ONLY is contradictory"
  50. #endif
  51. #if defined(RAYMATH_IMPLEMENTATION)
  52. #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
  53. #define RMDEF __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll).
  54. #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
  55. #define RMDEF __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
  56. #else
  57. #define RMDEF extern inline // Provide external definition
  58. #endif
  59. #elif defined(RAYMATH_HEADER_ONLY)
  60. #define RMDEF static inline // Functions may be inlined, no external out-of-line definition
  61. #else
  62. #if defined(__TINYC__)
  63. #define RMDEF static inline // plain inline not supported by tinycc (See issue #435)
  64. #else
  65. #define RMDEF inline // Functions may be inlined or external definition used
  66. #endif
  67. #endif
  68. //----------------------------------------------------------------------------------
  69. // Defines and Macros
  70. //----------------------------------------------------------------------------------
  71. #ifndef PI
  72. #define PI 3.14159265358979323846
  73. #endif
  74. #ifndef DEG2RAD
  75. #define DEG2RAD (PI/180.0f)
  76. #endif
  77. #ifndef RAD2DEG
  78. #define RAD2DEG (180.0f/PI)
  79. #endif
  80. // Return float vector for Matrix
  81. #ifndef MatrixToFloat
  82. #define MatrixToFloat(mat) (MatrixToFloatV(mat).v)
  83. #endif
  84. // Return float vector for Vector3
  85. #ifndef Vector3ToFloat
  86. #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v)
  87. #endif
  88. //----------------------------------------------------------------------------------
  89. // Types and Structures Definition
  90. //----------------------------------------------------------------------------------
  91. #if defined(RAYMATH_STANDALONE)
  92. // Vector2 type
  93. typedef struct Vector2 {
  94. float x;
  95. float y;
  96. } Vector2;
  97. // Vector3 type
  98. typedef struct Vector3 {
  99. float x;
  100. float y;
  101. float z;
  102. } Vector3;
  103. // Quaternion type
  104. typedef struct Quaternion {
  105. float x;
  106. float y;
  107. float z;
  108. float w;
  109. } Quaternion;
  110. // Matrix type (OpenGL style 4x4 - right handed, column major)
  111. typedef struct Matrix {
  112. float m0, m4, m8, m12;
  113. float m1, m5, m9, m13;
  114. float m2, m6, m10, m14;
  115. float m3, m7, m11, m15;
  116. } Matrix;
  117. #endif
  118. // NOTE: Helper types to be used instead of array return types for *ToFloat functions
  119. typedef struct float3 { float v[3]; } float3;
  120. typedef struct float16 { float v[16]; } float16;
  121. #include <math.h> // Required for: sinf(), cosf(), sqrtf(), tan(), fabs()
  122. //----------------------------------------------------------------------------------
  123. // Module Functions Definition - Utils math
  124. //----------------------------------------------------------------------------------
  125. // Clamp float value
  126. RMDEF float Clamp(float value, float min, float max)
  127. {
  128. const float res = value < min ? min : value;
  129. return res > max ? max : res;
  130. }
  131. // Calculate linear interpolation between two floats
  132. RMDEF float Lerp(float start, float end, float amount)
  133. {
  134. return start + amount*(end - start);
  135. }
  136. //----------------------------------------------------------------------------------
  137. // Module Functions Definition - Vector2 math
  138. //----------------------------------------------------------------------------------
  139. // Vector with components value 0.0f
  140. RMDEF Vector2 Vector2Zero(void)
  141. {
  142. Vector2 result = { 0.0f, 0.0f };
  143. return result;
  144. }
  145. // Vector with components value 1.0f
  146. RMDEF Vector2 Vector2One(void)
  147. {
  148. Vector2 result = { 1.0f, 1.0f };
  149. return result;
  150. }
  151. // Add two vectors (v1 + v2)
  152. RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2)
  153. {
  154. Vector2 result = { v1.x + v2.x, v1.y + v2.y };
  155. return result;
  156. }
  157. // Add vector and float value
  158. RMDEF Vector2 Vector2AddValue(Vector2 v, float add)
  159. {
  160. Vector2 result = { v.x + add, v.y + add };
  161. return result;
  162. }
  163. // Subtract two vectors (v1 - v2)
  164. RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
  165. {
  166. Vector2 result = { v1.x - v2.x, v1.y - v2.y };
  167. return result;
  168. }
  169. // Subtract vector by float value
  170. RMDEF Vector2 Vector2SubtractValue(Vector2 v, float sub)
  171. {
  172. Vector2 result = { v.x - sub, v.y - sub };
  173. return result;
  174. }
  175. // Calculate vector length
  176. RMDEF float Vector2Length(Vector2 v)
  177. {
  178. float result = sqrtf((v.x*v.x) + (v.y*v.y));
  179. return result;
  180. }
  181. // Calculate two vectors dot product
  182. RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2)
  183. {
  184. float result = (v1.x*v2.x + v1.y*v2.y);
  185. return result;
  186. }
  187. // Calculate distance between two vectors
  188. RMDEF float Vector2Distance(Vector2 v1, Vector2 v2)
  189. {
  190. float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
  191. return result;
  192. }
  193. // Calculate angle from two vectors in X-axis
  194. RMDEF float Vector2Angle(Vector2 v1, Vector2 v2)
  195. {
  196. float result = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
  197. if (result < 0) result += 360.0f;
  198. return result;
  199. }
  200. // Scale vector (multiply by value)
  201. RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
  202. {
  203. Vector2 result = { v.x*scale, v.y*scale };
  204. return result;
  205. }
  206. // Multiply vector by vector
  207. RMDEF Vector2 Vector2Multiply(Vector2 v1, Vector2 v2)
  208. {
  209. Vector2 result = { v1.x*v2.x, v1.y*v2.y };
  210. return result;
  211. }
  212. // Negate vector
  213. RMDEF Vector2 Vector2Negate(Vector2 v)
  214. {
  215. Vector2 result = { -v.x, -v.y };
  216. return result;
  217. }
  218. // Divide vector by vector
  219. RMDEF Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
  220. {
  221. Vector2 result = { v1.x/v2.x, v1.y/v2.y };
  222. return result;
  223. }
  224. // Normalize provided vector
  225. RMDEF Vector2 Vector2Normalize(Vector2 v)
  226. {
  227. Vector2 result = Vector2Scale(v, 1/Vector2Length(v));
  228. return result;
  229. }
  230. // Calculate linear interpolation between two vectors
  231. RMDEF Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount)
  232. {
  233. Vector2 result = { 0 };
  234. result.x = v1.x + amount*(v2.x - v1.x);
  235. result.y = v1.y + amount*(v2.y - v1.y);
  236. return result;
  237. }
  238. // Rotate Vector by float in Degrees.
  239. RMDEF Vector2 Vector2Rotate(Vector2 v, float degs)
  240. {
  241. float rads = degs*DEG2RAD;
  242. Vector2 result = {v.x * cosf(rads) - v.y * sinf(rads) , v.x * sinf(rads) + v.y * cosf(rads) };
  243. return result;
  244. }
  245. //----------------------------------------------------------------------------------
  246. // Module Functions Definition - Vector3 math
  247. //----------------------------------------------------------------------------------
  248. // Vector with components value 0.0f
  249. RMDEF Vector3 Vector3Zero(void)
  250. {
  251. Vector3 result = { 0.0f, 0.0f, 0.0f };
  252. return result;
  253. }
  254. // Vector with components value 1.0f
  255. RMDEF Vector3 Vector3One(void)
  256. {
  257. Vector3 result = { 1.0f, 1.0f, 1.0f };
  258. return result;
  259. }
  260. // Add two vectors
  261. RMDEF Vector3 Vector3Add(Vector3 v1, Vector3 v2)
  262. {
  263. Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
  264. return result;
  265. }
  266. // Add vector and float value
  267. RMDEF Vector3 Vector3AddValue(Vector3 v, float add)
  268. {
  269. Vector3 result = { v.x + add, v.y + add, v.z + add };
  270. return result;
  271. }
  272. // Subtract two vectors
  273. RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
  274. {
  275. Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
  276. return result;
  277. }
  278. // Subtract vector by float value
  279. RMDEF Vector3 Vector3SubtractValue(Vector3 v, float sub)
  280. {
  281. Vector3 result = { v.x - sub, v.y - sub, v.z - sub };
  282. return result;
  283. }
  284. // Multiply vector by scalar
  285. RMDEF Vector3 Vector3Scale(Vector3 v, float scalar)
  286. {
  287. Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar };
  288. return result;
  289. }
  290. // Multiply vector by vector
  291. RMDEF Vector3 Vector3Multiply(Vector3 v1, Vector3 v2)
  292. {
  293. Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z };
  294. return result;
  295. }
  296. // Calculate two vectors cross product
  297. RMDEF Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2)
  298. {
  299. Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x };
  300. return result;
  301. }
  302. // Calculate one vector perpendicular vector
  303. RMDEF Vector3 Vector3Perpendicular(Vector3 v)
  304. {
  305. Vector3 result = { 0 };
  306. float min = (float) fabs(v.x);
  307. Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
  308. if (fabs(v.y) < min)
  309. {
  310. min = (float) fabs(v.y);
  311. Vector3 tmp = {0.0f, 1.0f, 0.0f};
  312. cardinalAxis = tmp;
  313. }
  314. if (fabs(v.z) < min)
  315. {
  316. Vector3 tmp = {0.0f, 0.0f, 1.0f};
  317. cardinalAxis = tmp;
  318. }
  319. result = Vector3CrossProduct(v, cardinalAxis);
  320. return result;
  321. }
  322. // Calculate vector length
  323. RMDEF float Vector3Length(const Vector3 v)
  324. {
  325. float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  326. return result;
  327. }
  328. // Calculate two vectors dot product
  329. RMDEF float Vector3DotProduct(Vector3 v1, Vector3 v2)
  330. {
  331. float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  332. return result;
  333. }
  334. // Calculate distance between two vectors
  335. RMDEF float Vector3Distance(Vector3 v1, Vector3 v2)
  336. {
  337. float dx = v2.x - v1.x;
  338. float dy = v2.y - v1.y;
  339. float dz = v2.z - v1.z;
  340. float result = sqrtf(dx*dx + dy*dy + dz*dz);
  341. return result;
  342. }
  343. // Negate provided vector (invert direction)
  344. RMDEF Vector3 Vector3Negate(Vector3 v)
  345. {
  346. Vector3 result = { -v.x, -v.y, -v.z };
  347. return result;
  348. }
  349. // Divide vector by vector
  350. RMDEF Vector3 Vector3Divide(Vector3 v1, Vector3 v2)
  351. {
  352. Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
  353. return result;
  354. }
  355. // Normalize provided vector
  356. RMDEF Vector3 Vector3Normalize(Vector3 v)
  357. {
  358. Vector3 result = v;
  359. float length, ilength;
  360. length = Vector3Length(v);
  361. if (length == 0.0f) length = 1.0f;
  362. ilength = 1.0f/length;
  363. result.x *= ilength;
  364. result.y *= ilength;
  365. result.z *= ilength;
  366. return result;
  367. }
  368. // Orthonormalize provided vectors
  369. // Makes vectors normalized and orthogonal to each other
  370. // Gram-Schmidt function implementation
  371. RMDEF void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2)
  372. {
  373. *v1 = Vector3Normalize(*v1);
  374. Vector3 vn = Vector3CrossProduct(*v1, *v2);
  375. vn = Vector3Normalize(vn);
  376. *v2 = Vector3CrossProduct(vn, *v1);
  377. }
  378. // Transforms a Vector3 by a given Matrix
  379. RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
  380. {
  381. Vector3 result = { 0 };
  382. float x = v.x;
  383. float y = v.y;
  384. float z = v.z;
  385. result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
  386. result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
  387. result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
  388. return result;
  389. }
  390. // Transform a vector by quaternion rotation
  391. RMDEF Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
  392. {
  393. Vector3 result = { 0 };
  394. result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y);
  395. result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z);
  396. result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z);
  397. return result;
  398. }
  399. // Calculate linear interpolation between two vectors
  400. RMDEF Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
  401. {
  402. Vector3 result = { 0 };
  403. result.x = v1.x + amount*(v2.x - v1.x);
  404. result.y = v1.y + amount*(v2.y - v1.y);
  405. result.z = v1.z + amount*(v2.z - v1.z);
  406. return result;
  407. }
  408. // Calculate reflected vector to normal
  409. RMDEF Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
  410. {
  411. // I is the original vector
  412. // N is the normal of the incident plane
  413. // R = I - (2*N*( DotProduct[ I,N] ))
  414. Vector3 result = { 0 };
  415. float dotProduct = Vector3DotProduct(v, normal);
  416. result.x = v.x - (2.0f*normal.x)*dotProduct;
  417. result.y = v.y - (2.0f*normal.y)*dotProduct;
  418. result.z = v.z - (2.0f*normal.z)*dotProduct;
  419. return result;
  420. }
  421. // Return min value for each pair of components
  422. RMDEF Vector3 Vector3Min(Vector3 v1, Vector3 v2)
  423. {
  424. Vector3 result = { 0 };
  425. result.x = fminf(v1.x, v2.x);
  426. result.y = fminf(v1.y, v2.y);
  427. result.z = fminf(v1.z, v2.z);
  428. return result;
  429. }
  430. // Return max value for each pair of components
  431. RMDEF Vector3 Vector3Max(Vector3 v1, Vector3 v2)
  432. {
  433. Vector3 result = { 0 };
  434. result.x = fmaxf(v1.x, v2.x);
  435. result.y = fmaxf(v1.y, v2.y);
  436. result.z = fmaxf(v1.z, v2.z);
  437. return result;
  438. }
  439. // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
  440. // NOTE: Assumes P is on the plane of the triangle
  441. RMDEF Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  442. {
  443. //Vector v0 = b - a, v1 = c - a, v2 = p - a;
  444. Vector3 v0 = Vector3Subtract(b, a);
  445. Vector3 v1 = Vector3Subtract(c, a);
  446. Vector3 v2 = Vector3Subtract(p, a);
  447. float d00 = Vector3DotProduct(v0, v0);
  448. float d01 = Vector3DotProduct(v0, v1);
  449. float d11 = Vector3DotProduct(v1, v1);
  450. float d20 = Vector3DotProduct(v2, v0);
  451. float d21 = Vector3DotProduct(v2, v1);
  452. float denom = d00*d11 - d01*d01;
  453. Vector3 result = { 0 };
  454. result.y = (d11*d20 - d01*d21)/denom;
  455. result.z = (d00*d21 - d01*d20)/denom;
  456. result.x = 1.0f - (result.z + result.y);
  457. return result;
  458. }
  459. // Returns Vector3 as float array
  460. RMDEF float3 Vector3ToFloatV(Vector3 v)
  461. {
  462. float3 buffer = { 0 };
  463. buffer.v[0] = v.x;
  464. buffer.v[1] = v.y;
  465. buffer.v[2] = v.z;
  466. return buffer;
  467. }
  468. //----------------------------------------------------------------------------------
  469. // Module Functions Definition - Matrix math
  470. //----------------------------------------------------------------------------------
  471. // Compute matrix determinant
  472. RMDEF float MatrixDeterminant(Matrix mat)
  473. {
  474. // Cache the matrix values (speed optimization)
  475. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  476. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  477. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  478. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  479. float result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  480. a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  481. a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  482. a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  483. a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  484. a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  485. return result;
  486. }
  487. // Returns the trace of the matrix (sum of the values along the diagonal)
  488. RMDEF float MatrixTrace(Matrix mat)
  489. {
  490. float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15);
  491. return result;
  492. }
  493. // Transposes provided matrix
  494. RMDEF Matrix MatrixTranspose(Matrix mat)
  495. {
  496. Matrix result = { 0 };
  497. result.m0 = mat.m0;
  498. result.m1 = mat.m4;
  499. result.m2 = mat.m8;
  500. result.m3 = mat.m12;
  501. result.m4 = mat.m1;
  502. result.m5 = mat.m5;
  503. result.m6 = mat.m9;
  504. result.m7 = mat.m13;
  505. result.m8 = mat.m2;
  506. result.m9 = mat.m6;
  507. result.m10 = mat.m10;
  508. result.m11 = mat.m14;
  509. result.m12 = mat.m3;
  510. result.m13 = mat.m7;
  511. result.m14 = mat.m11;
  512. result.m15 = mat.m15;
  513. return result;
  514. }
  515. // Invert provided matrix
  516. RMDEF Matrix MatrixInvert(Matrix mat)
  517. {
  518. Matrix result = { 0 };
  519. // Cache the matrix values (speed optimization)
  520. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  521. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  522. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  523. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  524. float b00 = a00*a11 - a01*a10;
  525. float b01 = a00*a12 - a02*a10;
  526. float b02 = a00*a13 - a03*a10;
  527. float b03 = a01*a12 - a02*a11;
  528. float b04 = a01*a13 - a03*a11;
  529. float b05 = a02*a13 - a03*a12;
  530. float b06 = a20*a31 - a21*a30;
  531. float b07 = a20*a32 - a22*a30;
  532. float b08 = a20*a33 - a23*a30;
  533. float b09 = a21*a32 - a22*a31;
  534. float b10 = a21*a33 - a23*a31;
  535. float b11 = a22*a33 - a23*a32;
  536. // Calculate the invert determinant (inlined to avoid double-caching)
  537. float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  538. result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
  539. result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
  540. result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
  541. result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
  542. result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
  543. result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
  544. result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
  545. result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
  546. result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
  547. result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
  548. result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
  549. result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
  550. result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
  551. result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
  552. result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
  553. result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
  554. return result;
  555. }
  556. // Normalize provided matrix
  557. RMDEF Matrix MatrixNormalize(Matrix mat)
  558. {
  559. Matrix result = { 0 };
  560. float det = MatrixDeterminant(mat);
  561. result.m0 = mat.m0/det;
  562. result.m1 = mat.m1/det;
  563. result.m2 = mat.m2/det;
  564. result.m3 = mat.m3/det;
  565. result.m4 = mat.m4/det;
  566. result.m5 = mat.m5/det;
  567. result.m6 = mat.m6/det;
  568. result.m7 = mat.m7/det;
  569. result.m8 = mat.m8/det;
  570. result.m9 = mat.m9/det;
  571. result.m10 = mat.m10/det;
  572. result.m11 = mat.m11/det;
  573. result.m12 = mat.m12/det;
  574. result.m13 = mat.m13/det;
  575. result.m14 = mat.m14/det;
  576. result.m15 = mat.m15/det;
  577. return result;
  578. }
  579. // Returns identity matrix
  580. RMDEF Matrix MatrixIdentity(void)
  581. {
  582. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  583. 0.0f, 1.0f, 0.0f, 0.0f,
  584. 0.0f, 0.0f, 1.0f, 0.0f,
  585. 0.0f, 0.0f, 0.0f, 1.0f };
  586. return result;
  587. }
  588. // Add two matrices
  589. RMDEF Matrix MatrixAdd(Matrix left, Matrix right)
  590. {
  591. Matrix result = MatrixIdentity();
  592. result.m0 = left.m0 + right.m0;
  593. result.m1 = left.m1 + right.m1;
  594. result.m2 = left.m2 + right.m2;
  595. result.m3 = left.m3 + right.m3;
  596. result.m4 = left.m4 + right.m4;
  597. result.m5 = left.m5 + right.m5;
  598. result.m6 = left.m6 + right.m6;
  599. result.m7 = left.m7 + right.m7;
  600. result.m8 = left.m8 + right.m8;
  601. result.m9 = left.m9 + right.m9;
  602. result.m10 = left.m10 + right.m10;
  603. result.m11 = left.m11 + right.m11;
  604. result.m12 = left.m12 + right.m12;
  605. result.m13 = left.m13 + right.m13;
  606. result.m14 = left.m14 + right.m14;
  607. result.m15 = left.m15 + right.m15;
  608. return result;
  609. }
  610. // Subtract two matrices (left - right)
  611. RMDEF Matrix MatrixSubtract(Matrix left, Matrix right)
  612. {
  613. Matrix result = MatrixIdentity();
  614. result.m0 = left.m0 - right.m0;
  615. result.m1 = left.m1 - right.m1;
  616. result.m2 = left.m2 - right.m2;
  617. result.m3 = left.m3 - right.m3;
  618. result.m4 = left.m4 - right.m4;
  619. result.m5 = left.m5 - right.m5;
  620. result.m6 = left.m6 - right.m6;
  621. result.m7 = left.m7 - right.m7;
  622. result.m8 = left.m8 - right.m8;
  623. result.m9 = left.m9 - right.m9;
  624. result.m10 = left.m10 - right.m10;
  625. result.m11 = left.m11 - right.m11;
  626. result.m12 = left.m12 - right.m12;
  627. result.m13 = left.m13 - right.m13;
  628. result.m14 = left.m14 - right.m14;
  629. result.m15 = left.m15 - right.m15;
  630. return result;
  631. }
  632. // Returns translation matrix
  633. RMDEF Matrix MatrixTranslate(float x, float y, float z)
  634. {
  635. Matrix result = { 1.0f, 0.0f, 0.0f, x,
  636. 0.0f, 1.0f, 0.0f, y,
  637. 0.0f, 0.0f, 1.0f, z,
  638. 0.0f, 0.0f, 0.0f, 1.0f };
  639. return result;
  640. }
  641. // Create rotation matrix from axis and angle
  642. // NOTE: Angle should be provided in radians
  643. RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
  644. {
  645. Matrix result = { 0 };
  646. float x = axis.x, y = axis.y, z = axis.z;
  647. float length = sqrtf(x*x + y*y + z*z);
  648. if ((length != 1.0f) && (length != 0.0f))
  649. {
  650. length = 1.0f/length;
  651. x *= length;
  652. y *= length;
  653. z *= length;
  654. }
  655. float sinres = sinf(angle);
  656. float cosres = cosf(angle);
  657. float t = 1.0f - cosres;
  658. result.m0 = x*x*t + cosres;
  659. result.m1 = y*x*t + z*sinres;
  660. result.m2 = z*x*t - y*sinres;
  661. result.m3 = 0.0f;
  662. result.m4 = x*y*t - z*sinres;
  663. result.m5 = y*y*t + cosres;
  664. result.m6 = z*y*t + x*sinres;
  665. result.m7 = 0.0f;
  666. result.m8 = x*z*t + y*sinres;
  667. result.m9 = y*z*t - x*sinres;
  668. result.m10 = z*z*t + cosres;
  669. result.m11 = 0.0f;
  670. result.m12 = 0.0f;
  671. result.m13 = 0.0f;
  672. result.m14 = 0.0f;
  673. result.m15 = 1.0f;
  674. return result;
  675. }
  676. // Returns xyz-rotation matrix (angles in radians)
  677. RMDEF Matrix MatrixRotateXYZ(Vector3 ang)
  678. {
  679. Matrix result = MatrixIdentity();
  680. float cosz = cosf(-ang.z);
  681. float sinz = sinf(-ang.z);
  682. float cosy = cosf(-ang.y);
  683. float siny = sinf(-ang.y);
  684. float cosx = cosf(-ang.x);
  685. float sinx = sinf(-ang.x);
  686. result.m0 = cosz * cosy;
  687. result.m4 = (cosz * siny * sinx) - (sinz * cosx);
  688. result.m8 = (cosz * siny * cosx) + (sinz * sinx);
  689. result.m1 = sinz * cosy;
  690. result.m5 = (sinz * siny * sinx) + (cosz * cosx);
  691. result.m9 = (sinz * siny * cosx) - (cosz * sinx);
  692. result.m2 = -siny;
  693. result.m6 = cosy * sinx;
  694. result.m10= cosy * cosx;
  695. return result;
  696. }
  697. // Returns x-rotation matrix (angle in radians)
  698. RMDEF Matrix MatrixRotateX(float angle)
  699. {
  700. Matrix result = MatrixIdentity();
  701. float cosres = cosf(angle);
  702. float sinres = sinf(angle);
  703. result.m5 = cosres;
  704. result.m6 = -sinres;
  705. result.m9 = sinres;
  706. result.m10 = cosres;
  707. return result;
  708. }
  709. // Returns y-rotation matrix (angle in radians)
  710. RMDEF Matrix MatrixRotateY(float angle)
  711. {
  712. Matrix result = MatrixIdentity();
  713. float cosres = cosf(angle);
  714. float sinres = sinf(angle);
  715. result.m0 = cosres;
  716. result.m2 = sinres;
  717. result.m8 = -sinres;
  718. result.m10 = cosres;
  719. return result;
  720. }
  721. // Returns z-rotation matrix (angle in radians)
  722. RMDEF Matrix MatrixRotateZ(float angle)
  723. {
  724. Matrix result = MatrixIdentity();
  725. float cosres = cosf(angle);
  726. float sinres = sinf(angle);
  727. result.m0 = cosres;
  728. result.m1 = -sinres;
  729. result.m4 = sinres;
  730. result.m5 = cosres;
  731. return result;
  732. }
  733. // Returns scaling matrix
  734. RMDEF Matrix MatrixScale(float x, float y, float z)
  735. {
  736. Matrix result = { x, 0.0f, 0.0f, 0.0f,
  737. 0.0f, y, 0.0f, 0.0f,
  738. 0.0f, 0.0f, z, 0.0f,
  739. 0.0f, 0.0f, 0.0f, 1.0f };
  740. return result;
  741. }
  742. // Returns two matrix multiplication
  743. // NOTE: When multiplying matrices... the order matters!
  744. RMDEF Matrix MatrixMultiply(Matrix left, Matrix right)
  745. {
  746. Matrix result = { 0 };
  747. result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
  748. result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
  749. result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14;
  750. result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15;
  751. result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12;
  752. result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13;
  753. result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14;
  754. result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15;
  755. result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12;
  756. result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13;
  757. result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14;
  758. result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15;
  759. result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12;
  760. result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13;
  761. result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14;
  762. result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15;
  763. return result;
  764. }
  765. // Returns perspective projection matrix
  766. RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far)
  767. {
  768. Matrix result = { 0 };
  769. float rl = (float)(right - left);
  770. float tb = (float)(top - bottom);
  771. float fn = (float)(far - near);
  772. result.m0 = ((float) near*2.0f)/rl;
  773. result.m1 = 0.0f;
  774. result.m2 = 0.0f;
  775. result.m3 = 0.0f;
  776. result.m4 = 0.0f;
  777. result.m5 = ((float) near*2.0f)/tb;
  778. result.m6 = 0.0f;
  779. result.m7 = 0.0f;
  780. result.m8 = ((float)right + (float)left)/rl;
  781. result.m9 = ((float)top + (float)bottom)/tb;
  782. result.m10 = -((float)far + (float)near)/fn;
  783. result.m11 = -1.0f;
  784. result.m12 = 0.0f;
  785. result.m13 = 0.0f;
  786. result.m14 = -((float)far*(float)near*2.0f)/fn;
  787. result.m15 = 0.0f;
  788. return result;
  789. }
  790. // Returns perspective projection matrix
  791. // NOTE: Angle should be provided in radians
  792. RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double far)
  793. {
  794. double top = near*tan(fovy*0.5);
  795. double right = top*aspect;
  796. Matrix result = MatrixFrustum(-right, right, -top, top, near, far);
  797. return result;
  798. }
  799. // Returns orthographic projection matrix
  800. RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far)
  801. {
  802. Matrix result = { 0 };
  803. float rl = (float)(right - left);
  804. float tb = (float)(top - bottom);
  805. float fn = (float)(far - near);
  806. result.m0 = 2.0f/rl;
  807. result.m1 = 0.0f;
  808. result.m2 = 0.0f;
  809. result.m3 = 0.0f;
  810. result.m4 = 0.0f;
  811. result.m5 = 2.0f/tb;
  812. result.m6 = 0.0f;
  813. result.m7 = 0.0f;
  814. result.m8 = 0.0f;
  815. result.m9 = 0.0f;
  816. result.m10 = -2.0f/fn;
  817. result.m11 = 0.0f;
  818. result.m12 = -((float)left + (float)right)/rl;
  819. result.m13 = -((float)top + (float)bottom)/tb;
  820. result.m14 = -((float)far + (float)near)/fn;
  821. result.m15 = 1.0f;
  822. return result;
  823. }
  824. // Returns camera look-at matrix (view matrix)
  825. RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
  826. {
  827. Matrix result = { 0 };
  828. Vector3 z = Vector3Subtract(eye, target);
  829. z = Vector3Normalize(z);
  830. Vector3 x = Vector3CrossProduct(up, z);
  831. x = Vector3Normalize(x);
  832. Vector3 y = Vector3CrossProduct(z, x);
  833. y = Vector3Normalize(y);
  834. result.m0 = x.x;
  835. result.m1 = x.y;
  836. result.m2 = x.z;
  837. result.m3 = 0.0f;
  838. result.m4 = y.x;
  839. result.m5 = y.y;
  840. result.m6 = y.z;
  841. result.m7 = 0.0f;
  842. result.m8 = z.x;
  843. result.m9 = z.y;
  844. result.m10 = z.z;
  845. result.m11 = 0.0f;
  846. result.m12 = eye.x;
  847. result.m13 = eye.y;
  848. result.m14 = eye.z;
  849. result.m15 = 1.0f;
  850. result = MatrixInvert(result);
  851. return result;
  852. }
  853. // Returns float array of matrix data
  854. RMDEF float16 MatrixToFloatV(Matrix mat)
  855. {
  856. float16 buffer = { 0 };
  857. buffer.v[0] = mat.m0;
  858. buffer.v[1] = mat.m1;
  859. buffer.v[2] = mat.m2;
  860. buffer.v[3] = mat.m3;
  861. buffer.v[4] = mat.m4;
  862. buffer.v[5] = mat.m5;
  863. buffer.v[6] = mat.m6;
  864. buffer.v[7] = mat.m7;
  865. buffer.v[8] = mat.m8;
  866. buffer.v[9] = mat.m9;
  867. buffer.v[10] = mat.m10;
  868. buffer.v[11] = mat.m11;
  869. buffer.v[12] = mat.m12;
  870. buffer.v[13] = mat.m13;
  871. buffer.v[14] = mat.m14;
  872. buffer.v[15] = mat.m15;
  873. return buffer;
  874. }
  875. //----------------------------------------------------------------------------------
  876. // Module Functions Definition - Quaternion math
  877. //----------------------------------------------------------------------------------
  878. // Add two quaternions
  879. RMDEF Quaternion QuaternionAdd(Quaternion q1, Quaternion q2)
  880. {
  881. Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w};
  882. return result;
  883. }
  884. // Add quaternion and float value
  885. RMDEF Quaternion QuaternionAddValue(Quaternion q, float add)
  886. {
  887. Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add};
  888. return result;
  889. }
  890. // Subtract two quaternions
  891. RMDEF Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2)
  892. {
  893. Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w};
  894. return result;
  895. }
  896. // Subtract quaternion and float value
  897. RMDEF Quaternion QuaternionSubtractValue(Quaternion q, float sub)
  898. {
  899. Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub};
  900. return result;
  901. }
  902. // Returns identity quaternion
  903. RMDEF Quaternion QuaternionIdentity(void)
  904. {
  905. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  906. return result;
  907. }
  908. // Computes the length of a quaternion
  909. RMDEF float QuaternionLength(Quaternion q)
  910. {
  911. float result = (float)sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  912. return result;
  913. }
  914. // Normalize provided quaternion
  915. RMDEF Quaternion QuaternionNormalize(Quaternion q)
  916. {
  917. Quaternion result = { 0 };
  918. float length, ilength;
  919. length = QuaternionLength(q);
  920. if (length == 0.0f) length = 1.0f;
  921. ilength = 1.0f/length;
  922. result.x = q.x*ilength;
  923. result.y = q.y*ilength;
  924. result.z = q.z*ilength;
  925. result.w = q.w*ilength;
  926. return result;
  927. }
  928. // Invert provided quaternion
  929. RMDEF Quaternion QuaternionInvert(Quaternion q)
  930. {
  931. Quaternion result = q;
  932. float length = QuaternionLength(q);
  933. float lengthSq = length*length;
  934. if (lengthSq != 0.0)
  935. {
  936. float i = 1.0f/lengthSq;
  937. result.x *= -i;
  938. result.y *= -i;
  939. result.z *= -i;
  940. result.w *= i;
  941. }
  942. return result;
  943. }
  944. // Calculate two quaternion multiplication
  945. RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
  946. {
  947. Quaternion result = { 0 };
  948. float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
  949. float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
  950. result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
  951. result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
  952. result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
  953. result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
  954. return result;
  955. }
  956. // Scale quaternion by float value
  957. RMDEF Quaternion QuaternionScale(Quaternion q, float mul)
  958. {
  959. Quaternion result = { 0 };
  960. float qax = q.x, qay = q.y, qaz = q.z, qaw = q.w;
  961. result.x = qax * mul + qaw * mul + qay * mul - qaz * mul;
  962. result.y = qay * mul + qaw * mul + qaz * mul - qax * mul;
  963. result.z = qaz * mul + qaw * mul + qax * mul - qay * mul;
  964. result.w = qaw * mul - qax * mul - qay * mul - qaz * mul;
  965. return result;
  966. }
  967. // Divide two quaternions
  968. RMDEF Quaternion QuaternionDivide(Quaternion q1, Quaternion q2)
  969. {
  970. Quaternion result = {q1.x / q2.x, q1.y / q2.y, q1.z / q2.z, q1.w / q2.w};
  971. return result;
  972. }
  973. // Calculate linear interpolation between two quaternions
  974. RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
  975. {
  976. Quaternion result = { 0 };
  977. result.x = q1.x + amount*(q2.x - q1.x);
  978. result.y = q1.y + amount*(q2.y - q1.y);
  979. result.z = q1.z + amount*(q2.z - q1.z);
  980. result.w = q1.w + amount*(q2.w - q1.w);
  981. return result;
  982. }
  983. // Calculate slerp-optimized interpolation between two quaternions
  984. RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
  985. {
  986. Quaternion result = QuaternionLerp(q1, q2, amount);
  987. result = QuaternionNormalize(result);
  988. return result;
  989. }
  990. // Calculates spherical linear interpolation between two quaternions
  991. RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
  992. {
  993. Quaternion result = { 0 };
  994. float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
  995. if (fabs(cosHalfTheta) >= 1.0f) result = q1;
  996. else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
  997. else
  998. {
  999. float halfTheta = acosf(cosHalfTheta);
  1000. float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta);
  1001. if (fabs(sinHalfTheta) < 0.001f)
  1002. {
  1003. result.x = (q1.x*0.5f + q2.x*0.5f);
  1004. result.y = (q1.y*0.5f + q2.y*0.5f);
  1005. result.z = (q1.z*0.5f + q2.z*0.5f);
  1006. result.w = (q1.w*0.5f + q2.w*0.5f);
  1007. }
  1008. else
  1009. {
  1010. float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta;
  1011. float ratioB = sinf(amount*halfTheta)/sinHalfTheta;
  1012. result.x = (q1.x*ratioA + q2.x*ratioB);
  1013. result.y = (q1.y*ratioA + q2.y*ratioB);
  1014. result.z = (q1.z*ratioA + q2.z*ratioB);
  1015. result.w = (q1.w*ratioA + q2.w*ratioB);
  1016. }
  1017. }
  1018. return result;
  1019. }
  1020. // Calculate quaternion based on the rotation from one vector to another
  1021. RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
  1022. {
  1023. Quaternion result = { 0 };
  1024. float cos2Theta = Vector3DotProduct(from, to);
  1025. Vector3 cross = Vector3CrossProduct(from, to);
  1026. result.x = cross.x;
  1027. result.y = cross.y;
  1028. result.z = cross.y;
  1029. result.w = 1.0f + cos2Theta; // NOTE: Added QuaternioIdentity()
  1030. // Normalize to essentially nlerp the original and identity to 0.5
  1031. result = QuaternionNormalize(result);
  1032. // Above lines are equivalent to:
  1033. //Quaternion result = QuaternionNlerp(q, QuaternionIdentity(), 0.5f);
  1034. return result;
  1035. }
  1036. // Returns a quaternion for a given rotation matrix
  1037. RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
  1038. {
  1039. Quaternion result = { 0 };
  1040. float trace = MatrixTrace(mat);
  1041. if (trace > 0.0f)
  1042. {
  1043. float s = sqrtf(trace + 1)*2.0f;
  1044. float invS = 1.0f/s;
  1045. result.w = s*0.25f;
  1046. result.x = (mat.m6 - mat.m9)*invS;
  1047. result.y = (mat.m8 - mat.m2)*invS;
  1048. result.z = (mat.m1 - mat.m4)*invS;
  1049. }
  1050. else
  1051. {
  1052. float m00 = mat.m0, m11 = mat.m5, m22 = mat.m10;
  1053. if (m00 > m11 && m00 > m22)
  1054. {
  1055. float s = (float)sqrt(1.0f + m00 - m11 - m22)*2.0f;
  1056. float invS = 1.0f/s;
  1057. result.w = (mat.m6 - mat.m9)*invS;
  1058. result.x = s*0.25f;
  1059. result.y = (mat.m4 + mat.m1)*invS;
  1060. result.z = (mat.m8 + mat.m2)*invS;
  1061. }
  1062. else if (m11 > m22)
  1063. {
  1064. float s = sqrtf(1.0f + m11 - m00 - m22)*2.0f;
  1065. float invS = 1.0f/s;
  1066. result.w = (mat.m8 - mat.m2)*invS;
  1067. result.x = (mat.m4 + mat.m1)*invS;
  1068. result.y = s*0.25f;
  1069. result.z = (mat.m9 + mat.m6)*invS;
  1070. }
  1071. else
  1072. {
  1073. float s = sqrtf(1.0f + m22 - m00 - m11)*2.0f;
  1074. float invS = 1.0f/s;
  1075. result.w = (mat.m1 - mat.m4)*invS;
  1076. result.x = (mat.m8 + mat.m2)*invS;
  1077. result.y = (mat.m9 + mat.m6)*invS;
  1078. result.z = s*0.25f;
  1079. }
  1080. }
  1081. return result;
  1082. }
  1083. // Returns a matrix for a given quaternion
  1084. RMDEF Matrix QuaternionToMatrix(Quaternion q)
  1085. {
  1086. Matrix result = { 0 };
  1087. float x = q.x, y = q.y, z = q.z, w = q.w;
  1088. float x2 = x + x;
  1089. float y2 = y + y;
  1090. float z2 = z + z;
  1091. float length = QuaternionLength(q);
  1092. float lengthSquared = length*length;
  1093. float xx = x*x2/lengthSquared;
  1094. float xy = x*y2/lengthSquared;
  1095. float xz = x*z2/lengthSquared;
  1096. float yy = y*y2/lengthSquared;
  1097. float yz = y*z2/lengthSquared;
  1098. float zz = z*z2/lengthSquared;
  1099. float wx = w*x2/lengthSquared;
  1100. float wy = w*y2/lengthSquared;
  1101. float wz = w*z2/lengthSquared;
  1102. result.m0 = 1.0f - (yy + zz);
  1103. result.m1 = xy - wz;
  1104. result.m2 = xz + wy;
  1105. result.m3 = 0.0f;
  1106. result.m4 = xy + wz;
  1107. result.m5 = 1.0f - (xx + zz);
  1108. result.m6 = yz - wx;
  1109. result.m7 = 0.0f;
  1110. result.m8 = xz - wy;
  1111. result.m9 = yz + wx;
  1112. result.m10 = 1.0f - (xx + yy);
  1113. result.m11 = 0.0f;
  1114. result.m12 = 0.0f;
  1115. result.m13 = 0.0f;
  1116. result.m14 = 0.0f;
  1117. result.m15 = 1.0f;
  1118. return result;
  1119. }
  1120. // Returns rotation quaternion for an angle and axis
  1121. // NOTE: angle must be provided in radians
  1122. RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
  1123. {
  1124. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  1125. if (Vector3Length(axis) != 0.0f)
  1126. angle *= 0.5f;
  1127. axis = Vector3Normalize(axis);
  1128. float sinres = sinf(angle);
  1129. float cosres = cosf(angle);
  1130. result.x = axis.x*sinres;
  1131. result.y = axis.y*sinres;
  1132. result.z = axis.z*sinres;
  1133. result.w = cosres;
  1134. result = QuaternionNormalize(result);
  1135. return result;
  1136. }
  1137. // Returns the rotation angle and axis for a given quaternion
  1138. RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
  1139. {
  1140. if (fabs(q.w) > 1.0f) q = QuaternionNormalize(q);
  1141. Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
  1142. float resAngle = 2.0f*acosf(q.w);
  1143. float den = sqrtf(1.0f - q.w*q.w);
  1144. if (den > 0.0001f)
  1145. {
  1146. resAxis.x = q.x/den;
  1147. resAxis.y = q.y/den;
  1148. resAxis.z = q.z/den;
  1149. }
  1150. else
  1151. {
  1152. // This occurs when the angle is zero.
  1153. // Not a problem: just set an arbitrary normalized axis.
  1154. resAxis.x = 1.0f;
  1155. }
  1156. *outAxis = resAxis;
  1157. *outAngle = resAngle;
  1158. }
  1159. // Returns he quaternion equivalent to Euler angles
  1160. RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
  1161. {
  1162. Quaternion q = { 0 };
  1163. float x0 = cosf(roll*0.5f);
  1164. float x1 = sinf(roll*0.5f);
  1165. float y0 = cosf(pitch*0.5f);
  1166. float y1 = sinf(pitch*0.5f);
  1167. float z0 = cosf(yaw*0.5f);
  1168. float z1 = sinf(yaw*0.5f);
  1169. q.x = x1*y0*z0 - x0*y1*z1;
  1170. q.y = x0*y1*z0 + x1*y0*z1;
  1171. q.z = x0*y0*z1 - x1*y1*z0;
  1172. q.w = x0*y0*z0 + x1*y1*z1;
  1173. return q;
  1174. }
  1175. // Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
  1176. // NOTE: Angles are returned in a Vector3 struct in degrees
  1177. RMDEF Vector3 QuaternionToEuler(Quaternion q)
  1178. {
  1179. Vector3 result = { 0 };
  1180. // roll (x-axis rotation)
  1181. float x0 = 2.0f*(q.w*q.x + q.y*q.z);
  1182. float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
  1183. result.x = atan2f(x0, x1)*RAD2DEG;
  1184. // pitch (y-axis rotation)
  1185. float y0 = 2.0f*(q.w*q.y - q.z*q.x);
  1186. y0 = y0 > 1.0f ? 1.0f : y0;
  1187. y0 = y0 < -1.0f ? -1.0f : y0;
  1188. result.y = asinf(y0)*RAD2DEG;
  1189. // yaw (z-axis rotation)
  1190. float z0 = 2.0f*(q.w*q.z + q.x*q.y);
  1191. float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
  1192. result.z = atan2f(z0, z1)*RAD2DEG;
  1193. return result;
  1194. }
  1195. // Transform a quaternion given a transformation matrix
  1196. RMDEF Quaternion QuaternionTransform(Quaternion q, Matrix mat)
  1197. {
  1198. Quaternion result = { 0 };
  1199. result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w;
  1200. result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w;
  1201. result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w;
  1202. result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w;
  1203. return result;
  1204. }
  1205. #endif // RAYMATH_H