Browse Source

Matrix4 refactor

Marko Pintera 12 years ago
parent
commit
22cc7c8120

+ 10 - 10
BansheeEngine/Source/BsCamera.cpp

@@ -320,8 +320,8 @@ namespace BansheeEngine
 			Vector3 topLeft(-0.5f, 0.5f, 0.0f);
 			Vector3 bottomRight(0.5f, -0.5f, 0.0f);
 
-			topLeft = invProj * topLeft;
-			bottomRight = invProj * bottomRight;
+			topLeft = invProj.transform(topLeft);
+			bottomRight = invProj.transform(bottomRight);
 
 			left = topLeft.x;
 			top = topLeft.y;
@@ -635,15 +635,15 @@ namespace BansheeEngine
 		float farTop = nearTop * radio;
 
 		// near
-		mWorldSpaceCorners[0] = eyeToWorld.transformAffine(Vector3(nearRight, nearTop,    -mNearDist));
-		mWorldSpaceCorners[1] = eyeToWorld.transformAffine(Vector3(nearLeft,  nearTop,    -mNearDist));
-		mWorldSpaceCorners[2] = eyeToWorld.transformAffine(Vector3(nearLeft,  nearBottom, -mNearDist));
-		mWorldSpaceCorners[3] = eyeToWorld.transformAffine(Vector3(nearRight, nearBottom, -mNearDist));
+		mWorldSpaceCorners[0] = eyeToWorld.transform3x4(Vector3(nearRight, nearTop,    -mNearDist));
+		mWorldSpaceCorners[1] = eyeToWorld.transform3x4(Vector3(nearLeft,  nearTop,    -mNearDist));
+		mWorldSpaceCorners[2] = eyeToWorld.transform3x4(Vector3(nearLeft,  nearBottom, -mNearDist));
+		mWorldSpaceCorners[3] = eyeToWorld.transform3x4(Vector3(nearRight, nearBottom, -mNearDist));
 		// far
-		mWorldSpaceCorners[4] = eyeToWorld.transformAffine(Vector3(farRight,  farTop,     -farDist));
-		mWorldSpaceCorners[5] = eyeToWorld.transformAffine(Vector3(farLeft,   farTop,     -farDist));
-		mWorldSpaceCorners[6] = eyeToWorld.transformAffine(Vector3(farLeft,   farBottom,  -farDist));
-		mWorldSpaceCorners[7] = eyeToWorld.transformAffine(Vector3(farRight,  farBottom,  -farDist));
+		mWorldSpaceCorners[4] = eyeToWorld.transform3x4(Vector3(farRight,  farTop,     -farDist));
+		mWorldSpaceCorners[5] = eyeToWorld.transform3x4(Vector3(farLeft,   farTop,     -farDist));
+		mWorldSpaceCorners[6] = eyeToWorld.transform3x4(Vector3(farLeft,   farBottom,  -farDist));
+		mWorldSpaceCorners[7] = eyeToWorld.transform3x4(Vector3(farRight,  farBottom,  -farDist));
 
 
 		mRecalcWorldSpaceCorners = false;

+ 2 - 2
BansheeEngine/Source/BsGUIManager.cpp

@@ -1179,7 +1179,7 @@ namespace BansheeEngine
 
 		const Matrix4& worldTfrm = widget.SO()->getWorldTfrm();
 
-		Vector4 vecLocalPos = worldTfrm.inverse() * Vector4((float)windowPos.x, (float)windowPos.y, 0.0f, 1.0f);
+		Vector4 vecLocalPos = worldTfrm.inverse().transform3x4(Vector4((float)windowPos.x, (float)windowPos.y, 0.0f, 1.0f));
 		Int2 curLocalPos(Math::RoundToInt(vecLocalPos.x), Math::RoundToInt(vecLocalPos.y));
 
 		return curLocalPos;
@@ -1199,7 +1199,7 @@ namespace BansheeEngine
 
 			const Matrix4& worldTfrm = bridgeElement->_getParentWidget().SO()->getWorldTfrm();
 
-			Vector4 vecLocalPos = worldTfrm.inverse() * Vector4((float)windowPos.x, (float)windowPos.y, 0.0f, 1.0f);
+			Vector4 vecLocalPos = worldTfrm.inverse().transform3x4(Vector4((float)windowPos.x, (float)windowPos.y, 0.0f, 1.0f));
 			Rect bridgeBounds = bridgeElement->getBounds();
 
 			// Find coordinates relative to the bridge element

+ 1 - 1
BansheeEngine/Source/BsGUIWidget.cpp

@@ -308,7 +308,7 @@ namespace BansheeEngine
 
 		const Matrix4& worldTfrm = SO()->getWorldTfrm();
 		Vector3 vecPos((float)position.x, (float)position.y, 0.0f);
-		vecPos = worldTfrm.inverse() * vecPos;
+		vecPos = worldTfrm.inverse().transform3x4(vecPos);
 
 		Int2 localPos(Math::RoundToInt(vecPos.x), Math::RoundToInt(vecPos.y));
 		return mBounds.contains(localPos);

+ 1 - 1
CamelotClient/Source/BsDockManager.cpp

@@ -455,7 +455,7 @@ namespace BansheeEditor
 
 		const Matrix4& worldTfrm = widget->SO()->getWorldTfrm();
 
-		Vector4 tfrmdPos = worldTfrm * Vector4((float)widgetRelPos.x, (float)widgetRelPos.y, 0.0f, 1.0f);
+		Vector4 tfrmdPos = worldTfrm.transform3x4(Vector4((float)widgetRelPos.x, (float)widgetRelPos.y, 0.0f, 1.0f));
 		Vector2 windowPosVec(tfrmdPos.x, tfrmdPos.y);
 		Int2 windowPos(Math::RoundToInt(windowPosVec.x), Math::RoundToInt(windowPosVec.y));
 

+ 1 - 1
CamelotCore/Source/CmSceneObject.cpp

@@ -271,7 +271,7 @@ namespace CamelotFramework
 
 	void SceneObject::updateLocalTfrm() const
 	{
-		mCachedLocalTfrm.makeTransform(mPosition, mScale, mRotation);
+		mCachedLocalTfrm.setTRS(mPosition, mRotation, mScale);
 
 		mIsCachedLocalTfrmUpToDate = true;
 	}

