/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ------------------------------------------------------------------------------*/ #include "script_squirrel/cobject/matrix_decl.h" #include "script_squirrel/cobject/vector_decl.h" #include "math/matrix4.h" #include "math/matrix3.h" #include "math/quaternion.h" #include "nstring/nstring.h" #include "log/log.h" using namespace GS; #ifndef _T #define _T #endif _DECL_CLASS(Matrix4) _IMPL_NATIVE_CONSTRUCTION(Matrix4, Matrix4) //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, constructor) Matrix4 temp; int nparams = sa.GetParamCount(); switch (nparams) { case 1: temp.Set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); break; case 5: { _GetTypedParam(_u, 2, Vector4, Vector); _GetTypedParam(_v, 3, Vector4, Vector); _GetTypedParam(_w, 4, Vector4, Vector); _GetTypedParam(_x, 5, Vector4, Vector); if (_u && _v && _w && _x) { temp.Set(_u->x, _u->y, _u->z, _u->w, _v->x, _v->y, _v->z, _v->w, _w->x, _w->y, _w->z, _w->w, _x->x, _x->y, _x->z, _x->w); } else return sa.ThrowError("Matrix4() invalid parameters"); } break; case 17: temp.Set( sa.GetFloat(2), sa.GetFloat(3), sa.GetFloat(4), sa.GetFloat(5), sa.GetFloat(6), sa.GetFloat(7), sa.GetFloat(8), sa.GetFloat(9), sa.GetFloat(10), sa.GetFloat(11), sa.GetFloat(12), sa.GetFloat(13), sa.GetFloat(14), sa.GetFloat(15), sa.GetFloat(16), sa.GetFloat(17) ); break; default: return sa.ThrowError("Matrix4() wrong parameter count"); } return construct_Matrix4(v, new Matrix4(temp)); _END_IMPL //------------------------------------------------------------------------------ // The string class is used to speed up comparison as it uses a hash-based early // rejection. static String uc_m00("m00"), uc_m10("m10"), uc_m20("m20"), uc_m30("m30"), uc_m01("m01"), uc_m11("m11"), uc_m21("m21"), uc_m31("m31"), uc_m02("m02"), uc_m12("m12"), uc_m22("m22"), uc_m32("m32"), uc_m03("m03"), uc_m13("m13"), uc_m23("m23"), uc_m33("m33"); //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, _set) _GetSelf(Matrix4, Matrix4); switch (sa.GetType(2)) { case OT_STRING: { String idx(sa.GetString(2)); if (idx == uc_m00) return sa.Return(self->m[0][0] = sa.GetFloat(3)); if (idx == uc_m10) return sa.Return(self->m[1][0] = sa.GetFloat(3)); if (idx == uc_m20) return sa.Return(self->m[2][0] = sa.GetFloat(3)); if (idx == uc_m30) return sa.Return(self->m[3][0] = sa.GetFloat(3)); if (idx == uc_m01) return sa.Return(self->m[0][1] = sa.GetFloat(3)); if (idx == uc_m11) return sa.Return(self->m[1][1] = sa.GetFloat(3)); if (idx == uc_m21) return sa.Return(self->m[2][1] = sa.GetFloat(3)); if (idx == uc_m31) return sa.Return(self->m[3][1] = sa.GetFloat(3)); if (idx == uc_m02) return sa.Return(self->m[0][2] = sa.GetFloat(3)); if (idx == uc_m12) return sa.Return(self->m[1][2] = sa.GetFloat(3)); if (idx == uc_m22) return sa.Return(self->m[2][2] = sa.GetFloat(3)); if (idx == uc_m32) return sa.Return(self->m[3][2] = sa.GetFloat(3)); if (idx == uc_m03) return sa.Return(self->m[0][3] = sa.GetFloat(3)); if (idx == uc_m13) return sa.Return(self->m[1][3] = sa.GetFloat(3)); if (idx == uc_m23) return sa.Return(self->m[2][3] = sa.GetFloat(3)); if (idx == uc_m33) return sa.Return(self->m[3][3] = sa.GetFloat(3)); } break; } return SQ_ERROR; _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, _get) _GetSelf(Matrix4, Matrix4); switch (sa.GetType(2)) { case OT_STRING: { String idx(sa.GetString(2)); if (idx == uc_m00) return sa.Return(self->m[0][0]); if (idx == uc_m10) return sa.Return(self->m[1][0]); if (idx == uc_m20) return sa.Return(self->m[2][0]); if (idx == uc_m30) return sa.Return(self->m[3][0]); if (idx == uc_m01) return sa.Return(self->m[0][1]); if (idx == uc_m11) return sa.Return(self->m[1][1]); if (idx == uc_m21) return sa.Return(self->m[2][1]); if (idx == uc_m31) return sa.Return(self->m[3][1]); if (idx == uc_m02) return sa.Return(self->m[0][2]); if (idx == uc_m12) return sa.Return(self->m[1][2]); if (idx == uc_m22) return sa.Return(self->m[2][2]); if (idx == uc_m32) return sa.Return(self->m[3][2]); if (idx == uc_m03) return sa.Return(self->m[0][3]); if (idx == uc_m13) return sa.Return(self->m[1][3]); if (idx == uc_m23) return sa.Return(self->m[2][3]); if (idx == uc_m33) return sa.Return(self->m[3][3]); } break; } return SQ_ERROR; _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, GetRow) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(sa.GetInt(2)))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, SetRow) _GetSelf(Matrix4, Matrix4); _GetTypedParam(row, 3, Vector4, Vector) self->SetRow(sa.GetInt(2), *row); return 0; _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetColumn) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetColumn(sa.GetInt(2)))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, SetColumn) _GetSelf(Matrix4, Matrix4); _GetTypedParam(col, 3, Vector4, Vector) self->SetColumn(sa.GetInt(2), *col); return 0; _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetFront) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(2))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetBack) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(2).Reversed())); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetUp) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(1))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetDown) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(1).Reversed())); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetRight) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(0))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetLeft) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(0).Reversed())); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, GetPosition) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(3))); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, _mul) _GetSelf(Matrix4, Matrix4); _GetTypedParam(mtx, 2, Matrix4, Matrix4) _SA_RETURN_OBJECT(new_Matrix4(v, *self * *mtx)); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, AsMatrix3) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Matrix3(v, Matrix3::FromMatrix4(*self))); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix4, GetInverseMatrix) _GetSelf(Matrix4, Matrix4); _SA_RETURN_OBJECT(new_Matrix4(v, self->InversedFast())); _END_IMPL //----------------------------------------------------------------------------- _MEMBER_FUNCTION_IMPL(Matrix4, Print) _GetSelf(Matrix4, Matrix4); const char *label = "Matrix"; if (sa.GetParamCount() == 2) label = sa.GetString(2); __LOG__ << "Dumping matrix '" << label << "':\n"; for (int n = 0; n < 4; ++n) { Vector4 v = self->GetRow(n); __LOG__ << "Row " << n << ": { " << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "}\n"; } return 0; _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix4, RotationFromMatrix3) _GetSelf(Matrix4, Matrix4); _GetTypedParam(mtx, 2, Matrix3, Matrix3) self->m[0][0] = mtx->m[0][0]; self->m[1][0] = mtx->m[1][0]; self->m[2][0] = mtx->m[2][0]; self->m[0][1] = mtx->m[0][1]; self->m[1][1] = mtx->m[1][1]; self->m[2][1] = mtx->m[2][1]; self->m[0][2] = mtx->m[0][2]; self->m[1][2] = mtx->m[1][2]; self->m[2][2] = mtx->m[2][2]; return 0; _END_IMPL //------------------------------------------------------------------------------ /*# Topic: Matrix Type: Matrix3 Type: Matrix4 #*/ /*# Section: MatrixGeneric Desc: Global functions #*/ /*# Func: Matrix3 Proto: Matrix3:float m00...m33 Desc: Create a new 3x3 matrix. Example: // Construct a default unity matrix. local a = Matrix3() // Vector based constructor. local b = Matrix3(v0, v1, v2) // Float based constructor. local c = Matrix3(m00, m10, m20, m01, m11, m21, m02, m12, m22) #*/ /*# Func: Matrix4 Proto: Matrix4:float m00...m44 Desc: Create a new 4x4 matrix. Example: // Construct a default unity matrix. local a = Matrix4() // Vector based constructor. local b = Matrix4(v0, v1, v2, v3) // Float based constructor. local c = Matrix3(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33) #*/ /*# Func: RotationMatrixX Proto: Matrix3:float angle Desc: Create a 3x3 rotation matrix around the X axis, angle is in degree. Example: local m = RotationMatrixX(Deg(45)) #*/ /*# Func: RotationMatrixY Proto: Matrix3:float angle Desc: Create a 3x3 rotation matrix around the Y axis, angle is in degree. Example: local m = RotationMatrixY(Deg(45)) #*/ /*# Func: RotationMatrixZ Proto: Matrix3:float angle Desc: Create a 3x3 rotation matrix around the Z axis, angle is in degree. Example: local m = RotationMatrixZ(Deg(45)) #*/ /*# Func: MatrixToEuler Proto: Vector:Matrix3,RotationOrder Desc: Convert a world space matrix to Euler angles. #*/ /*# Func: EulerFromDirection Proto: Vector:Vector direction Desc: Convert a world space direction vector to an Euler angle triplet (x, y, z). #*/ /*# Func: EulerFromDirectionAndUp Proto: Vector:Vector direction,Vector up Desc: Convert a world space direction and up vectors to an Euler angle triplet (x, y, z). #*/ /*# Func: RotationMatrixFromDirection Proto: Matrix3:Vector direction Desc: Convert a world space direction vector to a 3x3 rotation matrix. #*/ /*# Func: RotationMatrixFromDirectionAndUp Proto: Matrix3:Vector direction,Vector up Desc: Convert a world space direction and up vectors to a 3x3 rotation matrix. #*/ /*# Func: TransformationMatrix Proto: Matrix4:Vector position,Vector euler,Vector scale,Vector pivot Desc: Create a position, rotation, scale, offset 4x4 matrix.
The offset is applied first, scale second, rotation third and finally position is applied. #*/ /*# Section: Matrix4Generic Desc: Matrix 4x4 #*/ _BEGIN_CLASS(Matrix4) _MEMBER_FUNCTION(Matrix4, constructor, -1, _T(". n|x n|x n|x n|x nnnn nnnn")) _MEMBER_FUNCTION(Matrix4, _get, 2, _T("xs")) _MEMBER_FUNCTION(Matrix4, _set, 3, _T("xsn")) _MEMBER_FUNCTION(Matrix4, _mul, 2, _T("xx")) /*# Func: GetRow Proto: Vector:int index Desc: Return a matrix row as a vector. #*/ _MEMBER_FUNCTION(Matrix4, GetRow, 2, _T("xi")) /*# Func: SetRow Proto: void:int index, Vector row Desc: Set a matrix row from a vector. #*/ _MEMBER_FUNCTION(Matrix4, SetRow, 3, _T("xix")) /*# Func: GetColumn Proto: Vector:int index Desc: Return a matrix column as a vector. #*/ _MEMBER_FUNCTION(Matrix4, GetColumn, 2, _T("xi")) /*# Func: SetColumn Proto: void:int index, Vector column Desc: Set a matrix column from a vector. #*/ _MEMBER_FUNCTION(Matrix4, SetColumn, 3, _T("xix")) /*# Func: AsMatrix3 Proto: Matrix3: Desc: Return matrix as a 3x3 matrix. #*/ _MEMBER_FUNCTION(Matrix4, AsMatrix3, 1, _T("x")) /*# Func: GetInverseMatrix Proto: Matrix4: Desc: Return inverse matrix. #*/ _MEMBER_FUNCTION(Matrix4, GetInverseMatrix, 1, _T("x")) /*# Func: Print Proto: void: Desc: Output matrix content to the engine log. #*/ _MEMBER_FUNCTION(Matrix4, Print, -1, _T("x")) /*# Func: RotationFromMatrix3 Proto: void:Matrix3 orientation Desc: Set the rotation part of a 4x4 transformation matrix from a 3x3 matrix. #*/ _MEMBER_FUNCTION(Matrix4, RotationFromMatrix3, 2, _T("xx")) /*# Section: Matrix4Component Desc: Transformation matrix component #*/ /*# Func: GetFront Proto: Vector: Desc: Return the transformation matrix front axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetFront, 1, _T("x")) /*# Func: GetBack Proto: Vector: Desc: Return the transformation matrix down axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetBack, 1, _T("x")) /*# Func: GetRight Proto: Vector: Desc: Return the transformation matrix right axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetRight, 1, _T("x")) /*# Func: GetLeft Proto: Vector: Desc: Return the transformation matrix left axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetLeft, 1, _T("x")) /*# Func: GetUp Proto: Vector: Desc: Return the transformation matrix up axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetUp, 1, _T("x")) /*# Func: GetDown Proto: Vector: Desc: Return the transformation matrix down axis vector. #*/ _MEMBER_FUNCTION(Matrix4, GetDown, 1, _T("x")) /*# Func: GetPosition Proto: Vector: Desc: Return the transformation matrix position vector. #*/ _MEMBER_FUNCTION(Matrix4, GetPosition, 1, _T("x")) _END_CLASS(Matrix4) //------------------------------------------------------------------------------ _DECL_CLASS(Matrix3); _IMPL_NATIVE_CONSTRUCTION(Matrix3, Matrix3); //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, constructor) Matrix3 temp, *newv = NULL; int nparams = sa.GetParamCount(); switch (nparams) { case 1: temp.Set(1, 0, 0, 0, 1, 0, 0, 0, 1); break; case 4: { _GetTypedParam(_u, 2, Vector4, Vector); _GetTypedParam(_v, 3, Vector4, Vector); _GetTypedParam(_w, 4, Vector4, Vector); if (_u && _v && _w) { temp.Set(*_u, *_v, *_w); } else return sa.ThrowError("Matrix3() invalid parameters"); } break; case 10: temp.Set( sa.GetFloat(2), sa.GetFloat(3), sa.GetFloat(4), sa.GetFloat(5), sa.GetFloat(6), sa.GetFloat(7), sa.GetFloat(8), sa.GetFloat(9), sa.GetFloat(10) ); break; default: return sa.ThrowError("Matrix3() wrong parameter count"); } newv = new Matrix3(temp); return construct_Matrix3(v, newv); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, _set) _GetSelf(Matrix3, Matrix3); switch (sa.GetType(2)) { case OT_STRING: { String idx(sa.GetString(2)); if (idx == uc_m00) return sa.Return(self->m[0][0] = sa.GetFloat(3)); if (idx == uc_m10) return sa.Return(self->m[1][0] = sa.GetFloat(3)); if (idx == uc_m20) return sa.Return(self->m[2][0] = sa.GetFloat(3)); if (idx == uc_m01) return sa.Return(self->m[0][1] = sa.GetFloat(3)); if (idx == uc_m11) return sa.Return(self->m[1][1] = sa.GetFloat(3)); if (idx == uc_m21) return sa.Return(self->m[2][1] = sa.GetFloat(3)); if (idx == uc_m02) return sa.Return(self->m[0][2] = sa.GetFloat(3)); if (idx == uc_m12) return sa.Return(self->m[1][2] = sa.GetFloat(3)); if (idx == uc_m22) return sa.Return(self->m[2][2] = sa.GetFloat(3)); } break; } return SQ_ERROR; _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, _get) _GetSelf(Matrix3, Matrix3); switch (sa.GetType(2)) { case OT_STRING: { String idx(sa.GetString(2)); if (idx == uc_m00) return sa.Return(self->m[0][0]); if (idx == uc_m10) return sa.Return(self->m[1][0]); if (idx == uc_m20) return sa.Return(self->m[2][0]); if (idx == uc_m01) return sa.Return(self->m[0][1]); if (idx == uc_m11) return sa.Return(self->m[1][1]); if (idx == uc_m21) return sa.Return(self->m[2][1]); if (idx == uc_m02) return sa.Return(self->m[0][2]); if (idx == uc_m12) return sa.Return(self->m[1][2]); if (idx == uc_m22) return sa.Return(self->m[2][2]); } break; } return SQ_ERROR; _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, GetRow) _GetSelf(Matrix3, Matrix3); _SA_RETURN_OBJECT(new_Vector(v, self->GetRow(sa.GetInt(2)))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix3, SetRow) _GetSelf(Matrix3, Matrix3); _GetTypedParam(row, 3, Vector4, Vector) self->SetRow(sa.GetInt(2), *row); return 0; _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix3, GetColumn) _GetSelf(Matrix3, Matrix3); _SA_RETURN_OBJECT(new_Vector(v, self->GetColumn(sa.GetInt(2)))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix3, SetColumn) _GetSelf(Matrix3, Matrix3); _GetTypedParam(col, 3, Vector4, Vector) self->SetColumn(sa.GetInt(2), *col); return 0; _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, _mul) _GetSelf(Matrix3, Matrix3); _GetTypedParam(mtx, 2, Matrix3, Matrix3) _SA_RETURN_OBJECT(new_Matrix3(v, *self * *mtx)); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, AsMatrix4) _GetSelf(Matrix3, Matrix3); _SA_RETURN_OBJECT(new_Matrix4(v, Matrix4::FromMatrix3(*self))); _END_IMPL //------------------------------------------------------------------------------ _MEMBER_FUNCTION_IMPL(Matrix3, FromOrthonormalBasis) // _CHECK_SELF(Matrix3, Matrix3); _GetTypedParam(_w, 2, Vector4, Vector) Vector4 *_v = NULL; switch (sa.GetParamCount()) { case 2: break; case 3: { _GetTypedParam(__v, 3, Vector4, Vector) _v = __v; } break; default: return sa.ThrowError("Matrix3::FromOrthonormalBasis() wrong parameter count"); } _SA_RETURN_OBJECT(new_Matrix3(v, Matrix3::FromOrthonormalBasis(*_w, _v))); _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix3, SlerpTo) _GetSelf(Matrix3, Matrix3); _GetTypedParam(to, 3, Matrix3, Matrix3) float t = sa.GetFloat(2); Matrix3 out = Quaternion::Slerp(t, Quaternion::FromMatrix3(*self), Quaternion::FromMatrix3(*to)).AsMatrix3(); _SA_RETURN_OBJECT(new_Matrix3(v, out)) _END_IMPL _MEMBER_FUNCTION_IMPL(Matrix3, AsEuler) _GetSelf(Matrix3, Matrix3); Math::rOrder rorder = Math::rOrder_Default; if (sa.GetParamCount() == 2) rorder = (Math::rOrder)sa.GetInt(2); _SA_RETURN_OBJECT(new_Vector(v, self->AsEuler(rorder))); _END_IMPL //------------------------------------------------------------------------------ /*# Section: Matrix3Generic Desc: Matrix 3x3 #*/ _BEGIN_CLASS(Matrix3) _MEMBER_FUNCTION(Matrix3, constructor, -1, _T(". n|x n|x n|x nnn nnn")) _MEMBER_FUNCTION(Matrix3, _get, 2, _T("xs")) _MEMBER_FUNCTION(Matrix3, _set, 3, _T("xsn")) _MEMBER_FUNCTION(Matrix3, _mul, 2, _T("xx")) /*# Func: GetRow Proto: Vector:int index Desc: Return a matrix row as a vector. #*/ _MEMBER_FUNCTION(Matrix3, GetRow, 2, _T("xi")) /*# Func: SetRow Proto: void:int index, Vector row Desc: Set a matrix row from a vector. #*/ _MEMBER_FUNCTION(Matrix3, SetRow, 3, _T("xix")) /*# Func: GetColumn Proto: Vector:int index Desc: Return a matrix column as a vector. #*/ _MEMBER_FUNCTION(Matrix3, GetColumn, 2, _T("xi")) /*# Func: SetColumn Proto: void:int index, Vector column Desc: Set a matrix column from a vector. #*/ _MEMBER_FUNCTION(Matrix3, SetColumn, 3, _T("xix")) /*# Func: AsMatrix4 Proto: Matrix4: Desc: Return matrix as a 4x4 matrix. #*/ _MEMBER_FUNCTION(Matrix3, AsMatrix4, 1, _T("x")) /*# Func: FromOrthonormalBasis Proto: Matrix3:Vector u,[Vector v] Desc: Build an orientation matrix from one or two basis vectors. #*/ _MEMBER_FUNCTION(Matrix3, FromOrthonormalBasis, -2, _T(".xx")) /*# Func: SlerpTo Proto: Matrix3:float t,Matrix3 to Desc: Interpolate a 3x3 orientation matrix to another 3x3 orientation matrix using spherical linear interpolation. Example: local m_a = ItemGetRotationMatrix(item_a) local m_b = ItemGetRotationMatrix(item_b) // m_c will store a rotation halfway between the rotation stored in the m_a and m_b matrices. local m_c = m_a.SlerpTo(0.5, m_b) #*/ _MEMBER_FUNCTION(Matrix3, SlerpTo, 3, _T("xnx")) /*# Func: AsEuler Proto: Vector:[RotationOrder method] Desc: Return a 3x3 orientation matrix as an Euler triplet. #*/ _MEMBER_FUNCTION(Matrix3, AsEuler, -1, _T("xi")) _END_CLASS(Matrix3)