2
0
Marko Pintera 12 жил өмнө
parent
commit
ae71d6b22b

+ 5 - 5
CamelotUtility/Source/CmMatrix3.cpp

@@ -911,14 +911,14 @@ namespace CamelotFramework
         subDiag[2] = 0.0;
         if (Math::abs(fC) >= EPSILON)
         {
-            float fLength = Math::sqrt(fB*fB+fC*fC);
-            float fInvLength = 1.0f/fLength;
-            fB *= fInvLength;
-            fC *= fInvLength;
+            float length = Math::sqrt(fB*fB+fC*fC);
+            float invLength = 1.0f/length;
+            fB *= invLength;
+            fC *= invLength;
             float fQ = 2.0f*fB*fE+fC*(fF-fD);
             diag[1] = fD+fC*fQ;
             diag[2] = fF-fC*fQ;
-            subDiag[0] = fLength;
+            subDiag[0] = length;
             subDiag[1] = fE-fB*fQ;
             m[0][0] = 1.0;
             m[0][1] = 0.0;

+ 479 - 12
MBansheeEngine/Matrix3.cs

@@ -1,21 +1,64 @@
-using System.Runtime.InteropServices;
+using System;
+using System.Runtime.InteropServices;
 
 namespace BansheeEngine
 {
     [StructLayout(LayoutKind.Sequential)]
-    public class Matrix3
+    public struct Matrix3
     {
-        public float[,] m = new float[3,3];
+        private struct EulerAngleOrderData
+		{
+            public EulerAngleOrderData(int a, int b, int c, float sign)
+            {
+                this.a = a;
+                this.b = b;
+                this.c = c;
+                this.sign = sign;
+            }
+
+			public int a, b, c;
+            public float sign;
+		};
+
+        private static EulerAngleOrderData[] EA_LOOKUP = 
+		{ new EulerAngleOrderData(0, 1, 2, 1.0f), new EulerAngleOrderData(0, 2, 1, -1.0f), new EulerAngleOrderData(1, 0, 2, -1.0f),
+		  new EulerAngleOrderData(1, 2, 0, 1.0f), new EulerAngleOrderData(2, 0, 1,  1.0f), new EulerAngleOrderData(2, 1, 0, -1.0f) };
+
+        public static readonly Matrix3 zero = new Matrix3();
+        public static readonly Matrix3 identity = new Matrix3(1, 0, 0, 0, 1, 0, 0, 0, 1);
+
+        public float m00;
+        public float m01;
+        public float m02;
+        public float m10;
+        public float m11;
+        public float m12;
+        public float m20;
+        public float m21;
+        public float m22;
+
+        public Matrix3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
+        {
+            this.m00 = m00;
+            this.m01 = m01;
+            this.m02 = m02;
+            this.m10 = m10;
+            this.m11 = m11;
+            this.m12 = m12;
+            this.m20 = m20;
+            this.m21 = m21;
+            this.m22 = m22;
+        }
 
         public float this[int row, int column]
         {
             get
             {
-                return m[row, column];
+                return this[row * 4 + column];
             }
             set
             {
-                m[row, column] = value;
+                this[row * 4 + column] = value;
             }
         }
 
@@ -23,24 +66,448 @@ namespace BansheeEngine
         {
             get
             {
-                return (float)m.GetValue(index);
+                switch (index)
+                {
+                    case 0:
+                        return m00;
+                    case 1:
+                        return m01;
+                    case 2:
+                        return m02;
+                    case 3:
+                        return m10;
+                    case 4:
+                        return m11;
+                    case 5:
+                        return m12;
+                    case 6:
+                        return m20;
+                    case 7:
+                        return m21;
+                    case 8:
+                        return m22;
+                    default:
+                        throw new IndexOutOfRangeException("Invalid matrix index.");
+                }
+
             }
             set
             {
-                m.SetValue(value, index);
+                switch (index)
+                {
+                    case 0:
+                        m00 = value;
+                        break;
+                    case 1:
+                        m01 = value;
+                        break;
+                    case 2:
+                        m02 = value;
+                        break;
+                    case 3:
+                        m10 = value;
+                        break;
+                    case 4:
+                        m11 = value;
+                        break;
+                    case 5:
+                        m12 = value;
+                        break;
+                    case 6:
+                        m20 = value;
+                        break;
+                    case 7:
+                        m21 = value;
+                        break;
+                    case 8:
+                        m22 = value;
+                        break;
+                    default:
+                        throw new IndexOutOfRangeException("Invalid matrix index.");
+                }
+            }
+        }
+
+        public static Matrix3 operator *(Matrix3 lhs, Matrix3 rhs)
+        {
+            return new Matrix3()
+            {
+                m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10 + lhs.m02 * rhs.m20,
+                m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11 + lhs.m02 * rhs.m21,
+                m02 = lhs.m00 * rhs.m02 + lhs.m01 * rhs.m12 + lhs.m02 * rhs.m22,
+                m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10 + lhs.m12 * rhs.m20,
+                m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21,
+                m12 = lhs.m10 * rhs.m02 + lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22,
+                m20 = lhs.m20 * rhs.m00 + lhs.m21 * rhs.m10 + lhs.m22 * rhs.m20,
+                m21 = lhs.m20 * rhs.m01 + lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21,
+                m22 = lhs.m20 * rhs.m02 + lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22,
+            };
+        }
+
+        public static bool operator== (Matrix3 lhs, Matrix3 rhs)
+        {
+            if (lhs.m00 == rhs.m00 && lhs.m01 == rhs.m01 && lhs.m02 == rhs.m02 && 
+                lhs.m10 == rhs.m10 && lhs.m11 == rhs.m11 && lhs.m12 == rhs.m12 &&
+                lhs.m20 == rhs.m20 && lhs.m21 == rhs.m21 && lhs.m22 == rhs.m22)
+                return true;
+            else
+                return false;
+        }
+
+        public static bool operator !=(Matrix3 lhs, Matrix3 rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        public override int GetHashCode()
+        {
+            float hash1 = m00.GetHashCode() ^ m10.GetHashCode() << 2 ^ m20.GetHashCode() >> 2;
+            float hash2 = m01.GetHashCode() ^ m11.GetHashCode() << 2 ^ m22.GetHashCode() >> 2;
+            float hash3 = m02.GetHashCode() ^ m12.GetHashCode() << 2 ^ m22.GetHashCode() >> 2;
+
+            return hash1.GetHashCode() ^ hash2.GetHashCode() << 2 ^ hash3.GetHashCode() >> 2;
+        }
+
+        public override bool Equals(object other)
+        {
+            if (!(other is Matrix3))
+                return false;
+
+            Matrix3 mat = (Matrix3)other;
+            if (m00 == mat.m00 && m01 == mat.m01 && m02 == mat.m02 &&
+                m10 == mat.m10 && m11 == mat.m11 && m12 == mat.m12 &&
+                m20 == mat.m20 && m21 == mat.m21 && m22 == mat.m22)
+                return true;
+            else
+                return false;
+        }
+
+        public void Invert()
+        {
+            float[,] invVals = new float[3,3];
+
+            invVals[0, 0] = m11 * m22 - m12 * m21;
+            invVals[1, 0] = m12 * m20 - m10 * m22;
+            invVals[2, 0] = m10 * m21 - m11 * m20;
+
+            float det = m00 * invVals[0, 0] + m01 * invVals[1, 0] + m02 * invVals[2, 0];
+
+            if (MathEx.Abs(det) <= 1e-06f)
+                throw new DivideByZeroException("Matrix determinant is zero. Cannot invert.");
+
+            invVals[0, 1] = m02 * m21 - m01 * m22;
+            invVals[0, 2] = m01 * m12 - m02 * m11;
+
+            invVals[1, 1] = m00 * m22 - m02 * m20;
+            invVals[1, 2] = m02 * m10 - m00 * m12;
+
+            invVals[2, 1] = m01 * m20 - m00 * m21;
+            invVals[2, 2] = m00 * m11 - m01 * m10;
+
+            float invDet = 1.0f/det;
+            for (int row = 0; row < 3; row++)
+            {
+                for (int col = 0; col < 3; col++)
+                    invVals[row, col] *= invDet;
             }
         }
 
+        public void Transpose()
+        {
+            float tmp = m10;
+            m10 = m01;
+            m01 = tmp;
+
+            tmp = m20;
+            m20 = m02;
+            m02 = tmp;
+
+            tmp = m12;
+            m12 = m21;
+            m21 = tmp;
+        }
+
+        public float Determinant()
+        {
+            float cofactor00 = m11 * m22 - m12 * m21;
+            float cofactor10 = m12 * m20 - m10 * m22;
+            float cofactor20 = m10 * m21 - m11 * m20;
+
+            float det = m00 * cofactor00 + m01 * cofactor10 + m02 * cofactor20;
+
+            return det;
+        }
+
         public Vector3 Transform(Vector3 vec)
         {
-            // TODO
-            return Vector3.zero;
+            Vector3 outVec;
+            outVec.x = m00 * vec.x + m01 * vec.y + m02 * vec.z;
+            outVec.y = m10 * vec.x + m11 * vec.y + m12 * vec.z;
+            outVec.z = m20 * vec.x + m21 * vec.y + m22 * vec.z;
+            return outVec;
+        }
+
+        public void QDUDecomposition(out Matrix3 matQ, out Vector3 vecD, out Vector3 vecU)
+        {
+            matQ = new Matrix3();
+            vecD = new Vector3();
+            vecU = new Vector3();
+
+            // Build orthogonal matrix Q
+            float invLength = MathEx.InvSqrt(m00*m00 + m10*m10 + m20*m20);
+            matQ.m00 = m00*invLength;
+            matQ.m10 = m10*invLength;
+            matQ.m20 = m20*invLength;
+
+            float dot = matQ.m00*m01 + matQ.m10*m11 + matQ.m20*m21;
+            matQ.m01 = m01-dot*matQ.m00;
+            matQ.m11 = m11-dot*matQ.m10;
+            matQ.m21 = m21-dot*matQ.m20;
+
+            invLength = MathEx.InvSqrt(matQ.m01*matQ.m01 + matQ.m11*matQ.m11 + matQ.m21*matQ.m21);
+            matQ.m01 *= invLength;
+            matQ.m11 *= invLength;
+            matQ.m21 *= invLength;
+
+            dot = matQ.m00*m02 + matQ.m10*m12 + matQ.m20*m22;
+            matQ.m02 = m02-dot*matQ.m00;
+            matQ.m12 = m12-dot*matQ.m10;
+            matQ.m22 = m22-dot*matQ.m20;
+
+            dot = matQ.m01*m02 + matQ.m11*m12 + matQ.m21*m22;
+            matQ.m02 -= dot*matQ.m01;
+            matQ.m12 -= dot*matQ.m11;
+            matQ.m22 -= dot*matQ.m21;
+
+            invLength = MathEx.InvSqrt(matQ.m02*matQ.m02 + matQ.m12*matQ.m12 + matQ.m22*matQ.m22);
+            matQ.m02 *= invLength;
+            matQ.m12 *= invLength;
+            matQ.m22 *= invLength;
+
+            // Guarantee that orthogonal matrix has determinant 1 (no reflections)
+            float fDet = matQ.m00*matQ.m11*matQ.m22 + matQ.m01*matQ.m12*matQ.m20 +
+                matQ.m02*matQ.m10*matQ.m21 - matQ.m02*matQ.m11*matQ.m20 -
+                matQ.m01*matQ.m10*matQ.m22 - matQ.m00*matQ.m12*matQ.m21;
+
+            if (fDet < 0.0f)
+            {
+                matQ.m00 = -matQ.m00;
+                matQ.m01 = -matQ.m01;
+                matQ.m02 = -matQ.m02;
+                matQ.m10 = -matQ.m10;
+                matQ.m11 = -matQ.m11;
+                matQ.m12 = -matQ.m12;
+                matQ.m20 = -matQ.m20;
+                matQ.m21 = -matQ.m21;
+                matQ.m21 = -matQ.m22;
+            }
+
+            // Build "right" matrix R
+            Matrix3 matRight = new Matrix3();
+            matRight.m00 = matQ.m00 * m00 + matQ.m10 * m10 + matQ.m20 * m20;
+            matRight.m01 = matQ.m00 * m01 + matQ.m10 * m11 + matQ.m20 * m21;
+            matRight.m11 = matQ.m01 * m01 + matQ.m11 * m11 + matQ.m21 * m21;
+            matRight.m02 = matQ.m00 * m02 + matQ.m10 * m12 + matQ.m20 * m22;
+            matRight.m12 = matQ.m01 * m02 + matQ.m11 * m12 + matQ.m21 * m22;
+            matRight.m22 = matQ.m02 * m02 + matQ.m12 * m12 + matQ.m22 * m22;
+
+            // The scaling component
+            vecD[0] = matRight.m00;
+            vecD[1] = matRight.m11;
+            vecD[2] = matRight.m22;
+
+            // The shear component
+            float invD0 = 1.0f/vecD[0];
+            vecU[0] = matRight.m01 * invD0;
+            vecU[1] = matRight.m02 * invD0;
+            vecU[2] = matRight.m12 / vecD[1];
+        }
+
+        /**
+         * @note    Returns angles in degrees.
+         */
+        public Vector3 ToEulerAngles(EulerAngleOrder order = EulerAngleOrder.XYZ)
+        {
+            EulerAngleOrderData l = EA_LOOKUP[(int)order];
+
+		    float xAngle = MathEx.Asin(l.sign * this[l.a, l.c]);
+		    if (xAngle < MathEx.HalfPi)
+		    {
+			    if (xAngle > -MathEx.HalfPi)
+			    {
+				    float yAngle = MathEx.Atan2(-l.sign * this[l.b, l.c], this[l.c, l.c]);
+				    float zAngle = MathEx.Atan2(-l.sign * this[l.a, l.b], this[l.a, l.a]);
+
+                    return new Vector3(xAngle * MathEx.Rad2Deg, yAngle * MathEx.Rad2Deg, zAngle * MathEx.Rad2Deg);
+			    }
+			    else
+			    {
+				    // WARNING.  Not a unique solution.
+				    float angle = MathEx.Atan2(l.sign * this[l.b, l.a], this[l.b, l.b]);
+				    float zAngle = 0.0f;  // Any angle works
+				    float yAngle = zAngle - angle;
+
+                    return new Vector3(xAngle * MathEx.Rad2Deg, yAngle * MathEx.Rad2Deg, zAngle * MathEx.Rad2Deg);
+			    }
+		    }
+		    else
+		    {
+			    // WARNING.  Not a unique solution.
+			    float angle = MathEx.Atan2(l.sign * this[l.b, l.a], this[l.b, l.b]);
+                float zAngle = 0.0f; // Any angle works
+			    float yAngle = angle - zAngle;
+
+                return new Vector3(xAngle * MathEx.Rad2Deg, yAngle * MathEx.Rad2Deg, zAngle * MathEx.Rad2Deg);
+		    }
+        }
+
+        public Quaternion ToQuaternion()
+        {
+            return Quaternion.FromRotationMatrix(this);
+        }
+
+        public void ToAxisAngle(out Vector3 axis, out float degAngle)
+        {
+            float trace = m00 + m11 + m22;
+            float cos = 0.5f*(trace-1.0f);
+            float radians = MathEx.Acos(cos);  // In [0, PI]
+            degAngle = radians*MathEx.Rad2Deg;
+
+            if (radians > 0.0f)
+            {
+                if (radians < MathEx.Pi)
+                {
+                    axis.x = m21 - m12;
+                    axis.y = m02 - m20;
+                    axis.z = m10 - m01;
+
+                    axis.Normalize();
+                }
+                else
+                {
+                    // Angle is PI
+                    float halfInverse;
+                    if (m00 >= m11)
+                    {
+                        // r00 >= r11
+                        if (m00 >= m22)
+                        {
+                            // r00 is maximum diagonal term
+                            axis.x = 0.5f*MathEx.Sqrt(m00 - m11 - m22 + 1.0f);
+                            halfInverse = 0.5f/axis.x;
+                            axis.y = halfInverse*m01;
+                            axis.z = halfInverse*m02;
+                        }
+                        else
+                        {
+                            // r22 is maximum diagonal term
+                            axis.z = 0.5f*MathEx.Sqrt(m22 - m00 - m11 + 1.0f);
+                            halfInverse = 0.5f/axis.z;
+                            axis.x = halfInverse*m02;
+                            axis.y = halfInverse*m12;
+                        }
+                    }
+                    else
+                    {
+                        // r11 > r00
+                        if (m11 >= m22)
+                        {
+                            // r11 is maximum diagonal term
+                            axis.y = 0.5f*MathEx.Sqrt(m11 - m00 - m22 + 1.0f);
+                            halfInverse  = 0.5f/axis.y;
+                            axis.x = halfInverse*m01;
+                            axis.z = halfInverse*m12;
+                        }
+                        else
+                        {
+                            // r22 is maximum diagonal term
+                            axis.z = 0.5f*MathEx.Sqrt(m22 - m00 - m11 + 1.0f);
+                            halfInverse = 0.5f/axis.z;
+                            axis.x = halfInverse*m02;
+                            axis.y = halfInverse*m12;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // The angle is 0 and the matrix is the identity.  Any axis will
+                // work, so just use the x-axis.
+                axis.x = 1.0f;
+                axis.y = 0.0f;
+                axis.z = 0.0f;
+            }
+        }
+
+        public static Matrix3 Inverse(Matrix3 mat)
+        {
+            Matrix3 copy = mat;
+            copy.Invert();
+            return copy;
+        }
+
+        public static Matrix3 Transpose(Matrix3 mat)
+        {
+            Matrix3 copy = mat;
+            copy.Transpose();
+            return copy;
+        }
+
+        public static Matrix3 FromEuler(Vector3 eulerDeg, EulerAngleOrder order)
+        {
+            EulerAngleOrderData l = EA_LOOKUP[(int)order];
+
+		    Matrix3[] mats = new Matrix3[3];
+		    float cos, sin;
+
+		    cos = MathEx.Cos(eulerDeg.y * MathEx.Deg2Rad);
+            sin = MathEx.Sin(eulerDeg.y * MathEx.Deg2Rad);
+		    mats[0] = new Matrix3(1.0f, 0.0f, 0.0f, 0.0f, cos, -sin, 0.0f, sin, cos);
+
+            cos = MathEx.Cos(eulerDeg.x * MathEx.Deg2Rad);
+            sin = MathEx.Sin(eulerDeg.x * MathEx.Deg2Rad);
+		    mats[1] = new Matrix3(cos, 0.0f, sin, 0.0f, 1.0f, 0.0f, -sin, 0.0f, cos);
+
+            cos = MathEx.Cos(eulerDeg.z * MathEx.Deg2Rad);
+            sin = MathEx.Sin(eulerDeg.z * MathEx.Deg2Rad);
+		    mats[2] = new Matrix3(cos,-sin, 0.0f, sin, cos, 0.0f, 0.0f, 0.0f, 1.0f);
+	
+		    return mats[l.a]*(mats[l.b]*mats[l.c]);
+        }
+
+        public static Matrix3 FromAxisAngle(Vector3 axis, float degAngle)
+        {
+            Matrix3 mat;
+
+            float cos = MathEx.Cos(degAngle * MathEx.Deg2Rad);
+            float sin = MathEx.Sin(degAngle * MathEx.Deg2Rad);
+            float oneMinusCos = 1.0f - cos;
+            float x2 = axis.x * axis.x;
+            float y2 = axis.y * axis.y;
+            float z2 = axis.z * axis.z;
+            float xym = axis.x * axis.y * oneMinusCos;
+            float xzm = axis.x * axis.z * oneMinusCos;
+            float yzm = axis.y * axis.z * oneMinusCos;
+            float xSin = axis.x * sin;
+            float ySin = axis.y * sin;
+            float zSin = axis.z * sin;
+
+            mat.m00 = x2 * oneMinusCos + cos;
+            mat.m01 = xym - zSin;
+            mat.m02 = xzm + ySin;
+            mat.m10 = xym + zSin;
+            mat.m11 = y2 * oneMinusCos + cos;
+            mat.m12 = yzm - xSin;
+            mat.m20 = xzm - ySin;
+            mat.m21 = yzm + xSin;
+            mat.m22 = z2 * oneMinusCos + cos;
+
+            return mat;
         }
 
-        public Vector3 ToEulerAngles(EulerAngleOrder order)
+        public static Matrix3 FromQuaternion(Quaternion quat)
         {
-            // TODO - Angles returned must be in degrees
-            return Vector3.zero;
+            return quat.ToRotationMatrix();
         }
     }
 }

+ 20 - 20
MBansheeEngine/Quaternion.cs

@@ -152,7 +152,7 @@ namespace BansheeEngine
 			    if (fallbackAxis != Vector3.zero)
 			    {
 				    // Rotate 180 degrees about the fallback axis
-				    this = AxisAngle(fallbackAxis, MathEx.Pi * MathEx.Rad2Deg);
+				    this = FromAxisAngle(fallbackAxis, MathEx.Pi * MathEx.Rad2Deg);
 			    }
 			    else
 			    {
@@ -161,7 +161,7 @@ namespace BansheeEngine
                     if (axis.sqrdMagnitude < ((1e-06f * 1e-06f))) // Pick another if collinear
 					    axis = Vector3.Cross(Vector3.yAxis, fromDirection);
 				    axis.Normalize();
-                    this = AxisAngle(axis, MathEx.Pi * MathEx.Rad2Deg);
+                    this = FromAxisAngle(axis, MathEx.Pi * MathEx.Rad2Deg);
 			    }
 		    }
 		    else
@@ -386,13 +386,13 @@ namespace BansheeEngine
             rotation.ToAxisAngle(out axis, out angleDeg);
         }
 
-        public static Quaternion RotationMatrix(Matrix3 rotMatrix)
+        public static Quaternion FromRotationMatrix(Matrix3 rotMatrix)
         {
             // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
             // article "Quaternion Calculus and Fast Animation".
 
             Quaternion quat = new Quaternion();
-            float trace = rotMatrix.m[0, 0] + rotMatrix.m[1, 1] + rotMatrix.m[2, 2];
+            float trace = rotMatrix.m00 + rotMatrix.m11 + rotMatrix.m22;
             float root;
 
             if (trace > 0.0f)
@@ -401,9 +401,9 @@ namespace BansheeEngine
                 root = MathEx.Sqrt(trace + 1.0f);  // 2w
                 quat.w = 0.5f*root;
                 root = 0.5f/root;  // 1/(4w)
-                quat.x = (rotMatrix.m[2, 1] - rotMatrix.m[1, 2]) * root;
-                quat.y = (rotMatrix.m[0, 2] - rotMatrix.m[2, 0]) * root;
-                quat.z = (rotMatrix.m[1, 0] - rotMatrix.m[0, 1]) * root;
+                quat.x = (rotMatrix.m21 - rotMatrix.m12) * root;
+                quat.y = (rotMatrix.m02 - rotMatrix.m20) * root;
+                quat.z = (rotMatrix.m10 - rotMatrix.m01) * root;
             }
             else
             {
@@ -411,23 +411,23 @@ namespace BansheeEngine
                 int[] nextLookup = { 1, 2, 0 };
                 int i = 0;
 
-                if (rotMatrix.m[1, 1] > rotMatrix.m[0, 0])
+                if (rotMatrix.m11 > rotMatrix.m00)
                     i = 1;
 
-                if (rotMatrix.m[2, 2] > rotMatrix.m[i, i])
+                if (rotMatrix.m22 > rotMatrix[i, i])
                     i = 2;
 
                 int j = nextLookup[i];
                 int k = nextLookup[j];
 
-                root = MathEx.Sqrt(rotMatrix.m[i,i] - rotMatrix.m[j, j] - rotMatrix.m[k, k] + 1.0f);
+                root = MathEx.Sqrt(rotMatrix[i,i] - rotMatrix[j, j] - rotMatrix[k, k] + 1.0f);
 
                 quat[i] = 0.5f*root;
                 root = 0.5f/root;
 
-                quat.w = (rotMatrix.m[k, j] - rotMatrix.m[j, k]) * root;
-                quat[j] = (rotMatrix.m[j, i] + rotMatrix.m[i, j]) * root;
-                quat[k] = (rotMatrix.m[k, i] + rotMatrix.m[i, k]) * root;
+                quat.w = (rotMatrix[k, j] - rotMatrix[j, k]) * root;
+                quat[j] = (rotMatrix[j, i] + rotMatrix[i, j]) * root;
+                quat[k] = (rotMatrix[k, i] + rotMatrix[i, k]) * root;
             }
 
 		    quat.Normalize();
@@ -435,7 +435,7 @@ namespace BansheeEngine
             return quat;
         }
 
-        public static Quaternion AxisAngle(Vector3 axis, float angleDeg)
+        public static Quaternion FromAxisAngle(Vector3 axis, float angleDeg)
         {
             Quaternion quat;
 
@@ -449,14 +449,14 @@ namespace BansheeEngine
             return quat;
         }
 
-        public static Quaternion Euler(float xDeg, float yDeg, float zDeg, EulerAngleOrder order = EulerAngleOrder.XYZ)
+        public static Quaternion FromEuler(float xDeg, float yDeg, float zDeg, EulerAngleOrder order = EulerAngleOrder.XYZ)
         {
             EulerAngleOrderData l = EA_LOOKUP[(int)order];
 
             Quaternion[] quats = new Quaternion[3];
-		    quats[0] = AxisAngle(Vector3.xAxis, xDeg);
-		    quats[1] = AxisAngle(Vector3.yAxis, yDeg);
-		    quats[2] = AxisAngle(Vector3.zAxis, zDeg);
+		    quats[0] = FromAxisAngle(Vector3.xAxis, xDeg);
+		    quats[1] = FromAxisAngle(Vector3.yAxis, yDeg);
+		    quats[2] = FromAxisAngle(Vector3.zAxis, zDeg);
 
             return quats[l.c]*(quats[l.a] * quats[l.b]);
         }
@@ -464,9 +464,9 @@ namespace BansheeEngine
         /**
          * @note Angles in degrees.
          */
-        public static Quaternion Euler(Vector3 euler, EulerAngleOrder order = EulerAngleOrder.XYZ)
+        public static Quaternion FromEuler(Vector3 euler, EulerAngleOrder order = EulerAngleOrder.XYZ)
         {
-            return Euler(euler.x, euler.y, euler.z, order);
+            return FromEuler(euler.x, euler.y, euler.z, order);
         }
 
         public override int GetHashCode()