+ 9 - 9
CamelotUtility/Include/CmAABox.cpp

@@ -99,35 +99,35 @@ namespace CamelotFramework
 		// First corner 
 		// min min min
 		currentCorner = oldMin;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// min,min,max
 		currentCorner.z = oldMax.z;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// min max max
 		currentCorner.y = oldMax.y;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// min max min
 		currentCorner.z = oldMin.z;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// max max min
 		currentCorner.x = oldMax.x;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// max max max
 		currentCorner.z = oldMax.z;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// max min max
 		currentCorner.y = oldMin.y;
-		merge( matrix * currentCorner );
+		merge(matrix.transform3x4(currentCorner));
 
 		// max min min
 		currentCorner.z = oldMin.z;
-		merge( matrix * currentCorner ); 
+		merge(matrix.transform3x4(currentCorner)); 
 	}
 
 	void AABox::transformAffine(const Matrix4& m)
@@ -137,7 +137,7 @@ namespace CamelotFramework
 		Vector3 centre = getCenter();
 		Vector3 halfSize = getHalfSize();
 
-		Vector3 newCentre = m.transformAffine(centre);
+		Vector3 newCentre = m.transform3x4(centre);
 		Vector3 newHalfSize(
 			Math::Abs(m[0][0]) * halfSize.x + Math::Abs(m[0][1]) * halfSize.y + Math::Abs(m[0][2]) * halfSize.z, 
 			Math::Abs(m[1][0]) * halfSize.x + Math::Abs(m[1][1]) * halfSize.y + Math::Abs(m[1][2]) * halfSize.z,

+ 12 - 12
CamelotUtility/Include/CmMatrix3.h

@@ -49,19 +49,19 @@ namespace CamelotFramework
 			memcpy(m, mat.m, 9*sizeof(float));
 		}
 
-        Matrix3(float fEntry00, float fEntry01, float fEntry02,
-                float fEntry10, float fEntry11, float fEntry12,
-                float fEntry20, float fEntry21, float fEntry22)
+        Matrix3(float m00, float m01, float m02,
+                float m10, float m11, float m12,
+                float m20, float m21, float m22)
 		{
-			m[0][0] = fEntry00;
-			m[0][1] = fEntry01;
-			m[0][2] = fEntry02;
-			m[1][0] = fEntry10;
-			m[1][1] = fEntry11;
-			m[1][2] = fEntry12;
-			m[2][0] = fEntry20;
-			m[2][1] = fEntry21;
-			m[2][2] = fEntry22;
+			m[0][0] = m00;
+			m[0][1] = m01;
+			m[0][2] = m02;
+			m[1][0] = m10;
+			m[1][1] = m11;
+			m[1][2] = m12;
+			m[2][0] = m20;
+			m[2][1] = m21;
+			m[2][2] = m22;
 		}
 
 		/**

+ 216 - 471
CamelotUtility/Include/CmMatrix4.h

@@ -25,10 +25,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 -----------------------------------------------------------------------------
 */
-#ifndef __Matrix4__
-#define __Matrix4__
+#pragma once
 
-// Precompiler options
 #include "CmPrerequisitesUtil.h"
 
 #include "CmVector3.h"
