specific.odin 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732
  1. package linalg
  2. import "core:builtin"
  3. import "core:math"
  4. F16_EPSILON :: 1e-3
  5. F32_EPSILON :: 1e-7
  6. F64_EPSILON :: 1e-15
  7. Vector2f16 :: distinct [2]f16
  8. Vector3f16 :: distinct [3]f16
  9. Vector4f16 :: distinct [4]f16
  10. Matrix1x1f16 :: distinct matrix[1, 1]f16
  11. Matrix1x2f16 :: distinct matrix[1, 2]f16
  12. Matrix1x3f16 :: distinct matrix[1, 3]f16
  13. Matrix1x4f16 :: distinct matrix[1, 4]f16
  14. Matrix2x1f16 :: distinct matrix[2, 1]f16
  15. Matrix2x2f16 :: distinct matrix[2, 2]f16
  16. Matrix2x3f16 :: distinct matrix[2, 3]f16
  17. Matrix2x4f16 :: distinct matrix[2, 4]f16
  18. Matrix3x1f16 :: distinct matrix[3, 1]f16
  19. Matrix3x2f16 :: distinct matrix[3, 2]f16
  20. Matrix3x3f16 :: distinct matrix[3, 3]f16
  21. Matrix3x4f16 :: distinct matrix[3, 4]f16
  22. Matrix4x1f16 :: distinct matrix[4, 1]f16
  23. Matrix4x2f16 :: distinct matrix[4, 2]f16
  24. Matrix4x3f16 :: distinct matrix[4, 3]f16
  25. Matrix4x4f16 :: distinct matrix[4, 4]f16
  26. Matrix1f16 :: Matrix1x1f16
  27. Matrix2f16 :: Matrix2x2f16
  28. Matrix3f16 :: Matrix3x3f16
  29. Matrix4f16 :: Matrix4x4f16
  30. Vector2f32 :: distinct [2]f32
  31. Vector3f32 :: distinct [3]f32
  32. Vector4f32 :: distinct [4]f32
  33. Matrix1x1f32 :: distinct matrix[1, 1]f32
  34. Matrix1x2f32 :: distinct matrix[1, 2]f32
  35. Matrix1x3f32 :: distinct matrix[1, 3]f32
  36. Matrix1x4f32 :: distinct matrix[1, 4]f32
  37. Matrix2x1f32 :: distinct matrix[2, 1]f32
  38. Matrix2x2f32 :: distinct matrix[2, 2]f32
  39. Matrix2x3f32 :: distinct matrix[2, 3]f32
  40. Matrix2x4f32 :: distinct matrix[2, 4]f32
  41. Matrix3x1f32 :: distinct matrix[3, 1]f32
  42. Matrix3x2f32 :: distinct matrix[3, 2]f32
  43. Matrix3x3f32 :: distinct matrix[3, 3]f32
  44. Matrix3x4f32 :: distinct matrix[3, 4]f32
  45. Matrix4x1f32 :: distinct matrix[4, 1]f32
  46. Matrix4x2f32 :: distinct matrix[4, 2]f32
  47. Matrix4x3f32 :: distinct matrix[4, 3]f32
  48. Matrix4x4f32 :: distinct matrix[4, 4]f32
  49. Matrix1f32 :: Matrix1x1f32
  50. Matrix2f32 :: Matrix2x2f32
  51. Matrix3f32 :: Matrix3x3f32
  52. Matrix4f32 :: Matrix4x4f32
  53. Vector2f64 :: distinct [2]f64
  54. Vector3f64 :: distinct [3]f64
  55. Vector4f64 :: distinct [4]f64
  56. Matrix1x1f64 :: distinct matrix[1, 1]f64
  57. Matrix1x2f64 :: distinct matrix[1, 2]f64
  58. Matrix1x3f64 :: distinct matrix[1, 3]f64
  59. Matrix1x4f64 :: distinct matrix[1, 4]f64
  60. Matrix2x1f64 :: distinct matrix[2, 1]f64
  61. Matrix2x2f64 :: distinct matrix[2, 2]f64
  62. Matrix2x3f64 :: distinct matrix[2, 3]f64
  63. Matrix2x4f64 :: distinct matrix[2, 4]f64
  64. Matrix3x1f64 :: distinct matrix[3, 1]f64
  65. Matrix3x2f64 :: distinct matrix[3, 2]f64
  66. Matrix3x3f64 :: distinct matrix[3, 3]f64
  67. Matrix3x4f64 :: distinct matrix[3, 4]f64
  68. Matrix4x1f64 :: distinct matrix[4, 1]f64
  69. Matrix4x2f64 :: distinct matrix[4, 2]f64
  70. Matrix4x3f64 :: distinct matrix[4, 3]f64
  71. Matrix4x4f64 :: distinct matrix[4, 4]f64
  72. Matrix1f64 :: Matrix1x1f64
  73. Matrix2f64 :: Matrix2x2f64
  74. Matrix3f64 :: Matrix3x3f64
  75. Matrix4f64 :: Matrix4x4f64
  76. Quaternionf16 :: distinct quaternion64
  77. Quaternionf32 :: distinct quaternion128
  78. Quaternionf64 :: distinct quaternion256
  79. MATRIX1F16_IDENTITY :: Matrix1f16(1)
  80. MATRIX2F16_IDENTITY :: Matrix2f16(1)
  81. MATRIX3F16_IDENTITY :: Matrix3f16(1)
  82. MATRIX4F16_IDENTITY :: Matrix4f16(1)
  83. MATRIX1F32_IDENTITY :: Matrix1f32(1)
  84. MATRIX2F32_IDENTITY :: Matrix2f32(1)
  85. MATRIX3F32_IDENTITY :: Matrix3f32(1)
  86. MATRIX4F32_IDENTITY :: Matrix4f32(1)
  87. MATRIX1F64_IDENTITY :: Matrix1f64(1)
  88. MATRIX2F64_IDENTITY :: Matrix2f64(1)
  89. MATRIX3F64_IDENTITY :: Matrix3f64(1)
  90. MATRIX4F64_IDENTITY :: Matrix4f64(1)
  91. QUATERNIONF16_IDENTITY :: Quaternionf16(1)
  92. QUATERNIONF32_IDENTITY :: Quaternionf32(1)
  93. QUATERNIONF64_IDENTITY :: Quaternionf64(1)
  94. VECTOR3F16_X_AXIS :: Vector3f16{1, 0, 0}
  95. VECTOR3F16_Y_AXIS :: Vector3f16{0, 1, 0}
  96. VECTOR3F16_Z_AXIS :: Vector3f16{0, 0, 1}
  97. VECTOR3F32_X_AXIS :: Vector3f32{1, 0, 0}
  98. VECTOR3F32_Y_AXIS :: Vector3f32{0, 1, 0}
  99. VECTOR3F32_Z_AXIS :: Vector3f32{0, 0, 1}
  100. VECTOR3F64_X_AXIS :: Vector3f64{1, 0, 0}
  101. VECTOR3F64_Y_AXIS :: Vector3f64{0, 1, 0}
  102. VECTOR3F64_Z_AXIS :: Vector3f64{0, 0, 1}
  103. vector2_orthogonal :: proc(v: $V/[2]$E) -> V where !IS_ARRAY(E), IS_FLOAT(E) {
  104. return {-v.y, v.x}
  105. }
  106. vector3_orthogonal :: proc(v: $V/[3]$E) -> V where !IS_ARRAY(E), IS_FLOAT(E) {
  107. x := abs(v.x)
  108. y := abs(v.y)
  109. z := abs(v.z)
  110. other: V
  111. if x < y {
  112. if x < z {
  113. other = {1, 0, 0}
  114. } else {
  115. other = {0, 0, 1}
  116. }
  117. } else {
  118. if y < z {
  119. other = {0, 1, 0}
  120. } else {
  121. other = {0, 0, 1}
  122. }
  123. }
  124. return normalize(cross(v, other))
  125. }
  126. orthogonal :: proc{vector2_orthogonal, vector3_orthogonal}
  127. vector4_srgb_to_linear_f16 :: proc(col: Vector4f16) -> Vector4f16 {
  128. r := math.pow(col.x, 2.2)
  129. g := math.pow(col.y, 2.2)
  130. b := math.pow(col.z, 2.2)
  131. a := col.w
  132. return {r, g, b, a}
  133. }
  134. vector4_srgb_to_linear_f32 :: proc(col: Vector4f32) -> Vector4f32 {
  135. r := math.pow(col.x, 2.2)
  136. g := math.pow(col.y, 2.2)
  137. b := math.pow(col.z, 2.2)
  138. a := col.w
  139. return {r, g, b, a}
  140. }
  141. vector4_srgb_to_linear_f64 :: proc(col: Vector4f64) -> Vector4f64 {
  142. r := math.pow(col.x, 2.2)
  143. g := math.pow(col.y, 2.2)
  144. b := math.pow(col.z, 2.2)
  145. a := col.w
  146. return {r, g, b, a}
  147. }
  148. vector4_srgb_to_linear :: proc{
  149. vector4_srgb_to_linear_f16,
  150. vector4_srgb_to_linear_f32,
  151. vector4_srgb_to_linear_f64,
  152. }
  153. vector4_linear_to_srgb_f16 :: proc(col: Vector4f16) -> Vector4f16 {
  154. a :: 2.51
  155. b :: 0.03
  156. c :: 2.43
  157. d :: 0.59
  158. e :: 0.14
  159. x := col.x
  160. y := col.y
  161. z := col.z
  162. x = (x * (a * x + b)) / (x * (c * x + d) + e)
  163. y = (y * (a * y + b)) / (y * (c * y + d) + e)
  164. z = (z * (a * z + b)) / (z * (c * z + d) + e)
  165. x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
  166. y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
  167. z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
  168. return {x, y, z, col.w}
  169. }
  170. vector4_linear_to_srgb_f32 :: proc(col: Vector4f32) -> Vector4f32 {
  171. a :: 2.51
  172. b :: 0.03
  173. c :: 2.43
  174. d :: 0.59
  175. e :: 0.14
  176. x := col.x
  177. y := col.y
  178. z := col.z
  179. x = (x * (a * x + b)) / (x * (c * x + d) + e)
  180. y = (y * (a * y + b)) / (y * (c * y + d) + e)
  181. z = (z * (a * z + b)) / (z * (c * z + d) + e)
  182. x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
  183. y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
  184. z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
  185. return {x, y, z, col.w}
  186. }
  187. vector4_linear_to_srgb_f64 :: proc(col: Vector4f64) -> Vector4f64 {
  188. a :: 2.51
  189. b :: 0.03
  190. c :: 2.43
  191. d :: 0.59
  192. e :: 0.14
  193. x := col.x
  194. y := col.y
  195. z := col.z
  196. x = (x * (a * x + b)) / (x * (c * x + d) + e)
  197. y = (y * (a * y + b)) / (y * (c * y + d) + e)
  198. z = (z * (a * z + b)) / (z * (c * z + d) + e)
  199. x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
  200. y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
  201. z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
  202. return {x, y, z, col.w}
  203. }
  204. vector4_linear_to_srgb :: proc{
  205. vector4_linear_to_srgb_f16,
  206. vector4_linear_to_srgb_f32,
  207. vector4_linear_to_srgb_f64,
  208. }
  209. vector4_hsl_to_rgb_f16 :: proc(h, s, l: f16, a: f16 = 1) -> Vector4f16 {
  210. hue_to_rgb :: proc(p, q, t: f16) -> f16 {
  211. t := t
  212. if t < 0 { t += 1 }
  213. if t > 1 { t -= 1 }
  214. switch {
  215. case t < 1.0/6.0: return p + (q - p) * 6.0 * t
  216. case t < 1.0/2.0: return q
  217. case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
  218. }
  219. return p
  220. }
  221. r, g, b: f16
  222. if s == 0 {
  223. r = l
  224. g = l
  225. b = l
  226. } else {
  227. q := l * (1+s) if l < 0.5 else l+s - l*s
  228. p := 2*l - q
  229. r = hue_to_rgb(p, q, h + 1.0/3.0)
  230. g = hue_to_rgb(p, q, h)
  231. b = hue_to_rgb(p, q, h - 1.0/3.0)
  232. }
  233. return {r, g, b, a}
  234. }
  235. vector4_hsl_to_rgb_f32 :: proc(h, s, l: f32, a: f32 = 1) -> Vector4f32 {
  236. hue_to_rgb :: proc(p, q, t: f32) -> f32 {
  237. t := t
  238. if t < 0 { t += 1 }
  239. if t > 1 { t -= 1 }
  240. switch {
  241. case t < 1.0/6.0: return p + (q - p) * 6.0 * t
  242. case t < 1.0/2.0: return q
  243. case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
  244. }
  245. return p
  246. }
  247. r, g, b: f32
  248. if s == 0 {
  249. r = l
  250. g = l
  251. b = l
  252. } else {
  253. q := l * (1+s) if l < 0.5 else l+s - l*s
  254. p := 2*l - q
  255. r = hue_to_rgb(p, q, h + 1.0/3.0)
  256. g = hue_to_rgb(p, q, h)
  257. b = hue_to_rgb(p, q, h - 1.0/3.0)
  258. }
  259. return {r, g, b, a}
  260. }
  261. vector4_hsl_to_rgb_f64 :: proc(h, s, l: f64, a: f64 = 1) -> Vector4f64 {
  262. hue_to_rgb :: proc(p, q, t: f64) -> f64 {
  263. t := t
  264. if t < 0 { t += 1 }
  265. if t > 1 { t -= 1 }
  266. switch {
  267. case t < 1.0/6.0: return p + (q - p) * 6.0 * t
  268. case t < 1.0/2.0: return q
  269. case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
  270. }
  271. return p
  272. }
  273. r, g, b: f64
  274. if s == 0 {
  275. r = l
  276. g = l
  277. b = l
  278. } else {
  279. q := l * (1+s) if l < 0.5 else l+s - l*s
  280. p := 2*l - q
  281. r = hue_to_rgb(p, q, h + 1.0/3.0)
  282. g = hue_to_rgb(p, q, h)
  283. b = hue_to_rgb(p, q, h - 1.0/3.0)
  284. }
  285. return {r, g, b, a}
  286. }
  287. vector4_hsl_to_rgb :: proc{
  288. vector4_hsl_to_rgb_f16,
  289. vector4_hsl_to_rgb_f32,
  290. vector4_hsl_to_rgb_f64,
  291. }
  292. vector4_rgb_to_hsl_f16 :: proc(col: Vector4f16) -> Vector4f16 {
  293. r := col.x
  294. g := col.y
  295. b := col.z
  296. a := col.w
  297. v_min := min(r, g, b)
  298. v_max := max(r, g, b)
  299. h, s, l: f16
  300. h = 0.0
  301. s = 0.0
  302. l = (v_min + v_max) * 0.5
  303. if v_max != v_min {
  304. d: = v_max - v_min
  305. s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
  306. switch {
  307. case v_max == r:
  308. h = (g - b) / d + (6.0 if g < b else 0.0)
  309. case v_max == g:
  310. h = (b - r) / d + 2.0
  311. case v_max == b:
  312. h = (r - g) / d + 4.0
  313. }
  314. h *= 1.0/6.0
  315. }
  316. return {h, s, l, a}
  317. }
  318. vector4_rgb_to_hsl_f32 :: proc(col: Vector4f32) -> Vector4f32 {
  319. r := col.x
  320. g := col.y
  321. b := col.z
  322. a := col.w
  323. v_min := min(r, g, b)
  324. v_max := max(r, g, b)
  325. h, s, l: f32
  326. h = 0.0
  327. s = 0.0
  328. l = (v_min + v_max) * 0.5
  329. if v_max != v_min {
  330. d: = v_max - v_min
  331. s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
  332. switch {
  333. case v_max == r:
  334. h = (g - b) / d + (6.0 if g < b else 0.0)
  335. case v_max == g:
  336. h = (b - r) / d + 2.0
  337. case v_max == b:
  338. h = (r - g) / d + 4.0
  339. }
  340. h *= 1.0/6.0
  341. }
  342. return {h, s, l, a}
  343. }
  344. vector4_rgb_to_hsl_f64 :: proc(col: Vector4f64) -> Vector4f64 {
  345. r := col.x
  346. g := col.y
  347. b := col.z
  348. a := col.w
  349. v_min := min(r, g, b)
  350. v_max := max(r, g, b)
  351. h, s, l: f64
  352. h = 0.0
  353. s = 0.0
  354. l = (v_min + v_max) * 0.5
  355. if v_max != v_min {
  356. d: = v_max - v_min
  357. s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
  358. switch {
  359. case v_max == r:
  360. h = (g - b) / d + (6.0 if g < b else 0.0)
  361. case v_max == g:
  362. h = (b - r) / d + 2.0
  363. case v_max == b:
  364. h = (r - g) / d + 4.0
  365. }
  366. h *= 1.0/6.0
  367. }
  368. return {h, s, l, a}
  369. }
  370. vector4_rgb_to_hsl :: proc{
  371. vector4_rgb_to_hsl_f16,
  372. vector4_rgb_to_hsl_f32,
  373. vector4_rgb_to_hsl_f64,
  374. }
  375. quaternion_angle_axis_f16 :: proc(angle_radians: f16, axis: Vector3f16) -> (q: Quaternionf16) {
  376. t := angle_radians*0.5
  377. v := normalize(axis) * math.sin(t)
  378. q.x = v.x
  379. q.y = v.y
  380. q.z = v.z
  381. q.w = math.cos(t)
  382. return
  383. }
  384. quaternion_angle_axis_f32 :: proc(angle_radians: f32, axis: Vector3f32) -> (q: Quaternionf32) {
  385. t := angle_radians*0.5
  386. v := normalize(axis) * math.sin(t)
  387. q.x = v.x
  388. q.y = v.y
  389. q.z = v.z
  390. q.w = math.cos(t)
  391. return
  392. }
  393. quaternion_angle_axis_f64 :: proc(angle_radians: f64, axis: Vector3f64) -> (q: Quaternionf64) {
  394. t := angle_radians*0.5
  395. v := normalize(axis) * math.sin(t)
  396. q.x = v.x
  397. q.y = v.y
  398. q.z = v.z
  399. q.w = math.cos(t)
  400. return
  401. }
  402. quaternion_angle_axis :: proc{
  403. quaternion_angle_axis_f16,
  404. quaternion_angle_axis_f32,
  405. quaternion_angle_axis_f64,
  406. }
  407. angle_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
  408. if abs(q.w) > math.SQRT_THREE*0.5 {
  409. return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
  410. }
  411. return math.cos(q.x) * 2
  412. }
  413. angle_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
  414. if abs(q.w) > math.SQRT_THREE*0.5 {
  415. return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
  416. }
  417. return math.cos(q.x) * 2
  418. }
  419. angle_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
  420. if abs(q.w) > math.SQRT_THREE*0.5 {
  421. return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
  422. }
  423. return math.cos(q.x) * 2
  424. }
  425. angle_from_quaternion :: proc{
  426. angle_from_quaternion_f16,
  427. angle_from_quaternion_f32,
  428. angle_from_quaternion_f64,
  429. }
  430. axis_from_quaternion_f16 :: proc(q: Quaternionf16) -> Vector3f16 {
  431. t1 := 1 - q.w*q.w
  432. if t1 < 0 {
  433. return {0, 0, 1}
  434. }
  435. t2 := 1.0 / math.sqrt(t1)
  436. return {q.x*t2, q.y*t2, q.z*t2}
  437. }
  438. axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> Vector3f32 {
  439. t1 := 1 - q.w*q.w
  440. if t1 < 0 {
  441. return {0, 0, 1}
  442. }
  443. t2 := 1.0 / math.sqrt(t1)
  444. return {q.x*t2, q.y*t2, q.z*t2}
  445. }
  446. axis_from_quaternion_f64 :: proc(q: Quaternionf64) -> Vector3f64 {
  447. t1 := 1 - q.w*q.w
  448. if t1 < 0 {
  449. return {0, 0, 1}
  450. }
  451. t2 := 1.0 / math.sqrt(t1)
  452. return {q.x*t2, q.y*t2, q.z*t2}
  453. }
  454. axis_from_quaternion :: proc{
  455. axis_from_quaternion_f16,
  456. axis_from_quaternion_f32,
  457. axis_from_quaternion_f64,
  458. }
  459. angle_axis_from_quaternion_f16 :: proc(q: Quaternionf16) -> (angle: f16, axis: Vector3f16) {
  460. angle = angle_from_quaternion(q)
  461. axis = axis_from_quaternion(q)
  462. return
  463. }
  464. angle_axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> (angle: f32, axis: Vector3f32) {
  465. angle = angle_from_quaternion(q)
  466. axis = axis_from_quaternion(q)
  467. return
  468. }
  469. angle_axis_from_quaternion_f64 :: proc(q: Quaternionf64) -> (angle: f64, axis: Vector3f64) {
  470. angle = angle_from_quaternion(q)
  471. axis = axis_from_quaternion(q)
  472. return
  473. }
  474. angle_axis_from_quaternion :: proc {
  475. angle_axis_from_quaternion_f16,
  476. angle_axis_from_quaternion_f32,
  477. angle_axis_from_quaternion_f64,
  478. }
  479. quaternion_from_forward_and_up_f16 :: proc(forward, up: Vector3f16) -> Quaternionf16 {
  480. f := normalize(forward)
  481. s := normalize(cross(f, up))
  482. u := cross(s, f)
  483. m := Matrix3f16{
  484. +s.x, +s.y, +s.z,
  485. +u.x, +u.y, +u.z,
  486. -f.x, -f.y, -f.z,
  487. }
  488. tr := trace(m)
  489. q: Quaternionf16
  490. switch {
  491. case tr > 0:
  492. S := 2 * math.sqrt(1 + tr)
  493. q.w = 0.25 * S
  494. q.x = (m[1, 2] - m[2, 1]) / S
  495. q.y = (m[2, 0] - m[0, 2]) / S
  496. q.z = (m[0, 1] - m[1, 0]) / S
  497. case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]):
  498. S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2])
  499. q.w = (m[1, 2] - m[2, 1]) / S
  500. q.x = 0.25 * S
  501. q.y = (m[1, 0] + m[0, 1]) / S
  502. q.z = (m[2, 0] + m[0, 2]) / S
  503. case m[1, 1] > m[2, 2]:
  504. S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2])
  505. q.w = (m[2, 0] - m[0, 2]) / S
  506. q.x = (m[1, 0] + m[0, 1]) / S
  507. q.y = 0.25 * S
  508. q.z = (m[2, 1] + m[1, 2]) / S
  509. case:
  510. S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1])
  511. q.w = (m[0, 1] - m[1, 0]) / S
  512. q.x = (m[2, 0] - m[0, 2]) / S
  513. q.y = (m[2, 1] + m[1, 2]) / S
  514. q.z = 0.25 * S
  515. }
  516. return normalize(q)
  517. }
  518. quaternion_from_forward_and_up_f32 :: proc(forward, up: Vector3f32) -> Quaternionf32 {
  519. f := normalize(forward)
  520. s := normalize(cross(f, up))
  521. u := cross(s, f)
  522. m := Matrix3f32{
  523. +s.x, +s.y, +s.z,
  524. +u.x, +u.y, +u.z,
  525. -f.x, -f.y, -f.z,
  526. }
  527. tr := trace(m)
  528. q: Quaternionf32
  529. switch {
  530. case tr > 0:
  531. S := 2 * math.sqrt(1 + tr)
  532. q.w = 0.25 * S
  533. q.x = (m[1, 2] - m[2, 1]) / S
  534. q.y = (m[2, 0] - m[0, 2]) / S
  535. q.z = (m[0, 1] - m[1, 0]) / S
  536. case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]):
  537. S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2])
  538. q.w = (m[1, 2] - m[2, 1]) / S
  539. q.x = 0.25 * S
  540. q.y = (m[1, 0] + m[0, 1]) / S
  541. q.z = (m[2, 0] + m[0, 2]) / S
  542. case m[1, 1] > m[2, 2]:
  543. S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2])
  544. q.w = (m[2, 0] - m[0, 2]) / S
  545. q.x = (m[1, 0] + m[0, 1]) / S
  546. q.y = 0.25 * S
  547. q.z = (m[2, 1] + m[1, 2]) / S
  548. case:
  549. S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1])
  550. q.w = (m[0, 1] - m[1, 0]) / S
  551. q.x = (m[2, 0] - m[0, 2]) / S
  552. q.y = (m[2, 1] + m[1, 2]) / S
  553. q.z = 0.25 * S
  554. }
  555. return normalize(q)
  556. }
  557. quaternion_from_forward_and_up_f64 :: proc(forward, up: Vector3f64) -> Quaternionf64 {
  558. f := normalize(forward)
  559. s := normalize(cross(f, up))
  560. u := cross(s, f)
  561. m := Matrix3f64{
  562. +s.x, +s.y, +s.z,
  563. +u.x, +u.y, +u.z,
  564. -f.x, -f.y, -f.z,
  565. }
  566. tr := trace(m)
  567. q: Quaternionf64
  568. switch {
  569. case tr > 0:
  570. S := 2 * math.sqrt(1 + tr)
  571. q.w = 0.25 * S
  572. q.x = (m[1, 2] - m[2, 1]) / S
  573. q.y = (m[2, 0] - m[0, 2]) / S
  574. q.z = (m[0, 1] - m[1, 0]) / S
  575. case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]):
  576. S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2])
  577. q.w = (m[1, 2] - m[2, 1]) / S
  578. q.x = 0.25 * S
  579. q.y = (m[1, 0] + m[0, 1]) / S
  580. q.z = (m[2, 0] + m[0, 2]) / S
  581. case m[1, 1] > m[2, 2]:
  582. S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2])
  583. q.w = (m[2, 0] - m[0, 2]) / S
  584. q.x = (m[1, 0] + m[0, 1]) / S
  585. q.y = 0.25 * S
  586. q.z = (m[2, 1] + m[1, 2]) / S
  587. case:
  588. S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1])
  589. q.w = (m[0, 1] - m[1, 0]) / S
  590. q.x = (m[2, 0] - m[0, 2]) / S
  591. q.y = (m[2, 1] + m[1, 2]) / S
  592. q.z = 0.25 * S
  593. }
  594. return normalize(q)
  595. }
  596. quaternion_from_forward_and_up :: proc{
  597. quaternion_from_forward_and_up_f16,
  598. quaternion_from_forward_and_up_f32,
  599. quaternion_from_forward_and_up_f64,
  600. }
  601. quaternion_look_at_f16 :: proc(eye, centre: Vector3f16, up: Vector3f16) -> Quaternionf16 {
  602. return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
  603. }
  604. quaternion_look_at_f32 :: proc(eye, centre: Vector3f32, up: Vector3f32) -> Quaternionf32 {
  605. return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
  606. }
  607. quaternion_look_at_f64 :: proc(eye, centre: Vector3f64, up: Vector3f64) -> Quaternionf64 {
  608. return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
  609. }
  610. quaternion_look_at :: proc{
  611. quaternion_look_at_f16,
  612. quaternion_look_at_f32,
  613. quaternion_look_at_f64,
  614. }
  615. quaternion_nlerp_f16 :: proc(a, b: Quaternionf16, t: f16) -> (c: Quaternionf16) {
  616. c.x = a.x + (b.x-a.x)*t
  617. c.y = a.y + (b.y-a.y)*t
  618. c.z = a.z + (b.z-a.z)*t
  619. c.w = a.w + (b.w-a.w)*t
  620. return normalize(c)
  621. }
  622. quaternion_nlerp_f32 :: proc(a, b: Quaternionf32, t: f32) -> (c: Quaternionf32) {
  623. c.x = a.x + (b.x-a.x)*t
  624. c.y = a.y + (b.y-a.y)*t
  625. c.z = a.z + (b.z-a.z)*t
  626. c.w = a.w + (b.w-a.w)*t
  627. return normalize(c)
  628. }
  629. quaternion_nlerp_f64 :: proc(a, b: Quaternionf64, t: f64) -> (c: Quaternionf64) {
  630. c.x = a.x + (b.x-a.x)*t
  631. c.y = a.y + (b.y-a.y)*t
  632. c.z = a.z + (b.z-a.z)*t
  633. c.w = a.w + (b.w-a.w)*t
  634. return normalize(c)
  635. }
  636. quaternion_nlerp :: proc{
  637. quaternion_nlerp_f16,
  638. quaternion_nlerp_f32,
  639. quaternion_nlerp_f64,
  640. }
  641. quaternion_slerp_f16 :: proc(x, y: Quaternionf16, t: f16) -> (q: Quaternionf16) {
  642. a, b := x, y
  643. cos_angle := dot(a, b)
  644. if cos_angle < 0 {
  645. b = -b
  646. cos_angle = -cos_angle
  647. }
  648. if cos_angle > 1 - F32_EPSILON {
  649. q.x = a.x + (b.x-a.x)*t
  650. q.y = a.y + (b.y-a.y)*t
  651. q.z = a.z + (b.z-a.z)*t
  652. q.w = a.w + (b.w-a.w)*t
  653. return
  654. }
  655. angle := math.acos(cos_angle)
  656. sin_angle := math.sin(angle)
  657. factor_a := math.sin((1-t) * angle) / sin_angle
  658. factor_b := math.sin(t * angle) / sin_angle
  659. q.x = factor_a * a.x + factor_b * b.x
  660. q.y = factor_a * a.y + factor_b * b.y
  661. q.z = factor_a * a.z + factor_b * b.z
  662. q.w = factor_a * a.w + factor_b * b.w
  663. return
  664. }
  665. quaternion_slerp_f32 :: proc(x, y: Quaternionf32, t: f32) -> (q: Quaternionf32) {
  666. a, b := x, y
  667. cos_angle := dot(a, b)
  668. if cos_angle < 0 {
  669. b = -b
  670. cos_angle = -cos_angle
  671. }
  672. if cos_angle > 1 - F32_EPSILON {
  673. q.x = a.x + (b.x-a.x)*t
  674. q.y = a.y + (b.y-a.y)*t
  675. q.z = a.z + (b.z-a.z)*t
  676. q.w = a.w + (b.w-a.w)*t
  677. return
  678. }
  679. angle := math.acos(cos_angle)
  680. sin_angle := math.sin(angle)
  681. factor_a := math.sin((1-t) * angle) / sin_angle
  682. factor_b := math.sin(t * angle) / sin_angle
  683. q.x = factor_a * a.x + factor_b * b.x
  684. q.y = factor_a * a.y + factor_b * b.y
  685. q.z = factor_a * a.z + factor_b * b.z
  686. q.w = factor_a * a.w + factor_b * b.w
  687. return
  688. }
  689. quaternion_slerp_f64 :: proc(x, y: Quaternionf64, t: f64) -> (q: Quaternionf64) {
  690. a, b := x, y
  691. cos_angle := dot(a, b)
  692. if cos_angle < 0 {
  693. b = -b
  694. cos_angle = -cos_angle
  695. }
  696. if cos_angle > 1 - F64_EPSILON {
  697. q.x = a.x + (b.x-a.x)*t
  698. q.y = a.y + (b.y-a.y)*t
  699. q.z = a.z + (b.z-a.z)*t
  700. q.w = a.w + (b.w-a.w)*t
  701. return
  702. }
  703. angle := math.acos(cos_angle)
  704. sin_angle := math.sin(angle)
  705. factor_a := math.sin((1-t) * angle) / sin_angle
  706. factor_b := math.sin(t * angle) / sin_angle
  707. q.x = factor_a * a.x + factor_b * b.x
  708. q.y = factor_a * a.y + factor_b * b.y
  709. q.z = factor_a * a.z + factor_b * b.z
  710. q.w = factor_a * a.w + factor_b * b.w
  711. return
  712. }
  713. quaternion_slerp :: proc{
  714. quaternion_slerp_f16,
  715. quaternion_slerp_f32,
  716. quaternion_slerp_f64,
  717. }
  718. quaternion_squad_f16 :: proc(q1, q2, s1, s2: Quaternionf16, h: f16) -> Quaternionf16 {
  719. slerp :: quaternion_slerp
  720. return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
  721. }
  722. quaternion_squad_f32 :: proc(q1, q2, s1, s2: Quaternionf32, h: f32) -> Quaternionf32 {
  723. slerp :: quaternion_slerp
  724. return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
  725. }
  726. quaternion_squad_f64 :: proc(q1, q2, s1, s2: Quaternionf64, h: f64) -> Quaternionf64 {
  727. slerp :: quaternion_slerp
  728. return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
  729. }
  730. quaternion_squad :: proc{
  731. quaternion_squad_f16,
  732. quaternion_squad_f32,
  733. quaternion_squad_f64,
  734. }
  735. quaternion_from_matrix4_f16 :: proc(m: Matrix4f16) -> (q: Quaternionf16) {
  736. m3: Matrix3f16 = ---
  737. m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  738. m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  739. m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  740. return quaternion_from_matrix3(m3)
  741. }
  742. quaternion_from_matrix4_f32 :: proc(m: Matrix4f32) -> (q: Quaternionf32) {
  743. m3: Matrix3f32 = ---
  744. m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  745. m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  746. m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  747. return quaternion_from_matrix3(m3)
  748. }
  749. quaternion_from_matrix4_f64 :: proc(m: Matrix4f64) -> (q: Quaternionf64) {
  750. m3: Matrix3f64 = ---
  751. m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  752. m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  753. m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  754. return quaternion_from_matrix3(m3)
  755. }
  756. quaternion_from_matrix4 :: proc{
  757. quaternion_from_matrix4_f16,
  758. quaternion_from_matrix4_f32,
  759. quaternion_from_matrix4_f64,
  760. }
  761. quaternion_from_matrix3_f16 :: proc(m: Matrix3f16) -> (q: Quaternionf16) {
  762. four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2]
  763. four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2]
  764. four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1]
  765. four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2]
  766. biggest_index := 0
  767. four_biggest_squared_minus_1 := four_w_squared_minus_1
  768. if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
  769. four_biggest_squared_minus_1 = four_x_squared_minus_1
  770. biggest_index = 1
  771. }
  772. if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
  773. four_biggest_squared_minus_1 = four_y_squared_minus_1
  774. biggest_index = 2
  775. }
  776. if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
  777. four_biggest_squared_minus_1 = four_z_squared_minus_1
  778. biggest_index = 3
  779. }
  780. biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
  781. mult := 0.25 / biggest_val
  782. q = 1
  783. switch biggest_index {
  784. case 0:
  785. q.w = biggest_val
  786. q.x = (m[2, 1] - m[1, 2]) * mult
  787. q.y = (m[0, 2] - m[2, 0]) * mult
  788. q.z = (m[1, 0] - m[0, 1]) * mult
  789. case 1:
  790. q.w = (m[2, 1] - m[1, 2]) * mult
  791. q.x = biggest_val
  792. q.y = (m[1, 0] + m[0, 1]) * mult
  793. q.z = (m[0, 2] + m[2, 0]) * mult
  794. case 2:
  795. q.w = (m[0, 2] - m[2, 0]) * mult
  796. q.x = (m[1, 0] + m[0, 1]) * mult
  797. q.y = biggest_val
  798. q.z = (m[2, 1] + m[1, 2]) * mult
  799. case 3:
  800. q.w = (m[1, 0] - m[0, 1]) * mult
  801. q.x = (m[0, 2] + m[2, 0]) * mult
  802. q.y = (m[2, 1] + m[1, 2]) * mult
  803. q.z = biggest_val
  804. }
  805. return
  806. }
  807. quaternion_from_matrix3_f32 :: proc(m: Matrix3f32) -> (q: Quaternionf32) {
  808. four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2]
  809. four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2]
  810. four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1]
  811. four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2]
  812. biggest_index := 0
  813. four_biggest_squared_minus_1 := four_w_squared_minus_1
  814. if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
  815. four_biggest_squared_minus_1 = four_x_squared_minus_1
  816. biggest_index = 1
  817. }
  818. if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
  819. four_biggest_squared_minus_1 = four_y_squared_minus_1
  820. biggest_index = 2
  821. }
  822. if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
  823. four_biggest_squared_minus_1 = four_z_squared_minus_1
  824. biggest_index = 3
  825. }
  826. biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
  827. mult := 0.25 / biggest_val
  828. q = 1
  829. switch biggest_index {
  830. case 0:
  831. q.w = biggest_val
  832. q.x = (m[2, 1] - m[1, 2]) * mult
  833. q.y = (m[0, 2] - m[2, 0]) * mult
  834. q.z = (m[1, 0] - m[0, 1]) * mult
  835. case 1:
  836. q.w = (m[2, 1] - m[1, 2]) * mult
  837. q.x = biggest_val
  838. q.y = (m[1, 0] + m[0, 1]) * mult
  839. q.z = (m[0, 2] + m[2, 0]) * mult
  840. case 2:
  841. q.w = (m[0, 2] - m[2, 0]) * mult
  842. q.x = (m[1, 0] + m[0, 1]) * mult
  843. q.y = biggest_val
  844. q.z = (m[2, 1] + m[1, 2]) * mult
  845. case 3:
  846. q.w = (m[1, 0] - m[0, 1]) * mult
  847. q.x = (m[0, 2] + m[2, 0]) * mult
  848. q.y = (m[2, 1] + m[1, 2]) * mult
  849. q.z = biggest_val
  850. }
  851. return
  852. }
  853. quaternion_from_matrix3_f64 :: proc(m: Matrix3f64) -> (q: Quaternionf64) {
  854. four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2]
  855. four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2]
  856. four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1]
  857. four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2]
  858. biggest_index := 0
  859. four_biggest_squared_minus_1 := four_w_squared_minus_1
  860. if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
  861. four_biggest_squared_minus_1 = four_x_squared_minus_1
  862. biggest_index = 1
  863. }
  864. if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
  865. four_biggest_squared_minus_1 = four_y_squared_minus_1
  866. biggest_index = 2
  867. }
  868. if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
  869. four_biggest_squared_minus_1 = four_z_squared_minus_1
  870. biggest_index = 3
  871. }
  872. biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
  873. mult := 0.25 / biggest_val
  874. q = 1
  875. switch biggest_index {
  876. case 0:
  877. q.w = biggest_val
  878. q.x = (m[2, 1] - m[1, 2]) * mult
  879. q.y = (m[0, 2] - m[2, 0]) * mult
  880. q.z = (m[1, 0] - m[0, 1]) * mult
  881. case 1:
  882. q.w = (m[2, 1] - m[1, 2]) * mult
  883. q.x = biggest_val
  884. q.y = (m[1, 0] + m[0, 1]) * mult
  885. q.z = (m[0, 2] + m[2, 0]) * mult
  886. case 2:
  887. q.w = (m[0, 2] - m[2, 0]) * mult
  888. q.x = (m[1, 0] + m[0, 1]) * mult
  889. q.y = biggest_val
  890. q.z = (m[2, 1] + m[1, 2]) * mult
  891. case 3:
  892. q.w = (m[1, 0] - m[0, 1]) * mult
  893. q.x = (m[0, 2] + m[2, 0]) * mult
  894. q.y = (m[2, 1] + m[1, 2]) * mult
  895. q.z = biggest_val
  896. }
  897. return
  898. }
  899. quaternion_from_matrix3 :: proc{
  900. quaternion_from_matrix3_f16,
  901. quaternion_from_matrix3_f32,
  902. quaternion_from_matrix3_f64,
  903. }
  904. quaternion_between_two_vector3_f16 :: proc(from, to: Vector3f16) -> (q: Quaternionf16) {
  905. x := normalize(from)
  906. y := normalize(to)
  907. cos_theta := dot(x, y)
  908. if abs(cos_theta + 1) < 2*F32_EPSILON {
  909. v := vector3_orthogonal(x)
  910. q.x = v.x
  911. q.y = v.y
  912. q.z = v.z
  913. q.w = 0
  914. return
  915. }
  916. v := cross(x, y)
  917. w := cos_theta + 1
  918. q.w = w
  919. q.x = v.x
  920. q.y = v.y
  921. q.z = v.z
  922. return normalize(q)
  923. }
  924. quaternion_between_two_vector3_f32 :: proc(from, to: Vector3f32) -> (q: Quaternionf32) {
  925. x := normalize(from)
  926. y := normalize(to)
  927. cos_theta := dot(x, y)
  928. if abs(cos_theta + 1) < 2*F32_EPSILON {
  929. v := vector3_orthogonal(x)
  930. q.x = v.x
  931. q.y = v.y
  932. q.z = v.z
  933. q.w = 0
  934. return
  935. }
  936. v := cross(x, y)
  937. w := cos_theta + 1
  938. q.w = w
  939. q.x = v.x
  940. q.y = v.y
  941. q.z = v.z
  942. return normalize(q)
  943. }
  944. quaternion_between_two_vector3_f64 :: proc(from, to: Vector3f64) -> (q: Quaternionf64) {
  945. x := normalize(from)
  946. y := normalize(to)
  947. cos_theta := dot(x, y)
  948. if abs(cos_theta + 1) < 2*F64_EPSILON {
  949. v := vector3_orthogonal(x)
  950. q.x = v.x
  951. q.y = v.y
  952. q.z = v.z
  953. q.w = 0
  954. return
  955. }
  956. v := cross(x, y)
  957. w := cos_theta + 1
  958. q.w = w
  959. q.x = v.x
  960. q.y = v.y
  961. q.z = v.z
  962. return normalize(q)
  963. }
  964. quaternion_between_two_vector3 :: proc{
  965. quaternion_between_two_vector3_f16,
  966. quaternion_between_two_vector3_f32,
  967. quaternion_between_two_vector3_f64,
  968. }
  969. matrix2_inverse_transpose_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
  970. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  971. id := 1.0/d
  972. c[0, 0] = +m[1, 1] * id
  973. c[1, 0] = -m[1, 0] * id
  974. c[0, 1] = -m[0, 1] * id
  975. c[1, 1] = +m[0, 0] * id
  976. return c
  977. }
  978. matrix2_inverse_transpose_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
  979. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  980. id := 1.0/d
  981. c[0, 0] = +m[1, 1] * id
  982. c[1, 0] = -m[1, 0] * id
  983. c[0, 1] = -m[0, 1] * id
  984. c[1, 1] = +m[0, 0] * id
  985. return c
  986. }
  987. matrix2_inverse_transpose_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
  988. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  989. id := 1.0/d
  990. c[0, 0] = +m[1, 1] * id
  991. c[1, 0] = -m[1, 0] * id
  992. c[0, 1] = -m[0, 1] * id
  993. c[1, 1] = +m[0, 0] * id
  994. return c
  995. }
  996. matrix2_inverse_transpose :: proc{
  997. matrix2_inverse_transpose_f16,
  998. matrix2_inverse_transpose_f32,
  999. matrix2_inverse_transpose_f64,
  1000. }
  1001. matrix2_determinant_f16 :: proc(m: Matrix2f16) -> f16 {
  1002. return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1003. }
  1004. matrix2_determinant_f32 :: proc(m: Matrix2f32) -> f32 {
  1005. return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1006. }
  1007. matrix2_determinant_f64 :: proc(m: Matrix2f64) -> f64 {
  1008. return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1009. }
  1010. matrix2_determinant :: proc{
  1011. matrix2_determinant_f16,
  1012. matrix2_determinant_f32,
  1013. matrix2_determinant_f64,
  1014. }
  1015. matrix2_inverse_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
  1016. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1017. id := 1.0/d
  1018. c[0, 0] = +m[1, 1] * id
  1019. c[0, 1] = -m[1, 0] * id
  1020. c[1, 0] = -m[0, 1] * id
  1021. c[1, 1] = +m[0, 0] * id
  1022. return c
  1023. }
  1024. matrix2_inverse_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
  1025. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1026. id := 1.0/d
  1027. c[0, 0] = +m[1, 1] * id
  1028. c[0, 1] = -m[1, 0] * id
  1029. c[1, 0] = -m[0, 1] * id
  1030. c[1, 1] = +m[0, 0] * id
  1031. return c
  1032. }
  1033. matrix2_inverse_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
  1034. d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
  1035. id := 1.0/d
  1036. c[0, 0] = +m[1, 1] * id
  1037. c[0, 1] = -m[1, 0] * id
  1038. c[1, 0] = -m[0, 1] * id
  1039. c[1, 1] = +m[0, 0] * id
  1040. return c
  1041. }
  1042. matrix2_inverse :: proc{
  1043. matrix2_inverse_f16,
  1044. matrix2_inverse_f32,
  1045. matrix2_inverse_f64,
  1046. }
  1047. matrix2_adjoint_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
  1048. c[0, 0] = +m[1, 1]
  1049. c[1, 0] = -m[0, 1]
  1050. c[0, 1] = -m[1, 0]
  1051. c[1, 1] = +m[0, 0]
  1052. return c
  1053. }
  1054. matrix2_adjoint_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
  1055. c[0, 0] = +m[1, 1]
  1056. c[1, 0] = -m[0, 1]
  1057. c[0, 1] = -m[1, 0]
  1058. c[1, 1] = +m[0, 0]
  1059. return c
  1060. }
  1061. matrix2_adjoint_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
  1062. c[0, 0] = +m[1, 1]
  1063. c[1, 0] = -m[0, 1]
  1064. c[0, 1] = -m[1, 0]
  1065. c[1, 1] = +m[0, 0]
  1066. return c
  1067. }
  1068. matrix2_adjoint :: proc{
  1069. matrix2_adjoint_f16,
  1070. matrix2_adjoint_f32,
  1071. matrix2_adjoint_f64,
  1072. }
  1073. matrix3_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix3f16) {
  1074. qxx := q.x * q.x
  1075. qyy := q.y * q.y
  1076. qzz := q.z * q.z
  1077. qxz := q.x * q.z
  1078. qxy := q.x * q.y
  1079. qyz := q.y * q.z
  1080. qwx := q.w * q.x
  1081. qwy := q.w * q.y
  1082. qwz := q.w * q.z
  1083. m[0, 0] = 1 - 2 * (qyy + qzz)
  1084. m[1, 0] = 2 * (qxy + qwz)
  1085. m[2, 0] = 2 * (qxz - qwy)
  1086. m[0, 1] = 2 * (qxy - qwz)
  1087. m[1, 1] = 1 - 2 * (qxx + qzz)
  1088. m[2, 1] = 2 * (qyz + qwx)
  1089. m[0, 2] = 2 * (qxz + qwy)
  1090. m[1, 2] = 2 * (qyz - qwx)
  1091. m[2, 2] = 1 - 2 * (qxx + qyy)
  1092. return m
  1093. }
  1094. matrix3_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix3f32) {
  1095. qxx := q.x * q.x
  1096. qyy := q.y * q.y
  1097. qzz := q.z * q.z
  1098. qxz := q.x * q.z
  1099. qxy := q.x * q.y
  1100. qyz := q.y * q.z
  1101. qwx := q.w * q.x
  1102. qwy := q.w * q.y
  1103. qwz := q.w * q.z
  1104. m[0, 0] = 1 - 2 * (qyy + qzz)
  1105. m[1, 0] = 2 * (qxy + qwz)
  1106. m[2, 0] = 2 * (qxz - qwy)
  1107. m[0, 1] = 2 * (qxy - qwz)
  1108. m[1, 1] = 1 - 2 * (qxx + qzz)
  1109. m[2, 1] = 2 * (qyz + qwx)
  1110. m[0, 2] = 2 * (qxz + qwy)
  1111. m[1, 2] = 2 * (qyz - qwx)
  1112. m[2, 2] = 1 - 2 * (qxx + qyy)
  1113. return m
  1114. }
  1115. matrix3_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix3f64) {
  1116. qxx := q.x * q.x
  1117. qyy := q.y * q.y
  1118. qzz := q.z * q.z
  1119. qxz := q.x * q.z
  1120. qxy := q.x * q.y
  1121. qyz := q.y * q.z
  1122. qwx := q.w * q.x
  1123. qwy := q.w * q.y
  1124. qwz := q.w * q.z
  1125. m[0, 0] = 1 - 2 * (qyy + qzz)
  1126. m[1, 0] = 2 * (qxy + qwz)
  1127. m[2, 0] = 2 * (qxz - qwy)
  1128. m[0, 1] = 2 * (qxy - qwz)
  1129. m[1, 1] = 1 - 2 * (qxx + qzz)
  1130. m[2, 1] = 2 * (qyz + qwx)
  1131. m[0, 2] = 2 * (qxz + qwy)
  1132. m[1, 2] = 2 * (qyz - qwx)
  1133. m[2, 2] = 1 - 2 * (qxx + qyy)
  1134. return m
  1135. }
  1136. matrix3_from_quaternion :: proc{
  1137. matrix3_from_quaternion_f16,
  1138. matrix3_from_quaternion_f32,
  1139. matrix3_from_quaternion_f64,
  1140. }
  1141. matrix3_inverse_f16 :: proc(m: Matrix3f16) -> Matrix3f16 {
  1142. return transpose(matrix3_inverse_transpose(m))
  1143. }
  1144. matrix3_inverse_f32 :: proc(m: Matrix3f32) -> Matrix3f32 {
  1145. return transpose(matrix3_inverse_transpose(m))
  1146. }
  1147. matrix3_inverse_f64 :: proc(m: Matrix3f64) -> Matrix3f64 {
  1148. return transpose(matrix3_inverse_transpose(m))
  1149. }
  1150. matrix3_inverse :: proc{
  1151. matrix3_inverse_f16,
  1152. matrix3_inverse_f32,
  1153. matrix3_inverse_f64,
  1154. }
  1155. matrix3_determinant_f16 :: proc(m: Matrix3f16) -> f16 {
  1156. a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
  1157. b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
  1158. c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
  1159. return a + b + c
  1160. }
  1161. matrix3_determinant_f32 :: proc(m: Matrix3f32) -> f32 {
  1162. a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
  1163. b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
  1164. c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
  1165. return a + b + c
  1166. }
  1167. matrix3_determinant_f64 :: proc(m: Matrix3f64) -> f64 {
  1168. a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
  1169. b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
  1170. c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
  1171. return a + b + c
  1172. }
  1173. matrix3_determinant :: proc{
  1174. matrix3_determinant_f16,
  1175. matrix3_determinant_f32,
  1176. matrix3_determinant_f64,
  1177. }
  1178. matrix3_adjoint_f16 :: proc(m: Matrix3f16) -> (adjoint: Matrix3f16) {
  1179. adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
  1180. adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
  1181. adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
  1182. adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
  1183. adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
  1184. adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
  1185. adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
  1186. adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
  1187. adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
  1188. return adjoint
  1189. }
  1190. matrix3_adjoint_f32 :: proc(m: Matrix3f32) -> (adjoint: Matrix3f32) {
  1191. adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
  1192. adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
  1193. adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
  1194. adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
  1195. adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
  1196. adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
  1197. adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
  1198. adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
  1199. adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
  1200. return adjoint
  1201. }
  1202. matrix3_adjoint_f64 :: proc(m: Matrix3f64) -> (adjoint: Matrix3f64) {
  1203. adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
  1204. adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
  1205. adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
  1206. adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
  1207. adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
  1208. adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
  1209. adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
  1210. adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
  1211. adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
  1212. return adjoint
  1213. }
  1214. matrix3_adjoint :: proc{
  1215. matrix3_adjoint_f16,
  1216. matrix3_adjoint_f32,
  1217. matrix3_adjoint_f64,
  1218. }
  1219. matrix3_inverse_transpose_f16 :: proc(m: Matrix3f16) -> (inverse_transpose: Matrix3f16) {
  1220. return builtin.inverse_transpose(m)
  1221. }
  1222. matrix3_inverse_transpose_f32 :: proc(m: Matrix3f32) -> (inverse_transpose: Matrix3f32) {
  1223. return builtin.inverse_transpose(m)
  1224. }
  1225. matrix3_inverse_transpose_f64 :: proc(m: Matrix3f64) -> (inverse_transpose: Matrix3f64) {
  1226. return builtin.inverse_transpose(m)
  1227. }
  1228. matrix3_inverse_transpose :: proc{
  1229. matrix3_inverse_transpose_f16,
  1230. matrix3_inverse_transpose_f32,
  1231. matrix3_inverse_transpose_f64,
  1232. }
  1233. matrix3_scale_f16 :: proc(s: Vector3f16) -> (m: Matrix3f16) {
  1234. m[0, 0] = s[0]
  1235. m[1, 1] = s[1]
  1236. m[2, 2] = s[2]
  1237. return m
  1238. }
  1239. matrix3_scale_f32 :: proc(s: Vector3f32) -> (m: Matrix3f32) {
  1240. m[0, 0] = s[0]
  1241. m[1, 1] = s[1]
  1242. m[2, 2] = s[2]
  1243. return m
  1244. }
  1245. matrix3_scale_f64 :: proc(s: Vector3f64) -> (m: Matrix3f64) {
  1246. m[0, 0] = s[0]
  1247. m[1, 1] = s[1]
  1248. m[2, 2] = s[2]
  1249. return m
  1250. }
  1251. matrix3_scale :: proc{
  1252. matrix3_scale_f16,
  1253. matrix3_scale_f32,
  1254. matrix3_scale_f64,
  1255. }
  1256. matrix3_rotate_f16 :: proc(angle_radians: f16, v: Vector3f16) -> (rot: Matrix3f16) {
  1257. c := math.cos(angle_radians)
  1258. s := math.sin(angle_radians)
  1259. a := normalize(v)
  1260. t := a * (1-c)
  1261. rot[0, 0] = c + t[0]*a[0]
  1262. rot[1, 0] = 0 + t[0]*a[1] + s*a[2]
  1263. rot[2, 0] = 0 + t[0]*a[2] - s*a[1]
  1264. rot[0, 1] = 0 + t[1]*a[0] - s*a[2]
  1265. rot[1, 1] = c + t[1]*a[1]
  1266. rot[2, 1] = 0 + t[1]*a[2] + s*a[0]
  1267. rot[0, 2] = 0 + t[2]*a[0] + s*a[1]
  1268. rot[1, 2] = 0 + t[2]*a[1] - s*a[0]
  1269. rot[2, 2] = c + t[2]*a[2]
  1270. return rot
  1271. }
  1272. matrix3_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> (rot: Matrix3f32) {
  1273. c := math.cos(angle_radians)
  1274. s := math.sin(angle_radians)
  1275. a := normalize(v)
  1276. t := a * (1-c)
  1277. rot[0, 0] = c + t[0]*a[0]
  1278. rot[1, 0] = 0 + t[0]*a[1] + s*a[2]
  1279. rot[2, 0] = 0 + t[0]*a[2] - s*a[1]
  1280. rot[0, 1] = 0 + t[1]*a[0] - s*a[2]
  1281. rot[1, 1] = c + t[1]*a[1]
  1282. rot[2, 1] = 0 + t[1]*a[2] + s*a[0]
  1283. rot[0, 2] = 0 + t[2]*a[0] + s*a[1]
  1284. rot[1, 2] = 0 + t[2]*a[1] - s*a[0]
  1285. rot[2, 2] = c + t[2]*a[2]
  1286. return rot
  1287. }
  1288. matrix3_rotate_f64 :: proc(angle_radians: f64, v: Vector3f64) -> (rot: Matrix3f64) {
  1289. c := math.cos(angle_radians)
  1290. s := math.sin(angle_radians)
  1291. a := normalize(v)
  1292. t := a * (1-c)
  1293. rot[0, 0] = c + t[0]*a[0]
  1294. rot[1, 0] = 0 + t[0]*a[1] + s*a[2]
  1295. rot[2, 0] = 0 + t[0]*a[2] - s*a[1]
  1296. rot[0, 1] = 0 + t[1]*a[0] - s*a[2]
  1297. rot[1, 1] = c + t[1]*a[1]
  1298. rot[2, 1] = 0 + t[1]*a[2] + s*a[0]
  1299. rot[0, 2] = 0 + t[2]*a[0] + s*a[1]
  1300. rot[1, 2] = 0 + t[2]*a[1] - s*a[0]
  1301. rot[2, 2] = c + t[2]*a[2]
  1302. return rot
  1303. }
  1304. matrix3_rotate :: proc{
  1305. matrix3_rotate_f16,
  1306. matrix3_rotate_f32,
  1307. matrix3_rotate_f64,
  1308. }
  1309. matrix3_look_at_f16 :: proc(eye, centre, up: Vector3f16) -> Matrix3f16 {
  1310. f := normalize(centre - eye)
  1311. s := normalize(cross(f, up))
  1312. u := cross(s, f)
  1313. return Matrix3f16{
  1314. +s.x, +s.y, +s.z,
  1315. +u.x, +u.y, +u.z,
  1316. -f.x, -f.y, -f.z,
  1317. }
  1318. }
  1319. matrix3_look_at_f32 :: proc(eye, centre, up: Vector3f32) -> Matrix3f32 {
  1320. f := normalize(centre - eye)
  1321. s := normalize(cross(f, up))
  1322. u := cross(s, f)
  1323. return Matrix3f32{
  1324. +s.x, +s.y, +s.z,
  1325. +u.x, +u.y, +u.z,
  1326. -f.x, -f.y, -f.z,
  1327. }
  1328. }
  1329. matrix3_look_at_f64 :: proc(eye, centre, up: Vector3f64) -> Matrix3f64 {
  1330. f := normalize(centre - eye)
  1331. s := normalize(cross(f, up))
  1332. u := cross(s, f)
  1333. return Matrix3f64{
  1334. +s.x, +s.y, +s.z,
  1335. +u.x, +u.y, +u.z,
  1336. -f.x, -f.y, -f.z,
  1337. }
  1338. }
  1339. matrix3_look_at :: proc{
  1340. matrix3_look_at_f16,
  1341. matrix3_look_at_f32,
  1342. matrix3_look_at_f64,
  1343. }
  1344. matrix4_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix4f16) {
  1345. qxx := q.x * q.x
  1346. qyy := q.y * q.y
  1347. qzz := q.z * q.z
  1348. qxz := q.x * q.z
  1349. qxy := q.x * q.y
  1350. qyz := q.y * q.z
  1351. qwx := q.w * q.x
  1352. qwy := q.w * q.y
  1353. qwz := q.w * q.z
  1354. m[0, 0] = 1 - 2 * (qyy + qzz)
  1355. m[1, 0] = 2 * (qxy + qwz)
  1356. m[2, 0] = 2 * (qxz - qwy)
  1357. m[0, 1] = 2 * (qxy - qwz)
  1358. m[1, 1] = 1 - 2 * (qxx + qzz)
  1359. m[2, 1] = 2 * (qyz + qwx)
  1360. m[0, 2] = 2 * (qxz + qwy)
  1361. m[1, 2] = 2 * (qyz - qwx)
  1362. m[2, 2] = 1 - 2 * (qxx + qyy)
  1363. m[3, 3] = 1
  1364. return m
  1365. }
  1366. matrix4_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix4f32) {
  1367. qxx := q.x * q.x
  1368. qyy := q.y * q.y
  1369. qzz := q.z * q.z
  1370. qxz := q.x * q.z
  1371. qxy := q.x * q.y
  1372. qyz := q.y * q.z
  1373. qwx := q.w * q.x
  1374. qwy := q.w * q.y
  1375. qwz := q.w * q.z
  1376. m[0, 0] = 1 - 2 * (qyy + qzz)
  1377. m[1, 0] = 2 * (qxy + qwz)
  1378. m[2, 0] = 2 * (qxz - qwy)
  1379. m[0, 1] = 2 * (qxy - qwz)
  1380. m[1, 1] = 1 - 2 * (qxx + qzz)
  1381. m[2, 1] = 2 * (qyz + qwx)
  1382. m[0, 2] = 2 * (qxz + qwy)
  1383. m[1, 2] = 2 * (qyz - qwx)
  1384. m[2, 2] = 1 - 2 * (qxx + qyy)
  1385. m[3, 3] = 1
  1386. return m
  1387. }
  1388. matrix4_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix4f64) {
  1389. qxx := q.x * q.x
  1390. qyy := q.y * q.y
  1391. qzz := q.z * q.z
  1392. qxz := q.x * q.z
  1393. qxy := q.x * q.y
  1394. qyz := q.y * q.z
  1395. qwx := q.w * q.x
  1396. qwy := q.w * q.y
  1397. qwz := q.w * q.z
  1398. m[0, 0] = 1 - 2 * (qyy + qzz)
  1399. m[1, 0] = 2 * (qxy + qwz)
  1400. m[2, 0] = 2 * (qxz - qwy)
  1401. m[0, 1] = 2 * (qxy - qwz)
  1402. m[1, 1] = 1 - 2 * (qxx + qzz)
  1403. m[2, 1] = 2 * (qyz + qwx)
  1404. m[0, 2] = 2 * (qxz + qwy)
  1405. m[1, 2] = 2 * (qyz - qwx)
  1406. m[2, 2] = 1 - 2 * (qxx + qyy)
  1407. m[3, 3] = 1
  1408. return m
  1409. }
  1410. matrix4_from_quaternion :: proc{
  1411. matrix4_from_quaternion_f16,
  1412. matrix4_from_quaternion_f32,
  1413. matrix4_from_quaternion_f64,
  1414. }
  1415. matrix4_from_trs_f16 :: proc(t: Vector3f16, r: Quaternionf16, s: Vector3f16) -> Matrix4f16 {
  1416. translation := matrix4_translate(t)
  1417. rotation := matrix4_from_quaternion(r)
  1418. scale := matrix4_scale(s)
  1419. return mul(translation, mul(rotation, scale))
  1420. }
  1421. matrix4_from_trs_f32 :: proc(t: Vector3f32, r: Quaternionf32, s: Vector3f32) -> Matrix4f32 {
  1422. translation := matrix4_translate(t)
  1423. rotation := matrix4_from_quaternion(r)
  1424. scale := matrix4_scale(s)
  1425. return mul(translation, mul(rotation, scale))
  1426. }
  1427. matrix4_from_trs_f64 :: proc(t: Vector3f64, r: Quaternionf64, s: Vector3f64) -> Matrix4f64 {
  1428. translation := matrix4_translate(t)
  1429. rotation := matrix4_from_quaternion(r)
  1430. scale := matrix4_scale(s)
  1431. return mul(translation, mul(rotation, scale))
  1432. }
  1433. matrix4_from_trs :: proc{
  1434. matrix4_from_trs_f16,
  1435. matrix4_from_trs_f32,
  1436. matrix4_from_trs_f64,
  1437. }
  1438. matrix4_inverse_f16 :: proc(m: Matrix4f16) -> Matrix4f16 {
  1439. return transpose(matrix4_inverse_transpose(m))
  1440. }
  1441. matrix4_inverse_f32 :: proc(m: Matrix4f32) -> Matrix4f32 {
  1442. return transpose(matrix4_inverse_transpose(m))
  1443. }
  1444. matrix4_inverse_f64 :: proc(m: Matrix4f64) -> Matrix4f64 {
  1445. return transpose(matrix4_inverse_transpose(m))
  1446. }
  1447. matrix4_inverse :: proc{
  1448. matrix4_inverse_f16,
  1449. matrix4_inverse_f32,
  1450. matrix4_inverse_f64,
  1451. }
  1452. matrix4_minor_f16 :: proc(m: Matrix4f16, c, r: int) -> f16 {
  1453. cut_down: Matrix3f16
  1454. for i in 0..<3 {
  1455. col := i if i < c else i+1
  1456. for j in 0..<3 {
  1457. row := j if j < r else j+1
  1458. cut_down[i][j] = m[col][row]
  1459. }
  1460. }
  1461. return matrix3_determinant(cut_down)
  1462. }
  1463. matrix4_minor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 {
  1464. cut_down: Matrix3f32
  1465. for i in 0..<3 {
  1466. col := i if i < c else i+1
  1467. for j in 0..<3 {
  1468. row := j if j < r else j+1
  1469. cut_down[i][j] = m[col][row]
  1470. }
  1471. }
  1472. return matrix3_determinant(cut_down)
  1473. }
  1474. matrix4_minor_f64 :: proc(m: Matrix4f64, c, r: int) -> f64 {
  1475. cut_down: Matrix3f64
  1476. for i in 0..<3 {
  1477. col := i if i < c else i+1
  1478. for j in 0..<3 {
  1479. row := j if j < r else j+1
  1480. cut_down[i][j] = m[col][row]
  1481. }
  1482. }
  1483. return matrix3_determinant(cut_down)
  1484. }
  1485. matrix4_minor :: proc{
  1486. matrix4_minor_f16,
  1487. matrix4_minor_f32,
  1488. matrix4_minor_f64,
  1489. }
  1490. matrix4_cofactor_f16 :: proc(m: Matrix4f16, c, r: int) -> f16 {
  1491. sign, minor: f16
  1492. sign = 1 if (c + r) % 2 == 0 else -1
  1493. minor = matrix4_minor(m, c, r)
  1494. return sign * minor
  1495. }
  1496. matrix4_cofactor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 {
  1497. sign, minor: f32
  1498. sign = 1 if (c + r) % 2 == 0 else -1
  1499. minor = matrix4_minor(m, c, r)
  1500. return sign * minor
  1501. }
  1502. matrix4_cofactor_f64 :: proc(m: Matrix4f64, c, r: int) -> f64 {
  1503. sign, minor: f64
  1504. sign = 1 if (c + r) % 2 == 0 else -1
  1505. minor = matrix4_minor(m, c, r)
  1506. return sign * minor
  1507. }
  1508. matrix4_cofactor :: proc{
  1509. matrix4_cofactor_f16,
  1510. matrix4_cofactor_f32,
  1511. matrix4_cofactor_f64,
  1512. }
  1513. matrix4_adjoint_f16 :: proc(m: Matrix4f16) -> (adjoint: Matrix4f16) {
  1514. for i in 0..<4 {
  1515. for j in 0..<4 {
  1516. adjoint[i][j] = matrix4_cofactor(m, i, j)
  1517. }
  1518. }
  1519. return
  1520. }
  1521. matrix4_adjoint_f32 :: proc(m: Matrix4f32) -> (adjoint: Matrix4f32) {
  1522. for i in 0..<4 {
  1523. for j in 0..<4 {
  1524. adjoint[i][j] = matrix4_cofactor(m, i, j)
  1525. }
  1526. }
  1527. return
  1528. }
  1529. matrix4_adjoint_f64 :: proc(m: Matrix4f64) -> (adjoint: Matrix4f64) {
  1530. for i in 0..<4 {
  1531. for j in 0..<4 {
  1532. adjoint[i][j] = matrix4_cofactor(m, i, j)
  1533. }
  1534. }
  1535. return
  1536. }
  1537. matrix4_adjoint :: proc{
  1538. matrix4_adjoint_f16,
  1539. matrix4_adjoint_f32,
  1540. matrix4_adjoint_f64,
  1541. }
  1542. matrix4_determinant_f16 :: proc(m: Matrix4f16) -> (determinant: f16) {
  1543. adjoint := matrix4_adjoint(m)
  1544. for i in 0..<4 {
  1545. determinant += m[i][0] * adjoint[i][0]
  1546. }
  1547. return
  1548. }
  1549. matrix4_determinant_f32 :: proc(m: Matrix4f32) -> (determinant: f32) {
  1550. adjoint := matrix4_adjoint(m)
  1551. for i in 0..<4 {
  1552. determinant += m[i][0] * adjoint[i][0]
  1553. }
  1554. return
  1555. }
  1556. matrix4_determinant_f64 :: proc(m: Matrix4f64) -> (determinant: f64) {
  1557. adjoint := matrix4_adjoint(m)
  1558. for i in 0..<4 {
  1559. determinant += m[i][0] * adjoint[i][0]
  1560. }
  1561. return
  1562. }
  1563. matrix4_determinant :: proc{
  1564. matrix4_determinant_f16,
  1565. matrix4_determinant_f32,
  1566. matrix4_determinant_f64,
  1567. }
  1568. matrix4_inverse_transpose_f16 :: proc(m: Matrix4f16) -> (inverse_transpose: Matrix4f16) {
  1569. adjoint := matrix4_adjoint(m)
  1570. determinant: f16 = 0
  1571. for i in 0..<4 {
  1572. determinant += m[i][0] * adjoint[i][0]
  1573. }
  1574. inv_determinant := 1.0 / determinant
  1575. for i in 0..<4 {
  1576. for j in 0..<4 {
  1577. inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
  1578. }
  1579. }
  1580. return
  1581. }
  1582. matrix4_inverse_transpose_f32 :: proc(m: Matrix4f32) -> (inverse_transpose: Matrix4f32) {
  1583. adjoint := matrix4_adjoint(m)
  1584. determinant: f32 = 0
  1585. for i in 0..<4 {
  1586. determinant += m[i][0] * adjoint[i][0]
  1587. }
  1588. inv_determinant := 1.0 / determinant
  1589. for i in 0..<4 {
  1590. for j in 0..<4 {
  1591. inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
  1592. }
  1593. }
  1594. return
  1595. }
  1596. matrix4_inverse_transpose_f64 :: proc(m: Matrix4f64) -> (inverse_transpose: Matrix4f64) {
  1597. adjoint := matrix4_adjoint(m)
  1598. determinant: f64 = 0
  1599. for i in 0..<4 {
  1600. determinant += m[i][0] * adjoint[i][0]
  1601. }
  1602. inv_determinant := 1.0 / determinant
  1603. for i in 0..<4 {
  1604. for j in 0..<4 {
  1605. inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
  1606. }
  1607. }
  1608. return
  1609. }
  1610. matrix4_inverse_transpose :: proc{
  1611. matrix4_inverse_transpose_f16,
  1612. matrix4_inverse_transpose_f32,
  1613. matrix4_inverse_transpose_f64,
  1614. }
  1615. matrix4_translate_f16 :: proc(v: Vector3f16) -> Matrix4f16 {
  1616. m := MATRIX4F16_IDENTITY
  1617. m[3][0] = v[0]
  1618. m[3][1] = v[1]
  1619. m[3][2] = v[2]
  1620. return m
  1621. }
  1622. matrix4_translate_f32 :: proc(v: Vector3f32) -> Matrix4f32 {
  1623. m := MATRIX4F32_IDENTITY
  1624. m[3][0] = v[0]
  1625. m[3][1] = v[1]
  1626. m[3][2] = v[2]
  1627. return m
  1628. }
  1629. matrix4_translate_f64 :: proc(v: Vector3f64) -> Matrix4f64 {
  1630. m := MATRIX4F64_IDENTITY
  1631. m[3][0] = v[0]
  1632. m[3][1] = v[1]
  1633. m[3][2] = v[2]
  1634. return m
  1635. }
  1636. matrix4_translate :: proc{
  1637. matrix4_translate_f16,
  1638. matrix4_translate_f32,
  1639. matrix4_translate_f64,
  1640. }
  1641. matrix4_rotate_f16 :: proc(angle_radians: f16, v: Vector3f16) -> Matrix4f16 {
  1642. c := math.cos(angle_radians)
  1643. s := math.sin(angle_radians)
  1644. a := normalize(v)
  1645. t := a * (1-c)
  1646. rot := MATRIX4F16_IDENTITY
  1647. rot[0][0] = c + t[0]*a[0]
  1648. rot[0][1] = 0 + t[0]*a[1] + s*a[2]
  1649. rot[0][2] = 0 + t[0]*a[2] - s*a[1]
  1650. rot[0][3] = 0
  1651. rot[1][0] = 0 + t[1]*a[0] - s*a[2]
  1652. rot[1][1] = c + t[1]*a[1]
  1653. rot[1][2] = 0 + t[1]*a[2] + s*a[0]
  1654. rot[1][3] = 0
  1655. rot[2][0] = 0 + t[2]*a[0] + s*a[1]
  1656. rot[2][1] = 0 + t[2]*a[1] - s*a[0]
  1657. rot[2][2] = c + t[2]*a[2]
  1658. rot[2][3] = 0
  1659. return rot
  1660. }
  1661. matrix4_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> Matrix4f32 {
  1662. c := math.cos(angle_radians)
  1663. s := math.sin(angle_radians)
  1664. a := normalize(v)
  1665. t := a * (1-c)
  1666. rot := MATRIX4F32_IDENTITY
  1667. rot[0][0] = c + t[0]*a[0]
  1668. rot[0][1] = 0 + t[0]*a[1] + s*a[2]
  1669. rot[0][2] = 0 + t[0]*a[2] - s*a[1]
  1670. rot[0][3] = 0
  1671. rot[1][0] = 0 + t[1]*a[0] - s*a[2]
  1672. rot[1][1] = c + t[1]*a[1]
  1673. rot[1][2] = 0 + t[1]*a[2] + s*a[0]
  1674. rot[1][3] = 0
  1675. rot[2][0] = 0 + t[2]*a[0] + s*a[1]
  1676. rot[2][1] = 0 + t[2]*a[1] - s*a[0]
  1677. rot[2][2] = c + t[2]*a[2]
  1678. rot[2][3] = 0
  1679. return rot
  1680. }
  1681. matrix4_rotate_f64 :: proc(angle_radians: f64, v: Vector3f64) -> Matrix4f64 {
  1682. c := math.cos(angle_radians)
  1683. s := math.sin(angle_radians)
  1684. a := normalize(v)
  1685. t := a * (1-c)
  1686. rot := MATRIX4F64_IDENTITY
  1687. rot[0][0] = c + t[0]*a[0]
  1688. rot[0][1] = 0 + t[0]*a[1] + s*a[2]
  1689. rot[0][2] = 0 + t[0]*a[2] - s*a[1]
  1690. rot[0][3] = 0
  1691. rot[1][0] = 0 + t[1]*a[0] - s*a[2]
  1692. rot[1][1] = c + t[1]*a[1]
  1693. rot[1][2] = 0 + t[1]*a[2] + s*a[0]
  1694. rot[1][3] = 0
  1695. rot[2][0] = 0 + t[2]*a[0] + s*a[1]
  1696. rot[2][1] = 0 + t[2]*a[1] - s*a[0]
  1697. rot[2][2] = c + t[2]*a[2]
  1698. rot[2][3] = 0
  1699. return rot
  1700. }
  1701. matrix4_rotate :: proc{
  1702. matrix4_rotate_f16,
  1703. matrix4_rotate_f32,
  1704. matrix4_rotate_f64,
  1705. }
  1706. matrix4_scale_f16 :: proc(v: Vector3f16) -> (m: Matrix4f16) {
  1707. m[0][0] = v[0]
  1708. m[1][1] = v[1]
  1709. m[2][2] = v[2]
  1710. m[3][3] = 1
  1711. return
  1712. }
  1713. matrix4_scale_f32 :: proc(v: Vector3f32) -> (m: Matrix4f32) {
  1714. m[0][0] = v[0]
  1715. m[1][1] = v[1]
  1716. m[2][2] = v[2]
  1717. m[3][3] = 1
  1718. return
  1719. }
  1720. matrix4_scale_f64 :: proc(v: Vector3f64) -> (m: Matrix4f64) {
  1721. m[0][0] = v[0]
  1722. m[1][1] = v[1]
  1723. m[2][2] = v[2]
  1724. m[3][3] = 1
  1725. return
  1726. }
  1727. matrix4_scale :: proc{
  1728. matrix4_scale_f16,
  1729. matrix4_scale_f32,
  1730. matrix4_scale_f64,
  1731. }
  1732. matrix4_look_at_f16 :: proc(eye, centre, up: Vector3f16, flip_z_axis := true) -> (m: Matrix4f16) {
  1733. f := normalize(centre - eye)
  1734. s := normalize(cross(f, up))
  1735. u := cross(s, f)
  1736. fe := dot(f, eye)
  1737. return {
  1738. +s.x, +s.y, +s.z, -dot(s, eye),
  1739. +u.x, +u.y, +u.z, -dot(u, eye),
  1740. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1741. 0, 0, 0, 1,
  1742. }
  1743. }
  1744. matrix4_look_at_f32 :: proc(eye, centre, up: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) {
  1745. f := normalize(centre - eye)
  1746. s := normalize(cross(f, up))
  1747. u := cross(s, f)
  1748. fe := dot(f, eye)
  1749. return {
  1750. +s.x, +s.y, +s.z, -dot(s, eye),
  1751. +u.x, +u.y, +u.z, -dot(u, eye),
  1752. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1753. 0, 0, 0, 1,
  1754. }
  1755. }
  1756. matrix4_look_at_f64 :: proc(eye, centre, up: Vector3f64, flip_z_axis := true) -> (m: Matrix4f64) {
  1757. f := normalize(centre - eye)
  1758. s := normalize(cross(f, up))
  1759. u := cross(s, f)
  1760. fe := dot(f, eye)
  1761. return {
  1762. +s.x, +s.y, +s.z, -dot(s, eye),
  1763. +u.x, +u.y, +u.z, -dot(u, eye),
  1764. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1765. 0, 0, 0, 1,
  1766. }
  1767. }
  1768. matrix4_look_at :: proc{
  1769. matrix4_look_at_f16,
  1770. matrix4_look_at_f32,
  1771. matrix4_look_at_f64,
  1772. }
  1773. matrix4_look_at_from_fru_f16 :: proc(eye, f, r, u: Vector3f16, flip_z_axis := true) -> (m: Matrix4f16) {
  1774. f, s, u := f, r, u
  1775. f = normalize(f)
  1776. s = normalize(s)
  1777. u = normalize(u)
  1778. fe := dot(f, eye)
  1779. return {
  1780. +s.x, +s.y, +s.z, -dot(s, eye),
  1781. +u.x, +u.y, +u.z, -dot(u, eye),
  1782. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1783. 0, 0, 0, 1,
  1784. }
  1785. }
  1786. matrix4_look_at_from_fru_f32 :: proc(eye, f, r, u: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) {
  1787. f, s, u := f, r, u
  1788. f = normalize(f)
  1789. s = normalize(s)
  1790. u = normalize(u)
  1791. fe := dot(f, eye)
  1792. return {
  1793. +s.x, +s.y, +s.z, -dot(s, eye),
  1794. +u.x, +u.y, +u.z, -dot(u, eye),
  1795. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1796. 0, 0, 0, 1,
  1797. }
  1798. }
  1799. matrix4_look_at_from_fru_f64 :: proc(eye, f, r, u: Vector3f64, flip_z_axis := true) -> (m: Matrix4f64) {
  1800. f, s, u := f, r, u
  1801. f = normalize(f)
  1802. s = normalize(s)
  1803. u = normalize(u)
  1804. fe := dot(f, eye)
  1805. return {
  1806. +s.x, +s.y, +s.z, -dot(s, eye),
  1807. +u.x, +u.y, +u.z, -dot(u, eye),
  1808. -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
  1809. 0, 0, 0, 1,
  1810. }
  1811. }
  1812. matrix4_look_at_from_fru :: proc{
  1813. matrix4_look_at_from_fru_f16,
  1814. matrix4_look_at_from_fru_f32,
  1815. matrix4_look_at_from_fru_f64,
  1816. }
  1817. matrix4_perspective_f16 :: proc(fovy, aspect, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) {
  1818. tan_half_fovy := math.tan(0.5 * fovy)
  1819. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1820. m[1, 1] = 1 / (tan_half_fovy)
  1821. m[2, 2] = +(far + near) / (far - near)
  1822. m[3, 2] = +1
  1823. m[2, 3] = -2*far*near / (far - near)
  1824. if flip_z_axis {
  1825. m[2] = -m[2]
  1826. }
  1827. return
  1828. }
  1829. matrix4_perspective_f32 :: proc(fovy, aspect, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) {
  1830. tan_half_fovy := math.tan(0.5 * fovy)
  1831. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1832. m[1, 1] = 1 / (tan_half_fovy)
  1833. m[2, 2] = +(far + near) / (far - near)
  1834. m[3, 2] = +1
  1835. m[2, 3] = -2*far*near / (far - near)
  1836. if flip_z_axis {
  1837. m[2] = -m[2]
  1838. }
  1839. return
  1840. }
  1841. matrix4_perspective_f64 :: proc(fovy, aspect, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) {
  1842. tan_half_fovy := math.tan(0.5 * fovy)
  1843. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1844. m[1, 1] = 1 / (tan_half_fovy)
  1845. m[2, 2] = +(far + near) / (far - near)
  1846. m[3, 2] = +1
  1847. m[2, 3] = -2*far*near / (far - near)
  1848. if flip_z_axis {
  1849. m[2] = -m[2]
  1850. }
  1851. return
  1852. }
  1853. matrix4_perspective :: proc{
  1854. matrix4_perspective_f16,
  1855. matrix4_perspective_f32,
  1856. matrix4_perspective_f64,
  1857. }
  1858. matrix_ortho3d_f16 :: proc(left, right, bottom, top, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) {
  1859. m[0, 0] = +2 / (right - left)
  1860. m[1, 1] = +2 / (top - bottom)
  1861. m[2, 2] = +2 / (far - near)
  1862. m[0, 3] = -(right + left) / (right - left)
  1863. m[1, 3] = -(top + bottom) / (top - bottom)
  1864. m[2, 3] = -(far + near) / (far- near)
  1865. m[3, 3] = 1
  1866. if flip_z_axis {
  1867. m[2] = -m[2]
  1868. }
  1869. return
  1870. }
  1871. matrix_ortho3d_f32 :: proc(left, right, bottom, top, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) {
  1872. m[0, 0] = +2 / (right - left)
  1873. m[1, 1] = +2 / (top - bottom)
  1874. m[2, 2] = +2 / (far - near)
  1875. m[0, 3] = -(right + left) / (right - left)
  1876. m[1, 3] = -(top + bottom) / (top - bottom)
  1877. m[2, 3] = -(far + near) / (far- near)
  1878. m[3, 3] = 1
  1879. if flip_z_axis {
  1880. m[2] = -m[2]
  1881. }
  1882. return
  1883. }
  1884. matrix_ortho3d_f64 :: proc(left, right, bottom, top, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) {
  1885. m[0, 0] = +2 / (right - left)
  1886. m[1, 1] = +2 / (top - bottom)
  1887. m[2, 2] = +2 / (far - near)
  1888. m[0, 3] = -(right + left) / (right - left)
  1889. m[1, 3] = -(top + bottom) / (top - bottom)
  1890. m[2, 3] = -(far + near) / (far- near)
  1891. m[3, 3] = 1
  1892. if flip_z_axis {
  1893. m[2] = -m[2]
  1894. }
  1895. return
  1896. }
  1897. matrix_ortho3d :: proc{
  1898. matrix_ortho3d_f16,
  1899. matrix_ortho3d_f32,
  1900. matrix_ortho3d_f64,
  1901. }
  1902. matrix4_infinite_perspective_f16 :: proc(fovy, aspect, near: f16, flip_z_axis := true) -> (m: Matrix4f16) {
  1903. tan_half_fovy := math.tan(0.5 * fovy)
  1904. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1905. m[1, 1] = 1 / (tan_half_fovy)
  1906. m[2, 2] = +1
  1907. m[3, 2] = +1
  1908. m[2, 3] = -2*near
  1909. if flip_z_axis {
  1910. m[2] = -m[2]
  1911. }
  1912. return
  1913. }
  1914. matrix4_infinite_perspective_f32 :: proc(fovy, aspect, near: f32, flip_z_axis := true) -> (m: Matrix4f32) {
  1915. tan_half_fovy := math.tan(0.5 * fovy)
  1916. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1917. m[1, 1] = 1 / (tan_half_fovy)
  1918. m[2, 2] = +1
  1919. m[3, 2] = +1
  1920. m[2, 3] = -2*near
  1921. if flip_z_axis {
  1922. m[2] = -m[2]
  1923. }
  1924. return
  1925. }
  1926. matrix4_infinite_perspective_f64 :: proc(fovy, aspect, near: f64, flip_z_axis := true) -> (m: Matrix4f64) {
  1927. tan_half_fovy := math.tan(0.5 * fovy)
  1928. m[0, 0] = 1 / (aspect*tan_half_fovy)
  1929. m[1, 1] = 1 / (tan_half_fovy)
  1930. m[2, 2] = +1
  1931. m[3, 2] = +1
  1932. m[2, 3] = -2*near
  1933. if flip_z_axis {
  1934. m[2] = -m[2]
  1935. }
  1936. return
  1937. }
  1938. matrix4_infinite_perspective :: proc{
  1939. matrix4_infinite_perspective_f16,
  1940. matrix4_infinite_perspective_f32,
  1941. matrix4_infinite_perspective_f64,
  1942. }
  1943. matrix2_from_scalar_f16 :: proc(f: f16) -> (m: Matrix2f16) {
  1944. m[0, 0], m[1, 0] = f, 0
  1945. m[0, 1], m[1, 1] = 0, f
  1946. return
  1947. }
  1948. matrix2_from_scalar_f32 :: proc(f: f32) -> (m: Matrix2f32) {
  1949. m[0, 0], m[1, 0] = f, 0
  1950. m[0, 1], m[1, 1] = 0, f
  1951. return
  1952. }
  1953. matrix2_from_scalar_f64 :: proc(f: f64) -> (m: Matrix2f64) {
  1954. m[0, 0], m[1, 0] = f, 0
  1955. m[0, 1], m[1, 1] = 0, f
  1956. return
  1957. }
  1958. matrix2_from_scalar :: proc{
  1959. matrix2_from_scalar_f16,
  1960. matrix2_from_scalar_f32,
  1961. matrix2_from_scalar_f64,
  1962. }
  1963. matrix3_from_scalar_f16 :: proc(f: f16) -> (m: Matrix3f16) {
  1964. m[0, 0], m[1, 0], m[2, 0] = f, 0, 0
  1965. m[0, 1], m[1, 1], m[2, 1] = 0, f, 0
  1966. m[0, 2], m[1, 2], m[2, 2] = 0, 0, f
  1967. return
  1968. }
  1969. matrix3_from_scalar_f32 :: proc(f: f32) -> (m: Matrix3f32) {
  1970. m[0, 0], m[1, 0], m[2, 0] = f, 0, 0
  1971. m[0, 1], m[1, 1], m[2, 1] = 0, f, 0
  1972. m[0, 2], m[1, 2], m[2, 2] = 0, 0, f
  1973. return
  1974. }
  1975. matrix3_from_scalar_f64 :: proc(f: f64) -> (m: Matrix3f64) {
  1976. m[0, 0], m[1, 0], m[2, 0] = f, 0, 0
  1977. m[0, 1], m[1, 1], m[2, 1] = 0, f, 0
  1978. m[0, 2], m[1, 2], m[2, 2] = 0, 0, f
  1979. return
  1980. }
  1981. matrix3_from_scalar :: proc{
  1982. matrix3_from_scalar_f16,
  1983. matrix3_from_scalar_f32,
  1984. matrix3_from_scalar_f64,
  1985. }
  1986. matrix4_from_scalar_f16 :: proc(f: f16) -> (m: Matrix4f16) {
  1987. m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0
  1988. m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0
  1989. m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0
  1990. m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f
  1991. return
  1992. }
  1993. matrix4_from_scalar_f32 :: proc(f: f32) -> (m: Matrix4f32) {
  1994. m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0
  1995. m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0
  1996. m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0
  1997. m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f
  1998. return
  1999. }
  2000. matrix4_from_scalar_f64 :: proc(f: f64) -> (m: Matrix4f64) {
  2001. m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0
  2002. m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0
  2003. m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0
  2004. m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f
  2005. return
  2006. }
  2007. matrix4_from_scalar :: proc{
  2008. matrix4_from_scalar_f16,
  2009. matrix4_from_scalar_f32,
  2010. matrix4_from_scalar_f64,
  2011. }
  2012. matrix2_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix2f16) {
  2013. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2014. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2015. return
  2016. }
  2017. matrix2_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix2f32) {
  2018. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2019. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2020. return
  2021. }
  2022. matrix2_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix2f64) {
  2023. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2024. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2025. return
  2026. }
  2027. matrix2_from_matrix3 :: proc{
  2028. matrix2_from_matrix3_f16,
  2029. matrix2_from_matrix3_f32,
  2030. matrix2_from_matrix3_f64,
  2031. }
  2032. matrix2_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix2f16) {
  2033. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2034. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2035. return
  2036. }
  2037. matrix2_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix2f32) {
  2038. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2039. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2040. return
  2041. }
  2042. matrix2_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix2f64) {
  2043. r[0, 0], r[1, 0] = m[0, 0], m[1, 0]
  2044. r[0, 1], r[1, 1] = m[0, 1], m[1, 1]
  2045. return
  2046. }
  2047. matrix2_from_matrix4 :: proc{
  2048. matrix2_from_matrix4_f16,
  2049. matrix2_from_matrix4_f32,
  2050. matrix2_from_matrix4_f64,
  2051. }
  2052. matrix3_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix3f16) {
  2053. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0
  2054. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0
  2055. r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1
  2056. return
  2057. }
  2058. matrix3_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix3f32) {
  2059. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0
  2060. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0
  2061. r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1
  2062. return
  2063. }
  2064. matrix3_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix3f64) {
  2065. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0
  2066. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0
  2067. r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1
  2068. return
  2069. }
  2070. matrix3_from_matrix2 :: proc{
  2071. matrix3_from_matrix2_f16,
  2072. matrix3_from_matrix2_f32,
  2073. matrix3_from_matrix2_f64,
  2074. }
  2075. matrix3_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix3f16) {
  2076. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  2077. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  2078. r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  2079. return
  2080. }
  2081. matrix3_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix3f32) {
  2082. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  2083. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  2084. r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  2085. return
  2086. }
  2087. matrix3_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix3f64) {
  2088. r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0]
  2089. r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1]
  2090. r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2]
  2091. return
  2092. }
  2093. matrix3_from_matrix4 :: proc{
  2094. matrix3_from_matrix4_f16,
  2095. matrix3_from_matrix4_f32,
  2096. matrix3_from_matrix4_f64,
  2097. }
  2098. matrix4_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix4f16) {
  2099. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0
  2100. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0
  2101. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0
  2102. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2103. return
  2104. }
  2105. matrix4_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix4f32) {
  2106. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0
  2107. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0
  2108. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0
  2109. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2110. return
  2111. }
  2112. matrix4_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix4f64) {
  2113. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0
  2114. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0
  2115. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0
  2116. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2117. return
  2118. }
  2119. matrix4_from_matrix2 :: proc{
  2120. matrix4_from_matrix2_f16,
  2121. matrix4_from_matrix2_f32,
  2122. matrix4_from_matrix2_f64,
  2123. }
  2124. matrix4_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix4f16) {
  2125. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0
  2126. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0
  2127. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0
  2128. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2129. return
  2130. }
  2131. matrix4_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix4f32) {
  2132. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0
  2133. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0
  2134. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0
  2135. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2136. return
  2137. }
  2138. matrix4_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix4f64) {
  2139. r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0
  2140. r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0
  2141. r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0
  2142. r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1
  2143. return
  2144. }
  2145. matrix4_from_matrix3 :: proc{
  2146. matrix4_from_matrix3_f16,
  2147. matrix4_from_matrix3_f32,
  2148. matrix4_from_matrix3_f64,
  2149. }
  2150. quaternion_from_scalar_f16 :: proc(f: f16) -> (q: Quaternionf16) {
  2151. q.w = f
  2152. return
  2153. }
  2154. quaternion_from_scalar_f32 :: proc(f: f32) -> (q: Quaternionf32) {
  2155. q.w = f
  2156. return
  2157. }
  2158. quaternion_from_scalar_f64 :: proc(f: f64) -> (q: Quaternionf64) {
  2159. q.w = f
  2160. return
  2161. }
  2162. quaternion_from_scalar :: proc{
  2163. quaternion_from_scalar_f16,
  2164. quaternion_from_scalar_f32,
  2165. quaternion_from_scalar_f64,
  2166. }
  2167. to_matrix2f16 :: proc{matrix2_from_scalar_f16, matrix2_from_matrix3_f16, matrix2_from_matrix4_f16}
  2168. to_matrix3f16 :: proc{matrix3_from_scalar_f16, matrix3_from_matrix2_f16, matrix3_from_matrix4_f16, matrix3_from_quaternion_f16}
  2169. to_matrix4f16 :: proc{matrix4_from_scalar_f16, matrix4_from_matrix2_f16, matrix4_from_matrix3_f16, matrix4_from_quaternion_f16}
  2170. to_quaternionf16 :: proc{quaternion_from_scalar_f16, quaternion_from_matrix3_f16, quaternion_from_matrix4_f16}
  2171. to_matrix2f32 :: proc{matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32}
  2172. to_matrix3f32 :: proc{matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32}
  2173. to_matrix4f32 :: proc{matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32}
  2174. to_quaternionf32 :: proc{quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32}
  2175. to_matrix2f64 :: proc{matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64}
  2176. to_matrix3f64 :: proc{matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64}
  2177. to_matrix4f64 :: proc{matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64}
  2178. to_quaternionf64 :: proc{quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64}
  2179. to_matrix2f :: proc{
  2180. matrix2_from_scalar_f16, matrix2_from_matrix3_f16, matrix2_from_matrix4_f16,
  2181. matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32,
  2182. matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64,
  2183. }
  2184. to_matrix3 :: proc{
  2185. matrix3_from_scalar_f16, matrix3_from_matrix2_f16, matrix3_from_matrix4_f16, matrix3_from_quaternion_f16,
  2186. matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32,
  2187. matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64,
  2188. }
  2189. to_matrix4 :: proc{
  2190. matrix4_from_scalar_f16, matrix4_from_matrix2_f16, matrix4_from_matrix3_f16, matrix4_from_quaternion_f16,
  2191. matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32,
  2192. matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64,
  2193. }
  2194. to_quaternion :: proc{
  2195. quaternion_from_scalar_f16, quaternion_from_matrix3_f16, quaternion_from_matrix4_f16,
  2196. quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32,
  2197. quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64,
  2198. }
  2199. matrix2_orthonormalize_f16 :: proc(m: Matrix2f16) -> (r: Matrix2f16) {
  2200. r[0] = normalize(m[0])
  2201. d0 := dot(r[0], r[1])
  2202. r[1] -= r[0] * d0
  2203. r[1] = normalize(r[1])
  2204. return
  2205. }
  2206. matrix2_orthonormalize_f32 :: proc(m: Matrix2f32) -> (r: Matrix2f32) {
  2207. r[0] = normalize(m[0])
  2208. d0 := dot(r[0], r[1])
  2209. r[1] -= r[0] * d0
  2210. r[1] = normalize(r[1])
  2211. return
  2212. }
  2213. matrix2_orthonormalize_f64 :: proc(m: Matrix2f64) -> (r: Matrix2f64) {
  2214. r[0] = normalize(m[0])
  2215. d0 := dot(r[0], r[1])
  2216. r[1] -= r[0] * d0
  2217. r[1] = normalize(r[1])
  2218. return
  2219. }
  2220. matrix2_orthonormalize :: proc{
  2221. matrix2_orthonormalize_f16,
  2222. matrix2_orthonormalize_f32,
  2223. matrix2_orthonormalize_f64,
  2224. }
  2225. matrix3_orthonormalize_f16 :: proc(m: Matrix3f16) -> (r: Matrix3f16) {
  2226. r[0] = normalize(m[0])
  2227. d0 := dot(r[0], r[1])
  2228. r[1] -= r[0] * d0
  2229. r[1] = normalize(r[1])
  2230. d1 := dot(r[1], r[2])
  2231. d0 = dot(r[0], r[2])
  2232. r[2] -= r[0]*d0 + r[1]*d1
  2233. r[2] = normalize(r[2])
  2234. return
  2235. }
  2236. matrix3_orthonormalize_f32 :: proc(m: Matrix3f32) -> (r: Matrix3f32) {
  2237. r[0] = normalize(m[0])
  2238. d0 := dot(r[0], r[1])
  2239. r[1] -= r[0] * d0
  2240. r[1] = normalize(r[1])
  2241. d1 := dot(r[1], r[2])
  2242. d0 = dot(r[0], r[2])
  2243. r[2] -= r[0]*d0 + r[1]*d1
  2244. r[2] = normalize(r[2])
  2245. return
  2246. }
  2247. matrix3_orthonormalize_f64 :: proc(m: Matrix3f64) -> (r: Matrix3f64) {
  2248. r[0] = normalize(m[0])
  2249. d0 := dot(r[0], r[1])
  2250. r[1] -= r[0] * d0
  2251. r[1] = normalize(r[1])
  2252. d1 := dot(r[1], r[2])
  2253. d0 = dot(r[0], r[2])
  2254. r[2] -= r[0]*d0 + r[1]*d1
  2255. r[2] = normalize(r[2])
  2256. return
  2257. }
  2258. matrix3_orthonormalize :: proc{
  2259. matrix3_orthonormalize_f16,
  2260. matrix3_orthonormalize_f32,
  2261. matrix3_orthonormalize_f64,
  2262. }
  2263. vector3_orthonormalize_f16 :: proc(x, y: Vector3f16) -> (z: Vector3f16) {
  2264. return normalize(x - y * dot(y, x))
  2265. }
  2266. vector3_orthonormalize_f32 :: proc(x, y: Vector3f32) -> (z: Vector3f32) {
  2267. return normalize(x - y * dot(y, x))
  2268. }
  2269. vector3_orthonormalize_f64 :: proc(x, y: Vector3f64) -> (z: Vector3f64) {
  2270. return normalize(x - y * dot(y, x))
  2271. }
  2272. vector3_orthonormalize :: proc{
  2273. vector3_orthonormalize_f16,
  2274. vector3_orthonormalize_f32,
  2275. vector3_orthonormalize_f64,
  2276. }
  2277. orthonormalize :: proc{
  2278. matrix2_orthonormalize_f16, matrix3_orthonormalize_f16, vector3_orthonormalize_f16,
  2279. matrix2_orthonormalize_f32, matrix3_orthonormalize_f32, vector3_orthonormalize_f32,
  2280. matrix2_orthonormalize_f64, matrix3_orthonormalize_f64, vector3_orthonormalize_f64,
  2281. }
  2282. matrix4_orientation_f16 :: proc(normal, up: Vector3f16) -> Matrix4f16 {
  2283. if all(equal(normal, up)) {
  2284. return MATRIX4F16_IDENTITY
  2285. }
  2286. rotation_axis := cross(up, normal)
  2287. angle := math.acos(dot(normal, up))
  2288. return matrix4_rotate(angle, rotation_axis)
  2289. }
  2290. matrix4_orientation_f32 :: proc(normal, up: Vector3f32) -> Matrix4f32 {
  2291. if all(equal(normal, up)) {
  2292. return MATRIX4F32_IDENTITY
  2293. }
  2294. rotation_axis := cross(up, normal)
  2295. angle := math.acos(dot(normal, up))
  2296. return matrix4_rotate(angle, rotation_axis)
  2297. }
  2298. matrix4_orientation_f64 :: proc(normal, up: Vector3f64) -> Matrix4f64 {
  2299. if all(equal(normal, up)) {
  2300. return MATRIX4F64_IDENTITY
  2301. }
  2302. rotation_axis := cross(up, normal)
  2303. angle := math.acos(dot(normal, up))
  2304. return matrix4_rotate(angle, rotation_axis)
  2305. }
  2306. matrix4_orientation :: proc{
  2307. matrix4_orientation_f16,
  2308. matrix4_orientation_f32,
  2309. matrix4_orientation_f64,
  2310. }
  2311. euclidean_from_polar_f16 :: proc(polar: Vector2f16) -> Vector3f16 {
  2312. latitude, longitude := polar.x, polar.y
  2313. cx, sx := math.cos(latitude), math.sin(latitude)
  2314. cy, sy := math.cos(longitude), math.sin(longitude)
  2315. return {
  2316. cx*sy,
  2317. sx,
  2318. cx*cy,
  2319. }
  2320. }
  2321. euclidean_from_polar_f32 :: proc(polar: Vector2f32) -> Vector3f32 {
  2322. latitude, longitude := polar.x, polar.y
  2323. cx, sx := math.cos(latitude), math.sin(latitude)
  2324. cy, sy := math.cos(longitude), math.sin(longitude)
  2325. return {
  2326. cx*sy,
  2327. sx,
  2328. cx*cy,
  2329. }
  2330. }
  2331. euclidean_from_polar_f64 :: proc(polar: Vector2f64) -> Vector3f64 {
  2332. latitude, longitude := polar.x, polar.y
  2333. cx, sx := math.cos(latitude), math.sin(latitude)
  2334. cy, sy := math.cos(longitude), math.sin(longitude)
  2335. return {
  2336. cx*sy,
  2337. sx,
  2338. cx*cy,
  2339. }
  2340. }
  2341. euclidean_from_polar :: proc{
  2342. euclidean_from_polar_f16,
  2343. euclidean_from_polar_f32,
  2344. euclidean_from_polar_f64,
  2345. }
  2346. polar_from_euclidean_f16 :: proc(euclidean: Vector3f16) -> Vector3f16 {
  2347. n := length(euclidean)
  2348. tmp := euclidean / n
  2349. xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
  2350. return {
  2351. math.asin(tmp.y),
  2352. math.atan2(tmp.x, tmp.z),
  2353. xz_dist,
  2354. }
  2355. }
  2356. polar_from_euclidean_f32 :: proc(euclidean: Vector3f32) -> Vector3f32 {
  2357. n := length(euclidean)
  2358. tmp := euclidean / n
  2359. xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
  2360. return {
  2361. math.asin(tmp.y),
  2362. math.atan2(tmp.x, tmp.z),
  2363. xz_dist,
  2364. }
  2365. }
  2366. polar_from_euclidean_f64 :: proc(euclidean: Vector3f64) -> Vector3f64 {
  2367. n := length(euclidean)
  2368. tmp := euclidean / n
  2369. xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
  2370. return {
  2371. math.asin(tmp.y),
  2372. math.atan2(tmp.x, tmp.z),
  2373. xz_dist,
  2374. }
  2375. }
  2376. polar_from_euclidean :: proc{
  2377. polar_from_euclidean_f16,
  2378. polar_from_euclidean_f32,
  2379. polar_from_euclidean_f64,
  2380. }