-- For luaJit compatibility. if table.unpack == nil then table.unpack = unpack end local Vector3 = require( "vector3" ) local Matrix = require( "matrix" ) local Quaternion = {} local metatable = { __index = Quaternion, __tostring = function( q ) return "{"..tostring( q.x )..", "..tostring( q.y )..", "..tostring( q.z )..", "..tostring( q.w ).."}" end, __add = function( q1, q2 ) return Quaternion:newT( RL.QuaternionAdd( q1, q2 ) ) end, __sub = function( q1, q2 ) return Quaternion:newT( RL.QuaternionSubtract( q1, q2 ) ) end, __mul = function( q1, q2 ) return Quaternion:newT( RL.QuaternionMultiply( q1, q2 ) ) end, __div = function( q1, q2 ) return Quaternion:newT( RL.QuaternionDivide( q1, q2 ) ) end, __unm = function( q ) return Quaternion:newT( RL.QuaternionInvert( q ) ) end, __len = function() return 4 end, __eq = function( q1, q2 ) return RL.QuaternionEquals( q1, q2 ) == 1 end, __concat = function( a, b ) return tostring( a )..tostring( b ) end, } function Quaternion:new( x, y, z, w ) local object = setmetatable( {}, metatable ) object.x = x or 0 object.y = y or 0 object.z = z or 0 object.w = w or 1 return object end function Quaternion:newT( t ) local object = setmetatable( {}, metatable ) object.x, object.y, object.z, object.w = table.unpack( t ) return object end function Quaternion:set( x, y, z, w ) self.x = x or 0 self.y = y or 0 self.z = z or 0 self.w = w or 1 end function Quaternion:setT( t ) self.x, self.y, self.z, self.w = table.unpack( t ) end function Quaternion:arr() return { self.x, self.y, self.z, self.w } end function Quaternion:unpack() return self.x, self.y, self.z, self.w end function Quaternion:clone() return Quaternion:new( self.x, self.y, self.z, self.w ) end function Quaternion:addValue( value ) return Quaternion:newT( RL.QuaternionAddValue( self, value ) ) end function Quaternion:subValue( value ) return Quaternion:newT( RL.QuaternionSubtractValue( self, value ) ) end function Quaternion:identity() return Quaternion:newT( RL.QuaternionIdentity() ) end function Quaternion:length() return RL.QuaternionLength( self ) end function Quaternion:normalize() return Quaternion:newT( RL.QuaternionNormalize( self ) ) end function Quaternion:invert() return Quaternion:newT( RL.QuaternionInvert( self ) ) end function Quaternion:scale( scalar ) return Quaternion:newT( RL.QuaternionScale( self, scalar ) ) end function Quaternion:lerp( q2, value ) return Quaternion:newT( RL.QuaternionLerp( self, q2, value ) ) end function Quaternion:nLerp( q2, value ) return Quaternion:newT( RL.QuaternionNLerp( self, q2, value ) ) end function Quaternion:sLerp( q2, value ) return Quaternion:newT( RL.QuaternionSLerp( self, q2, value ) ) end function Quaternion:fromVector3ToVector3( from, to ) return Vector3:newT( RL.QuaternionFromVector3ToVector3( from, to ) ) end function Quaternion:fromMatrix( mat ) return Quaternion:newT( RL.QuaternionFromMatrix( mat ) ) end function Quaternion:toMatrix() return Matrix:newT( RL.QuaternionToMatrix( self ) ) end function Quaternion:fromAxisAngle( axis, angle ) return Quaternion:newT( RL.QuaternionFromAxisAngle( axis, angle ) ) end function Quaternion:toAxisAngle() local axis, angle = Quaternion:newT( RL.QuaternionToAxisAngle( self ) ) return Vector3:new( axis ), angle end function Quaternion:fromEuler( pitch, yaw, roll ) return Quaternion:newT( RL.QuaternionFromEuler( pitch, yaw, roll ) ) end function Quaternion:toEuler() return Vector3:newT( RL.QuaternionToEuler( self ) ) end function Quaternion:transform( mat ) return Quaternion:newT( RL.QuaternionTransform( self, mat ) ) end local TEMP_COUNT = 100 local tempPool = {} local curTemp = 1 for _ = 1, TEMP_COUNT do table.insert( tempPool, Quaternion:new( 0, 0, 0, 1 ) ) end -- Uses pre generated objects to avoid "slow" table generation. function Quaternion:temp( x, y, z, w ) local object = tempPool[ curTemp ] curTemp = curTemp + 1 if TEMP_COUNT < curTemp then curTemp = 1 end object.x = x or 0 object.y = y or 0 object.z = z or 0 object.w = w or 1 return object end -- Uses pre generated objects to avoid "slow" table generation. function Quaternion:tempT( t ) local object = tempPool[ curTemp ] curTemp = curTemp + 1 if TEMP_COUNT < curTemp then curTemp = 1 end object.x, object.y, object.z, object.w = table.unpack( t ) return object end function Quaternion:getTempId() return curTemp end return Quaternion