@@ -38,66 +36,24 @@ THE SOFTWARE.
 
 namespace CamelotFramework
 {
-	/** \addtogroup Core
-	*  @{
-	*/
-	/** \addtogroup Math
-	*  @{
-	*/
-	/** Class encapsulating a standard 4x4 homogeneous matrix.
-        @remarks
-            We use column vectors when applying matrix multiplications,
-            This means a vector is represented as a single column, 4-row
-            matrix. This has the effect that the transformations implemented
-            by the matrices happens right-to-left e.g. if vector V is to be
-            transformed by M1 then M2 then M3, the calculation would be
-            M3 * M2 * M1 * V. The order that matrices are concatenated is
-            vital since matrix multiplication is not commutative, i.e. you
-            can get a different result if you concatenate in the wrong order.
-        @par
-            The use of column vectors and right-to-left ordering is the
-            standard in most mathematical texts, and is the same as used in
-            OpenGL. It is, however, the opposite of Direct3D, which has
-            inexplicably chosen to differ from the accepted standard and uses
-            row vectors and left-to-right matrix multiplication.
-        @par
-            We deal with the differences between D3D and OpenGL etc.
-            internally when operating through different render systems. 
-            Users only need to conform to standard maths conventions, i.e.
-            right-to-left matrix multiplication, (Engine transposes matrices it
-            passes to D3D to compensate).
-        @par
-            The generic form M * V which shows the layout of the matrix 
-            entries is shown below:
-            <pre>
-                [ m[0][0]  m[0][1]  m[0][2]  m[0][3] ]   {x}
-                | m[1][0]  m[1][1]  m[1][2]  m[1][3] | * {y}
-                | m[2][0]  m[2][1]  m[2][2]  m[2][3] |   {z}
-                [ m[3][0]  m[3][1]  m[3][2]  m[3][3] ]   {1}
-            </pre>
-    */
     class CM_UTILITY_EXPORT Matrix4
     {
-    protected:
-        /// The matrix entries, indexed by [row][col].
-        union {
+    private:
+        union 
+		{
             float m[4][4];
             float _m[16];
         };
+
     public:
-        /** Default constructor.
-            @note
-                It does <b>NOT</b> initialize the matrix for efficiency.
-        */
-        inline Matrix4()
-        {
-        }
+        Matrix4()
+        { }
 
-        inline Matrix4(
+        Matrix4(
             float m00, float m01, float m02, float m03,
             float m10, float m11, float m12, float m13,
             float m20, float m21, float m22, float m23,
-            float m30, float m31, float m32, float m33 )
+            float m30, float m31, float m32, float m33)
         {
             m[0][0] = m00;
             m[0][1] = m01;
@@ -117,30 +73,31 @@ namespace CamelotFramework
             m[3][3] = m33;
         }
 
-        /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3 matrix.
-         */
+		Matrix4(const Matrix4& mat)
+		{
+			memcpy(_m, mat._m, 16*sizeof(float));
+		}
 
-        inline Matrix4(const Matrix3& m3x3)
+        /**
+         * @brief	Creates a 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3 matrix.
+         */
+        Matrix4(const Matrix3& mat3)
         {
-          operator=(IDENTITY);
-          operator=(m3x3);
+			m[0][0] = mat3.m[0][0]; m[0][1] = mat3.m[0][1]; m[0][2] = mat3.m[0][2]; m[0][3] = 0.0f;
+			m[1][0] = mat3.m[1][0]; m[1][1] = mat3.m[1][1]; m[1][2] = mat3.m[1][2]; m[1][3] = 0.0f;
+			m[2][0] = mat3.m[2][0]; m[2][1] = mat3.m[2][1]; m[2][2] = mat3.m[2][2]; m[2][3] = 0.0f;
+			m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f;
         }
 
-        /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling Quaternion.
+        /**
+         * @brief	Creates a 4x4 transformation matrix with translation, rotation and scale.
          */
-        
-        inline Matrix4(const Quaternion& rot)
+        Matrix4(const Vector3& translation, const Quaternion& rot, const Vector3& scale)
         {
-          Matrix3 m3x3;
-          rot.toRotationMatrix(m3x3);
-          operator=(IDENTITY);
-          operator=(m3x3);
+			setTRS(translation, rot, scale);
         }
         
-
-		/** Exchange the contents of this matrix with another. 
-		*/
-		inline void swap(Matrix4& other)
+		void swap(Matrix4& other)
 		{
 			std::swap(m[0][0], other.m[0][0]);
 			std::swap(m[0][1], other.m[0][1]);
@@ -160,189 +117,126 @@ namespace CamelotFramework
 			std::swap(m[3][3], other.m[3][3]);
 		}
 
-		inline float* operator [] ( size_t iRow )
+		float* operator[] (size_t row)
         {
-            assert( iRow < 4 );
-            return m[iRow];
-        }
+            assert(row < 4);
 
-        inline const float *operator [] ( size_t iRow ) const
-        {
-            assert( iRow < 4 );
-            return m[iRow];
+            return m[row];
         }
 
-        inline Matrix4 concatenate(const Matrix4 &m2) const
+        const float *operator[] (size_t row) const
         {
-            Matrix4 r;
-            r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
-            r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
-            r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
-            r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
-
-            r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
-            r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
-            r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
-            r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
-
-            r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
-            r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
-            r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
-            r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
-
-            r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
-            r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
-            r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
-            r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
+            assert(row < 4);
 
-            return r;
+            return m[row];
         }
 
-        /** Matrix concatenation using '*'.
-        */
-        inline Matrix4 operator * ( const Matrix4 &m2 ) const
+        Matrix4 operator* (const Matrix4 &rhs) const
         {
-            return concatenate( m2 );
-        }
+			Matrix4 r;
 
-        /** Vector transformation using '*'.
-            @remarks
-                Transforms the given 3-D vector by the matrix, projecting the 
-                result back into <i>w</i> = 1.
-            @note
-                This means that the initial <i>w</i> is considered to be 1.0,
-                and then all the tree elements of the resulting 3-D vector are
-                divided by the resulting <i>w</i>.
-        */
-        inline Vector3 operator * ( const Vector3 &v ) const
-        {
-            Vector3 r;
+			r.m[0][0] = m[0][0] * rhs.m[0][0] + m[0][1] * rhs.m[1][0] + m[0][2] * rhs.m[2][0] + m[0][3] * rhs.m[3][0];
+			r.m[0][1] = m[0][0] * rhs.m[0][1] + m[0][1] * rhs.m[1][1] + m[0][2] * rhs.m[2][1] + m[0][3] * rhs.m[3][1];
+			r.m[0][2] = m[0][0] * rhs.m[0][2] + m[0][1] * rhs.m[1][2] + m[0][2] * rhs.m[2][2] + m[0][3] * rhs.m[3][2];
+			r.m[0][3] = m[0][0] * rhs.m[0][3] + m[0][1] * rhs.m[1][3] + m[0][2] * rhs.m[2][3] + m[0][3] * rhs.m[3][3];
 
-            float fInvW = 1.0f / ( m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] );
+			r.m[1][0] = m[1][0] * rhs.m[0][0] + m[1][1] * rhs.m[1][0] + m[1][2] * rhs.m[2][0] + m[1][3] * rhs.m[3][0];
+			r.m[1][1] = m[1][0] * rhs.m[0][1] + m[1][1] * rhs.m[1][1] + m[1][2] * rhs.m[2][1] + m[1][3] * rhs.m[3][1];
+			r.m[1][2] = m[1][0] * rhs.m[0][2] + m[1][1] * rhs.m[1][2] + m[1][2] * rhs.m[2][2] + m[1][3] * rhs.m[3][2];
+			r.m[1][3] = m[1][0] * rhs.m[0][3] + m[1][1] * rhs.m[1][3] + m[1][2] * rhs.m[2][3] + m[1][3] * rhs.m[3][3];
 
-            r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW;
-            r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW;
-            r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW;
+			r.m[2][0] = m[2][0] * rhs.m[0][0] + m[2][1] * rhs.m[1][0] + m[2][2] * rhs.m[2][0] + m[2][3] * rhs.m[3][0];
+			r.m[2][1] = m[2][0] * rhs.m[0][1] + m[2][1] * rhs.m[1][1] + m[2][2] * rhs.m[2][1] + m[2][3] * rhs.m[3][1];
+			r.m[2][2] = m[2][0] * rhs.m[0][2] + m[2][1] * rhs.m[1][2] + m[2][2] * rhs.m[2][2] + m[2][3] * rhs.m[3][2];
+			r.m[2][3] = m[2][0] * rhs.m[0][3] + m[2][1] * rhs.m[1][3] + m[2][2] * rhs.m[2][3] + m[2][3] * rhs.m[3][3];
 
-            return r;
-        }
-        inline Vector4 operator * (const Vector4& v) const
-        {
-            return Vector4(
-                m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, 
-                m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
-                m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
-                m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
-                );
-        }
-        inline Plane operator * (const Plane& p) const
-        {
-            Plane ret;
-			Matrix4 invTrans = inverse().transpose();
-			Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d );
-			v4 = invTrans * v4;
-			ret.normal.x = v4.x; 
-			ret.normal.y = v4.y; 
-			ret.normal.z = v4.z;
-			ret.d = v4.w / ret.normal.normalize();
-
-            return ret;
-        }
+			r.m[3][0] = m[3][0] * rhs.m[0][0] + m[3][1] * rhs.m[1][0] + m[3][2] * rhs.m[2][0] + m[3][3] * rhs.m[3][0];
+			r.m[3][1] = m[3][0] * rhs.m[0][1] + m[3][1] * rhs.m[1][1] + m[3][2] * rhs.m[2][1] + m[3][3] * rhs.m[3][1];
+			r.m[3][2] = m[3][0] * rhs.m[0][2] + m[3][1] * rhs.m[1][2] + m[3][2] * rhs.m[2][2] + m[3][3] * rhs.m[3][2];
+			r.m[3][3] = m[3][0] * rhs.m[0][3] + m[3][1] * rhs.m[1][3] + m[3][2] * rhs.m[2][3] + m[3][3] * rhs.m[3][3];
 
+			return r;
+        }
 
