raymath.h 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941
  1. /**********************************************************************************************
  2. *
  3. * raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
  4. *
  5. * CONVENTIONS:
  6. * - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
  7. * math operations performed by the library consider the structure as it was column-major
  8. * It is like transposed versions of the matrices are used for all the maths
  9. * It benefits some functions making them cache-friendly and also avoids matrix
  10. * transpositions sometimes required by OpenGL
  11. * Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3]
  12. * - Functions are always self-contained, no function use another raymath function inside,
  13. * required code is directly re-implemented inside
  14. * - Functions input parameters are always received by value (2 unavoidable exceptions)
  15. * - Functions use always a "result" variable for return (except C++ operators)
  16. * - Functions are always defined inline
  17. * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
  18. * - No compound literals used to make sure libray is compatible with C++
  19. *
  20. * CONFIGURATION:
  21. * #define RAYMATH_IMPLEMENTATION
  22. * Generates the implementation of the library into the included file.
  23. * If not defined, the library is in header only mode and can be included in other headers
  24. * or source files without problems. But only ONE file should hold the implementation.
  25. *
  26. * #define RAYMATH_STATIC_INLINE
  27. * Define static inline functions code, so #include header suffices for use.
  28. * This may use up lots of memory.
  29. *
  30. * #define RAYMATH_DISABLE_CPP_OPERATORS
  31. * Disables C++ operator overloads for raymath types.
  32. *
  33. * LICENSE: zlib/libpng
  34. *
  35. * Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
  36. *
  37. * This software is provided "as-is", without any express or implied warranty. In no event
  38. * will the authors be held liable for any damages arising from the use of this software.
  39. *
  40. * Permission is granted to anyone to use this software for any purpose, including commercial
  41. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  42. *
  43. * 1. The origin of this software must not be misrepresented; you must not claim that you
  44. * wrote the original software. If you use this software in a product, an acknowledgment
  45. * in the product documentation would be appreciated but is not required.
  46. *
  47. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  48. * as being the original software.
  49. *
  50. * 3. This notice may not be removed or altered from any source distribution.
  51. *
  52. **********************************************************************************************/
  53. #ifndef RAYMATH_H
  54. #define RAYMATH_H
  55. #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE)
  56. #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory"
  57. #endif
  58. // Function specifiers definition
  59. #if defined(RAYMATH_IMPLEMENTATION)
  60. #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
  61. #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll)
  62. #elif defined(BUILD_LIBTYPE_SHARED)
  63. #define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib)
  64. #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
  65. #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
  66. #else
  67. #define RMAPI extern inline // Provide external definition
  68. #endif
  69. #elif defined(RAYMATH_STATIC_INLINE)
  70. #define RMAPI static inline // Functions may be inlined, no external out-of-line definition
  71. #else
  72. #if defined(__TINYC__)
  73. #define RMAPI static inline // plain inline not supported by tinycc (See issue #435)
  74. #else
  75. #define RMAPI inline // Functions may be inlined or external definition used
  76. #endif
  77. #endif
  78. //----------------------------------------------------------------------------------
  79. // Defines and Macros
  80. //----------------------------------------------------------------------------------
  81. #ifndef PI
  82. #define PI 3.14159265358979323846f
  83. #endif
  84. #ifndef EPSILON
  85. #define EPSILON 0.000001f
  86. #endif
  87. #ifndef DEG2RAD
  88. #define DEG2RAD (PI/180.0f)
  89. #endif
  90. #ifndef RAD2DEG
  91. #define RAD2DEG (180.0f/PI)
  92. #endif
  93. // Get float vector for Matrix
  94. #ifndef MatrixToFloat
  95. #define MatrixToFloat(mat) (MatrixToFloatV(mat).v)
  96. #endif
  97. // Get float vector for Vector3
  98. #ifndef Vector3ToFloat
  99. #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v)
  100. #endif
  101. //----------------------------------------------------------------------------------
  102. // Types and Structures Definition
  103. //----------------------------------------------------------------------------------
  104. #if !defined(RL_VECTOR2_TYPE)
  105. // Vector2 type
  106. typedef struct Vector2 {
  107. float x;
  108. float y;
  109. } Vector2;
  110. #define RL_VECTOR2_TYPE
  111. #endif
  112. #if !defined(RL_VECTOR3_TYPE)
  113. // Vector3 type
  114. typedef struct Vector3 {
  115. float x;
  116. float y;
  117. float z;
  118. } Vector3;
  119. #define RL_VECTOR3_TYPE
  120. #endif
  121. #if !defined(RL_VECTOR4_TYPE)
  122. // Vector4 type
  123. typedef struct Vector4 {
  124. float x;
  125. float y;
  126. float z;
  127. float w;
  128. } Vector4;
  129. #define RL_VECTOR4_TYPE
  130. #endif
  131. #if !defined(RL_QUATERNION_TYPE)
  132. // Quaternion type
  133. typedef Vector4 Quaternion;
  134. #define RL_QUATERNION_TYPE
  135. #endif
  136. #if !defined(RL_MATRIX_TYPE)
  137. // Matrix type (OpenGL style 4x4 - right handed, column major)
  138. typedef struct Matrix {
  139. float m0, m4, m8, m12; // Matrix first row (4 components)
  140. float m1, m5, m9, m13; // Matrix second row (4 components)
  141. float m2, m6, m10, m14; // Matrix third row (4 components)
  142. float m3, m7, m11, m15; // Matrix fourth row (4 components)
  143. } Matrix;
  144. #define RL_MATRIX_TYPE
  145. #endif
  146. // NOTE: Helper types to be used instead of array return types for *ToFloat functions
  147. typedef struct float3 {
  148. float v[3];
  149. } float3;
  150. typedef struct float16 {
  151. float v[16];
  152. } float16;
  153. #include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf()
  154. //----------------------------------------------------------------------------------
  155. // Module Functions Definition - Utils math
  156. //----------------------------------------------------------------------------------
  157. // Clamp float value
  158. RMAPI float Clamp(float value, float min, float max)
  159. {
  160. float result = (value < min)? min : value;
  161. if (result > max) result = max;
  162. return result;
  163. }
  164. // Calculate linear interpolation between two floats
  165. RMAPI float Lerp(float start, float end, float amount)
  166. {
  167. float result = start + amount*(end - start);
  168. return result;
  169. }
  170. // Normalize input value within input range
  171. RMAPI float Normalize(float value, float start, float end)
  172. {
  173. float result = (value - start)/(end - start);
  174. return result;
  175. }
  176. // Remap input value within input range to output range
  177. RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd)
  178. {
  179. float result = (value - inputStart)/(inputEnd - inputStart)*(outputEnd - outputStart) + outputStart;
  180. return result;
  181. }
  182. // Wrap input value from min to max
  183. RMAPI float Wrap(float value, float min, float max)
  184. {
  185. float result = value - (max - min)*floorf((value - min)/(max - min));
  186. return result;
  187. }
  188. // Check whether two given floats are almost equal
  189. RMAPI int FloatEquals(float x, float y)
  190. {
  191. #if !defined(EPSILON)
  192. #define EPSILON 0.000001f
  193. #endif
  194. int result = (fabsf(x - y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y))));
  195. return result;
  196. }
  197. //----------------------------------------------------------------------------------
  198. // Module Functions Definition - Vector2 math
  199. //----------------------------------------------------------------------------------
  200. // Vector with components value 0.0f
  201. RMAPI Vector2 Vector2Zero(void)
  202. {
  203. Vector2 result = { 0.0f, 0.0f };
  204. return result;
  205. }
  206. // Vector with components value 1.0f
  207. RMAPI Vector2 Vector2One(void)
  208. {
  209. Vector2 result = { 1.0f, 1.0f };
  210. return result;
  211. }
  212. // Add two vectors (v1 + v2)
  213. RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2)
  214. {
  215. Vector2 result = { v1.x + v2.x, v1.y + v2.y };
  216. return result;
  217. }
  218. // Add vector and float value
  219. RMAPI Vector2 Vector2AddValue(Vector2 v, float add)
  220. {
  221. Vector2 result = { v.x + add, v.y + add };
  222. return result;
  223. }
  224. // Subtract two vectors (v1 - v2)
  225. RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
  226. {
  227. Vector2 result = { v1.x - v2.x, v1.y - v2.y };
  228. return result;
  229. }
  230. // Subtract vector by float value
  231. RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub)
  232. {
  233. Vector2 result = { v.x - sub, v.y - sub };
  234. return result;
  235. }
  236. // Calculate vector length
  237. RMAPI float Vector2Length(Vector2 v)
  238. {
  239. float result = sqrtf((v.x*v.x) + (v.y*v.y));
  240. return result;
  241. }
  242. // Calculate vector square length
  243. RMAPI float Vector2LengthSqr(Vector2 v)
  244. {
  245. float result = (v.x*v.x) + (v.y*v.y);
  246. return result;
  247. }
  248. // Calculate two vectors dot product
  249. RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2)
  250. {
  251. float result = (v1.x*v2.x + v1.y*v2.y);
  252. return result;
  253. }
  254. // Calculate distance between two vectors
  255. RMAPI float Vector2Distance(Vector2 v1, Vector2 v2)
  256. {
  257. float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
  258. return result;
  259. }
  260. // Calculate square distance between two vectors
  261. RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
  262. {
  263. float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
  264. return result;
  265. }
  266. // Calculate angle between two vectors
  267. // NOTE: Angle is calculated from origin point (0, 0)
  268. RMAPI float Vector2Angle(Vector2 v1, Vector2 v2)
  269. {
  270. float result = 0.0f;
  271. float dot = v1.x*v2.x + v1.y*v2.y;
  272. float det = v1.x*v2.y - v1.y*v2.x;
  273. result = atan2f(det, dot);
  274. return result;
  275. }
  276. // Calculate angle defined by a two vectors line
  277. // NOTE: Parameters need to be normalized
  278. // Current implementation should be aligned with glm::angle
  279. RMAPI float Vector2LineAngle(Vector2 start, Vector2 end)
  280. {
  281. float result = 0.0f;
  282. // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior
  283. result = -atan2f(end.y - start.y, end.x - start.x);
  284. return result;
  285. }
  286. // Scale vector (multiply by value)
  287. RMAPI Vector2 Vector2Scale(Vector2 v, float scale)
  288. {
  289. Vector2 result = { v.x*scale, v.y*scale };
  290. return result;
  291. }
  292. // Multiply vector by vector
  293. RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2)
  294. {
  295. Vector2 result = { v1.x*v2.x, v1.y*v2.y };
  296. return result;
  297. }
  298. // Negate vector
  299. RMAPI Vector2 Vector2Negate(Vector2 v)
  300. {
  301. Vector2 result = { -v.x, -v.y };
  302. return result;
  303. }
  304. // Divide vector by vector
  305. RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
  306. {
  307. Vector2 result = { v1.x/v2.x, v1.y/v2.y };
  308. return result;
  309. }
  310. // Normalize provided vector
  311. RMAPI Vector2 Vector2Normalize(Vector2 v)
  312. {
  313. Vector2 result = { 0 };
  314. float length = sqrtf((v.x*v.x) + (v.y*v.y));
  315. if (length > 0)
  316. {
  317. float ilength = 1.0f/length;
  318. result.x = v.x*ilength;
  319. result.y = v.y*ilength;
  320. }
  321. return result;
  322. }
  323. // Transforms a Vector2 by a given Matrix
  324. RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat)
  325. {
  326. Vector2 result = { 0 };
  327. float x = v.x;
  328. float y = v.y;
  329. float z = 0;
  330. result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
  331. result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
  332. return result;
  333. }
  334. // Calculate linear interpolation between two vectors
  335. RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount)
  336. {
  337. Vector2 result = { 0 };
  338. result.x = v1.x + amount*(v2.x - v1.x);
  339. result.y = v1.y + amount*(v2.y - v1.y);
  340. return result;
  341. }
  342. // Calculate reflected vector to normal
  343. RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal)
  344. {
  345. Vector2 result = { 0 };
  346. float dotProduct = (v.x*normal.x + v.y*normal.y); // Dot product
  347. result.x = v.x - (2.0f*normal.x)*dotProduct;
  348. result.y = v.y - (2.0f*normal.y)*dotProduct;
  349. return result;
  350. }
  351. // Get min value for each pair of components
  352. RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2)
  353. {
  354. Vector2 result = { 0 };
  355. result.x = fminf(v1.x, v2.x);
  356. result.y = fminf(v1.y, v2.y);
  357. return result;
  358. }
  359. // Get max value for each pair of components
  360. RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2)
  361. {
  362. Vector2 result = { 0 };
  363. result.x = fmaxf(v1.x, v2.x);
  364. result.y = fmaxf(v1.y, v2.y);
  365. return result;
  366. }
  367. // Rotate vector by angle
  368. RMAPI Vector2 Vector2Rotate(Vector2 v, float angle)
  369. {
  370. Vector2 result = { 0 };
  371. float cosres = cosf(angle);
  372. float sinres = sinf(angle);
  373. result.x = v.x*cosres - v.y*sinres;
  374. result.y = v.x*sinres + v.y*cosres;
  375. return result;
  376. }
  377. // Move Vector towards target
  378. RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
  379. {
  380. Vector2 result = { 0 };
  381. float dx = target.x - v.x;
  382. float dy = target.y - v.y;
  383. float value = (dx*dx) + (dy*dy);
  384. if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;
  385. float dist = sqrtf(value);
  386. result.x = v.x + dx/dist*maxDistance;
  387. result.y = v.y + dy/dist*maxDistance;
  388. return result;
  389. }
  390. // Invert the given vector
  391. RMAPI Vector2 Vector2Invert(Vector2 v)
  392. {
  393. Vector2 result = { 1.0f/v.x, 1.0f/v.y };
  394. return result;
  395. }
  396. // Clamp the components of the vector between
  397. // min and max values specified by the given vectors
  398. RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max)
  399. {
  400. Vector2 result = { 0 };
  401. result.x = fminf(max.x, fmaxf(min.x, v.x));
  402. result.y = fminf(max.y, fmaxf(min.y, v.y));
  403. return result;
  404. }
  405. // Clamp the magnitude of the vector between two min and max values
  406. RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max)
  407. {
  408. Vector2 result = v;
  409. float length = (v.x*v.x) + (v.y*v.y);
  410. if (length > 0.0f)
  411. {
  412. length = sqrtf(length);
  413. float scale = 1; // By default, 1 as the neutral element.
  414. if (length < min)
  415. {
  416. scale = min/length;
  417. }
  418. else if (length > max)
  419. {
  420. scale = max/length;
  421. }
  422. result.x = v.x*scale;
  423. result.y = v.y*scale;
  424. }
  425. return result;
  426. }
  427. // Check whether two given vectors are almost equal
  428. RMAPI int Vector2Equals(Vector2 p, Vector2 q)
  429. {
  430. #if !defined(EPSILON)
  431. #define EPSILON 0.000001f
  432. #endif
  433. int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
  434. ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y)))));
  435. return result;
  436. }
  437. // Compute the direction of a refracted ray
  438. // v: normalized direction of the incoming ray
  439. // n: normalized normal vector of the interface of two optical media
  440. // r: ratio of the refractive index of the medium from where the ray comes
  441. // to the refractive index of the medium on the other side of the surface
  442. RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r)
  443. {
  444. Vector2 result = { 0 };
  445. float dot = v.x*n.x + v.y*n.y;
  446. float d = 1.0f - r*r*(1.0f - dot*dot);
  447. if (d >= 0.0f)
  448. {
  449. d = sqrtf(d);
  450. v.x = r*v.x - (r*dot + d)*n.x;
  451. v.y = r*v.y - (r*dot + d)*n.y;
  452. result = v;
  453. }
  454. return result;
  455. }
  456. //----------------------------------------------------------------------------------
  457. // Module Functions Definition - Vector3 math
  458. //----------------------------------------------------------------------------------
  459. // Vector with components value 0.0f
  460. RMAPI Vector3 Vector3Zero(void)
  461. {
  462. Vector3 result = { 0.0f, 0.0f, 0.0f };
  463. return result;
  464. }
  465. // Vector with components value 1.0f
  466. RMAPI Vector3 Vector3One(void)
  467. {
  468. Vector3 result = { 1.0f, 1.0f, 1.0f };
  469. return result;
  470. }
  471. // Add two vectors
  472. RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2)
  473. {
  474. Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
  475. return result;
  476. }
  477. // Add vector and float value
  478. RMAPI Vector3 Vector3AddValue(Vector3 v, float add)
  479. {
  480. Vector3 result = { v.x + add, v.y + add, v.z + add };
  481. return result;
  482. }
  483. // Subtract two vectors
  484. RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
  485. {
  486. Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
  487. return result;
  488. }
  489. // Subtract vector by float value
  490. RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub)
  491. {
  492. Vector3 result = { v.x - sub, v.y - sub, v.z - sub };
  493. return result;
  494. }
  495. // Multiply vector by scalar
  496. RMAPI Vector3 Vector3Scale(Vector3 v, float scalar)
  497. {
  498. Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar };
  499. return result;
  500. }
  501. // Multiply vector by vector
  502. RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2)
  503. {
  504. Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z };
  505. return result;
  506. }
  507. // Calculate two vectors cross product
  508. RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2)
  509. {
  510. Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x };
  511. return result;
  512. }
  513. // Calculate one vector perpendicular vector
  514. RMAPI Vector3 Vector3Perpendicular(Vector3 v)
  515. {
  516. Vector3 result = { 0 };
  517. float min = fabsf(v.x);
  518. Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
  519. if (fabsf(v.y) < min)
  520. {
  521. min = fabsf(v.y);
  522. Vector3 tmp = {0.0f, 1.0f, 0.0f};
  523. cardinalAxis = tmp;
  524. }
  525. if (fabsf(v.z) < min)
  526. {
  527. Vector3 tmp = {0.0f, 0.0f, 1.0f};
  528. cardinalAxis = tmp;
  529. }
  530. // Cross product between vectors
  531. result.x = v.y*cardinalAxis.z - v.z*cardinalAxis.y;
  532. result.y = v.z*cardinalAxis.x - v.x*cardinalAxis.z;
  533. result.z = v.x*cardinalAxis.y - v.y*cardinalAxis.x;
  534. return result;
  535. }
  536. // Calculate vector length
  537. RMAPI float Vector3Length(const Vector3 v)
  538. {
  539. float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  540. return result;
  541. }
  542. // Calculate vector square length
  543. RMAPI float Vector3LengthSqr(const Vector3 v)
  544. {
  545. float result = v.x*v.x + v.y*v.y + v.z*v.z;
  546. return result;
  547. }
  548. // Calculate two vectors dot product
  549. RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2)
  550. {
  551. float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  552. return result;
  553. }
  554. // Calculate distance between two vectors
  555. RMAPI float Vector3Distance(Vector3 v1, Vector3 v2)
  556. {
  557. float result = 0.0f;
  558. float dx = v2.x - v1.x;
  559. float dy = v2.y - v1.y;
  560. float dz = v2.z - v1.z;
  561. result = sqrtf(dx*dx + dy*dy + dz*dz);
  562. return result;
  563. }
  564. // Calculate square distance between two vectors
  565. RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2)
  566. {
  567. float result = 0.0f;
  568. float dx = v2.x - v1.x;
  569. float dy = v2.y - v1.y;
  570. float dz = v2.z - v1.z;
  571. result = dx*dx + dy*dy + dz*dz;
  572. return result;
  573. }
  574. // Calculate angle between two vectors
  575. RMAPI float Vector3Angle(Vector3 v1, Vector3 v2)
  576. {
  577. float result = 0.0f;
  578. Vector3 cross = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x };
  579. float len = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z);
  580. float dot = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  581. result = atan2f(len, dot);
  582. return result;
  583. }
  584. // Negate provided vector (invert direction)
  585. RMAPI Vector3 Vector3Negate(Vector3 v)
  586. {
  587. Vector3 result = { -v.x, -v.y, -v.z };
  588. return result;
  589. }
  590. // Divide vector by vector
  591. RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2)
  592. {
  593. Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
  594. return result;
  595. }
  596. // Normalize provided vector
  597. RMAPI Vector3 Vector3Normalize(Vector3 v)
  598. {
  599. Vector3 result = v;
  600. float length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  601. if (length != 0.0f)
  602. {
  603. float ilength = 1.0f/length;
  604. result.x *= ilength;
  605. result.y *= ilength;
  606. result.z *= ilength;
  607. }
  608. return result;
  609. }
  610. //Calculate the projection of the vector v1 on to v2
  611. RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2)
  612. {
  613. Vector3 result = { 0 };
  614. float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  615. float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
  616. float mag = v1dv2/v2dv2;
  617. result.x = v2.x*mag;
  618. result.y = v2.y*mag;
  619. result.z = v2.z*mag;
  620. return result;
  621. }
  622. //Calculate the rejection of the vector v1 on to v2
  623. RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2)
  624. {
  625. Vector3 result = { 0 };
  626. float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
  627. float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
  628. float mag = v1dv2/v2dv2;
  629. result.x = v1.x - (v2.x*mag);
  630. result.y = v1.y - (v2.y*mag);
  631. result.z = v1.z - (v2.z*mag);
  632. return result;
  633. }
  634. // Orthonormalize provided vectors
  635. // Makes vectors normalized and orthogonal to each other
  636. // Gram-Schmidt function implementation
  637. RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2)
  638. {
  639. float length = 0.0f;
  640. float ilength = 0.0f;
  641. // Vector3Normalize(*v1);
  642. Vector3 v = *v1;
  643. length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  644. if (length == 0.0f) length = 1.0f;
  645. ilength = 1.0f/length;
  646. v1->x *= ilength;
  647. v1->y *= ilength;
  648. v1->z *= ilength;
  649. // Vector3CrossProduct(*v1, *v2)
  650. Vector3 vn1 = { v1->y*v2->z - v1->z*v2->y, v1->z*v2->x - v1->x*v2->z, v1->x*v2->y - v1->y*v2->x };
  651. // Vector3Normalize(vn1);
  652. v = vn1;
  653. length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  654. if (length == 0.0f) length = 1.0f;
  655. ilength = 1.0f/length;
  656. vn1.x *= ilength;
  657. vn1.y *= ilength;
  658. vn1.z *= ilength;
  659. // Vector3CrossProduct(vn1, *v1)
  660. Vector3 vn2 = { vn1.y*v1->z - vn1.z*v1->y, vn1.z*v1->x - vn1.x*v1->z, vn1.x*v1->y - vn1.y*v1->x };
  661. *v2 = vn2;
  662. }
  663. // Transforms a Vector3 by a given Matrix
  664. RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat)
  665. {
  666. Vector3 result = { 0 };
  667. float x = v.x;
  668. float y = v.y;
  669. float z = v.z;
  670. result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
  671. result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
  672. result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
  673. return result;
  674. }
  675. // Transform a vector by quaternion rotation
  676. RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
  677. {
  678. Vector3 result = { 0 };
  679. result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y);
  680. result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z);
  681. result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z);
  682. return result;
  683. }
  684. // Rotates a vector around an axis
  685. RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle)
  686. {
  687. // Using Euler-Rodrigues Formula
  688. // Ref.: https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula
  689. Vector3 result = v;
  690. // Vector3Normalize(axis);
  691. float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z);
  692. if (length == 0.0f) length = 1.0f;
  693. float ilength = 1.0f/length;
  694. axis.x *= ilength;
  695. axis.y *= ilength;
  696. axis.z *= ilength;
  697. angle /= 2.0f;
  698. float a = sinf(angle);
  699. float b = axis.x*a;
  700. float c = axis.y*a;
  701. float d = axis.z*a;
  702. a = cosf(angle);
  703. Vector3 w = { b, c, d };
  704. // Vector3CrossProduct(w, v)
  705. Vector3 wv = { w.y*v.z - w.z*v.y, w.z*v.x - w.x*v.z, w.x*v.y - w.y*v.x };
  706. // Vector3CrossProduct(w, wv)
  707. Vector3 wwv = { w.y*wv.z - w.z*wv.y, w.z*wv.x - w.x*wv.z, w.x*wv.y - w.y*wv.x };
  708. // Vector3Scale(wv, 2*a)
  709. a *= 2;
  710. wv.x *= a;
  711. wv.y *= a;
  712. wv.z *= a;
  713. // Vector3Scale(wwv, 2)
  714. wwv.x *= 2;
  715. wwv.y *= 2;
  716. wwv.z *= 2;
  717. result.x += wv.x;
  718. result.y += wv.y;
  719. result.z += wv.z;
  720. result.x += wwv.x;
  721. result.y += wwv.y;
  722. result.z += wwv.z;
  723. return result;
  724. }
  725. // Move Vector towards target
  726. RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDistance)
  727. {
  728. Vector3 result = { 0 };
  729. float dx = target.x - v.x;
  730. float dy = target.y - v.y;
  731. float dz = target.z - v.z;
  732. float value = (dx*dx) + (dy*dy) + (dz*dz);
  733. if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;
  734. float dist = sqrtf(value);
  735. result.x = v.x + dx/dist*maxDistance;
  736. result.y = v.y + dy/dist*maxDistance;
  737. result.z = v.z + dz/dist*maxDistance;
  738. return result;
  739. }
  740. // Calculate linear interpolation between two vectors
  741. RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
  742. {
  743. Vector3 result = { 0 };
  744. result.x = v1.x + amount*(v2.x - v1.x);
  745. result.y = v1.y + amount*(v2.y - v1.y);
  746. result.z = v1.z + amount*(v2.z - v1.z);
  747. return result;
  748. }
  749. // Calculate cubic hermite interpolation between two vectors and their tangents
  750. // as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic
  751. RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 v2, Vector3 tangent2, float amount)
  752. {
  753. Vector3 result = { 0 };
  754. float amountPow2 = amount*amount;
  755. float amountPow3 = amount*amount*amount;
  756. result.x = (2*amountPow3 - 3*amountPow2 + 1)*v1.x + (amountPow3 - 2*amountPow2 + amount)*tangent1.x + (-2*amountPow3 + 3*amountPow2)*v2.x + (amountPow3 - amountPow2)*tangent2.x;
  757. result.y = (2*amountPow3 - 3*amountPow2 + 1)*v1.y + (amountPow3 - 2*amountPow2 + amount)*tangent1.y + (-2*amountPow3 + 3*amountPow2)*v2.y + (amountPow3 - amountPow2)*tangent2.y;
  758. result.z = (2*amountPow3 - 3*amountPow2 + 1)*v1.z + (amountPow3 - 2*amountPow2 + amount)*tangent1.z + (-2*amountPow3 + 3*amountPow2)*v2.z + (amountPow3 - amountPow2)*tangent2.z;
  759. return result;
  760. }
  761. // Calculate reflected vector to normal
  762. RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
  763. {
  764. Vector3 result = { 0 };
  765. // I is the original vector
  766. // N is the normal of the incident plane
  767. // R = I - (2*N*(DotProduct[I, N]))
  768. float dotProduct = (v.x*normal.x + v.y*normal.y + v.z*normal.z);
  769. result.x = v.x - (2.0f*normal.x)*dotProduct;
  770. result.y = v.y - (2.0f*normal.y)*dotProduct;
  771. result.z = v.z - (2.0f*normal.z)*dotProduct;
  772. return result;
  773. }
  774. // Get min value for each pair of components
  775. RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2)
  776. {
  777. Vector3 result = { 0 };
  778. result.x = fminf(v1.x, v2.x);
  779. result.y = fminf(v1.y, v2.y);
  780. result.z = fminf(v1.z, v2.z);
  781. return result;
  782. }
  783. // Get max value for each pair of components
  784. RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2)
  785. {
  786. Vector3 result = { 0 };
  787. result.x = fmaxf(v1.x, v2.x);
  788. result.y = fmaxf(v1.y, v2.y);
  789. result.z = fmaxf(v1.z, v2.z);
  790. return result;
  791. }
  792. // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
  793. // NOTE: Assumes P is on the plane of the triangle
  794. RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  795. {
  796. Vector3 result = { 0 };
  797. Vector3 v0 = { b.x - a.x, b.y - a.y, b.z - a.z }; // Vector3Subtract(b, a)
  798. Vector3 v1 = { c.x - a.x, c.y - a.y, c.z - a.z }; // Vector3Subtract(c, a)
  799. Vector3 v2 = { p.x - a.x, p.y - a.y, p.z - a.z }; // Vector3Subtract(p, a)
  800. float d00 = (v0.x*v0.x + v0.y*v0.y + v0.z*v0.z); // Vector3DotProduct(v0, v0)
  801. float d01 = (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z); // Vector3DotProduct(v0, v1)
  802. float d11 = (v1.x*v1.x + v1.y*v1.y + v1.z*v1.z); // Vector3DotProduct(v1, v1)
  803. float d20 = (v2.x*v0.x + v2.y*v0.y + v2.z*v0.z); // Vector3DotProduct(v2, v0)
  804. float d21 = (v2.x*v1.x + v2.y*v1.y + v2.z*v1.z); // Vector3DotProduct(v2, v1)
  805. float denom = d00*d11 - d01*d01;
  806. result.y = (d11*d20 - d01*d21)/denom;
  807. result.z = (d00*d21 - d01*d20)/denom;
  808. result.x = 1.0f - (result.z + result.y);
  809. return result;
  810. }
  811. // Projects a Vector3 from screen space into object space
  812. // NOTE: We are avoiding calling other raymath functions despite available
  813. RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view)
  814. {
  815. Vector3 result = { 0 };
  816. // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it
  817. Matrix matViewProj = { // MatrixMultiply(view, projection);
  818. view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12,
  819. view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13,
  820. view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14,
  821. view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15,
  822. view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12,
  823. view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13,
  824. view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14,
  825. view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15,
  826. view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12,
  827. view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13,
  828. view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14,
  829. view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15,
  830. view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12,
  831. view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13,
  832. view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14,
  833. view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 };
  834. // Calculate inverted matrix -> MatrixInvert(matViewProj);
  835. // Cache the matrix values (speed optimization)
  836. float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3;
  837. float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7;
  838. float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11;
  839. float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15;
  840. float b00 = a00*a11 - a01*a10;
  841. float b01 = a00*a12 - a02*a10;
  842. float b02 = a00*a13 - a03*a10;
  843. float b03 = a01*a12 - a02*a11;
  844. float b04 = a01*a13 - a03*a11;
  845. float b05 = a02*a13 - a03*a12;
  846. float b06 = a20*a31 - a21*a30;
  847. float b07 = a20*a32 - a22*a30;
  848. float b08 = a20*a33 - a23*a30;
  849. float b09 = a21*a32 - a22*a31;
  850. float b10 = a21*a33 - a23*a31;
  851. float b11 = a22*a33 - a23*a32;
  852. // Calculate the invert determinant (inlined to avoid double-caching)
  853. float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  854. Matrix matViewProjInv = {
  855. (a11*b11 - a12*b10 + a13*b09)*invDet,
  856. (-a01*b11 + a02*b10 - a03*b09)*invDet,
  857. (a31*b05 - a32*b04 + a33*b03)*invDet,
  858. (-a21*b05 + a22*b04 - a23*b03)*invDet,
  859. (-a10*b11 + a12*b08 - a13*b07)*invDet,
  860. (a00*b11 - a02*b08 + a03*b07)*invDet,
  861. (-a30*b05 + a32*b02 - a33*b01)*invDet,
  862. (a20*b05 - a22*b02 + a23*b01)*invDet,
  863. (a10*b10 - a11*b08 + a13*b06)*invDet,
  864. (-a00*b10 + a01*b08 - a03*b06)*invDet,
  865. (a30*b04 - a31*b02 + a33*b00)*invDet,
  866. (-a20*b04 + a21*b02 - a23*b00)*invDet,
  867. (-a10*b09 + a11*b07 - a12*b06)*invDet,
  868. (a00*b09 - a01*b07 + a02*b06)*invDet,
  869. (-a30*b03 + a31*b01 - a32*b00)*invDet,
  870. (a20*b03 - a21*b01 + a22*b00)*invDet };
  871. // Create quaternion from source point
  872. Quaternion quat = { source.x, source.y, source.z, 1.0f };
  873. // Multiply quat point by unprojecte matrix
  874. Quaternion qtransformed = { // QuaternionTransform(quat, matViewProjInv)
  875. matViewProjInv.m0*quat.x + matViewProjInv.m4*quat.y + matViewProjInv.m8*quat.z + matViewProjInv.m12*quat.w,
  876. matViewProjInv.m1*quat.x + matViewProjInv.m5*quat.y + matViewProjInv.m9*quat.z + matViewProjInv.m13*quat.w,
  877. matViewProjInv.m2*quat.x + matViewProjInv.m6*quat.y + matViewProjInv.m10*quat.z + matViewProjInv.m14*quat.w,
  878. matViewProjInv.m3*quat.x + matViewProjInv.m7*quat.y + matViewProjInv.m11*quat.z + matViewProjInv.m15*quat.w };
  879. // Normalized world points in vectors
  880. result.x = qtransformed.x/qtransformed.w;
  881. result.y = qtransformed.y/qtransformed.w;
  882. result.z = qtransformed.z/qtransformed.w;
  883. return result;
  884. }
  885. // Get Vector3 as float array
  886. RMAPI float3 Vector3ToFloatV(Vector3 v)
  887. {
  888. float3 buffer = { 0 };
  889. buffer.v[0] = v.x;
  890. buffer.v[1] = v.y;
  891. buffer.v[2] = v.z;
  892. return buffer;
  893. }
  894. // Invert the given vector
  895. RMAPI Vector3 Vector3Invert(Vector3 v)
  896. {
  897. Vector3 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z };
  898. return result;
  899. }
  900. // Clamp the components of the vector between
  901. // min and max values specified by the given vectors
  902. RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max)
  903. {
  904. Vector3 result = { 0 };
  905. result.x = fminf(max.x, fmaxf(min.x, v.x));
  906. result.y = fminf(max.y, fmaxf(min.y, v.y));
  907. result.z = fminf(max.z, fmaxf(min.z, v.z));
  908. return result;
  909. }
  910. // Clamp the magnitude of the vector between two values
  911. RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max)
  912. {
  913. Vector3 result = v;
  914. float length = (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
  915. if (length > 0.0f)
  916. {
  917. length = sqrtf(length);
  918. float scale = 1; // By default, 1 as the neutral element.
  919. if (length < min)
  920. {
  921. scale = min/length;
  922. }
  923. else if (length > max)
  924. {
  925. scale = max/length;
  926. }
  927. result.x = v.x*scale;
  928. result.y = v.y*scale;
  929. result.z = v.z*scale;
  930. }
  931. return result;
  932. }
  933. // Check whether two given vectors are almost equal
  934. RMAPI int Vector3Equals(Vector3 p, Vector3 q)
  935. {
  936. #if !defined(EPSILON)
  937. #define EPSILON 0.000001f
  938. #endif
  939. int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
  940. ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
  941. ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z)))));
  942. return result;
  943. }
  944. // Compute the direction of a refracted ray
  945. // v: normalized direction of the incoming ray
  946. // n: normalized normal vector of the interface of two optical media
  947. // r: ratio of the refractive index of the medium from where the ray comes
  948. // to the refractive index of the medium on the other side of the surface
  949. RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r)
  950. {
  951. Vector3 result = { 0 };
  952. float dot = v.x*n.x + v.y*n.y + v.z*n.z;
  953. float d = 1.0f - r*r*(1.0f - dot*dot);
  954. if (d >= 0.0f)
  955. {
  956. d = sqrtf(d);
  957. v.x = r*v.x - (r*dot + d)*n.x;
  958. v.y = r*v.y - (r*dot + d)*n.y;
  959. v.z = r*v.z - (r*dot + d)*n.z;
  960. result = v;
  961. }
  962. return result;
  963. }
  964. //----------------------------------------------------------------------------------
  965. // Module Functions Definition - Vector4 math
  966. //----------------------------------------------------------------------------------
  967. RMAPI Vector4 Vector4Zero(void)
  968. {
  969. Vector4 result = { 0.0f, 0.0f, 0.0f, 0.0f };
  970. return result;
  971. }
  972. RMAPI Vector4 Vector4One(void)
  973. {
  974. Vector4 result = { 1.0f, 1.0f, 1.0f, 1.0f };
  975. return result;
  976. }
  977. RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2)
  978. {
  979. Vector4 result = {
  980. v1.x + v2.x,
  981. v1.y + v2.y,
  982. v1.z + v2.z,
  983. v1.w + v2.w
  984. };
  985. return result;
  986. }
  987. RMAPI Vector4 Vector4AddValue(Vector4 v, float add)
  988. {
  989. Vector4 result = {
  990. v.x + add,
  991. v.y + add,
  992. v.z + add,
  993. v.w + add
  994. };
  995. return result;
  996. }
  997. RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2)
  998. {
  999. Vector4 result = {
  1000. v1.x - v2.x,
  1001. v1.y - v2.y,
  1002. v1.z - v2.z,
  1003. v1.w - v2.w
  1004. };
  1005. return result;
  1006. }
  1007. RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add)
  1008. {
  1009. Vector4 result = {
  1010. v.x - add,
  1011. v.y - add,
  1012. v.z - add,
  1013. v.w - add
  1014. };
  1015. return result;
  1016. }
  1017. RMAPI float Vector4Length(Vector4 v)
  1018. {
  1019. float result = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));
  1020. return result;
  1021. }
  1022. RMAPI float Vector4LengthSqr(Vector4 v)
  1023. {
  1024. float result = (v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w);
  1025. return result;
  1026. }
  1027. RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2)
  1028. {
  1029. float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w);
  1030. return result;
  1031. }
  1032. // Calculate distance between two vectors
  1033. RMAPI float Vector4Distance(Vector4 v1, Vector4 v2)
  1034. {
  1035. float result = sqrtf(
  1036. (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) +
  1037. (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w));
  1038. return result;
  1039. }
  1040. // Calculate square distance between two vectors
  1041. RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2)
  1042. {
  1043. float result =
  1044. (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) +
  1045. (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w);
  1046. return result;
  1047. }
  1048. RMAPI Vector4 Vector4Scale(Vector4 v, float scale)
  1049. {
  1050. Vector4 result = { v.x*scale, v.y*scale, v.z*scale, v.w*scale };
  1051. return result;
  1052. }
  1053. // Multiply vector by vector
  1054. RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2)
  1055. {
  1056. Vector4 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.w*v2.w };
  1057. return result;
  1058. }
  1059. // Negate vector
  1060. RMAPI Vector4 Vector4Negate(Vector4 v)
  1061. {
  1062. Vector4 result = { -v.x, -v.y, -v.z, -v.w };
  1063. return result;
  1064. }
  1065. // Divide vector by vector
  1066. RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2)
  1067. {
  1068. Vector4 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z, v1.w/v2.w };
  1069. return result;
  1070. }
  1071. // Normalize provided vector
  1072. RMAPI Vector4 Vector4Normalize(Vector4 v)
  1073. {
  1074. Vector4 result = { 0 };
  1075. float length = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));
  1076. if (length > 0)
  1077. {
  1078. float ilength = 1.0f/length;
  1079. result.x = v.x*ilength;
  1080. result.y = v.y*ilength;
  1081. result.z = v.z*ilength;
  1082. result.w = v.w*ilength;
  1083. }
  1084. return result;
  1085. }
  1086. // Get min value for each pair of components
  1087. RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2)
  1088. {
  1089. Vector4 result = { 0 };
  1090. result.x = fminf(v1.x, v2.x);
  1091. result.y = fminf(v1.y, v2.y);
  1092. result.z = fminf(v1.z, v2.z);
  1093. result.w = fminf(v1.w, v2.w);
  1094. return result;
  1095. }
  1096. // Get max value for each pair of components
  1097. RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2)
  1098. {
  1099. Vector4 result = { 0 };
  1100. result.x = fmaxf(v1.x, v2.x);
  1101. result.y = fmaxf(v1.y, v2.y);
  1102. result.z = fmaxf(v1.z, v2.z);
  1103. result.w = fmaxf(v1.w, v2.w);
  1104. return result;
  1105. }
  1106. // Calculate linear interpolation between two vectors
  1107. RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount)
  1108. {
  1109. Vector4 result = { 0 };
  1110. result.x = v1.x + amount*(v2.x - v1.x);
  1111. result.y = v1.y + amount*(v2.y - v1.y);
  1112. result.z = v1.z + amount*(v2.z - v1.z);
  1113. result.w = v1.w + amount*(v2.w - v1.w);
  1114. return result;
  1115. }
  1116. // Move Vector towards target
  1117. RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDistance)
  1118. {
  1119. Vector4 result = { 0 };
  1120. float dx = target.x - v.x;
  1121. float dy = target.y - v.y;
  1122. float dz = target.z - v.z;
  1123. float dw = target.w - v.w;
  1124. float value = (dx*dx) + (dy*dy) + (dz*dz) + (dw*dw);
  1125. if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;
  1126. float dist = sqrtf(value);
  1127. result.x = v.x + dx/dist*maxDistance;
  1128. result.y = v.y + dy/dist*maxDistance;
  1129. result.z = v.z + dz/dist*maxDistance;
  1130. result.w = v.w + dw/dist*maxDistance;
  1131. return result;
  1132. }
  1133. // Invert the given vector
  1134. RMAPI Vector4 Vector4Invert(Vector4 v)
  1135. {
  1136. Vector4 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z, 1.0f/v.w };
  1137. return result;
  1138. }
  1139. // Check whether two given vectors are almost equal
  1140. RMAPI int Vector4Equals(Vector4 p, Vector4 q)
  1141. {
  1142. #if !defined(EPSILON)
  1143. #define EPSILON 0.000001f
  1144. #endif
  1145. int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
  1146. ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
  1147. ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&
  1148. ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))));
  1149. return result;
  1150. }
  1151. //----------------------------------------------------------------------------------
  1152. // Module Functions Definition - Matrix math
  1153. //----------------------------------------------------------------------------------
  1154. // Compute matrix determinant
  1155. RMAPI float MatrixDeterminant(Matrix mat)
  1156. {
  1157. float result = 0.0f;
  1158. // Cache the matrix values (speed optimization)
  1159. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  1160. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  1161. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  1162. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  1163. result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  1164. a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  1165. a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  1166. a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  1167. a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  1168. a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  1169. return result;
  1170. }
  1171. // Get the trace of the matrix (sum of the values along the diagonal)
  1172. RMAPI float MatrixTrace(Matrix mat)
  1173. {
  1174. float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15);
  1175. return result;
  1176. }
  1177. // Transposes provided matrix
  1178. RMAPI Matrix MatrixTranspose(Matrix mat)
  1179. {
  1180. Matrix result = { 0 };
  1181. result.m0 = mat.m0;
  1182. result.m1 = mat.m4;
  1183. result.m2 = mat.m8;
  1184. result.m3 = mat.m12;
  1185. result.m4 = mat.m1;
  1186. result.m5 = mat.m5;
  1187. result.m6 = mat.m9;
  1188. result.m7 = mat.m13;
  1189. result.m8 = mat.m2;
  1190. result.m9 = mat.m6;
  1191. result.m10 = mat.m10;
  1192. result.m11 = mat.m14;
  1193. result.m12 = mat.m3;
  1194. result.m13 = mat.m7;
  1195. result.m14 = mat.m11;
  1196. result.m15 = mat.m15;
  1197. return result;
  1198. }
  1199. // Invert provided matrix
  1200. RMAPI Matrix MatrixInvert(Matrix mat)
  1201. {
  1202. Matrix result = { 0 };
  1203. // Cache the matrix values (speed optimization)
  1204. float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
  1205. float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
  1206. float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
  1207. float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
  1208. float b00 = a00*a11 - a01*a10;
  1209. float b01 = a00*a12 - a02*a10;
  1210. float b02 = a00*a13 - a03*a10;
  1211. float b03 = a01*a12 - a02*a11;
  1212. float b04 = a01*a13 - a03*a11;
  1213. float b05 = a02*a13 - a03*a12;
  1214. float b06 = a20*a31 - a21*a30;
  1215. float b07 = a20*a32 - a22*a30;
  1216. float b08 = a20*a33 - a23*a30;
  1217. float b09 = a21*a32 - a22*a31;
  1218. float b10 = a21*a33 - a23*a31;
  1219. float b11 = a22*a33 - a23*a32;
  1220. // Calculate the invert determinant (inlined to avoid double-caching)
  1221. float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  1222. result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
  1223. result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
  1224. result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
  1225. result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
  1226. result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
  1227. result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
  1228. result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
  1229. result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
  1230. result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
  1231. result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
  1232. result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
  1233. result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
  1234. result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
  1235. result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
  1236. result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
  1237. result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
  1238. return result;
  1239. }
  1240. // Get identity matrix
  1241. RMAPI Matrix MatrixIdentity(void)
  1242. {
  1243. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1244. 0.0f, 1.0f, 0.0f, 0.0f,
  1245. 0.0f, 0.0f, 1.0f, 0.0f,
  1246. 0.0f, 0.0f, 0.0f, 1.0f };
  1247. return result;
  1248. }
  1249. // Add two matrices
  1250. RMAPI Matrix MatrixAdd(Matrix left, Matrix right)
  1251. {
  1252. Matrix result = { 0 };
  1253. result.m0 = left.m0 + right.m0;
  1254. result.m1 = left.m1 + right.m1;
  1255. result.m2 = left.m2 + right.m2;
  1256. result.m3 = left.m3 + right.m3;
  1257. result.m4 = left.m4 + right.m4;
  1258. result.m5 = left.m5 + right.m5;
  1259. result.m6 = left.m6 + right.m6;
  1260. result.m7 = left.m7 + right.m7;
  1261. result.m8 = left.m8 + right.m8;
  1262. result.m9 = left.m9 + right.m9;
  1263. result.m10 = left.m10 + right.m10;
  1264. result.m11 = left.m11 + right.m11;
  1265. result.m12 = left.m12 + right.m12;
  1266. result.m13 = left.m13 + right.m13;
  1267. result.m14 = left.m14 + right.m14;
  1268. result.m15 = left.m15 + right.m15;
  1269. return result;
  1270. }
  1271. // Subtract two matrices (left - right)
  1272. RMAPI Matrix MatrixSubtract(Matrix left, Matrix right)
  1273. {
  1274. Matrix result = { 0 };
  1275. result.m0 = left.m0 - right.m0;
  1276. result.m1 = left.m1 - right.m1;
  1277. result.m2 = left.m2 - right.m2;
  1278. result.m3 = left.m3 - right.m3;
  1279. result.m4 = left.m4 - right.m4;
  1280. result.m5 = left.m5 - right.m5;
  1281. result.m6 = left.m6 - right.m6;
  1282. result.m7 = left.m7 - right.m7;
  1283. result.m8 = left.m8 - right.m8;
  1284. result.m9 = left.m9 - right.m9;
  1285. result.m10 = left.m10 - right.m10;
  1286. result.m11 = left.m11 - right.m11;
  1287. result.m12 = left.m12 - right.m12;
  1288. result.m13 = left.m13 - right.m13;
  1289. result.m14 = left.m14 - right.m14;
  1290. result.m15 = left.m15 - right.m15;
  1291. return result;
  1292. }
  1293. // Get two matrix multiplication
  1294. // NOTE: When multiplying matrices... the order matters!
  1295. RMAPI Matrix MatrixMultiply(Matrix left, Matrix right)
  1296. {
  1297. Matrix result = { 0 };
  1298. result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
  1299. result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
  1300. result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14;
  1301. result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15;
  1302. result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12;
  1303. result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13;
  1304. result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14;
  1305. result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15;
  1306. result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12;
  1307. result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13;
  1308. result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14;
  1309. result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15;
  1310. result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12;
  1311. result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13;
  1312. result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14;
  1313. result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15;
  1314. return result;
  1315. }
  1316. // Get translation matrix
  1317. RMAPI Matrix MatrixTranslate(float x, float y, float z)
  1318. {
  1319. Matrix result = { 1.0f, 0.0f, 0.0f, x,
  1320. 0.0f, 1.0f, 0.0f, y,
  1321. 0.0f, 0.0f, 1.0f, z,
  1322. 0.0f, 0.0f, 0.0f, 1.0f };
  1323. return result;
  1324. }
  1325. // Create rotation matrix from axis and angle
  1326. // NOTE: Angle should be provided in radians
  1327. RMAPI Matrix MatrixRotate(Vector3 axis, float angle)
  1328. {
  1329. Matrix result = { 0 };
  1330. float x = axis.x, y = axis.y, z = axis.z;
  1331. float lengthSquared = x*x + y*y + z*z;
  1332. if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f))
  1333. {
  1334. float ilength = 1.0f/sqrtf(lengthSquared);
  1335. x *= ilength;
  1336. y *= ilength;
  1337. z *= ilength;
  1338. }
  1339. float sinres = sinf(angle);
  1340. float cosres = cosf(angle);
  1341. float t = 1.0f - cosres;
  1342. result.m0 = x*x*t + cosres;
  1343. result.m1 = y*x*t + z*sinres;
  1344. result.m2 = z*x*t - y*sinres;
  1345. result.m3 = 0.0f;
  1346. result.m4 = x*y*t - z*sinres;
  1347. result.m5 = y*y*t + cosres;
  1348. result.m6 = z*y*t + x*sinres;
  1349. result.m7 = 0.0f;
  1350. result.m8 = x*z*t + y*sinres;
  1351. result.m9 = y*z*t - x*sinres;
  1352. result.m10 = z*z*t + cosres;
  1353. result.m11 = 0.0f;
  1354. result.m12 = 0.0f;
  1355. result.m13 = 0.0f;
  1356. result.m14 = 0.0f;
  1357. result.m15 = 1.0f;
  1358. return result;
  1359. }
  1360. // Get x-rotation matrix
  1361. // NOTE: Angle must be provided in radians
  1362. RMAPI Matrix MatrixRotateX(float angle)
  1363. {
  1364. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1365. 0.0f, 1.0f, 0.0f, 0.0f,
  1366. 0.0f, 0.0f, 1.0f, 0.0f,
  1367. 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity()
  1368. float cosres = cosf(angle);
  1369. float sinres = sinf(angle);
  1370. result.m5 = cosres;
  1371. result.m6 = sinres;
  1372. result.m9 = -sinres;
  1373. result.m10 = cosres;
  1374. return result;
  1375. }
  1376. // Get y-rotation matrix
  1377. // NOTE: Angle must be provided in radians
  1378. RMAPI Matrix MatrixRotateY(float angle)
  1379. {
  1380. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1381. 0.0f, 1.0f, 0.0f, 0.0f,
  1382. 0.0f, 0.0f, 1.0f, 0.0f,
  1383. 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity()
  1384. float cosres = cosf(angle);
  1385. float sinres = sinf(angle);
  1386. result.m0 = cosres;
  1387. result.m2 = -sinres;
  1388. result.m8 = sinres;
  1389. result.m10 = cosres;
  1390. return result;
  1391. }
  1392. // Get z-rotation matrix
  1393. // NOTE: Angle must be provided in radians
  1394. RMAPI Matrix MatrixRotateZ(float angle)
  1395. {
  1396. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1397. 0.0f, 1.0f, 0.0f, 0.0f,
  1398. 0.0f, 0.0f, 1.0f, 0.0f,
  1399. 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity()
  1400. float cosres = cosf(angle);
  1401. float sinres = sinf(angle);
  1402. result.m0 = cosres;
  1403. result.m1 = sinres;
  1404. result.m4 = -sinres;
  1405. result.m5 = cosres;
  1406. return result;
  1407. }
  1408. // Get xyz-rotation matrix
  1409. // NOTE: Angle must be provided in radians
  1410. RMAPI Matrix MatrixRotateXYZ(Vector3 angle)
  1411. {
  1412. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1413. 0.0f, 1.0f, 0.0f, 0.0f,
  1414. 0.0f, 0.0f, 1.0f, 0.0f,
  1415. 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity()
  1416. float cosz = cosf(-angle.z);
  1417. float sinz = sinf(-angle.z);
  1418. float cosy = cosf(-angle.y);
  1419. float siny = sinf(-angle.y);
  1420. float cosx = cosf(-angle.x);
  1421. float sinx = sinf(-angle.x);
  1422. result.m0 = cosz*cosy;
  1423. result.m1 = (cosz*siny*sinx) - (sinz*cosx);
  1424. result.m2 = (cosz*siny*cosx) + (sinz*sinx);
  1425. result.m4 = sinz*cosy;
  1426. result.m5 = (sinz*siny*sinx) + (cosz*cosx);
  1427. result.m6 = (sinz*siny*cosx) - (cosz*sinx);
  1428. result.m8 = -siny;
  1429. result.m9 = cosy*sinx;
  1430. result.m10= cosy*cosx;
  1431. return result;
  1432. }
  1433. // Get zyx-rotation matrix
  1434. // NOTE: Angle must be provided in radians
  1435. RMAPI Matrix MatrixRotateZYX(Vector3 angle)
  1436. {
  1437. Matrix result = { 0 };
  1438. float cz = cosf(angle.z);
  1439. float sz = sinf(angle.z);
  1440. float cy = cosf(angle.y);
  1441. float sy = sinf(angle.y);
  1442. float cx = cosf(angle.x);
  1443. float sx = sinf(angle.x);
  1444. result.m0 = cz*cy;
  1445. result.m4 = cz*sy*sx - cx*sz;
  1446. result.m8 = sz*sx + cz*cx*sy;
  1447. result.m12 = 0;
  1448. result.m1 = cy*sz;
  1449. result.m5 = cz*cx + sz*sy*sx;
  1450. result.m9 = cx*sz*sy - cz*sx;
  1451. result.m13 = 0;
  1452. result.m2 = -sy;
  1453. result.m6 = cy*sx;
  1454. result.m10 = cy*cx;
  1455. result.m14 = 0;
  1456. result.m3 = 0;
  1457. result.m7 = 0;
  1458. result.m11 = 0;
  1459. result.m15 = 1;
  1460. return result;
  1461. }
  1462. // Get scaling matrix
  1463. RMAPI Matrix MatrixScale(float x, float y, float z)
  1464. {
  1465. Matrix result = { x, 0.0f, 0.0f, 0.0f,
  1466. 0.0f, y, 0.0f, 0.0f,
  1467. 0.0f, 0.0f, z, 0.0f,
  1468. 0.0f, 0.0f, 0.0f, 1.0f };
  1469. return result;
  1470. }
  1471. // Get perspective projection matrix
  1472. RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double nearPlane, double farPlane)
  1473. {
  1474. Matrix result = { 0 };
  1475. float rl = (float)(right - left);
  1476. float tb = (float)(top - bottom);
  1477. float fn = (float)(farPlane - nearPlane);
  1478. result.m0 = ((float)nearPlane*2.0f)/rl;
  1479. result.m1 = 0.0f;
  1480. result.m2 = 0.0f;
  1481. result.m3 = 0.0f;
  1482. result.m4 = 0.0f;
  1483. result.m5 = ((float)nearPlane*2.0f)/tb;
  1484. result.m6 = 0.0f;
  1485. result.m7 = 0.0f;
  1486. result.m8 = ((float)right + (float)left)/rl;
  1487. result.m9 = ((float)top + (float)bottom)/tb;
  1488. result.m10 = -((float)farPlane + (float)nearPlane)/fn;
  1489. result.m11 = -1.0f;
  1490. result.m12 = 0.0f;
  1491. result.m13 = 0.0f;
  1492. result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
  1493. result.m15 = 0.0f;
  1494. return result;
  1495. }
  1496. // Get perspective projection matrix
  1497. // NOTE: Fovy angle must be provided in radians
  1498. RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, double farPlane)
  1499. {
  1500. Matrix result = { 0 };
  1501. double top = nearPlane*tan(fovY*0.5);
  1502. double bottom = -top;
  1503. double right = top*aspect;
  1504. double left = -right;
  1505. // MatrixFrustum(-right, right, -top, top, near, far);
  1506. float rl = (float)(right - left);
  1507. float tb = (float)(top - bottom);
  1508. float fn = (float)(farPlane - nearPlane);
  1509. result.m0 = ((float)nearPlane*2.0f)/rl;
  1510. result.m5 = ((float)nearPlane*2.0f)/tb;
  1511. result.m8 = ((float)right + (float)left)/rl;
  1512. result.m9 = ((float)top + (float)bottom)/tb;
  1513. result.m10 = -((float)farPlane + (float)nearPlane)/fn;
  1514. result.m11 = -1.0f;
  1515. result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
  1516. return result;
  1517. }
  1518. // Get orthographic projection matrix
  1519. RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double nearPlane, double farPlane)
  1520. {
  1521. Matrix result = { 0 };
  1522. float rl = (float)(right - left);
  1523. float tb = (float)(top - bottom);
  1524. float fn = (float)(farPlane - nearPlane);
  1525. result.m0 = 2.0f/rl;
  1526. result.m1 = 0.0f;
  1527. result.m2 = 0.0f;
  1528. result.m3 = 0.0f;
  1529. result.m4 = 0.0f;
  1530. result.m5 = 2.0f/tb;
  1531. result.m6 = 0.0f;
  1532. result.m7 = 0.0f;
  1533. result.m8 = 0.0f;
  1534. result.m9 = 0.0f;
  1535. result.m10 = -2.0f/fn;
  1536. result.m11 = 0.0f;
  1537. result.m12 = -((float)left + (float)right)/rl;
  1538. result.m13 = -((float)top + (float)bottom)/tb;
  1539. result.m14 = -((float)farPlane + (float)nearPlane)/fn;
  1540. result.m15 = 1.0f;
  1541. return result;
  1542. }
  1543. // Get camera look-at matrix (view matrix)
  1544. RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
  1545. {
  1546. Matrix result = { 0 };
  1547. float length = 0.0f;
  1548. float ilength = 0.0f;
  1549. // Vector3Subtract(eye, target)
  1550. Vector3 vz = { eye.x - target.x, eye.y - target.y, eye.z - target.z };
  1551. // Vector3Normalize(vz)
  1552. Vector3 v = vz;
  1553. length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  1554. if (length == 0.0f) length = 1.0f;
  1555. ilength = 1.0f/length;
  1556. vz.x *= ilength;
  1557. vz.y *= ilength;
  1558. vz.z *= ilength;
  1559. // Vector3CrossProduct(up, vz)
  1560. Vector3 vx = { up.y*vz.z - up.z*vz.y, up.z*vz.x - up.x*vz.z, up.x*vz.y - up.y*vz.x };
  1561. // Vector3Normalize(x)
  1562. v = vx;
  1563. length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  1564. if (length == 0.0f) length = 1.0f;
  1565. ilength = 1.0f/length;
  1566. vx.x *= ilength;
  1567. vx.y *= ilength;
  1568. vx.z *= ilength;
  1569. // Vector3CrossProduct(vz, vx)
  1570. Vector3 vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x };
  1571. result.m0 = vx.x;
  1572. result.m1 = vy.x;
  1573. result.m2 = vz.x;
  1574. result.m3 = 0.0f;
  1575. result.m4 = vx.y;
  1576. result.m5 = vy.y;
  1577. result.m6 = vz.y;
  1578. result.m7 = 0.0f;
  1579. result.m8 = vx.z;
  1580. result.m9 = vy.z;
  1581. result.m10 = vz.z;
  1582. result.m11 = 0.0f;
  1583. result.m12 = -(vx.x*eye.x + vx.y*eye.y + vx.z*eye.z); // Vector3DotProduct(vx, eye)
  1584. result.m13 = -(vy.x*eye.x + vy.y*eye.y + vy.z*eye.z); // Vector3DotProduct(vy, eye)
  1585. result.m14 = -(vz.x*eye.x + vz.y*eye.y + vz.z*eye.z); // Vector3DotProduct(vz, eye)
  1586. result.m15 = 1.0f;
  1587. return result;
  1588. }
  1589. // Get float array of matrix data
  1590. RMAPI float16 MatrixToFloatV(Matrix mat)
  1591. {
  1592. float16 result = { 0 };
  1593. result.v[0] = mat.m0;
  1594. result.v[1] = mat.m1;
  1595. result.v[2] = mat.m2;
  1596. result.v[3] = mat.m3;
  1597. result.v[4] = mat.m4;
  1598. result.v[5] = mat.m5;
  1599. result.v[6] = mat.m6;
  1600. result.v[7] = mat.m7;
  1601. result.v[8] = mat.m8;
  1602. result.v[9] = mat.m9;
  1603. result.v[10] = mat.m10;
  1604. result.v[11] = mat.m11;
  1605. result.v[12] = mat.m12;
  1606. result.v[13] = mat.m13;
  1607. result.v[14] = mat.m14;
  1608. result.v[15] = mat.m15;
  1609. return result;
  1610. }
  1611. //----------------------------------------------------------------------------------
  1612. // Module Functions Definition - Quaternion math
  1613. //----------------------------------------------------------------------------------
  1614. // Add two quaternions
  1615. RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2)
  1616. {
  1617. Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w};
  1618. return result;
  1619. }
  1620. // Add quaternion and float value
  1621. RMAPI Quaternion QuaternionAddValue(Quaternion q, float add)
  1622. {
  1623. Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add};
  1624. return result;
  1625. }
  1626. // Subtract two quaternions
  1627. RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2)
  1628. {
  1629. Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w};
  1630. return result;
  1631. }
  1632. // Subtract quaternion and float value
  1633. RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub)
  1634. {
  1635. Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub};
  1636. return result;
  1637. }
  1638. // Get identity quaternion
  1639. RMAPI Quaternion QuaternionIdentity(void)
  1640. {
  1641. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  1642. return result;
  1643. }
  1644. // Computes the length of a quaternion
  1645. RMAPI float QuaternionLength(Quaternion q)
  1646. {
  1647. float result = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1648. return result;
  1649. }
  1650. // Normalize provided quaternion
  1651. RMAPI Quaternion QuaternionNormalize(Quaternion q)
  1652. {
  1653. Quaternion result = { 0 };
  1654. float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1655. if (length == 0.0f) length = 1.0f;
  1656. float ilength = 1.0f/length;
  1657. result.x = q.x*ilength;
  1658. result.y = q.y*ilength;
  1659. result.z = q.z*ilength;
  1660. result.w = q.w*ilength;
  1661. return result;
  1662. }
  1663. // Invert provided quaternion
  1664. RMAPI Quaternion QuaternionInvert(Quaternion q)
  1665. {
  1666. Quaternion result = q;
  1667. float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
  1668. if (lengthSq != 0.0f)
  1669. {
  1670. float invLength = 1.0f/lengthSq;
  1671. result.x *= -invLength;
  1672. result.y *= -invLength;
  1673. result.z *= -invLength;
  1674. result.w *= invLength;
  1675. }
  1676. return result;
  1677. }
  1678. // Calculate two quaternion multiplication
  1679. RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
  1680. {
  1681. Quaternion result = { 0 };
  1682. float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
  1683. float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
  1684. result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
  1685. result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
  1686. result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
  1687. result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
  1688. return result;
  1689. }
  1690. // Scale quaternion by float value
  1691. RMAPI Quaternion QuaternionScale(Quaternion q, float mul)
  1692. {
  1693. Quaternion result = { 0 };
  1694. result.x = q.x*mul;
  1695. result.y = q.y*mul;
  1696. result.z = q.z*mul;
  1697. result.w = q.w*mul;
  1698. return result;
  1699. }
  1700. // Divide two quaternions
  1701. RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2)
  1702. {
  1703. Quaternion result = { q1.x/q2.x, q1.y/q2.y, q1.z/q2.z, q1.w/q2.w };
  1704. return result;
  1705. }
  1706. // Calculate linear interpolation between two quaternions
  1707. RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
  1708. {
  1709. Quaternion result = { 0 };
  1710. result.x = q1.x + amount*(q2.x - q1.x);
  1711. result.y = q1.y + amount*(q2.y - q1.y);
  1712. result.z = q1.z + amount*(q2.z - q1.z);
  1713. result.w = q1.w + amount*(q2.w - q1.w);
  1714. return result;
  1715. }
  1716. // Calculate slerp-optimized interpolation between two quaternions
  1717. RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
  1718. {
  1719. Quaternion result = { 0 };
  1720. // QuaternionLerp(q1, q2, amount)
  1721. result.x = q1.x + amount*(q2.x - q1.x);
  1722. result.y = q1.y + amount*(q2.y - q1.y);
  1723. result.z = q1.z + amount*(q2.z - q1.z);
  1724. result.w = q1.w + amount*(q2.w - q1.w);
  1725. // QuaternionNormalize(q);
  1726. Quaternion q = result;
  1727. float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1728. if (length == 0.0f) length = 1.0f;
  1729. float ilength = 1.0f/length;
  1730. result.x = q.x*ilength;
  1731. result.y = q.y*ilength;
  1732. result.z = q.z*ilength;
  1733. result.w = q.w*ilength;
  1734. return result;
  1735. }
  1736. // Calculates spherical linear interpolation between two quaternions
  1737. RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
  1738. {
  1739. Quaternion result = { 0 };
  1740. #if !defined(EPSILON)
  1741. #define EPSILON 0.000001f
  1742. #endif
  1743. float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
  1744. if (cosHalfTheta < 0)
  1745. {
  1746. q2.x = -q2.x; q2.y = -q2.y; q2.z = -q2.z; q2.w = -q2.w;
  1747. cosHalfTheta = -cosHalfTheta;
  1748. }
  1749. if (fabsf(cosHalfTheta) >= 1.0f) result = q1;
  1750. else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
  1751. else
  1752. {
  1753. float halfTheta = acosf(cosHalfTheta);
  1754. float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta);
  1755. if (fabsf(sinHalfTheta) < EPSILON)
  1756. {
  1757. result.x = (q1.x*0.5f + q2.x*0.5f);
  1758. result.y = (q1.y*0.5f + q2.y*0.5f);
  1759. result.z = (q1.z*0.5f + q2.z*0.5f);
  1760. result.w = (q1.w*0.5f + q2.w*0.5f);
  1761. }
  1762. else
  1763. {
  1764. float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta;
  1765. float ratioB = sinf(amount*halfTheta)/sinHalfTheta;
  1766. result.x = (q1.x*ratioA + q2.x*ratioB);
  1767. result.y = (q1.y*ratioA + q2.y*ratioB);
  1768. result.z = (q1.z*ratioA + q2.z*ratioB);
  1769. result.w = (q1.w*ratioA + q2.w*ratioB);
  1770. }
  1771. }
  1772. return result;
  1773. }
  1774. // Calculate quaternion cubic spline interpolation using Cubic Hermite Spline algorithm
  1775. // as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic
  1776. RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTangent1, Quaternion q2, Quaternion inTangent2, float t)
  1777. {
  1778. float t2 = t*t;
  1779. float t3 = t2*t;
  1780. float h00 = 2*t3 - 3*t2 + 1;
  1781. float h10 = t3 - 2*t2 + t;
  1782. float h01 = -2*t3 + 3*t2;
  1783. float h11 = t3 - t2;
  1784. Quaternion p0 = QuaternionScale(q1, h00);
  1785. Quaternion m0 = QuaternionScale(outTangent1, h10);
  1786. Quaternion p1 = QuaternionScale(q2, h01);
  1787. Quaternion m1 = QuaternionScale(inTangent2, h11);
  1788. Quaternion result = { 0 };
  1789. result = QuaternionAdd(p0, m0);
  1790. result = QuaternionAdd(result, p1);
  1791. result = QuaternionAdd(result, m1);
  1792. result = QuaternionNormalize(result);
  1793. return result;
  1794. }
  1795. // Calculate quaternion based on the rotation from one vector to another
  1796. RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
  1797. {
  1798. Quaternion result = { 0 };
  1799. float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to)
  1800. Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to)
  1801. result.x = cross.x;
  1802. result.y = cross.y;
  1803. result.z = cross.z;
  1804. result.w = 1.0f + cos2Theta;
  1805. // QuaternionNormalize(q);
  1806. // NOTE: Normalize to essentially nlerp the original and identity to 0.5
  1807. Quaternion q = result;
  1808. float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1809. if (length == 0.0f) length = 1.0f;
  1810. float ilength = 1.0f/length;
  1811. result.x = q.x*ilength;
  1812. result.y = q.y*ilength;
  1813. result.z = q.z*ilength;
  1814. result.w = q.w*ilength;
  1815. return result;
  1816. }
  1817. // Get a quaternion for a given rotation matrix
  1818. RMAPI Quaternion QuaternionFromMatrix(Matrix mat)
  1819. {
  1820. Quaternion result = { 0 };
  1821. float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10;
  1822. float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10;
  1823. float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10;
  1824. float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5;
  1825. int biggestIndex = 0;
  1826. float fourBiggestSquaredMinus1 = fourWSquaredMinus1;
  1827. if (fourXSquaredMinus1 > fourBiggestSquaredMinus1)
  1828. {
  1829. fourBiggestSquaredMinus1 = fourXSquaredMinus1;
  1830. biggestIndex = 1;
  1831. }
  1832. if (fourYSquaredMinus1 > fourBiggestSquaredMinus1)
  1833. {
  1834. fourBiggestSquaredMinus1 = fourYSquaredMinus1;
  1835. biggestIndex = 2;
  1836. }
  1837. if (fourZSquaredMinus1 > fourBiggestSquaredMinus1)
  1838. {
  1839. fourBiggestSquaredMinus1 = fourZSquaredMinus1;
  1840. biggestIndex = 3;
  1841. }
  1842. float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f;
  1843. float mult = 0.25f/biggestVal;
  1844. switch (biggestIndex)
  1845. {
  1846. case 0:
  1847. result.w = biggestVal;
  1848. result.x = (mat.m6 - mat.m9)*mult;
  1849. result.y = (mat.m8 - mat.m2)*mult;
  1850. result.z = (mat.m1 - mat.m4)*mult;
  1851. break;
  1852. case 1:
  1853. result.x = biggestVal;
  1854. result.w = (mat.m6 - mat.m9)*mult;
  1855. result.y = (mat.m1 + mat.m4)*mult;
  1856. result.z = (mat.m8 + mat.m2)*mult;
  1857. break;
  1858. case 2:
  1859. result.y = biggestVal;
  1860. result.w = (mat.m8 - mat.m2)*mult;
  1861. result.x = (mat.m1 + mat.m4)*mult;
  1862. result.z = (mat.m6 + mat.m9)*mult;
  1863. break;
  1864. case 3:
  1865. result.z = biggestVal;
  1866. result.w = (mat.m1 - mat.m4)*mult;
  1867. result.x = (mat.m8 + mat.m2)*mult;
  1868. result.y = (mat.m6 + mat.m9)*mult;
  1869. break;
  1870. }
  1871. return result;
  1872. }
  1873. // Get a matrix for a given quaternion
  1874. RMAPI Matrix QuaternionToMatrix(Quaternion q)
  1875. {
  1876. Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
  1877. 0.0f, 1.0f, 0.0f, 0.0f,
  1878. 0.0f, 0.0f, 1.0f, 0.0f,
  1879. 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity()
  1880. float a2 = q.x*q.x;
  1881. float b2 = q.y*q.y;
  1882. float c2 = q.z*q.z;
  1883. float ac = q.x*q.z;
  1884. float ab = q.x*q.y;
  1885. float bc = q.y*q.z;
  1886. float ad = q.w*q.x;
  1887. float bd = q.w*q.y;
  1888. float cd = q.w*q.z;
  1889. result.m0 = 1 - 2*(b2 + c2);
  1890. result.m1 = 2*(ab + cd);
  1891. result.m2 = 2*(ac - bd);
  1892. result.m4 = 2*(ab - cd);
  1893. result.m5 = 1 - 2*(a2 + c2);
  1894. result.m6 = 2*(bc + ad);
  1895. result.m8 = 2*(ac + bd);
  1896. result.m9 = 2*(bc - ad);
  1897. result.m10 = 1 - 2*(a2 + b2);
  1898. return result;
  1899. }
  1900. // Get rotation quaternion for an angle and axis
  1901. // NOTE: Angle must be provided in radians
  1902. RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
  1903. {
  1904. Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
  1905. float axisLength = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z);
  1906. if (axisLength != 0.0f)
  1907. {
  1908. angle *= 0.5f;
  1909. float length = 0.0f;
  1910. float ilength = 0.0f;
  1911. // Vector3Normalize(axis)
  1912. length = axisLength;
  1913. if (length == 0.0f) length = 1.0f;
  1914. ilength = 1.0f/length;
  1915. axis.x *= ilength;
  1916. axis.y *= ilength;
  1917. axis.z *= ilength;
  1918. float sinres = sinf(angle);
  1919. float cosres = cosf(angle);
  1920. result.x = axis.x*sinres;
  1921. result.y = axis.y*sinres;
  1922. result.z = axis.z*sinres;
  1923. result.w = cosres;
  1924. // QuaternionNormalize(q);
  1925. Quaternion q = result;
  1926. length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1927. if (length == 0.0f) length = 1.0f;
  1928. ilength = 1.0f/length;
  1929. result.x = q.x*ilength;
  1930. result.y = q.y*ilength;
  1931. result.z = q.z*ilength;
  1932. result.w = q.w*ilength;
  1933. }
  1934. return result;
  1935. }
  1936. // Get the rotation angle and axis for a given quaternion
  1937. RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
  1938. {
  1939. if (fabsf(q.w) > 1.0f)
  1940. {
  1941. // QuaternionNormalize(q);
  1942. float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
  1943. if (length == 0.0f) length = 1.0f;
  1944. float ilength = 1.0f/length;
  1945. q.x = q.x*ilength;
  1946. q.y = q.y*ilength;
  1947. q.z = q.z*ilength;
  1948. q.w = q.w*ilength;
  1949. }
  1950. Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
  1951. float resAngle = 2.0f*acosf(q.w);
  1952. float den = sqrtf(1.0f - q.w*q.w);
  1953. if (den > EPSILON)
  1954. {
  1955. resAxis.x = q.x/den;
  1956. resAxis.y = q.y/den;
  1957. resAxis.z = q.z/den;
  1958. }
  1959. else
  1960. {
  1961. // This occurs when the angle is zero.
  1962. // Not a problem: just set an arbitrary normalized axis.
  1963. resAxis.x = 1.0f;
  1964. }
  1965. *outAxis = resAxis;
  1966. *outAngle = resAngle;
  1967. }
  1968. // Get the quaternion equivalent to Euler angles
  1969. // NOTE: Rotation order is ZYX
  1970. RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll)
  1971. {
  1972. Quaternion result = { 0 };
  1973. float x0 = cosf(pitch*0.5f);
  1974. float x1 = sinf(pitch*0.5f);
  1975. float y0 = cosf(yaw*0.5f);
  1976. float y1 = sinf(yaw*0.5f);
  1977. float z0 = cosf(roll*0.5f);
  1978. float z1 = sinf(roll*0.5f);
  1979. result.x = x1*y0*z0 - x0*y1*z1;
  1980. result.y = x0*y1*z0 + x1*y0*z1;
  1981. result.z = x0*y0*z1 - x1*y1*z0;
  1982. result.w = x0*y0*z0 + x1*y1*z1;
  1983. return result;
  1984. }
  1985. // Get the Euler angles equivalent to quaternion (roll, pitch, yaw)
  1986. // NOTE: Angles are returned in a Vector3 struct in radians
  1987. RMAPI Vector3 QuaternionToEuler(Quaternion q)
  1988. {
  1989. Vector3 result = { 0 };
  1990. // Roll (x-axis rotation)
  1991. float x0 = 2.0f*(q.w*q.x + q.y*q.z);
  1992. float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
  1993. result.x = atan2f(x0, x1);
  1994. // Pitch (y-axis rotation)
  1995. float y0 = 2.0f*(q.w*q.y - q.z*q.x);
  1996. y0 = y0 > 1.0f ? 1.0f : y0;
  1997. y0 = y0 < -1.0f ? -1.0f : y0;
  1998. result.y = asinf(y0);
  1999. // Yaw (z-axis rotation)
  2000. float z0 = 2.0f*(q.w*q.z + q.x*q.y);
  2001. float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
  2002. result.z = atan2f(z0, z1);
  2003. return result;
  2004. }
  2005. // Transform a quaternion given a transformation matrix
  2006. RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat)
  2007. {
  2008. Quaternion result = { 0 };
  2009. result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w;
  2010. result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w;
  2011. result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w;
  2012. result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w;
  2013. return result;
  2014. }
  2015. // Check whether two given quaternions are almost equal
  2016. RMAPI int QuaternionEquals(Quaternion p, Quaternion q)
  2017. {
  2018. #if !defined(EPSILON)
  2019. #define EPSILON 0.000001f
  2020. #endif
  2021. int result = (((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
  2022. ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
  2023. ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&
  2024. ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) ||
  2025. (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
  2026. ((fabsf(p.y + q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
  2027. ((fabsf(p.z + q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&
  2028. ((fabsf(p.w + q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w))))));
  2029. return result;
  2030. }
  2031. // Decompose a transformation matrix into its rotational, translational and scaling components
  2032. RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale)
  2033. {
  2034. // Extract translation.
  2035. translation->x = mat.m12;
  2036. translation->y = mat.m13;
  2037. translation->z = mat.m14;
  2038. // Extract upper-left for determinant computation
  2039. const float a = mat.m0;
  2040. const float b = mat.m4;
  2041. const float c = mat.m8;
  2042. const float d = mat.m1;
  2043. const float e = mat.m5;
  2044. const float f = mat.m9;
  2045. const float g = mat.m2;
  2046. const float h = mat.m6;
  2047. const float i = mat.m10;
  2048. const float A = e*i - f*h;
  2049. const float B = f*g - d*i;
  2050. const float C = d*h - e*g;
  2051. // Extract scale
  2052. const float det = a*A + b*B + c*C;
  2053. Vector3 abc = { a, b, c };
  2054. Vector3 def = { d, e, f };
  2055. Vector3 ghi = { g, h, i };
  2056. float scalex = Vector3Length(abc);
  2057. float scaley = Vector3Length(def);
  2058. float scalez = Vector3Length(ghi);
  2059. Vector3 s = { scalex, scaley, scalez };
  2060. if (det < 0) s = Vector3Negate(s);
  2061. *scale = s;
  2062. // Remove scale from the matrix if it is not close to zero
  2063. Matrix clone = mat;
  2064. if (!FloatEquals(det, 0))
  2065. {
  2066. clone.m0 /= s.x;
  2067. clone.m4 /= s.x;
  2068. clone.m8 /= s.x;
  2069. clone.m1 /= s.y;
  2070. clone.m5 /= s.y;
  2071. clone.m9 /= s.y;
  2072. clone.m2 /= s.z;
  2073. clone.m6 /= s.z;
  2074. clone.m10 /= s.z;
  2075. // Extract rotation
  2076. *rotation = QuaternionFromMatrix(clone);
  2077. }
  2078. else
  2079. {
  2080. // Set to identity if close to zero
  2081. *rotation = QuaternionIdentity();
  2082. }
  2083. }
  2084. #if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)
  2085. // Optional C++ math operators
  2086. //-------------------------------------------------------------------------------
  2087. // Vector2 operators
  2088. static constexpr Vector2 Vector2Zeros = { 0, 0 };
  2089. static constexpr Vector2 Vector2Ones = { 1, 1 };
  2090. static constexpr Vector2 Vector2UnitX = { 1, 0 };
  2091. static constexpr Vector2 Vector2UnitY = { 0, 1 };
  2092. inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
  2093. {
  2094. return Vector2Add(lhs, rhs);
  2095. }
  2096. inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)
  2097. {
  2098. lhs = Vector2Add(lhs, rhs);
  2099. return lhs;
  2100. }
  2101. inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
  2102. {
  2103. return Vector2Subtract(lhs, rhs);
  2104. }
  2105. inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
  2106. {
  2107. lhs = Vector2Subtract(lhs, rhs);
  2108. return lhs;
  2109. }
  2110. inline Vector2 operator * (const Vector2& lhs, const float& rhs)
  2111. {
  2112. return Vector2Scale(lhs, rhs);
  2113. }
  2114. inline const Vector2& operator *= (Vector2& lhs, const float& rhs)
  2115. {
  2116. lhs = Vector2Scale(lhs, rhs);
  2117. return lhs;
  2118. }
  2119. inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
  2120. {
  2121. return Vector2Multiply(lhs, rhs);
  2122. }
  2123. inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)
  2124. {
  2125. lhs = Vector2Multiply(lhs, rhs);
  2126. return lhs;
  2127. }
  2128. inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
  2129. {
  2130. return Vector2Transform(lhs, rhs);
  2131. }
  2132. inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)
  2133. {
  2134. lhs = Vector2Transform(lhs, rhs);
  2135. return lhs;
  2136. }
  2137. inline Vector2 operator / (const Vector2& lhs, const float& rhs)
  2138. {
  2139. return Vector2Scale(lhs, 1.0f / rhs);
  2140. }
  2141. inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
  2142. {
  2143. lhs = Vector2Scale(lhs, rhs);
  2144. return lhs;
  2145. }
  2146. inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
  2147. {
  2148. return Vector2Divide(lhs, rhs);
  2149. }
  2150. inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)
  2151. {
  2152. lhs = Vector2Divide(lhs, rhs);
  2153. return lhs;
  2154. }
  2155. inline bool operator == (const Vector2& lhs, const Vector2& rhs)
  2156. {
  2157. return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);
  2158. }
  2159. inline bool operator != (const Vector2& lhs, const Vector2& rhs)
  2160. {
  2161. return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);
  2162. }
  2163. // Vector3 operators
  2164. static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };
  2165. static constexpr Vector3 Vector3Ones = { 1, 1, 1 };
  2166. static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };
  2167. static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };
  2168. static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };
  2169. inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
  2170. {
  2171. return Vector3Add(lhs, rhs);
  2172. }
  2173. inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)
  2174. {
  2175. lhs = Vector3Add(lhs, rhs);
  2176. return lhs;
  2177. }
  2178. inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
  2179. {
  2180. return Vector3Subtract(lhs, rhs);
  2181. }
  2182. inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
  2183. {
  2184. lhs = Vector3Subtract(lhs, rhs);
  2185. return lhs;
  2186. }
  2187. inline Vector3 operator * (const Vector3& lhs, const float& rhs)
  2188. {
  2189. return Vector3Scale(lhs, rhs);
  2190. }
  2191. inline const Vector3& operator *= (Vector3& lhs, const float& rhs)
  2192. {
  2193. lhs = Vector3Scale(lhs, rhs);
  2194. return lhs;
  2195. }
  2196. inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
  2197. {
  2198. return Vector3Multiply(lhs, rhs);
  2199. }
  2200. inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)
  2201. {
  2202. lhs = Vector3Multiply(lhs, rhs);
  2203. return lhs;
  2204. }
  2205. inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
  2206. {
  2207. return Vector3Transform(lhs, rhs);
  2208. }
  2209. inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)
  2210. {
  2211. lhs = Vector3Transform(lhs, rhs);
  2212. return lhs;
  2213. }
  2214. inline Vector3 operator / (const Vector3& lhs, const float& rhs)
  2215. {
  2216. return Vector3Scale(lhs, 1.0f / rhs);
  2217. }
  2218. inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
  2219. {
  2220. lhs = Vector3Scale(lhs, rhs);
  2221. return lhs;
  2222. }
  2223. inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
  2224. {
  2225. return Vector3Divide(lhs, rhs);
  2226. }
  2227. inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)
  2228. {
  2229. lhs = Vector3Divide(lhs, rhs);
  2230. return lhs;
  2231. }
  2232. inline bool operator == (const Vector3& lhs, const Vector3& rhs)
  2233. {
  2234. return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);
  2235. }
  2236. inline bool operator != (const Vector3& lhs, const Vector3& rhs)
  2237. {
  2238. return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);
  2239. }
  2240. // Vector4 operators
  2241. static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };
  2242. static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };
  2243. static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };
  2244. static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };
  2245. static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };
  2246. static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };
  2247. inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
  2248. {
  2249. return Vector4Add(lhs, rhs);
  2250. }
  2251. inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)
  2252. {
  2253. lhs = Vector4Add(lhs, rhs);
  2254. return lhs;
  2255. }
  2256. inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
  2257. {
  2258. return Vector4Subtract(lhs, rhs);
  2259. }
  2260. inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
  2261. {
  2262. lhs = Vector4Subtract(lhs, rhs);
  2263. return lhs;
  2264. }
  2265. inline Vector4 operator * (const Vector4& lhs, const float& rhs)
  2266. {
  2267. return Vector4Scale(lhs, rhs);
  2268. }
  2269. inline const Vector4& operator *= (Vector4& lhs, const float& rhs)
  2270. {
  2271. lhs = Vector4Scale(lhs, rhs);
  2272. return lhs;
  2273. }
  2274. inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
  2275. {
  2276. return Vector4Multiply(lhs, rhs);
  2277. }
  2278. inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
  2279. {
  2280. lhs = Vector4Multiply(lhs, rhs);
  2281. return lhs;
  2282. }
  2283. inline Vector4 operator / (const Vector4& lhs, const float& rhs)
  2284. {
  2285. return Vector4Scale(lhs, 1.0f / rhs);
  2286. }
  2287. inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
  2288. {
  2289. lhs = Vector4Scale(lhs, rhs);
  2290. return lhs;
  2291. }
  2292. inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
  2293. {
  2294. return Vector4Divide(lhs, rhs);
  2295. }
  2296. inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)
  2297. {
  2298. lhs = Vector4Divide(lhs, rhs);
  2299. return lhs;
  2300. }
  2301. inline bool operator == (const Vector4& lhs, const Vector4& rhs)
  2302. {
  2303. return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);
  2304. }
  2305. inline bool operator != (const Vector4& lhs, const Vector4& rhs)
  2306. {
  2307. return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);
  2308. }
  2309. // Quaternion operators
  2310. static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };
  2311. static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };
  2312. static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };
  2313. inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
  2314. {
  2315. return QuaternionAddValue(lhs, rhs);
  2316. }
  2317. inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)
  2318. {
  2319. lhs = QuaternionAddValue(lhs, rhs);
  2320. return lhs;
  2321. }
  2322. inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
  2323. {
  2324. return QuaternionSubtractValue(lhs, rhs);
  2325. }
  2326. inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)
  2327. {
  2328. lhs = QuaternionSubtractValue(lhs, rhs);
  2329. return lhs;
  2330. }
  2331. inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
  2332. {
  2333. return QuaternionTransform(lhs, rhs);
  2334. }
  2335. inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)
  2336. {
  2337. lhs = QuaternionTransform(lhs, rhs);
  2338. return lhs;
  2339. }
  2340. // Matrix operators
  2341. inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
  2342. {
  2343. return MatrixAdd(lhs, rhs);
  2344. }
  2345. inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)
  2346. {
  2347. lhs = MatrixAdd(lhs, rhs);
  2348. return lhs;
  2349. }
  2350. inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
  2351. {
  2352. return MatrixSubtract(lhs, rhs);
  2353. }
  2354. inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)
  2355. {
  2356. lhs = MatrixSubtract(lhs, rhs);
  2357. return lhs;
  2358. }
  2359. inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)
  2360. {
  2361. return MatrixMultiply(lhs, rhs);
  2362. }
  2363. inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)
  2364. {
  2365. lhs = MatrixMultiply(lhs, rhs);
  2366. return lhs;
  2367. }
  2368. //-------------------------------------------------------------------------------
  2369. #endif // C++ operators
  2370. #endif // RAYMATH_H