Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

1378 linhas
38 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-2017 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(), 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 vectors
  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. // Subtract two vectors (v1 - v2)
  158. RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
  159. {
  160. Vector2 result = { v1.x - v2.x, v1.y - v2.y };
  161. return result;
  162. }
  163. // Calculate vector length
  164. RMDEF float Vector2Length(Vector2 v)
  165. {
  166. float result = sqrtf((v.x*v.x) + (v.y*v.y));
  167. return result;
  168. }
  169. // Calculate two vectors dot product
  170. RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2)
  171. {
  172. float result = (v1.x*v2.x + v1.y*v2.y);
  173. return result;
  174. }
  175. // Calculate distance between two vectors
  176. RMDEF float Vector2Distance(Vector2 v1, Vector2 v2)
  177. {
  178. float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
  179. return result;
  180. }
  181. // Calculate angle from two vectors in X-axis
  182. RMDEF float Vector2Angle(Vector2 v1, Vector2 v2)
  183. {
  184. float result = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
  185. if (result < 0) result += 360.0f;
  186. return result;
  187. }
  188. // Scale vector (multiply by value)
  189. RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
  190. {
  191. Vector2 result = { v.x*scale, v.y*scale };
  192. return result;
  193. }
  194. // Multiply vector by vector
  195. RMDEF Vector2 Vector2MultiplyV(Vector2 v1, Vector2 v2)
  196. {
  197. Vector2 result = { v1.x*v2.x, v1.y*v2.y };
  198. return result;
  199. }
  200. // Negate vector
  201. RMDEF Vector2 Vector2Negate(Vector2 v)
  202. {
  203. Vector2 result = { -v.x, -v.y };
  204. return result;
  205. }
  206. // Divide vector by a float value
  207. RMDEF Vector2 Vector2Divide(Vector2 v, float div)
  208. {
  209. Vector2 result = { v.x/div, v.y/div };
  210. return result;
  211. }
  212. // Divide vector by vector
  213. RMDEF Vector2 Vector2DivideV(Vector2 v1, Vector2 v2)
  214. {
  215. Vector2 result = { v1.x/v2.x, v1.y/v2.y };
  216. return result;
  217. }
  218. // Normalize provided vector
  219. RMDEF Vector2 Vector2Normalize(Vector2 v)
  220. {
  221. Vector2 result = Vector2Divide(v, Vector2Length(v));
  222. return result;
  223. }
  224. // Calculate linear interpolation between two vectors
  225. RMDEF Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount)
  226. {
  227. Vector2 result = { 0 };
  228. result.x = v1.x + amount*(v2.x - v1.x);
  229. result.y = v1.y + amount*(v2.y - v1.y);
  230. return result;
  231. }
  232. //----------------------------------------------------------------------------------
  233. // Module Functions Definition - Vector3 math
  234. //----------------------------------------------------------------------------------
  235. // Vector with components value 0.0f
  236. RMDEF Vector3 Vector3Zero(void)
  237. {
  238. Vector3 result = { 0.0f, 0.0f, 0.0f };
  239. return result;
  240. }
  241. // Vector with components value 1.0f
  242. RMDEF Vector3 Vector3One(void)
  243. {
  244. Vector3 result = { 1.0f, 1.0f, 1.0f };
  245. return result;
  246. }
  247. // Add two vectors
  248. RMDEF Vector3 Vector3Add(Vector3 v1, Vector3 v2)
  249. {
  250. Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
  251. return result;
  252. }
  253. // Subtract two vectors
  254. RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
  255. {
  256. Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
  257. return result;
  258. }
  259. // Multiply vector by scalar
  260. RMDEF Vector3 Vector3Multiply(Vector3 v, float scalar)
  261. {
  262. Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar };
  263. return result;
  264. }
  265. // Multiply vector by vector
  266. RMDEF Vector3 Vector3MultiplyV(Vector3 v1, Vector3 v2)
  267. {
  268. Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z };
  269. return result;
  270. }
  271. // Calculate two vectors cross product
  272. RMDEF Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2)
  273. {
  274. 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 };
  275. return result;
  276. }
  277. // Calculate one vector perpendicular vector
  278. RMDEF Vector3 Vector3Perpendicular(Vector3 v)
  279. {
  280. Vector3 result = { 0 };
  281. float min = (float) fabs(v.x);
  282. Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
  283. if (fabs(v.y) < min)
  284. {
  285. min = (float) fabs(v.y);
  286. Vector3 tmp = {0.0f, 1.0f, 0.0f};
  287. cardinalAxis = tmp;
  288. }
  289. if (fabs(v.z) < min)
  290. {
  291. Vector3 tmp = {0.0f, 0.0f, 1.0f};
  292. cardinalAxis = tmp;
  293. }
  294. result = Vector3CrossProduct(v, cardinalAxis);
  295. return result;
  296. }
  297. // Calculate vector length
  298. RMDEF float Vector3Length(const Vector3 v)
  299. {
  300. float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  301. return result;
  302. }
  303. // Calculate two vectors dot product
  304. RMDEF float Vector3DotProduct(Vector3 v1, Vector3 v2)
  305. {
  306. float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  307. return result;
  308. }
  309. // Calculate distance between two vectors
  310. RMDEF float Vector3Distance(Vector3 v1, Vector3 v2)
  311. {
  312. float dx = v2.x - v1.x;
  313. float dy = v2.y - v1.y;
  314. float dz = v2.z - v1.z;
  315. float result = sqrtf(dx*dx + dy*dy + dz*dz);
  316. return result;
  317. }
  318. // Scale provided vector
  319. RMDEF Vector3 Vector3Scale(Vector3 v, float scale)
  320. {
  321. Vector3 result = { v.x*scale, v.y*scale, v.z*scale };
  322. return result;
  323. }
  324. // Negate provided vector (invert direction)
  325. RMDEF Vector3 Vector3Negate(Vector3 v)
  326. {
  327. Vector3 result = { -v.x, -v.y, -v.z };
  328. return result;
  329. }
  330. // Divide vector by a float value
  331. RMDEF Vector3 Vector3Divide(Vector3 v, float div)
  332. {
  333. Vector3 result = { v.x / div, v.y / div, v.z / div };
  334. return result;
  335. }
  336. // Divide vector by vector
  337. RMDEF Vector3 Vector3DivideV(Vector3 v1, Vector3 v2)
  338. {
  339. Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
  340. return result;
  341. }
  342. // Normalize provided vector
  343. RMDEF Vector3 Vector3Normalize(Vector3 v)
  344. {
  345. Vector3 result = v;
  346. float length, ilength;
  347. length = Vector3Length(v);
  348. if (length == 0.0f) length = 1.0f;
  349. ilength = 1.0f/length;
  350. result.x *= ilength;
  351. result.y *= ilength;
  352. result.z *= ilength;
  353. return result;
  354. }
  355. // Orthonormalize provided vectors
  356. // Makes vectors normalized and orthogonal to each other
  357. // Gram-Schmidt function implementation
  358. RMDEF void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2)
  359. {
  360. *v1 = Vector3Normalize(*v1);
  361. Vector3 vn = Vector3CrossProduct(*v1, *v2);
  362. vn = Vector3Normalize(vn);
  363. *v2 = Vector3CrossProduct(vn, *v1);
  364. }
  365. // Transforms a Vector3 by a given Matrix
  366. RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
  367. {
  368. Vector3 result = { 0 };
  369. float x = v.x;
  370. float y = v.y;
  371. float z = v.z;
  372. result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
  373. result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
  374. result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
  375. return result;
  376. };
  377. // Transform a vector by quaternion rotation
  378. RMDEF Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
  379. {
  380. Vector3 result = { 0 };
  381. 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);
  382. 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);
  383. 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);
  384. return result;
  385. }
  386. // Calculate linear interpolation between two vectors
  387. RMDEF Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
  388. {
  389. Vector3 result = { 0 };
  390. result.x = v1.x + amount*(v2.x - v1.x);
  391. result.y = v1.y + amount*(v2.y - v1.y);
  392. result.z = v1.z + amount*(v2.z - v1.z);
  393. return result;
  394. }
  395. // Calculate reflected vector to normal
  396. RMDEF Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
  397. {
  398. // I is the original vector
  399. // N is the normal of the incident plane
  400. // R = I - (2*N*( DotProduct[ I,N] ))
  401. Vector3 result = { 0 };
  402. float dotProduct = Vector3DotProduct(v, normal);
  403. result.x = v.x - (2.0f*normal.x)*dotProduct;
  404. result.y = v.y - (2.0f*normal.y)*dotProduct;
  405. result.z = v.z - (2.0f*normal.z)*dotProduct;
  406. return result;
  407. }
  408. // Return min value for each pair of components
  409. RMDEF Vector3 Vector3Min(Vector3 v1, Vector3 v2)
  410. {
  411. Vector3 result = { 0 };
  412. result.x = fminf(v1.x, v2.x);
  413. result.y = fminf(v1.y, v2.y);
  414. result.z = fminf(v1.z, v2.z);
  415. return result;
  416. }
  417. // Return max value for each pair of components
  418. RMDEF Vector3 Vector3Max(Vector3 v1, Vector3 v2)
  419. {
  420. Vector3 result = { 0 };
  421. result.x = fmaxf(v1.x, v2.x);
  422. result.y = fmaxf(v1.y, v2.y);
  423. result.z = fmaxf(v1.z, v2.z);
  424. return result;
  425. }
  426. // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
  427. // NOTE: Assumes P is on the plane of the triangle
  428. RMDEF Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  429. {
  430. //Vector v0 = b - a, v1 = c - a, v2 = p - a;
  431. Vector3 v0 = Vector3Subtract(b, a);
  432. Vector3 v1 = Vector3Subtract(c, a);
  433. Vector3 v2 = Vector3Subtract(p, a);
  434. float d00 = Vector3DotProduct(v0, v0);
  435. float d01 = Vector3DotProduct(v0, v1);
  436. float d11 = Vector3DotProduct(v1, v1);
  437. float d20 = Vector3DotProduct(v2, v0);
  438. float d21 = Vector3DotProduct(v2, v1);
  439. float denom = d00*d11 - d01*d01;
  440. Vector3 result = { 0 };
  441. result.y = (d11*d20 - d01*d21)/denom;
  442. result.z = (d00*d21 - d01*d20)/denom;
  443. result.x = 1.0f - (result.z + result.y);
  444. return result;
  445. }
  446. // Returns Vector3 as float array
  447. RMDEF float3 Vector3ToFloatV(Vector3 v)
  448. {
  449. float3 buffer = { 0 };
  450. buffer.v[0] = v.x;
  451. buffer.v[1] = v.y;
  452. buffer.v[2] = v.z;
  453. return buffer;
  454. }
  455. //----------------------------------------------------------------------------------
  456. // Module Functions Definition - Matrix math
  457. //----------------------------------------------------------------------------------
  458. // Compute matrix determinant
  459. RMDEF float MatrixDeterminant(Matrix mat)
  460. {
  461. float result = { 0 };
  462. // Cache the matrix values (speed optimization)
  463. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  464. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  465. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  466. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  467. result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  468. a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  469. a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  470. a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  471. a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  472. a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  473. return result;
  474. }
  475. // Returns the trace of the matrix (sum of the values along the diagonal)
  476. RMDEF float MatrixTrace(Matrix mat)
  477. {
  478. float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15);
  479. return result;
  480. }
  481. // Transposes provided matrix
  482. RMDEF Matrix MatrixTranspose(Matrix mat)
  483. {
  484. Matrix result = { 0 };
  485. result.m0 = mat.m0;
  486. result.m1 = mat.m4;
  487. result.m2 = mat.m8;
  488. result.m3 = mat.m12;
  489. result.m4 = mat.m1;
  490. result.m5 = mat.m5;
  491. result.m6 = mat.m9;
  492. result.m7 = mat.m13;
  493. result.m8 = mat.m2;
  494. result.m9 = mat.m6;
  495. result.m10 = mat.m10;
  496. result.m11 = mat.m14;
  497. result.m12 = mat.m3;
  498. result.m13 = mat.m7;
  499. result.m14 = mat.m11;
  500. result.m15 = mat.m15;
  501. return result;
  502. }
  503. // Invert provided matrix
  504. RMDEF Matrix MatrixInvert(Matrix mat)
  505. {
  506. Matrix result = { 0 };
  507. // Cache the matrix values (speed optimization)
  508. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  509. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  510. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  511. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  512. float b00 = a00*a11 - a01*a10;
  513. float b01 = a00*a12 - a02*a10;
  514. float b02 = a00*a13 - a03*a10;
  515. float b03 = a01*a12 - a02*a11;
  516. float b04 = a01*a13 - a03*a11;
  517. float b05 = a02*a13 - a03*a12;
  518. float b06 = a20*a31 - a21*a30;
  519. float b07 = a20*a32 - a22*a30;
  520. float b08 = a20*a33 - a23*a30;
  521. float b09 = a21*a32 - a22*a31;
  522. float b10 = a21*a33 - a23*a31;
  523. float b11 = a22*a33 - a23*a32;
  524. // Calculate the invert determinant (inlined to avoid double-caching)
  525. float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  526. result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
  527. result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
  528. result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
  529. result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
  530. result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
  531. result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
  532. result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
  533. result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
  534. result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
  535. result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
  536. result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
  537. result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
  538. result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
  539. result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
  540. result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
  541. result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
  542. return result;
  543. }
  544. // Normalize provided matrix
  545. RMDEF Matrix MatrixNormalize(Matrix mat)
  546. {
  547. Matrix result = { 0 };
  548. float det = MatrixDeterminant(mat);
  549. result.m0 = mat.m0/det;
  550. result.m1 = mat.m1/det;
  551. result.m2 = mat.m2/det;
  552. result.m3 = mat.m3/det;
  553. result.m4 = mat.m4/det;
  554. result.m5 = mat.m5/det;
  555. result.m6 = mat.m6/det;
  556. result.m7 = mat.m7/det;
  557. result.m8 = mat.m8/det;
  558. result.m9 = mat.m9/det;
  559. result.m10 = mat.m10/det;
  560. result.m11 = mat.m11/det;
  561. result.m12 = mat.m12/det;
  562. result.m13 = mat.m13/det;
  563. result.m14 = mat.m14/det;
  564. result.m15 = mat.m15/det;
  565. return result;
  566. }
  567. // Returns identity matrix
  568. RMDEF Matrix MatrixIdentity(void)
  569. {
  570. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  571. 0.0f, 1.0f, 0.0f, 0.0f,
  572. 0.0f, 0.0f, 1.0f, 0.0f,
  573. 0.0f, 0.0f, 0.0f, 1.0f };
  574. return result;
  575. }
  576. // Add two matrices
  577. RMDEF Matrix MatrixAdd(Matrix left, Matrix right)
  578. {
  579. Matrix result = MatrixIdentity();
  580. result.m0 = left.m0 + right.m0;
  581. result.m1 = left.m1 + right.m1;
  582. result.m2 = left.m2 + right.m2;
  583. result.m3 = left.m3 + right.m3;
  584. result.m4 = left.m4 + right.m4;
  585. result.m5 = left.m5 + right.m5;
  586. result.m6 = left.m6 + right.m6;
  587. result.m7 = left.m7 + right.m7;
  588. result.m8 = left.m8 + right.m8;
  589. result.m9 = left.m9 + right.m9;
  590. result.m10 = left.m10 + right.m10;
  591. result.m11 = left.m11 + right.m11;
  592. result.m12 = left.m12 + right.m12;
  593. result.m13 = left.m13 + right.m13;
  594. result.m14 = left.m14 + right.m14;
  595. result.m15 = left.m15 + right.m15;
  596. return result;
  597. }
  598. // Subtract two matrices (left - right)
  599. RMDEF Matrix MatrixSubtract(Matrix left, Matrix right)
  600. {
  601. Matrix result = MatrixIdentity();
  602. result.m0 = left.m0 - right.m0;
  603. result.m1 = left.m1 - right.m1;
  604. result.m2 = left.m2 - right.m2;
  605. result.m3 = left.m3 - right.m3;
  606. result.m4 = left.m4 - right.m4;
  607. result.m5 = left.m5 - right.m5;
  608. result.m6 = left.m6 - right.m6;
  609. result.m7 = left.m7 - right.m7;
  610. result.m8 = left.m8 - right.m8;
  611. result.m9 = left.m9 - right.m9;
  612. result.m10 = left.m10 - right.m10;
  613. result.m11 = left.m11 - right.m11;
  614. result.m12 = left.m12 - right.m12;
  615. result.m13 = left.m13 - right.m13;
  616. result.m14 = left.m14 - right.m14;
  617. result.m15 = left.m15 - right.m15;
  618. return result;
  619. }
  620. // Returns translation matrix
  621. RMDEF Matrix MatrixTranslate(float x, float y, float z)
  622. {
  623. Matrix result = { 1.0f, 0.0f, 0.0f, x,
  624. 0.0f, 1.0f, 0.0f, y,
  625. 0.0f, 0.0f, 1.0f, z,
  626. 0.0f, 0.0f, 0.0f, 1.0f };
  627. return result;
  628. }
  629. // Create rotation matrix from axis and angle
  630. // NOTE: Angle should be provided in radians
  631. RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
  632. {
  633. Matrix result = { 0 };
  634. float x = axis.x, y = axis.y, z = axis.z;
  635. float length = sqrtf(x*x + y*y + z*z);
  636. if ((length != 1.0f) && (length != 0.0f))
  637. {
  638. length = 1.0f/length;
  639. x *= length;
  640. y *= length;
  641. z *= length;
  642. }
  643. float sinres = sinf(angle);
  644. float cosres = cosf(angle);
  645. float t = 1.0f - cosres;
  646. result.m0 = x*x*t + cosres;
  647. result.m1 = y*x*t + z*sinres;
  648. result.m2 = z*x*t - y*sinres;
  649. result.m3 = 0.0f;
  650. result.m4 = x*y*t - z*sinres;
  651. result.m5 = y*y*t + cosres;
  652. result.m6 = z*y*t + x*sinres;
  653. result.m7 = 0.0f;
  654. result.m8 = x*z*t + y*sinres;
  655. result.m9 = y*z*t - x*sinres;
  656. result.m10 = z*z*t + cosres;
  657. result.m11 = 0.0f;
  658. result.m12 = 0.0f;
  659. result.m13 = 0.0f;
  660. result.m14 = 0.0f;
  661. result.m15 = 1.0f;
  662. return result;
  663. }
  664. // Returns x-rotation matrix (angle in radians)
  665. RMDEF Matrix MatrixRotateX(float angle)
  666. {
  667. Matrix result = MatrixIdentity();
  668. float cosres = cosf(angle);
  669. float sinres = sinf(angle);
  670. result.m5 = cosres;
  671. result.m6 = -sinres;
  672. result.m9 = sinres;
  673. result.m10 = cosres;
  674. return result;
  675. }
  676. // Returns y-rotation matrix (angle in radians)
  677. RMDEF Matrix MatrixRotateY(float angle)
  678. {
  679. Matrix result = MatrixIdentity();
  680. float cosres = cosf(angle);
  681. float sinres = sinf(angle);
  682. result.m0 = cosres;
  683. result.m2 = sinres;
  684. result.m8 = -sinres;
  685. result.m10 = cosres;
  686. return result;
  687. }
  688. // Returns z-rotation matrix (angle in radians)
  689. RMDEF Matrix MatrixRotateZ(float angle)
  690. {
  691. Matrix result = MatrixIdentity();
  692. float cosres = cosf(angle);
  693. float sinres = sinf(angle);
  694. result.m0 = cosres;
  695. result.m1 = -sinres;
  696. result.m4 = sinres;
  697. result.m5 = cosres;
  698. return result;
  699. }
  700. // Returns scaling matrix
  701. RMDEF Matrix MatrixScale(float x, float y, float z)
  702. {
  703. Matrix result = { x, 0.0f, 0.0f, 0.0f,
  704. 0.0f, y, 0.0f, 0.0f,
  705. 0.0f, 0.0f, z, 0.0f,
  706. 0.0f, 0.0f, 0.0f, 1.0f };
  707. return result;
  708. }
  709. // Returns two matrix multiplication
  710. // NOTE: When multiplying matrices... the order matters!
  711. RMDEF Matrix MatrixMultiply(Matrix left, Matrix right)
  712. {
  713. Matrix result = { 0 };
  714. result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
  715. result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
  716. result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14;
  717. result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15;
  718. result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12;
  719. result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13;
  720. result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14;
  721. result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15;
  722. result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12;
  723. result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13;
  724. result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14;
  725. result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15;
  726. result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12;
  727. result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13;
  728. result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14;
  729. result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15;
  730. return result;
  731. }
  732. // Returns perspective projection matrix
  733. RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far)
  734. {
  735. Matrix result = { 0 };
  736. float rl = (float)(right - left);
  737. float tb = (float)(top - bottom);
  738. float fn = (float)(far - near);
  739. result.m0 = ((float) near*2.0f)/rl;
  740. result.m1 = 0.0f;
  741. result.m2 = 0.0f;
  742. result.m3 = 0.0f;
  743. result.m4 = 0.0f;
  744. result.m5 = ((float) near*2.0f)/tb;
  745. result.m6 = 0.0f;
  746. result.m7 = 0.0f;
  747. result.m8 = ((float)right + (float)left)/rl;
  748. result.m9 = ((float)top + (float)bottom)/tb;
  749. result.m10 = -((float)far + (float)near)/fn;
  750. result.m11 = -1.0f;
  751. result.m12 = 0.0f;
  752. result.m13 = 0.0f;
  753. result.m14 = -((float)far*(float)near*2.0f)/fn;
  754. result.m15 = 0.0f;
  755. return result;
  756. }
  757. // Returns perspective projection matrix
  758. // NOTE: Angle should be provided in radians
  759. RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double far)
  760. {
  761. double top = near*tan(fovy*0.5);
  762. double right = top*aspect;
  763. Matrix result = MatrixFrustum(-right, right, -top, top, near, far);
  764. return result;
  765. }
  766. // Returns orthographic projection matrix
  767. RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far)
  768. {
  769. Matrix result = { 0 };
  770. float rl = (float)(right - left);
  771. float tb = (float)(top - bottom);
  772. float fn = (float)(far - near);
  773. result.m0 = 2.0f/rl;
  774. result.m1 = 0.0f;
  775. result.m2 = 0.0f;
  776. result.m3 = 0.0f;
  777. result.m4 = 0.0f;
  778. result.m5 = 2.0f/tb;
  779. result.m6 = 0.0f;
  780. result.m7 = 0.0f;
  781. result.m8 = 0.0f;
  782. result.m9 = 0.0f;
  783. result.m10 = -2.0f/fn;
  784. result.m11 = 0.0f;
  785. result.m12 = -((float)left + (float)right)/rl;
  786. result.m13 = -((float)top + (float)bottom)/tb;
  787. result.m14 = -((float)far + (float)near)/fn;
  788. result.m15 = 1.0f;
  789. return result;
  790. }
  791. // Returns camera look-at matrix (view matrix)
  792. RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
  793. {
  794. Matrix result = { 0 };
  795. Vector3 z = Vector3Subtract(eye, target);
  796. z = Vector3Normalize(z);
  797. Vector3 x = Vector3CrossProduct(up, z);
  798. x = Vector3Normalize(x);
  799. Vector3 y = Vector3CrossProduct(z, x);
  800. y = Vector3Normalize(y);
  801. result.m0 = x.x;
  802. result.m1 = x.y;
  803. result.m2 = x.z;
  804. result.m3 = 0.0f;
  805. result.m4 = y.x;
  806. result.m5 = y.y;
  807. result.m6 = y.z;
  808. result.m7 = 0.0f;
  809. result.m8 = z.x;
  810. result.m9 = z.y;
  811. result.m10 = z.z;
  812. result.m11 = 0.0f;
  813. result.m12 = eye.x;
  814. result.m13 = eye.y;
  815. result.m14 = eye.z;
  816. result.m15 = 1.0f;
  817. result = MatrixInvert(result);
  818. return result;
  819. }
  820. // Returns float array of matrix data
  821. RMDEF float16 MatrixToFloatV(Matrix mat)
  822. {
  823. float16 buffer = { 0 };
  824. buffer.v[0] = mat.m0;
  825. buffer.v[1] = mat.m1;
  826. buffer.v[2] = mat.m2;
  827. buffer.v[3] = mat.m3;
  828. buffer.v[4] = mat.m4;
  829. buffer.v[5] = mat.m5;
  830. buffer.v[6] = mat.m6;
  831. buffer.v[7] = mat.m7;
  832. buffer.v[8] = mat.m8;
  833. buffer.v[9] = mat.m9;
  834. buffer.v[10] = mat.m10;
  835. buffer.v[11] = mat.m11;
  836. buffer.v[12] = mat.m12;
  837. buffer.v[13] = mat.m13;
  838. buffer.v[14] = mat.m14;
  839. buffer.v[15] = mat.m15;
  840. return buffer;
  841. }
  842. //----------------------------------------------------------------------------------
  843. // Module Functions Definition - Quaternion math
  844. //----------------------------------------------------------------------------------
  845. // Returns identity quaternion
  846. RMDEF Quaternion QuaternionIdentity(void)
  847. {
  848. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  849. return result;
  850. }
  851. // Computes the length of a quaternion
  852. RMDEF float QuaternionLength(Quaternion q)
  853. {
  854. float result = (float)sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  855. return result;
  856. }
  857. // Normalize provided quaternion
  858. RMDEF Quaternion QuaternionNormalize(Quaternion q)
  859. {
  860. Quaternion result = { 0 };
  861. float length, ilength;
  862. length = QuaternionLength(q);
  863. if (length == 0.0f) length = 1.0f;
  864. ilength = 1.0f/length;
  865. result.x = q.x*ilength;
  866. result.y = q.y*ilength;
  867. result.z = q.z*ilength;
  868. result.w = q.w*ilength;
  869. return result;
  870. }
  871. // Invert provided quaternion
  872. RMDEF Quaternion QuaternionInvert(Quaternion q)
  873. {
  874. Quaternion result = q;
  875. float length = QuaternionLength(q);
  876. float lengthSq = length*length;
  877. if (lengthSq != 0.0)
  878. {
  879. float i = 1.0f/lengthSq;
  880. result.x *= -i;
  881. result.y *= -i;
  882. result.z *= -i;
  883. result.w *= i;
  884. }
  885. return result;
  886. }
  887. // Calculate two quaternion multiplication
  888. RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
  889. {
  890. Quaternion result = { 0 };
  891. float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
  892. float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
  893. result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
  894. result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
  895. result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
  896. result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
  897. return result;
  898. }
  899. // Calculate linear interpolation between two quaternions
  900. RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
  901. {
  902. Quaternion result = { 0 };
  903. result.x = q1.x + amount*(q2.x - q1.x);
  904. result.y = q1.y + amount*(q2.y - q1.y);
  905. result.z = q1.z + amount*(q2.z - q1.z);
  906. result.w = q1.w + amount*(q2.w - q1.w);
  907. return result;
  908. }
  909. // Calculate slerp-optimized interpolation between two quaternions
  910. RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
  911. {
  912. Quaternion result = QuaternionLerp(q1, q2, amount);
  913. result = QuaternionNormalize(result);
  914. return result;
  915. }
  916. // Calculates spherical linear interpolation between two quaternions
  917. RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
  918. {
  919. Quaternion result = { 0 };
  920. float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
  921. if (fabs(cosHalfTheta) >= 1.0f) result = q1;
  922. else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
  923. else
  924. {
  925. float halfTheta = (float) acos(cosHalfTheta);
  926. float sinHalfTheta = (float) sqrt(1.0f - cosHalfTheta*cosHalfTheta);
  927. if (fabs(sinHalfTheta) < 0.001f)
  928. {
  929. result.x = (q1.x*0.5f + q2.x*0.5f);
  930. result.y = (q1.y*0.5f + q2.y*0.5f);
  931. result.z = (q1.z*0.5f + q2.z*0.5f);
  932. result.w = (q1.w*0.5f + q2.w*0.5f);
  933. }
  934. else
  935. {
  936. float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta;
  937. float ratioB = sinf(amount*halfTheta)/sinHalfTheta;
  938. result.x = (q1.x*ratioA + q2.x*ratioB);
  939. result.y = (q1.y*ratioA + q2.y*ratioB);
  940. result.z = (q1.z*ratioA + q2.z*ratioB);
  941. result.w = (q1.w*ratioA + q2.w*ratioB);
  942. }
  943. }
  944. return result;
  945. }
  946. // Calculate quaternion based on the rotation from one vector to another
  947. RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
  948. {
  949. Quaternion result = { 0 };
  950. float cos2Theta = Vector3DotProduct(from, to);
  951. Vector3 cross = Vector3CrossProduct(from, to);
  952. result.x = cross.x;
  953. result.y = cross.y;
  954. result.z = cross.y;
  955. result.w = 1.0f + cos2Theta; // NOTE: Added QuaternioIdentity()
  956. // Normalize to essentially nlerp the original and identity to 0.5
  957. result = QuaternionNormalize(result);
  958. // Above lines are equivalent to:
  959. //Quaternion result = QuaternionNlerp(q, QuaternionIdentity(), 0.5f);
  960. return result;
  961. }
  962. // Returns a quaternion for a given rotation matrix
  963. RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
  964. {
  965. Quaternion result = { 0 };
  966. float trace = MatrixTrace(mat);
  967. if (trace > 0.0f)
  968. {
  969. float s = (float)sqrt(trace + 1)*2.0f;
  970. float invS = 1.0f/s;
  971. result.w = s*0.25f;
  972. result.x = (mat.m6 - mat.m9)*invS;
  973. result.y = (mat.m8 - mat.m2)*invS;
  974. result.z = (mat.m1 - mat.m4)*invS;
  975. }
  976. else
  977. {
  978. float m00 = mat.m0, m11 = mat.m5, m22 = mat.m10;
  979. if (m00 > m11 && m00 > m22)
  980. {
  981. float s = (float)sqrt(1.0f + m00 - m11 - m22)*2.0f;
  982. float invS = 1.0f/s;
  983. result.w = (mat.m6 - mat.m9)*invS;
  984. result.x = s*0.25f;
  985. result.y = (mat.m4 + mat.m1)*invS;
  986. result.z = (mat.m8 + mat.m2)*invS;
  987. }
  988. else if (m11 > m22)
  989. {
  990. float s = (float)sqrt(1.0f + m11 - m00 - m22)*2.0f;
  991. float invS = 1.0f/s;
  992. result.w = (mat.m8 - mat.m2)*invS;
  993. result.x = (mat.m4 + mat.m1)*invS;
  994. result.y = s*0.25f;
  995. result.z = (mat.m9 + mat.m6)*invS;
  996. }
  997. else
  998. {
  999. float s = (float)sqrt(1.0f + m22 - m00 - m11)*2.0f;
  1000. float invS = 1.0f/s;
  1001. result.w = (mat.m1 - mat.m4)*invS;
  1002. result.x = (mat.m8 + mat.m2)*invS;
  1003. result.y = (mat.m9 + mat.m6)*invS;
  1004. result.z = s*0.25f;
  1005. }
  1006. }
  1007. return result;
  1008. }
  1009. // Returns a matrix for a given quaternion
  1010. RMDEF Matrix QuaternionToMatrix(Quaternion q)
  1011. {
  1012. Matrix result = { 0 };
  1013. float x = q.x, y = q.y, z = q.z, w = q.w;
  1014. float x2 = x + x;
  1015. float y2 = y + y;
  1016. float z2 = z + z;
  1017. float length = QuaternionLength(q);
  1018. float lengthSquared = length*length;
  1019. float xx = x*x2/lengthSquared;
  1020. float xy = x*y2/lengthSquared;
  1021. float xz = x*z2/lengthSquared;
  1022. float yy = y*y2/lengthSquared;
  1023. float yz = y*z2/lengthSquared;
  1024. float zz = z*z2/lengthSquared;
  1025. float wx = w*x2/lengthSquared;
  1026. float wy = w*y2/lengthSquared;
  1027. float wz = w*z2/lengthSquared;
  1028. result.m0 = 1.0f - (yy + zz);
  1029. result.m1 = xy - wz;
  1030. result.m2 = xz + wy;
  1031. result.m3 = 0.0f;
  1032. result.m4 = xy + wz;
  1033. result.m5 = 1.0f - (xx + zz);
  1034. result.m6 = yz - wx;
  1035. result.m7 = 0.0f;
  1036. result.m8 = xz - wy;
  1037. result.m9 = yz + wx;
  1038. result.m10 = 1.0f - (xx + yy);
  1039. result.m11 = 0.0f;
  1040. result.m12 = 0.0f;
  1041. result.m13 = 0.0f;
  1042. result.m14 = 0.0f;
  1043. result.m15 = 1.0f;
  1044. return result;
  1045. }
  1046. // Returns rotation quaternion for an angle and axis
  1047. // NOTE: angle must be provided in radians
  1048. RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
  1049. {
  1050. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  1051. if (Vector3Length(axis) != 0.0f)
  1052. angle *= 0.5f;
  1053. axis = Vector3Normalize(axis);
  1054. float sinres = sinf(angle);
  1055. float cosres = cosf(angle);
  1056. result.x = axis.x*sinres;
  1057. result.y = axis.y*sinres;
  1058. result.z = axis.z*sinres;
  1059. result.w = cosres;
  1060. result = QuaternionNormalize(result);
  1061. return result;
  1062. }
  1063. // Returns the rotation angle and axis for a given quaternion
  1064. RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
  1065. {
  1066. if (fabs(q.w) > 1.0f) q = QuaternionNormalize(q);
  1067. Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
  1068. float resAngle = 0.0f;
  1069. resAngle = 2.0f*(float)acos(q.w);
  1070. float den = (float)sqrt(1.0f - q.w*q.w);
  1071. if (den > 0.0001f)
  1072. {
  1073. resAxis.x = q.x/den;
  1074. resAxis.y = q.y/den;
  1075. resAxis.z = q.z/den;
  1076. }
  1077. else
  1078. {
  1079. // This occurs when the angle is zero.
  1080. // Not a problem: just set an arbitrary normalized axis.
  1081. resAxis.x = 1.0f;
  1082. }
  1083. *outAxis = resAxis;
  1084. *outAngle = resAngle;
  1085. }
  1086. // Returns he quaternion equivalent to Euler angles
  1087. RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
  1088. {
  1089. Quaternion q = { 0 };
  1090. float x0 = cosf(roll*0.5f);
  1091. float x1 = sinf(roll*0.5f);
  1092. float y0 = cosf(pitch*0.5f);
  1093. float y1 = sinf(pitch*0.5f);
  1094. float z0 = cosf(yaw*0.5f);
  1095. float z1 = sinf(yaw*0.5f);
  1096. q.x = x1*y0*z0 - x0*y1*z1;
  1097. q.y = x0*y1*z0 + x1*y0*z1;
  1098. q.z = x0*y0*z1 - x1*y1*z0;
  1099. q.w = x0*y0*z0 + x1*y1*z1;
  1100. return q;
  1101. }
  1102. // Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
  1103. // NOTE: Angles are returned in a Vector3 struct in degrees
  1104. RMDEF Vector3 QuaternionToEuler(Quaternion q)
  1105. {
  1106. Vector3 result = { 0 };
  1107. // roll (x-axis rotation)
  1108. float x0 = 2.0f*(q.w*q.x + q.y*q.z);
  1109. float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
  1110. result.x = atan2f(x0, x1)*RAD2DEG;
  1111. // pitch (y-axis rotation)
  1112. float y0 = 2.0f*(q.w*q.y - q.z*q.x);
  1113. y0 = y0 > 1.0f ? 1.0f : y0;
  1114. y0 = y0 < -1.0f ? -1.0f : y0;
  1115. result.y = asinf(y0)*RAD2DEG;
  1116. // yaw (z-axis rotation)
  1117. float z0 = 2.0f*(q.w*q.z + q.x*q.y);
  1118. float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
  1119. result.z = atan2f(z0, z1)*RAD2DEG;
  1120. return result;
  1121. }
  1122. // Transform a quaternion given a transformation matrix
  1123. RMDEF Quaternion QuaternionTransform(Quaternion q, Matrix mat)
  1124. {
  1125. Quaternion result = { 0 };
  1126. result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w;
  1127. result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w;
  1128. result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w;
  1129. result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w;
  1130. return result;
  1131. }
  1132. #endif // RAYMATH_H