-        /** Matrix addition.
-        */
-        inline Matrix4 operator + ( const Matrix4 &m2 ) const
+        Matrix4 operator+ (const Matrix4 &rhs) const
         {
             Matrix4 r;
 
-            r.m[0][0] = m[0][0] + m2.m[0][0];
-            r.m[0][1] = m[0][1] + m2.m[0][1];
-            r.m[0][2] = m[0][2] + m2.m[0][2];
-            r.m[0][3] = m[0][3] + m2.m[0][3];
+            r.m[0][0] = m[0][0] + rhs.m[0][0];
+            r.m[0][1] = m[0][1] + rhs.m[0][1];
+            r.m[0][2] = m[0][2] + rhs.m[0][2];
+            r.m[0][3] = m[0][3] + rhs.m[0][3];
 
-            r.m[1][0] = m[1][0] + m2.m[1][0];
-            r.m[1][1] = m[1][1] + m2.m[1][1];
-            r.m[1][2] = m[1][2] + m2.m[1][2];
-            r.m[1][3] = m[1][3] + m2.m[1][3];
+            r.m[1][0] = m[1][0] + rhs.m[1][0];
+            r.m[1][1] = m[1][1] + rhs.m[1][1];
+            r.m[1][2] = m[1][2] + rhs.m[1][2];
+            r.m[1][3] = m[1][3] + rhs.m[1][3];
 
-            r.m[2][0] = m[2][0] + m2.m[2][0];
-            r.m[2][1] = m[2][1] + m2.m[2][1];
-            r.m[2][2] = m[2][2] + m2.m[2][2];
-            r.m[2][3] = m[2][3] + m2.m[2][3];
+            r.m[2][0] = m[2][0] + rhs.m[2][0];
+            r.m[2][1] = m[2][1] + rhs.m[2][1];
+            r.m[2][2] = m[2][2] + rhs.m[2][2];
+            r.m[2][3] = m[2][3] + rhs.m[2][3];
 
-            r.m[3][0] = m[3][0] + m2.m[3][0];
-            r.m[3][1] = m[3][1] + m2.m[3][1];
-            r.m[3][2] = m[3][2] + m2.m[3][2];
-            r.m[3][3] = m[3][3] + m2.m[3][3];
+            r.m[3][0] = m[3][0] + rhs.m[3][0];
+            r.m[3][1] = m[3][1] + rhs.m[3][1];
+            r.m[3][2] = m[3][2] + rhs.m[3][2];
+            r.m[3][3] = m[3][3] + rhs.m[3][3];
 
             return r;
         }
 
-        /** Matrix subtraction.
-        */
-        inline Matrix4 operator - ( const Matrix4 &m2 ) const
+        Matrix4 operator- (const Matrix4 &rhs) const
         {
             Matrix4 r;
-            r.m[0][0] = m[0][0] - m2.m[0][0];
-            r.m[0][1] = m[0][1] - m2.m[0][1];
-            r.m[0][2] = m[0][2] - m2.m[0][2];
-            r.m[0][3] = m[0][3] - m2.m[0][3];
-
-            r.m[1][0] = m[1][0] - m2.m[1][0];
-            r.m[1][1] = m[1][1] - m2.m[1][1];
-            r.m[1][2] = m[1][2] - m2.m[1][2];
-            r.m[1][3] = m[1][3] - m2.m[1][3];
-
-            r.m[2][0] = m[2][0] - m2.m[2][0];
-            r.m[2][1] = m[2][1] - m2.m[2][1];
-            r.m[2][2] = m[2][2] - m2.m[2][2];
-            r.m[2][3] = m[2][3] - m2.m[2][3];
-
-            r.m[3][0] = m[3][0] - m2.m[3][0];
-            r.m[3][1] = m[3][1] - m2.m[3][1];
-            r.m[3][2] = m[3][2] - m2.m[3][2];
-            r.m[3][3] = m[3][3] - m2.m[3][3];
+            r.m[0][0] = m[0][0] - rhs.m[0][0];
+            r.m[0][1] = m[0][1] - rhs.m[0][1];
+            r.m[0][2] = m[0][2] - rhs.m[0][2];
+            r.m[0][3] = m[0][3] - rhs.m[0][3];
+
+            r.m[1][0] = m[1][0] - rhs.m[1][0];
+            r.m[1][1] = m[1][1] - rhs.m[1][1];
+            r.m[1][2] = m[1][2] - rhs.m[1][2];
+            r.m[1][3] = m[1][3] - rhs.m[1][3];
+
+            r.m[2][0] = m[2][0] - rhs.m[2][0];
+            r.m[2][1] = m[2][1] - rhs.m[2][1];
+            r.m[2][2] = m[2][2] - rhs.m[2][2];
+            r.m[2][3] = m[2][3] - rhs.m[2][3];
+
+            r.m[3][0] = m[3][0] - rhs.m[3][0];
+            r.m[3][1] = m[3][1] - rhs.m[3][1];
+            r.m[3][2] = m[3][2] - rhs.m[3][2];
+            r.m[3][3] = m[3][3] - rhs.m[3][3];
 
             return r;
         }
 
