raymath.odin 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. package raylib
  2. import "core:math"
  3. import "core:math/linalg"
  4. EPSILON :: 0.000001
  5. //----------------------------------------------------------------------------------
  6. // Module Functions Definition - Utils math
  7. //----------------------------------------------------------------------------------
  8. // Clamp float value
  9. @(require_results)
  10. Clamp :: proc "c" (value: f32, min, max: f32) -> f32 {
  11. return clamp(value, min, max)
  12. }
  13. // Calculate linear interpolation between two floats
  14. @(require_results)
  15. Lerp :: proc "c" (start, end: f32, amount: f32) -> f32 {
  16. return start*(1-amount) + end*amount
  17. }
  18. // Normalize input value within input range
  19. @(require_results)
  20. Normalize :: proc "c" (value: f32, start, end: f32) -> f32 {
  21. return (value - start) / (end - start)
  22. }
  23. // Remap input value within input range to output range
  24. @(require_results)
  25. Remap :: proc "c" (value: f32, inputStart, inputEnd: f32, outputStart, outputEnd: f32) -> f32 {
  26. return (value - inputStart)/(inputEnd - inputStart)*(outputEnd - outputStart) + outputStart
  27. }
  28. // Wrap input value from min to max
  29. @(require_results)
  30. Wrap :: proc "c" (value: f32, min, max: f32) -> f32 {
  31. return value - (max - min)*math.floor((value - min)/(max - min))
  32. }
  33. // Check whether two given floats are almost equal
  34. @(require_results)
  35. FloatEquals :: proc "c" (x, y: f32) -> bool {
  36. return abs(x - y) <= EPSILON*fmaxf(1.0, fmaxf(abs(x), abs(y)))
  37. }
  38. //----------------------------------------------------------------------------------
  39. // Module Functions Definition - Vector2 math
  40. //----------------------------------------------------------------------------------
  41. // Vector with components value 0.0
  42. @(require_results, deprecated="Prefer Vector2(0)")
  43. Vector2Zero :: proc "c" () -> Vector2 {
  44. return Vector2(0)
  45. }
  46. // Vector with components value 1.0
  47. @(require_results, deprecated="Prefer Vector2(1)")
  48. Vector2One :: proc "c" () -> Vector2 {
  49. return Vector2(1)
  50. }
  51. // Add two vectors (v1 + v2)
  52. @(require_results, deprecated="Prefer v1 + v2")
  53. Vector2Add :: proc "c" (v1, v2: Vector2) -> Vector2 {
  54. return v1 + v2
  55. }
  56. // Add vector and float value
  57. @(require_results, deprecated="Prefer v + value")
  58. Vector2AddValue :: proc "c" (v: Vector2, value: f32) -> Vector2 {
  59. return v + value
  60. }
  61. // Subtract two vectors (v1 - v2)
  62. @(require_results, deprecated="Prefer a - b")
  63. Vector2Subtract :: proc "c" (a, b: Vector2) -> Vector2 {
  64. return a - b
  65. }
  66. // Subtract vector by float value
  67. @(require_results, deprecated="Prefer v + value")
  68. Vector2SubtractValue :: proc "c" (v: Vector2, value: f32) -> Vector2 {
  69. return v - value
  70. }
  71. // Calculate vector length
  72. @(require_results)
  73. Vector2Length :: proc "c" (v: Vector2) -> f32 {
  74. return linalg.length(v)
  75. }
  76. // Calculate vector square length
  77. @(require_results)
  78. Vector2LengthSqr :: proc "c" (v: Vector2) -> f32 {
  79. return linalg.length2(v)
  80. }
  81. // Calculate two vectors dot product
  82. @(require_results)
  83. Vector2DotProduct :: proc "c" (v1, v2: Vector2) -> f32 {
  84. return linalg.dot(v1, v2)
  85. }
  86. // Calculate distance between two vectors
  87. @(require_results)
  88. Vector2Distance :: proc "c" (v1, v2: Vector2) -> f32 {
  89. return linalg.distance(v1, v2)
  90. }
  91. // Calculate square distance between two vectors
  92. @(require_results)
  93. Vector2DistanceSqrt :: proc "c" (v1, v2: Vector2) -> f32 {
  94. return linalg.length2(v2-v1)
  95. }
  96. // Calculate angle between two vectors
  97. // NOTE: Angle is calculated from origin point (0, 0)
  98. @(require_results)
  99. Vector2Angle :: proc "c" (v1, v2: Vector2) -> f32 {
  100. return linalg.angle_between(v1, v2)
  101. }
  102. // Calculate angle defined by a two vectors line
  103. // NOTE: Parameters need to be normalized
  104. // Current implementation should be aligned with glm::angle
  105. @(require_results)
  106. Vector2LineAngle :: proc "c" (start, end: Vector2) -> f32 {
  107. // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior
  108. return -math.atan2(end.y - start.y, end.x - start.x)
  109. }
  110. // Scale vector (multiply by value)
  111. @(require_results, deprecated="Prefer v * scale")
  112. Vector2Scale :: proc "c" (v: Vector2, scale: f32) -> Vector2 {
  113. return v * scale
  114. }
  115. // Multiply vector by vector
  116. @(require_results, deprecated="Prefer v1 * v2")
  117. Vector2Multiply :: proc "c" (v1, v2: Vector2) -> Vector2 {
  118. return v1 * v2
  119. }
  120. // Negate vector
  121. @(require_results, deprecated="Prefer -v")
  122. Vector2Negate :: proc "c" (v: Vector2) -> Vector2 {
  123. return -v
  124. }
  125. // Divide vector by vector
  126. @(require_results, deprecated="Prefer v1 / v2")
  127. Vector2Divide :: proc "c" (v1, v2: Vector2) -> Vector2 {
  128. return v1 / v2
  129. }
  130. // Normalize provided vector
  131. @(require_results)
  132. Vector2Normalize :: proc "c" (v: Vector2) -> Vector2 {
  133. return linalg.normalize0(v)
  134. }
  135. // Transforms a Vector2 by a given Matrix
  136. @(require_results)
  137. Vector2Transform :: proc "c" (v: Vector2, m: Matrix) -> Vector2 {
  138. v4 := Vector4{v.x, v.y, 0, 1}
  139. return (m * v4).xy
  140. }
  141. // Calculate linear interpolation between two vectors
  142. @(require_results, deprecated="Prefer = linalg.lerp(v1, v2, amount)")
  143. Vector2Lerp :: proc "c" (v1, v2: Vector2, amount: f32) -> Vector2 {
  144. return linalg.lerp(v1, v2, Vector2(amount))
  145. }
  146. // Calculate reflected vector to normal
  147. @(require_results, deprecated="Prefer = linalg.reflect(v, normal)")
  148. Vector2Reflect :: proc "c" (v, normal: Vector2) -> Vector2 {
  149. return linalg.reflect(v, normal)
  150. }
  151. // Rotate vector by angle
  152. @(require_results)
  153. Vector2Rotate :: proc "c" (v: Vector2, angle: f32) -> Vector2 {
  154. c, s := math.cos(angle), math.sin(angle)
  155. return Vector2{
  156. v.x*c - v.y*s,
  157. v.x*s + v.y*c,
  158. }
  159. }
  160. // Move Vector towards target
  161. @(require_results)
  162. Vector2MoveTowards :: proc "c" (v, target: Vector2, maxDistance: f32) -> Vector2 {
  163. dv := target - v
  164. value := linalg.dot(dv, dv)
  165. if value == 0 || (maxDistance >= 0 && value <= maxDistance*maxDistance) {
  166. return target
  167. }
  168. dist := math.sqrt(value)
  169. return v + dv/dist*maxDistance
  170. }
  171. // Invert the given vector
  172. @(require_results, deprecated="Prefer 1.0/v")
  173. Vector2Invert :: proc "c" (v: Vector2) -> Vector2 {
  174. return 1.0/v
  175. }
  176. // Clamp the components of the vector between
  177. // min and max values specified by the given vectors
  178. @(require_results)
  179. Vector2Clamp :: proc "c" (v: Vector2, min, max: Vector2) -> Vector2 {
  180. return Vector2{
  181. clamp(v.x, min.x, max.x),
  182. clamp(v.y, min.y, max.y),
  183. }
  184. }
  185. // Clamp the magnitude of the vector between two min and max values
  186. @(require_results)
  187. Vector2ClampValue :: proc "c" (v: Vector2, min, max: f32) -> Vector2 {
  188. result := v
  189. length := linalg.dot(v, v)
  190. if length > 0 {
  191. length = math.sqrt(length)
  192. scale := f32(1)
  193. if length < min {
  194. scale = min/length
  195. } else if length > max {
  196. scale = max/length
  197. }
  198. result = v*scale
  199. }
  200. return result
  201. }
  202. @(require_results)
  203. Vector2Equals :: proc "c" (p, q: Vector2) -> bool {
  204. return FloatEquals(p.x, q.x) &&
  205. FloatEquals(p.y, q.y)
  206. }
  207. //----------------------------------------------------------------------------------
  208. // Module Functions Definition - Vector3 math
  209. //----------------------------------------------------------------------------------
  210. // Vector with components value 0.0
  211. @(require_results, deprecated="Prefer Vector3(0)")
  212. Vector3Zero :: proc "c" () -> Vector3 {
  213. return Vector3(0)
  214. }
  215. // Vector with components value 1.0
  216. @(require_results, deprecated="Prefer Vector3(1)")
  217. Vector3One :: proc "c" () -> Vector3 {
  218. return Vector3(1)
  219. }
  220. // Add two vectors (v1 + v2)
  221. @(require_results, deprecated="Prefer v1 + v2")
  222. Vector3Add :: proc "c" (v1, v2: Vector3) -> Vector3 {
  223. return v1 + v2
  224. }
  225. // Add vector and float value
  226. @(require_results, deprecated="Prefer v + value")
  227. Vector3AddValue :: proc "c" (v: Vector3, value: f32) -> Vector3 {
  228. return v + value
  229. }
  230. // Subtract two vectors (v1 - v2)
  231. @(require_results, deprecated="Prefer a - b")
  232. Vector3Subtract :: proc "c" (a, b: Vector3) -> Vector3 {
  233. return a - b
  234. }
  235. // Subtract vector by float value
  236. @(require_results, deprecated="Prefer v + value")
  237. Vector3SubtractValue :: proc "c" (v: Vector3, value: f32) -> Vector3 {
  238. return v - value
  239. }
  240. // Calculate vector length
  241. @(require_results)
  242. Vector3Length :: proc "c" (v: Vector3) -> f32 {
  243. return linalg.length(v)
  244. }
  245. // Calculate vector square length
  246. @(require_results)
  247. Vector3LengthSqr :: proc "c" (v: Vector3) -> f32 {
  248. return linalg.length2(v)
  249. }
  250. // Calculate two vectors dot product
  251. @(require_results)
  252. Vector3DotProduct :: proc "c" (v1, v2: Vector3) -> f32 {
  253. return linalg.dot(v1, v2)
  254. }
  255. // Calculate two vectors dot product
  256. @(require_results)
  257. Vector3CrossProduct :: proc "c" (v1, v2: Vector3) -> Vector3 {
  258. return linalg.cross(v1, v2)
  259. }
  260. // Calculate distance between two vectors
  261. @(require_results)
  262. Vector3Distance :: proc "c" (v1, v2: Vector3) -> f32 {
  263. return linalg.distance(v1, v2)
  264. }
  265. // Calculate square distance between two vectors
  266. @(require_results)
  267. Vector3DistanceSqrt :: proc "c" (v1, v2: Vector3) -> f32 {
  268. return linalg.length2(v2-v1)
  269. }
  270. // Calculate angle between two vectors
  271. // NOTE: Angle is calculated from origin point (0, 0)
  272. @(require_results)
  273. Vector3Angle :: proc "c" (v1, v2: Vector3) -> f32 {
  274. return linalg.angle_between(v1, v2)
  275. }
  276. // Calculate angle defined by a two vectors line
  277. // NOTE: Parameters need to be normalized
  278. // Current implementation should be aligned with glm::angle
  279. @(require_results)
  280. Vector3LineAngle :: proc "c" (start, end: Vector3) -> f32 {
  281. // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior
  282. return -math.atan2(end.y - start.y, end.x - start.x)
  283. }
  284. // Scale vector (multiply by value)
  285. @(require_results, deprecated="Prefer v * scale")
  286. Vector3Scale :: proc "c" (v: Vector3, scale: f32) -> Vector3 {
  287. return v * scale
  288. }
  289. // Multiply vector by vector
  290. @(require_results, deprecated="Prefer v1 * v2")
  291. Vector3Multiply :: proc "c" (v1, v2: Vector3) -> Vector3 {
  292. return v1 * v2
  293. }
  294. // Negate vector
  295. @(require_results, deprecated="Prefer -v")
  296. Vector3Negate :: proc "c" (v: Vector3) -> Vector3 {
  297. return -v
  298. }
  299. // Divide vector by vector
  300. @(require_results, deprecated="Prefer v1 / v2")
  301. Vector3Divide :: proc "c" (v1, v2: Vector3) -> Vector3 {
  302. return v1 / v2
  303. }
  304. // Normalize provided vector
  305. @(require_results)
  306. Vector3Normalize :: proc "c" (v: Vector3) -> Vector3 {
  307. return linalg.normalize0(v)
  308. }
  309. // Calculate the projection of the vector v1 on to v2
  310. @(require_results)
  311. Vector3Project :: proc "c" (v1, v2: Vector3) -> Vector3 {
  312. return linalg.projection(v1, v2)
  313. }
  314. // Calculate the rejection of the vector v1 on to v2
  315. @(require_results)
  316. Vector3Reject :: proc "c" (v1, v2: Vector3) -> Vector3 {
  317. mag := linalg.dot(v1, v2)/linalg.dot(v2, v2)
  318. return v1 - v2*mag
  319. }
  320. // Orthonormalize provided vectors
  321. // Makes vectors normalized and orthogonal to each other
  322. // Gram-Schmidt function implementation
  323. Vector3OrthoNormalize :: proc "c" (v1, v2: ^Vector3) {
  324. v1^ = linalg.normalize0(v1^)
  325. v3 := linalg.normalize0(linalg.cross(v1^, v2^))
  326. v2^ = linalg.cross(v3, v1^)
  327. }
  328. // Transform a vector by quaternion rotation
  329. @(require_results)
  330. Vector3RotateByQuaternion :: proc "c" (v: Vector3, q: Quaternion) -> Vector3 {
  331. return linalg.mul(q, v)
  332. }
  333. // Rotates a vector around an axis
  334. @(require_results)
  335. Vector3RotateByAxisAngle :: proc "c" (v: Vector3, axis: Vector3, angle: f32) -> Vector3 {
  336. axis, angle := axis, angle
  337. axis = linalg.normalize0(axis)
  338. angle *= 0.5
  339. a := math.sin(angle)
  340. b := axis.x*a
  341. c := axis.y*a
  342. d := axis.z*a
  343. a = math.cos(angle)
  344. w := Vector3{b, c, d}
  345. wv := linalg.cross(w, v)
  346. wwv := linalg.cross(w, wv)
  347. a *= 2
  348. wv *= a
  349. wwv *= 2
  350. return v + wv + wwv
  351. }
  352. // Transforms a Vector3 by a given Matrix
  353. @(require_results)
  354. Vector3Transform :: proc "c" (v: Vector3, m: Matrix) -> Vector3 {
  355. v4 := Vector4{v.x, v.y, v.z, 1}
  356. return (m * v4).xyz
  357. }
  358. // Calculate linear interpolation between two vectors
  359. @(require_results, deprecated="Prefer = linalg.lerp(v1, v2, amount)")
  360. Vector3Lerp :: proc "c" (v1, v2: Vector3, amount: f32) -> Vector3 {
  361. return linalg.lerp(v1, v2, Vector3(amount))
  362. }
  363. // Calculate reflected vector to normal
  364. @(require_results, deprecated="Prefer = linalg.reflect(v, normal)")
  365. Vector3Reflect :: proc "c" (v, normal: Vector3) -> Vector3 {
  366. return linalg.reflect(v, normal)
  367. }
  368. // Compute the direction of a refracted ray
  369. // v: normalized direction of the incoming ray
  370. // n: normalized normal vector of the interface of two optical media
  371. // r: ratio of the refractive index of the medium from where the ray comes
  372. // to the refractive index of the medium on the other side of the surface
  373. @(require_results, deprecated="Prefer = linalg.refract(v, n, r)")
  374. Vector3Refract :: proc "c" (v, n: Vector3, r: f32) -> Vector3 {
  375. return linalg.refract(v, n, r)
  376. }
  377. // Move Vector towards target
  378. @(require_results)
  379. Vector3MoveTowards :: proc "c" (v, target: Vector3, maxDistance: f32) -> Vector3 {
  380. dv := target - v
  381. value := linalg.dot(dv, dv)
  382. if value == 0 || (maxDistance >= 0 && value <= maxDistance*maxDistance) {
  383. return target
  384. }
  385. dist := math.sqrt(value)
  386. return v + dv/dist*maxDistance
  387. }
  388. // Invert the given vector
  389. @(require_results, deprecated="Prefer 1.0/v")
  390. Vector3Invert :: proc "c" (v: Vector3) -> Vector3 {
  391. return 1.0/v
  392. }
  393. // Clamp the components of the vector between
  394. // min and max values specified by the given vectors
  395. @(require_results)
  396. Vector3Clamp :: proc "c" (v: Vector3, min, max: Vector3) -> Vector3 {
  397. return Vector3{
  398. clamp(v.x, min.x, max.x),
  399. clamp(v.y, min.y, max.y),
  400. clamp(v.z, min.z, max.z),
  401. }
  402. }
  403. // Clamp the magnitude of the vector between two min and max values
  404. @(require_results)
  405. Vector3ClampValue :: proc "c" (v: Vector3, min, max: f32) -> Vector3 {
  406. result := v
  407. length := linalg.dot(v, v)
  408. if length > 0 {
  409. length = math.sqrt(length)
  410. scale := f32(1)
  411. if length < min {
  412. scale = min/length
  413. } else if length > max {
  414. scale = max/length
  415. }
  416. result = v*scale
  417. }
  418. return result
  419. }
  420. @(require_results)
  421. Vector3Equals :: proc "c" (p, q: Vector3) -> bool {
  422. return FloatEquals(p.x, q.x) &&
  423. FloatEquals(p.y, q.y) &&
  424. FloatEquals(p.z, q.z)
  425. }
  426. @(require_results)
  427. Vector3Min :: proc "c" (v1, v2: Vector3) -> Vector3 {
  428. return linalg.min(v1, v2)
  429. }
  430. @(require_results)
  431. Vector3Max :: proc "c" (v1, v2: Vector3) -> Vector3 {
  432. return linalg.max(v1, v2)
  433. }
  434. // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
  435. // NOTE: Assumes P is on the plane of the triangle
  436. @(require_results)
  437. Vector3Barycenter :: proc "c" (p: Vector3, a, b, c: Vector3) -> (result: Vector3) {
  438. v0 := b - a
  439. v1 := c - a
  440. v2 := p - a
  441. d00 := linalg.dot(v0, v0)
  442. d01 := linalg.dot(v0, v1)
  443. d11 := linalg.dot(v1, v1)
  444. d20 := linalg.dot(v2, v0)
  445. d21 := linalg.dot(v2, v1)
  446. denom := d00*d11 - d01*d01
  447. result.y = (d11*d20 - d01*d21)/denom
  448. result.z = (d00*d21 - d01*d20)/denom
  449. result.x = 1 - (result.z + result.y)
  450. return result
  451. }
  452. // Projects a Vector3 from screen space into object space
  453. @(require_results)
  454. Vector3Unproject :: proc "c" (source: Vector3, projection: Matrix, view: Matrix) -> Vector3 {
  455. matViewProj := view * projection
  456. matViewProjInv := linalg.inverse(matViewProj)
  457. quat: Quaternion
  458. quat.x = source.x
  459. quat.y = source.y
  460. quat.z = source.z
  461. quat.w = 1
  462. qtransformed := QuaternionTransform(quat, matViewProjInv)
  463. return Vector3{qtransformed.x/qtransformed.w, qtransformed.y/qtransformed.w, qtransformed.z/qtransformed.w}
  464. }
  465. //----------------------------------------------------------------------------------
  466. // Module Functions Definition - Matrix math
  467. //----------------------------------------------------------------------------------
  468. // Compute matrix determinant
  469. @(require_results)
  470. MatrixDeterminant :: proc "c" (mat: Matrix) -> f32 {
  471. return linalg.determinant(mat)
  472. }
  473. // Get the trace of the matrix (sum of the values along the diagonal)
  474. @(require_results)
  475. MatrixTrace :: proc "c" (mat: Matrix) -> f32 {
  476. return linalg.trace(mat)
  477. }
  478. // Transposes provided matrix
  479. @(require_results)
  480. MatrixTranspose :: proc "c" (mat: Matrix) -> Matrix {
  481. return linalg.transpose(mat)
  482. }
  483. // Invert provided matrix
  484. @(require_results)
  485. MatrixInvert :: proc "c" (mat: Matrix) -> Matrix {
  486. return linalg.inverse(mat)
  487. }
  488. // Get identity matrix
  489. @(require_results, deprecated="Prefer Matrix(1)")
  490. MatrixIdentity :: proc "c" () -> Matrix {
  491. return Matrix(1)
  492. }
  493. // Add two matrices
  494. @(require_results, deprecated="Prefer left + right")
  495. MatrixAdd :: proc "c" (left, right: Matrix) -> Matrix {
  496. return left + right
  497. }
  498. // Subtract two matrices (left - right)
  499. @(require_results, deprecated="Prefer left - right")
  500. MatrixSubtract :: proc "c" (left, right: Matrix) -> Matrix {
  501. return left - right
  502. }
  503. // Get two matrix multiplication
  504. // NOTE: When multiplying matrices... the order matters!
  505. @(require_results, deprecated="Prefer left * right")
  506. MatrixMultiply :: proc "c" (left, right: Matrix) -> Matrix {
  507. return left * right
  508. }
  509. // Get translation matrix
  510. @(require_results)
  511. MatrixTranslate :: proc "c" (x, y, z: f32) -> Matrix {
  512. return {
  513. 1, 0, 0, x,
  514. 0, 1, 0, y,
  515. 0, 0, 1, z,
  516. 0, 0, 0, 1,
  517. }
  518. }
  519. // Create rotation matrix from axis and angle
  520. // NOTE: Angle should be provided in radians
  521. @(require_results)
  522. MatrixRotate :: proc "c" (axis: Vector3, angle: f32) -> Matrix {
  523. return auto_cast linalg.matrix4_rotate(angle, axis)
  524. }
  525. // Get x-rotation matrix
  526. // NOTE: Angle must be provided in radians
  527. @(require_results)
  528. MatrixRotateX :: proc "c" (angle: f32) -> Matrix {
  529. return auto_cast linalg.matrix4_rotate(angle, Vector3{1, 0, 0})
  530. }
  531. // Get y-rotation matrix
  532. // NOTE: Angle must be provided in radians
  533. @(require_results)
  534. MatrixRotateY :: proc "c" (angle: f32) -> Matrix {
  535. return auto_cast linalg.matrix4_rotate(angle, Vector3{0, 1, 0})
  536. }
  537. // Get z-rotation matrix
  538. // NOTE: Angle must be provided in radians
  539. @(require_results)
  540. MatrixRotateZ :: proc "c" (angle: f32) -> Matrix {
  541. return auto_cast linalg.matrix4_rotate(angle, Vector3{0, 0, 1})
  542. }
  543. // Get xyz-rotation matrix
  544. // NOTE: Angle must be provided in radians
  545. @(require_results)
  546. MatrixRotateXYZ :: proc "c" (angle: Vector3) -> Matrix {
  547. return auto_cast linalg.matrix4_from_euler_angles_xyz(angle.x, angle.y, angle.z)
  548. }
  549. // Get zyx-rotation matrix
  550. // NOTE: Angle must be provided in radians
  551. @(require_results)
  552. MatrixRotateZYX :: proc "c" (angle: Vector3) -> Matrix {
  553. return auto_cast linalg.matrix4_from_euler_angles_zyx(angle.x, angle.y, angle.z)
  554. }
  555. // Get scaling matrix
  556. @(require_results)
  557. MatrixScale :: proc "c" (x, y, z: f32) -> Matrix {
  558. return auto_cast linalg.matrix4_scale(Vector3{x, y, z})
  559. }
  560. // Get orthographic projection matrix
  561. @(require_results)
  562. MatrixOrtho :: proc "c" (left, right, bottom, top, near, far: f32) -> Matrix {
  563. return auto_cast linalg.matrix_ortho3d(left, right, bottom, top, near, far)
  564. }
  565. // Get perspective projection matrix
  566. // NOTE: Fovy angle must be provided in radians
  567. @(require_results)
  568. MatrixPerspective :: proc "c" (fovY, aspect, nearPlane, farPlane: f32) -> Matrix {
  569. return auto_cast linalg.matrix4_perspective(fovY, aspect, nearPlane, farPlane)
  570. }
  571. // Get camera look-at matrix (view matrix)
  572. @(require_results)
  573. MatrixLookAt :: proc "c" (eye, target, up: Vector3) -> Matrix {
  574. return auto_cast linalg.matrix4_look_at(eye, target, up)
  575. }
  576. // Get float array of matrix data
  577. @(require_results)
  578. MatrixToFloatV :: proc "c" (mat: Matrix) -> [16]f32 {
  579. return transmute([16]f32)linalg.transpose(mat)
  580. }
  581. //----------------------------------------------------------------------------------
  582. // Module Functions Definition - Quaternion math
  583. //----------------------------------------------------------------------------------
  584. // Add two quaternions
  585. @(require_results, deprecated="Prefer q1 + q2")
  586. QuaternionAdd :: proc "c" (q1, q2: Quaternion) -> Quaternion {
  587. return q1 + q2
  588. }
  589. // Add quaternion and float value
  590. @(require_results)
  591. QuaternionAddValue :: proc "c" (q: Quaternion, add: f32) -> Quaternion {
  592. return q + Quaternion(add)
  593. }
  594. // Subtract two quaternions
  595. @(require_results, deprecated="Prefer q1 - q2")
  596. QuaternionSubtract :: proc "c" (q1, q2: Quaternion) -> Quaternion {
  597. return q1 - q2
  598. }
  599. // Subtract quaternion and float value
  600. @(require_results)
  601. QuaternionSubtractValue :: proc "c" (q: Quaternion, sub: f32) -> Quaternion {
  602. return q - Quaternion(sub)
  603. }
  604. // Get identity quaternion
  605. @(require_results, deprecated="Prefer Quaternion(1)")
  606. QuaternionIdentity :: proc "c" () -> Quaternion {
  607. return 1
  608. }
  609. // Computes the length of a quaternion
  610. @(require_results, deprecated="Prefer abs(q)")
  611. QuaternionLength :: proc "c" (q: Quaternion) -> f32 {
  612. return abs(q)
  613. }
  614. // Normalize provided quaternion
  615. @(require_results)
  616. QuaternionNormalize :: proc "c" (q: Quaternion) -> Quaternion {
  617. return linalg.normalize0(q)
  618. }
  619. // Invert provided quaternion
  620. @(require_results, deprecated="Prefer 1/q")
  621. QuaternionInvert :: proc "c" (q: Quaternion) -> Quaternion {
  622. return 1/q
  623. }
  624. // Calculate two quaternion multiplication
  625. @(require_results, deprecated="Prefer q1 * q2")
  626. QuaternionMultiply :: proc "c" (q1, q2: Quaternion) -> Quaternion {
  627. return q1 * q2
  628. }
  629. // Scale quaternion by float value
  630. @(require_results)
  631. QuaternionScale :: proc "c" (q: Quaternion, mul: f32) -> Quaternion {
  632. return q * Quaternion(mul)
  633. }
  634. // Divide two quaternions
  635. @(require_results, deprecated="Prefer q1 / q2")
  636. QuaternionDivide :: proc "c" (q1, q2: Quaternion) -> Quaternion {
  637. return q1 / q2
  638. }
  639. // Calculate linear interpolation between two quaternions
  640. @(require_results)
  641. QuaternionLerp :: proc "c" (q1, q2: Quaternion, amount: f32) -> (q3: Quaternion) {
  642. q3.x = q1.x + (q2.x-q1.x)*amount
  643. q3.y = q1.y + (q2.y-q1.y)*amount
  644. q3.z = q1.z + (q2.z-q1.z)*amount
  645. q3.w = q1.w + (q2.w-q1.w)*amount
  646. return
  647. }
  648. // Calculate slerp-optimized interpolation between two quaternions
  649. @(require_results)
  650. QuaternionNlerp :: proc "c" (q1, q2: Quaternion, amount: f32) -> Quaternion {
  651. return linalg.quaternion_nlerp(q1, q2, amount)
  652. }
  653. // Calculates spherical linear interpolation between two quaternions
  654. @(require_results)
  655. QuaternionSlerp :: proc "c" (q1, q2: Quaternion, amount: f32) -> Quaternion {
  656. return linalg.quaternion_slerp(q1, q2, amount)
  657. }
  658. // Calculate quaternion based on the rotation from one vector to another
  659. @(require_results)
  660. QuaternionFromVector3ToVector3 :: proc "c" (from, to: Vector3) -> Quaternion {
  661. return linalg.quaternion_between_two_vector3(from, to)
  662. }
  663. // Get a quaternion for a given rotation matrix
  664. @(require_results)
  665. QuaternionFromMatrix :: proc "c" (mat: Matrix) -> Quaternion {
  666. return linalg.quaternion_from_matrix4(linalg.Matrix4f32(mat))
  667. }
  668. // Get a matrix for a given quaternion
  669. @(require_results)
  670. QuaternionToMatrix :: proc "c" (q: Quaternion) -> Matrix {
  671. return auto_cast linalg.matrix4_from_quaternion(q)
  672. }
  673. // Get rotation quaternion for an angle and axis NOTE: Angle must be provided in radians
  674. @(require_results)
  675. QuaternionFromAxisAngle :: proc "c" (axis: Vector3, angle: f32) -> Quaternion {
  676. return linalg.quaternion_angle_axis(angle, axis)
  677. }
  678. // Get the rotation angle and axis for a given quaternion
  679. @(require_results)
  680. QuaternionToAxisAngle :: proc "c" (q: Quaternion) -> (outAxis: Vector3, outAngle: f32) {
  681. outAngle, outAxis = linalg.angle_axis_from_quaternion(q)
  682. return
  683. }
  684. // Get the quaternion equivalent to Euler angles NOTE: Rotation order is ZYX
  685. @(require_results)
  686. QuaternionFromEuler :: proc "c" (pitch, yaw, roll: f32) -> Quaternion {
  687. return linalg.quaternion_from_pitch_yaw_roll(pitch, yaw, roll)
  688. }
  689. // Get the Euler angles equivalent to quaternion (roll, pitch, yaw) NOTE: Angles are returned in a Vector3 struct in radians
  690. @(require_results)
  691. QuaternionToEuler :: proc "c" (q: Quaternion) -> Vector3 {
  692. result: Vector3
  693. // Roll (x-axis rotation)
  694. x0 := 2.0*(q.w*q.x + q.y*q.z)
  695. x1 := 1.0 - 2.0*(q.x*q.x + q.y*q.y)
  696. result.x = math.atan2(x0, x1)
  697. // Pitch (y-axis rotation)
  698. y0 := 2.0*(q.w*q.y - q.z*q.x)
  699. y0 = 1.0 if y0 > 1.0 else y0
  700. y0 = -1.0 if y0 < -1.0 else y0
  701. result.y = math.asin(y0)
  702. // Yaw (z-axis rotation)
  703. z0 := 2.0*(q.w*q.z + q.x*q.y)
  704. z1 := 1.0 - 2.0*(q.y*q.y + q.z*q.z)
  705. result.z = math.atan2(z0, z1)
  706. return result
  707. }
  708. // Transform a quaternion given a transformation matrix
  709. @(require_results)
  710. QuaternionTransform :: proc "c" (q: Quaternion, mat: Matrix) -> Quaternion {
  711. v := mat * transmute(Vector4)q
  712. return transmute(Quaternion)v
  713. }
  714. // Check whether two given quaternions are almost equal
  715. @(require_results)
  716. QuaternionEquals :: proc "c" (p, q: Quaternion) -> bool {
  717. return FloatEquals(p.x, q.x) &&
  718. FloatEquals(p.y, q.y) &&
  719. FloatEquals(p.z, q.z) &&
  720. FloatEquals(p.w, q.w)
  721. }
  722. @(private, require_results)
  723. fmaxf :: proc "contextless" (x, y: f32) -> f32 {
  724. if math.is_nan(x) {
  725. return y
  726. }
  727. if math.is_nan(y) {
  728. return x
  729. }
  730. if math.sign_bit(x) != math.sign_bit(y) {
  731. return y if math.sign_bit(x) else x
  732. }
  733. return y if x < y else x
  734. }