Quaternions In Unreal Tournament
Below is some code that will allow you to use Quaternions in Unreal Tournament. These are taken from a brushbuilder made by Tarquin. All credit for the code goes to him. Other implementations have also been made to allow the use of Quaternions, but they should all be functionally similar. This quaternion definition has a minor bug which occurs when a full 180° rotation is applied, however, so be forewarned.
Quaternion definition
struct Quat { var() float W,X,Y,Z; };
Vector expression
// Sets the components of a vector. Vect cannot be used as it will not accept an expression. function vector eVect( float x , float y , float z ) { // for some reason vect() wont work when setting an array element local vector v ; v.x = x ; v.y = y ; v.z = z ; return v ; }
Converting Axial Rotation to a Quaternion
// Takes a vector representing an axis and an angle in radians. // Returns the quaternion representing a rotation of Theta about the axis. function quat RotationToQuat( vector Axis , float Theta ) { // Theta must be given in radians // Axis need not be normalised local quat Q ; local float L ; Axis = Normal( Axis ); Q.W = cos( Theta / 2 ) ; Q.X = Axis.X * sin( Theta / 2 ) ; Q.Y = Axis.Y * sin( Theta / 2 ) ; Q.Z = Axis.Z * sin( Theta / 2 ) ; // NORMALISE L = Sqrt( Q.W**2 + Q.X ** 2 + Q.Y ** 2 + Q.Z**2 ) ; Q.W /= L ; Q.X /= L ; Q.Y /= L ; Q.Z /= L ; return Q ; }
Multipliplication in quaternions
Overload?s the * operator to multiply quaternions.
final operator(16) quat * ( quat Q1 , quat Q2 ) { local vector V1 , V2 , Vp ; local quat Qp ; V1 = eVect( Q1.X , Q1.Y , Q1.Z ) ; V2 = eVect( Q2.X , Q2.Y , Q2.Z ) ; Qp.W = Q1.W * Q2.W - ( V1 dot V2 ) ; Vp = ( Q1.W * V2 ) + ( Q2.W * V1 ) - ( V1 cross V2 ) ; Qp.X = Vp.X ; Qp.Y = Vp.Y ; Qp.Z = Vp.Z ; return Qp ; }
Converting Quaternions to a Transformation Matrix
function matrix3x3 QuatToMatrix ( quat Q ) { local matrix3x3 M ; local float w,x,y,z ; w = Q.W ; x = Q.X ; y = Q.Y ; z = Q.Z ; M.a11 = 1 - ( 2 * y** 2 ) - ( 2 * z** 2 ) ; M.a12 = 2*x*y - 2*z*w ; M.a13 = 2*x*z + 2*y*w ; M.a21 = 2*x*y + 2*z*w ; M.a22 = 1 - 2*x**2 -2*z**2 ; M.a23 = 2*y*z - 2*x*w ; M.a31 = 2*x*z - 2*y*w ; M.a32 = 2*y*z + 2*x*w ; M.a33 = 1 - 2*x**2 - 2*y**2 ; /* 1 - 2Y - 2Z 2XY - 2ZW 2XZ + 2YW 2XY + 2ZW 1 - 2X - 2Z 2YZ - 2XW 2XZ - 2YW 2YZ + 2XW 1 - 2X - 2Y */ return M ; }
Matrix Functions
Functions to define a matrix and multiply a matrix and a vector, ie. apply the transformation the matrix represents to the vector.
function Matrix3x3 defMatrix9f( float a11,float a12,float a13, float a21,float a22,float a23,float a31,float a32,float a33 ) { local Matrix3x3 theMatrix ; theMatrix.a11 = a11 ; theMatrix.a12 = a12 ; theMatrix.a13 = a13 ; theMatrix.a21 = a21 ; theMatrix.a22 = a22 ; theMatrix.a23 = a23 ; theMatrix.a31 = a31 ; theMatrix.a32 = a32 ; theMatrix.a33 = a33 ; return theMatrix ; } static final operator(16) vector * ( Matrix3x3 M , vector v ) { local vector Mv , R1 , R2 , R3 ; R1.x = M.a11 ; R1.y = M.a12 ; R1.z = M.a13 ; R2.x = M.a21 ; R2.y = M.a22 ; R2.z = M.a23 ; R3.x = M.a31 ; R3.y = M.a32 ; R3.z = M.a33 ; Mv.x = R1 dot v ; Mv.y = R2 dot v ; Mv.z = R3 dot v ; return Mv ; }