-        /** Tests 2 matrices for equality.
-        */
-        inline bool operator == ( const Matrix4& m2 ) const
+        inline bool operator== (const Matrix4& rhs ) const
         {
             if( 
-                m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
-                m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
-                m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
-                m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
+                m[0][0] != rhs.m[0][0] || m[0][1] != rhs.m[0][1] || m[0][2] != rhs.m[0][2] || m[0][3] != rhs.m[0][3] ||
+                m[1][0] != rhs.m[1][0] || m[1][1] != rhs.m[1][1] || m[1][2] != rhs.m[1][2] || m[1][3] != rhs.m[1][3] ||
+                m[2][0] != rhs.m[2][0] || m[2][1] != rhs.m[2][1] || m[2][2] != rhs.m[2][2] || m[2][3] != rhs.m[2][3] ||
+                m[3][0] != rhs.m[3][0] || m[3][1] != rhs.m[3][1] || m[3][2] != rhs.m[3][2] || m[3][3] != rhs.m[3][3] )
                 return false;
             return true;
         }
 
-        /** Tests 2 matrices for inequality.
-        */
-        inline bool operator != ( const Matrix4& m2 ) const
+        inline bool operator!= (const Matrix4& rhs) const
         {
-            if( 
-                m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
-                m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
-                m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
-                m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
-                return true;
-            return false;
+            return !operator==(rhs);
         }
 
-        /** Assignment from 3x3 matrix.
-        */
-        inline void operator = ( const Matrix3& mat3 )
-        {
-            m[0][0] = mat3.m[0][0]; m[0][1] = mat3.m[0][1]; m[0][2] = mat3.m[0][2];
-            m[1][0] = mat3.m[1][0]; m[1][1] = mat3.m[1][1]; m[1][2] = mat3.m[1][2];
-            m[2][0] = mat3.m[2][0]; m[2][1] = mat3.m[2][1]; m[2][2] = mat3.m[2][2];
-        }
+		Matrix4 operator*(float rhs) const
+		{
+			return Matrix4(
+				rhs*m[0][0], rhs*m[0][1], rhs*m[0][2], rhs*m[0][3],
+				rhs*m[1][0], rhs*m[1][1], rhs*m[1][2], rhs*m[1][3],
+				rhs*m[2][0], rhs*m[2][1], rhs*m[2][2], rhs*m[2][3],
+				rhs*m[3][0], rhs*m[3][1], rhs*m[3][2], rhs*m[3][3]);
+		}
 
-        inline Matrix4 transpose(void) const
+        Matrix4 transpose() const
         {
             return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
                            m[0][1], m[1][1], m[2][1], m[3][1],
@@ -350,118 +244,10 @@ namespace CamelotFramework
                            m[0][3], m[1][3], m[2][3], m[3][3]);
         }
 
-        /*
-        -----------------------------------------------------------------------
-        Translation Transformation
-        -----------------------------------------------------------------------
-        */
-        /** Sets the translation transformation part of the matrix.
-        */
-        inline void setTrans( const Vector3& v )
-        {
-            m[0][3] = v.x;
-            m[1][3] = v.y;
-            m[2][3] = v.z;
-        }
-
-        /** Extracts the translation transformation part of the matrix.
+        /**
+         * @brief	Extracts the rotation/scaling part of the Matrix as a 3x3 matrix.
          */
-        inline Vector3 getTrans() const
-        {
-          return Vector3(m[0][3], m[1][3], m[2][3]);
-        }
-        
-
-        /** Builds a translation matrix
-        */
-        inline void makeTrans( const Vector3& v )
-        {
-            m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = v.x;
-            m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = v.y;
-            m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = v.z;
-            m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
-        }
-
-        inline void makeTrans( float tx, float ty, float tz )
-        {
-            m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
-            m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
-            m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
-            m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
-        }
-
-        /** Gets a translation matrix.
-        */
-        inline static Matrix4 getTrans( const Vector3& v )
-        {
-            Matrix4 r;
-
-            r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = v.x;
-            r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = v.y;
-            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = v.z;
-            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
-
-            return r;
-        }
-
-        /** Gets a translation matrix - variation for not using a vector.
-        */
-        inline static Matrix4 getTrans( float t_x, float t_y, float t_z )
-        {
-            Matrix4 r;
-
-            r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = t_x;
-            r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = t_y;
-            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = t_z;
-            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
-
-            return r;
-        }
-
-        /*
-        -----------------------------------------------------------------------
-        Scale Transformation
-        -----------------------------------------------------------------------
-        */
-        /** Sets the scale part of the matrix.
-        */
-        inline void setScale( const Vector3& v )
-        {
-            m[0][0] = v.x;
-            m[1][1] = v.y;
-            m[2][2] = v.z;
-        }
-
-        /** Gets a scale matrix.
-        */
-        inline static Matrix4 getScale( const Vector3& v )
-        {
-            Matrix4 r;
-            r.m[0][0] = v.x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
-            r.m[1][0] = 0.0; r.m[1][1] = v.y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
-            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = v.z; r.m[2][3] = 0.0;
-            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
-
-            return r;
-        }
-
-        /** Gets a scale matrix - variation for not using a vector.
-        */
-        inline static Matrix4 getScale( float s_x, float s_y, float s_z )
-        {
-            Matrix4 r;
-            r.m[0][0] = s_x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
-            r.m[1][0] = 0.0; r.m[1][1] = s_y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
-            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = s_z; r.m[2][3] = 0.0;
-            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
-
-            return r;
-        }
-
-        /** Extracts the rotation / scaling part of the Matrix as a 3x3 matrix. 
-        @param m3x3 Destination Matrix3
-        */
-        inline void extract3x3Matrix(Matrix3& m3x3) const
+        void extract3x3Matrix(Matrix3& m3x3) const
         {
             m3x3.m[0][0] = m[0][0];
             m3x3.m[0][1] = m[0][1];
@@ -472,190 +258,149 @@ namespace CamelotFramework
             m3x3.m[2][0] = m[2][0];
             m3x3.m[2][1] = m[2][1];
             m3x3.m[2][2] = m[2][2];
-
-        }
-
-		/** Determines if this matrix involves a scaling. */
-		inline bool hasScale() const
-		{
-			// check magnitude of column vectors (==local axes)
-			float t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0];
-			if (!Math::RealEqual(t, 1.0, (float)1e-04))
-				return true;
-			t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1];
-			if (!Math::RealEqual(t, 1.0, (float)1e-04))
-				return true;
-			t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2];
-			if (!Math::RealEqual(t, 1.0, (float)1e-04))
-				return true;
-
-			return false;
-		}
-
-		/** Determines if this matrix involves a negative scaling. */
-		inline bool hasNegativeScale() const
-		{
-			return determinant() < 0;
-		}
-
-		/** Extracts the rotation / scaling part as a quaternion from the Matrix.
-         */
-        inline Quaternion extractQuaternion() const
-        {
-          Matrix3 m3x3;
-          extract3x3Matrix(m3x3);
-          return Quaternion(m3x3);
         }
 
-        static const Matrix4 ZERO;
-        static const Matrix4 IDENTITY;
-        /** Useful little matrix which takes 2D clipspace {-1, 1} to {0,1}
-            and inverts the Y. */
-        static const Matrix4 CLIPSPACE2DTOIMAGESPACE;
-
-        inline Matrix4 operator*(float scalar) const
-        {
-            return Matrix4(
-                scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
-                scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
-                scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
-                scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
-        }
-
-        /** Function for writing to a stream.
-        */
-        inline CM_UTILITY_EXPORT friend std::ostream& operator <<
-            ( std::ostream& o, const Matrix4& mat )
-        {
-            o << "Matrix4(";
-			for (size_t i = 0; i < 4; ++i)
-            {
-                o << " row" << (unsigned)i << "{";
-                for(size_t j = 0; j < 4; ++j)
-                {
-                    o << mat[i][j] << " ";
-                }
-                o << "}";
-            }
-            o << ")";
-            return o;
-        }
-		
 		Matrix4 adjoint() const;
 		float determinant() const;
 		Matrix4 inverse() const;
+        
+        /**
+         * @brief	Creates a matrix from translation, rotation and scale. 
+         * 			
+		 * @note	The transformation are applied in scale->rotation->translation order.
+         */
+        void setTRS(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
 
-        /** Building a Matrix4 from orientation / scale / position.
-        @remarks
-            Transform is performed in the order scale, rotate, translation, i.e. translation is independent
-            of orientation axes, scale does not affect size of translation, rotation and scaling are always
-            centered on the origin.
-        */
-        void makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
-
-        /** Building an inverse Matrix4 from orientation / scale / position.
-        @remarks
-            As makeTransform except it build the inverse given the same data as makeTransform, so
-            performing -translation, -rotate, 1/scale in that order.
-        */
-        void makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
-
-        /** Decompose a Matrix4 to orientation / scale / position.
-        */
-        void decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const;
-
-        /** Check whether or not the matrix is affine matrix.
-            @remarks
-                An affine matrix is a 4x4 matrix with row 3 equal to (0, 0, 0, 1),
-                e.g. no projective coefficients.
-        */
-        inline bool isAffine(void) const
+        /**
+         * @brief	Creates a matrix from inverse translation, rotation and scale. 
+         * 			
+		 * @note	This is cheaper than "setTRS" and then performing "inverse".
+         */
+        void setInverseTRS(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
+
+        /**
+         * @brief	Decompose a Matrix4 to translation, rotation and scale.
+         *
+         * @note	Matrix must consist only of translation, rotation and uniform scale transformations,
+         * 			otherwise accurate results are not guaranteed. Applying non-uniform scale guarantees
+         * 			results will not be accurate.
+         */
+        void decomposition(Vector3& position, Quaternion& rotation, Vector3& scale) const;
+
+        /**
+		 * @brief	Check whether or not the matrix is affine matrix.
+		 *
+		 * @note	An affine matrix is a 4x4 matrix with row 3 equal to (0, 0, 0, 1),
+		 *			i.e. no projective coefficients.
+         */
+        bool isAffine() const
         {
             return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
         }
 
-        /** Returns the inverse of the affine matrix.
-            @note
-                The matrix must be an affine matrix. @see Matrix4::isAffine.
-        */
+        /**
+         * @brief	Returns the inverse of the affine matrix.
+         *
+         * @note	Matrix must be affine.
+         */
         Matrix4 inverseAffine(void) const;
 
-        /** Concatenate two affine matrices.
-            @note
-                The matrices must be affine matrix. @see Matrix4::isAffine.
-        */
-        inline Matrix4 concatenateAffine(const Matrix4 &m2) const
+        /**
+         * @brief	Concatenate two affine matrices.
+         *
+         * @note	Both matrices must be affine.
+         */
+        Matrix4 concatenateAffine(const Matrix4 &other) const
         {
-            assert(isAffine() && m2.isAffine());
+            assert(isAffine() && other.isAffine());
 
             return Matrix4(
-                m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0],
-                m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1],
-                m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2],
-                m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3],
+                m[0][0] * other.m[0][0] + m[0][1] * other.m[1][0] + m[0][2] * other.m[2][0],
+                m[0][0] * other.m[0][1] + m[0][1] * other.m[1][1] + m[0][2] * other.m[2][1],
+                m[0][0] * other.m[0][2] + m[0][1] * other.m[1][2] + m[0][2] * other.m[2][2],
+                m[0][0] * other.m[0][3] + m[0][1] * other.m[1][3] + m[0][2] * other.m[2][3] + m[0][3],
 
-                m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0],
-                m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1],
-                m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2],
-                m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3],
+                m[1][0] * other.m[0][0] + m[1][1] * other.m[1][0] + m[1][2] * other.m[2][0],
+                m[1][0] * other.m[0][1] + m[1][1] * other.m[1][1] + m[1][2] * other.m[2][1],
+                m[1][0] * other.m[0][2] + m[1][1] * other.m[1][2] + m[1][2] * other.m[2][2],
+                m[1][0] * other.m[0][3] + m[1][1] * other.m[1][3] + m[1][2] * other.m[2][3] + m[1][3],
 
-                m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0],
-                m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1],
-                m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2],
-                m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3],
+                m[2][0] * other.m[0][0] + m[2][1] * other.m[1][0] + m[2][2] * other.m[2][0],
+                m[2][0] * other.m[0][1] + m[2][1] * other.m[1][1] + m[2][2] * other.m[2][1],
+                m[2][0] * other.m[0][2] + m[2][1] * other.m[1][2] + m[2][2] * other.m[2][2],
+                m[2][0] * other.m[0][3] + m[2][1] * other.m[1][3] + m[2][2] * other.m[2][3] + m[2][3],
 
                 0, 0, 0, 1);
         }
 
-        /** 3-D Vector transformation specially for an affine matrix.
-            @remarks
-                Transforms the given 3-D vector by the matrix, projecting the 
-                result back into <i>w</i> = 1.
-            @note
-                The matrix must be an affine matrix. @see Matrix4::isAffine.
-        */
-        inline Vector3 transformAffine(const Vector3& v) const
+        /**
+         * @brief	Transform a 3D vector by this matrix.
+         * 			
+         * @note	Matrix must be affine, if it is not use "transform" method.
+         */
+        Vector3 transform3x4(const Vector3& v) const
         {
-            assert(isAffine());
-
             return Vector3(
                     m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3], 
                     m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3],
                     m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]);
         }
 
-        /** 4-D Vector transformation specially for an affine matrix.
-            @note
-                The matrix must be an affine matrix. @see Matrix4::isAffine.
-        */
-        inline Vector4 transformAffine(const Vector4& v) const
+        /**
+         * @brief	Transform a 4D vector by this matrix.
+         * 			
+         * @note	Matrix must be affine, if it is not use "transform" method.
+         */
+        Vector4 transform3x4(const Vector4& v) const
         {
-            assert(isAffine());
-
             return Vector4(
                 m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, 
                 m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
                 m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
                 v.w);
         }
-    };
 
-    /* Removed from Vector4 and made a non-member here because otherwise
-       CmMatrix4.h and CmVector4.h have to try to include and inline each 
-       other, which frankly doesn't work ;)
-   */
-    inline Vector4 operator * (const Vector4& v, const Matrix4& mat)
-    {
-        return Vector4(
-            v.x*mat[0][0] + v.y*mat[1][0] + v.z*mat[2][0] + v.w*mat[3][0],
-            v.x*mat[0][1] + v.y*mat[1][1] + v.z*mat[2][1] + v.w*mat[3][1],
-            v.x*mat[0][2] + v.y*mat[1][2] + v.z*mat[2][2] + v.w*mat[3][2],
-            v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3]
-            );
-    }
-	/** @} */
-	/** @} */
+        /**
+         * @brief	Transform a 3D vector by this matrix.  
+         *
+         * @note	w component of the vector is assumed to be 1. After transformation all components
+         * 			are projected back so that w remains 1.
+         * 			
+		 *			If your matrix doesn't contain projection components use "transform3x4" method as it is faster.
+         */
+        Vector3 transform(const Vector3 &v) const
+        {
+            Vector3 r;
+
+            float fInvW = 1.0f / (m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3]);
+
+            r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW;
+            r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW;
+            r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW;
+
+            return r;
+        }
+
+        /**
+         * @brief	Transform a 3D vector by this matrix.  
+         *
+         * @note	After transformation all components are projected back so that w remains 1.
+         * 			
+		 *			If your matrix doesn't contain projection components use "transform3x4" method as it is faster.
+         */
+        Vector4 transform(const Vector4& v) const
+        {
+            return Vector4(
+                m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, 
+                m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
+                m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
+                m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
+                );
+        }
+
+		static const Matrix4 ZERO;
+		static const Matrix4 IDENTITY;
+    };
 
 	CM_ALLOW_MEMCPY_SERIALIZATION(Matrix4);
-}
-#endif
+}

+ 1 - 1
CamelotUtility/Source/CmFRect.cpp

@@ -88,7 +88,7 @@ namespace CamelotFramework
 		verts[3] = Vector4(x + width, y + height, 0.0f, 1.0f);
 
 		for(UINT32 i = 0; i < 4; i++)
-			verts[i] = matrix * verts[i];
+			verts[i] = matrix.transform(verts[i]);
 
 		float minX = std::numeric_limits<float>::max();
 		float maxX = std::numeric_limits<float>::min();

+ 32 - 50
CamelotUtility/Source/CmMatrix4.cpp

@@ -32,35 +32,26 @@ THE SOFTWARE.
 
 namespace CamelotFramework
 {
-
     const Matrix4 Matrix4::ZERO(
-        0, 0, 0, 0,
-        0, 0, 0, 0,
-        0, 0, 0, 0,
-        0, 0, 0, 0 );
+        0.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f, 0.0f);
 
     const Matrix4 Matrix4::IDENTITY(
-        1, 0, 0, 0,
-        0, 1, 0, 0,
-        0, 0, 1, 0,
-        0, 0, 0, 1 );
-
-    const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE(
-        0.5,    0,  0, 0.5, 
-          0, -0.5,  0, 0.5, 
-          0,    0,  1,   0,
-          0,    0,  0,   1);
-
-    //-----------------------------------------------------------------------
-    inline static float
-        MINOR(const Matrix4& m, const size_t r0, const size_t r1, const size_t r2, 
+		1.0f, 0.0f, 0.0f, 0.0f,
+		0.0f, 1.0f, 0.0f, 0.0f,
+		0.0f, 0.0f, 1.0f, 0.0f,
+		0.0f, 0.0f, 0.0f, 1.0f);
+
+    static float MINOR(const Matrix4& m, const size_t r0, const size_t r1, const size_t r2, 
 								const size_t c0, const size_t c1, const size_t c2)
     {
         return m[r0][c0] * (m[r1][c1] * m[r2][c2] - m[r2][c1] * m[r1][c2]) -
             m[r0][c1] * (m[r1][c0] * m[r2][c2] - m[r2][c0] * m[r1][c2]) +
             m[r0][c2] * (m[r1][c0] * m[r2][c1] - m[r2][c0] * m[r1][c1]);
     }
-    //-----------------------------------------------------------------------
+
     Matrix4 Matrix4::adjoint() const
     {
         return Matrix4( MINOR(*this, 1, 2, 3, 1, 2, 3),
@@ -83,7 +74,7 @@ namespace CamelotFramework
             -MINOR(*this, 0, 1, 3, 0, 1, 2),
             MINOR(*this, 0, 1, 2, 0, 1, 2));
     }
-    //-----------------------------------------------------------------------
+
     float Matrix4::determinant() const
     {
         return m[0][0] * MINOR(*this, 1, 2, 3, 1, 2, 3) -
@@ -91,7 +82,7 @@ namespace CamelotFramework
             m[0][2] * MINOR(*this, 1, 2, 3, 0, 1, 3) -
             m[0][3] * MINOR(*this, 1, 2, 3, 0, 1, 2);
     }
-    //-----------------------------------------------------------------------
+
     Matrix4 Matrix4::inverse() const
     {
         float m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
@@ -153,8 +144,8 @@ namespace CamelotFramework
             d20, d21, d22, d23,
             d30, d31, d32, d33);
     }
-    //-----------------------------------------------------------------------
-    Matrix4 Matrix4::inverseAffine(void) const
+
+    Matrix4 Matrix4::inverseAffine() const
     {
         assert(isAffine());
 
@@ -197,37 +188,31 @@ namespace CamelotFramework
             r20, r21, r22, r23,
               0,   0,   0,   1);
     }
-    //-----------------------------------------------------------------------
-    void Matrix4::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
-    {
-        // Ordering:
-        //    1. Scale
-        //    2. Rotate
-        //    3. Translate
 
+    void Matrix4::setTRS(const Vector3& translation, const Quaternion& rotation, const Vector3& scale)
+    {
         Matrix3 rot3x3;
-        orientation.toRotationMatrix(rot3x3);
+        rotation.toRotationMatrix(rot3x3);
 
-        // Set up final matrix with scale, rotation and translation
-        m[0][0] = scale.x * rot3x3[0][0]; m[0][1] = scale.y * rot3x3[0][1]; m[0][2] = scale.z * rot3x3[0][2]; m[0][3] = position.x;
-        m[1][0] = scale.x * rot3x3[1][0]; m[1][1] = scale.y * rot3x3[1][1]; m[1][2] = scale.z * rot3x3[1][2]; m[1][3] = position.y;
-        m[2][0] = scale.x * rot3x3[2][0]; m[2][1] = scale.y * rot3x3[2][1]; m[2][2] = scale.z * rot3x3[2][2]; m[2][3] = position.z;
+        m[0][0] = scale.x * rot3x3[0][0]; m[0][1] = scale.y * rot3x3[0][1]; m[0][2] = scale.z * rot3x3[0][2]; m[0][3] = translation.x;
+        m[1][0] = scale.x * rot3x3[1][0]; m[1][1] = scale.y * rot3x3[1][1]; m[1][2] = scale.z * rot3x3[1][2]; m[1][3] = translation.y;
+        m[2][0] = scale.x * rot3x3[2][0]; m[2][1] = scale.y * rot3x3[2][1]; m[2][2] = scale.z * rot3x3[2][2]; m[2][3] = translation.z;
 
         // No projection term
         m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
     }
-    //-----------------------------------------------------------------------
-    void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
+
+    void Matrix4::setInverseTRS(const Vector3& translation, const Quaternion& rotation, const Vector3& scale)
     {
         // Invert the parameters
-        Vector3 invTranslate = -position;
+        Vector3 invTranslate = -translation;
         Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z);
-        Quaternion invRot = orientation.inverse();
+        Quaternion invRot = rotation.inverse();
 
         // Because we're inverting, order is translation, rotation, scale
         // So make translation relative to scale & rotation
-        invTranslate = invRot.rotate(invTranslate); // rotate
-        invTranslate *= invScale; // scale
+        invTranslate = invRot.rotate(invTranslate);
+        invTranslate *= invScale;
 
         // Next, make a 3x3 rotation matrix
         Matrix3 rot3x3;
@@ -241,20 +226,17 @@ namespace CamelotFramework
         // No projection term
         m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
     }
-    //-----------------------------------------------------------------------
-	void Matrix4::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const
-	{
-		assert(isAffine());
 
+	void Matrix4::decomposition(Vector3& position, Quaternion& rotation, Vector3& scale) const
+	{
 		Matrix3 m3x3;
 		extract3x3Matrix(m3x3);
 
 		Matrix3 matQ;
 		Vector3 vecU;
-		m3x3.QDUDecomposition( matQ, scale, vecU ); 
+		m3x3.QDUDecomposition(matQ, scale, vecU); 
 
-		orientation = Quaternion( matQ );
-		position = Vector3( m[0][3], m[1][3], m[2][3] );
+		rotation = Quaternion(matQ);
+		position = Vector3(m[0][3], m[1][3], m[2][3]);
 	}
-
 }

+ 8 - 3
CamelotUtility/Source/CmQuaternion.cpp

@@ -56,7 +56,7 @@ namespace CamelotFramework
         float trace = mat[0][0]+mat[1][1]+mat[2][2];
         float root;
 
-        if ( trace > 0.0 )
+        if (trace > 0.0f)
         {
             // |w| > 1/2, may as well choose w > 1/2
             root = Math::Sqrt(trace + 1.0f);  // 2w
@@ -71,17 +71,22 @@ namespace CamelotFramework
             // |w| <= 1/2
             static size_t nextLookup[3] = { 1, 2, 0 };
             size_t i = 0;
-            if ( mat[1][1] > mat[0][0] )
+
+            if (mat[1][1] > mat[0][0])
                 i = 1;
-            if ( mat[2][2] > mat[i][i] )
+
+            if (mat[2][2] > mat[i][i])
                 i = 2;
+
             size_t j = nextLookup[i];
             size_t k = nextLookup[j];
 
             root = Math::Sqrt(mat[i][i]-mat[j][j]-mat[k][k] + 1.0f);
+
             float* cmpntLookup[3] = { &x, &y, &z };
             *cmpntLookup[i] = 0.5f*root;
             root = 0.5f/root;
+
             w = (mat[k][j]-mat[j][k])*root;
             *cmpntLookup[j] = (mat[j][i]+mat[i][j])*root;
             *cmpntLookup[k] = (mat[k][i]+mat[i][k])*root;

+ 1 - 1
CamelotUtility/Source/CmRect.cpp

@@ -88,7 +88,7 @@ namespace CamelotFramework
 		verts[3] = Vector4((float)x + width, (float)y + height, 0.0f, 1.0f);
 
 		for(UINT32 i = 0; i < 4; i++)
-			verts[i] = matrix * verts[i];
+			verts[i] = matrix.transform(verts[i]);
 
 		float minX = std::numeric_limits<float>::max();
 		float maxX = std::numeric_limits<float>::min();