Browse Source

Port Matrix3x3 and Matrix4x4 to NMF

Daniele Bartolini 12 years ago
parent
commit
643518ce06

+ 0 - 2
engine/Android.mk

@@ -113,8 +113,6 @@ LOCAL_SRC_FILES :=\
 	core/json/JSONParser.cpp\
 \
 	core/math/Color4.cpp\
-	core/math/Matrix3x3.cpp\
-	core/math/Matrix4x4.cpp\
 \
 	core/mem/LinearAllocator.cpp\
 	core/mem/Memory.cpp\

+ 1 - 3
engine/CMakeLists.txt

@@ -131,8 +131,6 @@ set (CONTAINERS_HEADERS
 
 set (MATH_SRC
 	core/math/Color4.cpp
-	core/math/Matrix3x3.cpp
-	core/math/Matrix4x4.cpp
 )
 
 set (MATH_HEADERS
@@ -488,7 +486,7 @@ if (LINUX)
 		#-pedantic-errors
 		-Wall
 		-Wextra
-		-Werror
+		#-Werror
 		-Wno-long-long
 		-Wno-variadic-macros
 		-Wno-unknown-pragmas

+ 4 - 4
engine/audio/backend/ALSoundWorld.cpp

@@ -227,7 +227,7 @@ public:
 
 	ALSoundWorld()
 	{
-		set_listener_pose(Matrix4x4::IDENTITY);
+		set_listener_pose(matrix4x4::IDENTITY);
 	}
 
 	virtual ~ALSoundWorld()
@@ -322,9 +322,9 @@ public:
 
 	virtual void set_listener_pose(const Matrix4x4& pose)
 	{
-		const Vector3 pos = pose.translation();
-		const Vector3 up = pose.y();
-		const Vector3 at = pose.z();
+		const Vector3 pos = matrix4x4::translation(pose);
+		const Vector3 up = matrix4x4::y(pose);
+		const Vector3 at = matrix4x4::z(pose);
 
 		AL_CHECK(alListener3f(AL_POSITION, pos.x, pos.y, pos.z));
 		//AL_CHECK(alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z));

+ 30 - 40
engine/core/math/Frustum.h

@@ -114,35 +114,35 @@ namespace frustum
 	//-----------------------------------------------------------------------------
 	inline void from_matrix(Frustum& f, const Matrix4x4& m)
 	{
-		f.left.n.x		= m.m[3] + m.m[0];
-		f.left.n.y		= m.m[7] + m.m[4];
-		f.left.n.z		= m.m[11] + m.m[8];
-		f.left.d		= m.m[15] + m.m[12];
-
-		f.right.n.x		= m.m[3] - m.m[0];
-		f.right.n.y		= m.m[7] - m.m[4];
-		f.right.n.z		= m.m[11] - m.m[8];
-		f.right.d		= m.m[15] - m.m[12];
-
-		f.bottom.n.x	= m.m[3] + m.m[1];
-		f.bottom.n.y	= m.m[7] + m.m[5];
-		f.bottom.n.z	= m.m[11] + m.m[9];
-		f.bottom.d		= m.m[15] + m.m[13];
-
-		f.top.n.x		= m.m[3] - m.m[1];
-		f.top.n.y		= m.m[7] - m.m[5];
-		f.top.n.z		= m.m[11] - m.m[9];
-		f.top.d			= m.m[15] - m.m[13];
-
-		f.near.n.x		= m.m[3] + m.m[2];
-		f.near.n.y		= m.m[7] + m.m[6];
-		f.near.n.z		= m.m[11] + m.m[10];
-		f.near.d		= m.m[15] + m.m[14];
-
-		f.far.n.x		= m.m[3] - m.m[2];
-		f.far.n.y		= m.m[7] - m.m[6];
-		f.far.n.z		= m.m[11] - m.m[10];
-		f.far.d			= m.m[15] - m.m[14];
+		f.left.n.x		= m[3] + m[0];
+		f.left.n.y		= m[7] + m[4];
+		f.left.n.z		= m[11] + m[8];
+		f.left.d		= m[15] + m[12];
+
+		f.right.n.x		= m[3] - m[0];
+		f.right.n.y		= m[7] - m[4];
+		f.right.n.z		= m[11] - m[8];
+		f.right.d		= m[15] - m[12];
+
+		f.bottom.n.x	= m[3] + m[1];
+		f.bottom.n.y	= m[7] + m[5];
+		f.bottom.n.z	= m[11] + m[9];
+		f.bottom.d		= m[15] + m[13];
+
+		f.top.n.x		= m[3] - m[1];
+		f.top.n.y		= m[7] - m[5];
+		f.top.n.z		= m[11] - m[9];
+		f.top.d			= m[15] - m[13];
+
+		f.near.n.x		= m[3] + m[2];
+		f.near.n.y		= m[7] + m[6];
+		f.near.n.z		= m[11] + m[10];
+		f.near.d		= m[15] + m[14];
+
+		f.far.n.x		= m[3] - m[2];
+		f.far.n.y		= m[7] - m[6];
+		f.far.n.z		= m[11] - m[10];
+		f.far.d			= m[15] - m[14];
 
 		plane::normalize(f.left);
 		plane::normalize(f.right);
@@ -177,17 +177,7 @@ namespace frustum
 //-----------------------------------------------------------------------------
 inline Frustum::Frustum()
 {
-}
-
-//-----------------------------------------------------------------------------
-inline Frustum::Frustum(const Frustum& f)
-{
-	left	= f.left;
-	right	= f.right;
-	bottom	= f.bottom;
-	top		= f.top;
-	near	= f.near;
-	far		= f.far;
+	// Do not initialize
 }
 
 } // namespace crown

+ 54 - 5
engine/core/math/MathTypes.h

@@ -26,6 +26,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+#include "Types.h"
+
 namespace crown
 {
 
@@ -38,7 +40,6 @@ struct Vector2
 	Vector2(float val);
 	Vector2(float nx, float ny);
 	Vector2(const float v[2]);
-	Vector2(const Vector2& a);
 
 	float operator[](uint32_t i) const;
 	float& operator[](uint32_t i);
@@ -58,7 +59,6 @@ struct Vector3
 	Vector3(float val);
 	Vector3(float nx, float ny, float nz);
 	Vector3(const float v[3]);
-	Vector3(const Vector3& a);
 
 	float operator[](uint32_t i) const;
 	float& operator[](uint32_t i);
@@ -75,10 +75,10 @@ struct Vector3
 struct Vector4
 {
 	Vector4();
+	Vector4(const Vector3& a, float w);
 	Vector4(float val);
 	Vector4(float nx, float ny, float nz, float nw);
 	Vector4(const float v[3]);
-	Vector4(const Vector4& a);
 
 	float operator[](uint32_t i) const;
 	float& operator[](uint32_t i);
@@ -103,6 +103,57 @@ struct Quaternion
 	float x, y, z, w;
 };
 
+/// @ingroup Math
+struct Matrix3x3
+{
+	Matrix3x3();
+	Matrix3x3(const Vector3& x, const Vector3& y, const Vector3& z);
+	Matrix3x3(const Quaternion& r);
+
+	Matrix3x3(float r1c1, float r2c1, float r3c1, float r1c2, float r2c2, float r3c2,
+				float r1c3, float r2c3, float r3c3);
+
+	Matrix3x3(const float v[9]);
+
+	float& operator[](uint32_t i);
+	const float& operator[](uint32_t i) const;
+
+	Matrix3x3& operator+=(const Matrix3x3& a);
+	Matrix3x3& operator-=(const Matrix3x3& a);
+	Matrix3x3& operator*=(const Matrix3x3& a);
+	Matrix3x3& operator*=(float k);
+	Matrix3x3& operator/=(float k);
+
+	Vector3 x, y, z;
+};
+
+/// @ingroup Math
+struct Matrix4x4
+{
+	Matrix4x4();
+	Matrix4x4(const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& t);
+	Matrix4x4(const Quaternion& r, const Vector3& p);
+	Matrix4x4(const Matrix3x3& m);
+
+	Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
+				float r1c2, float r2c2, float r3c2, float r4c2,
+				float r1c3, float r2c3, float r3c3, float r4c3,
+				float r1c4, float r2c4, float r3c4, float r4c4);
+
+	Matrix4x4(const float v[16]);
+
+	float& operator[](uint32_t i);
+	const float& operator[](uint32_t i) const;
+
+	Matrix4x4& operator+=(const Matrix4x4& a);
+	Matrix4x4& operator-=(const Matrix4x4& a);
+	Matrix4x4& operator*=(const Matrix4x4& a);
+	Matrix4x4& operator*=(float k);
+	Matrix4x4& operator/=(float k);
+
+	Vector4 x, y, z, t;
+};
+
 /// @ingroup Math
 struct AABB
 {
@@ -125,7 +176,6 @@ struct Plane
 	/// Does nothing for efficiency.
 	Plane();						
 	Plane(const Vector3& n, float d);
-	Plane(const Plane& p);
 
 	Vector3 n;
 	float d;
@@ -135,7 +185,6 @@ struct Plane
 struct Frustum
 {
 	Frustum();
-	Frustum(const Frustum& f);
 
 	Plane left;
 	Plane right;

+ 0 - 650
engine/core/math/Matrix3x3.cpp

@@ -1,650 +0,0 @@
-/*
-Copyright (c) 2013 Daniele Bartolini, Michele Rossi
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "Assert.h"
-#include "Matrix3x3.h"
-#include "Types.h"
-#include "Matrix4x4.h"
-#include "MathUtils.h"
-#include "Quaternion.h"
-#include "Vector3.h"
-
-namespace crown
-{
-
-const Matrix3x3 Matrix3x3::IDENTITY = Matrix3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
-
-//-----------------------------------------------------------------------------
-Matrix3x3::Matrix3x3()
-{
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3::Matrix3x3(float r1c1, float r2c1, float r3c1, float r1c2, float r2c2, float r3c2,
-	float r1c3, float r2c3, float r3c3)
-{
-	m[0] = r1c1;
-	m[1] = r2c1;
-	m[2] = r3c1;
-	m[3] = r1c2;
-	m[4] = r2c2;
-	m[5] = r3c2;
-	m[6] = r1c3;
-	m[7] = r2c3;
-	m[8] = r3c3;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3::Matrix3x3(const float v[9])
-{
-	m[0] = v[0];
-	m[1] = v[1];
-	m[2] = v[2];
-	m[3] = v[3];
-	m[4] = v[4];
-	m[5] = v[5];
-	m[6] = v[6];
-	m[7] = v[7];
-	m[8] = v[8];
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3::Matrix3x3(const Matrix3x3& a)
-{
-	m[0] = a.m[0];
-	m[1] = a.m[1];
-	m[2] = a.m[2];
-	m[3] = a.m[3];
-	m[4] = a.m[4];
-	m[5] = a.m[5];
-	m[6] = a.m[6];
-	m[7] = a.m[7];
-	m[8] = a.m[8];
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator=(const Matrix3x3& a)
-{
-	m[0] = a.m[0];
-	m[1] = a.m[1];
-	m[2] = a.m[2];
-	m[3] = a.m[3];
-	m[4] = a.m[4];
-	m[5] = a.m[5];
-	m[6] = a.m[6];
-	m[7] = a.m[7];
-	m[8] = a.m[8];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-float Matrix3x3::operator[](uint32_t i) const
-{
-	CE_ASSERT(i < 9, "Index must be < 9");
-
-	return m[i];
-}
-
-//-----------------------------------------------------------------------------
-float& Matrix3x3::operator[](uint32_t i)
-{
-	CE_ASSERT(i < 9, "Index must be < 9");
-
-	return m[i];
-}
-
-//-----------------------------------------------------------------------------
-float Matrix3x3::operator()(uint32_t row, uint32_t column) const
-{
-	CE_ASSERT(row < 3 && column < 3, "Row and column must be < 3");
-
-	return m[row + column * 3];
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::operator+(const Matrix3x3& a) const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0] + a.m[0];
-	tmp.m[1] = m[1] + a.m[1];
-	tmp.m[2] = m[2] + a.m[2];
-	tmp.m[3] = m[3] + a.m[3];
-	tmp.m[4] = m[4] + a.m[4];
-	tmp.m[5] = m[5] + a.m[5];
-	tmp.m[6] = m[6] + a.m[6];
-	tmp.m[7] = m[7] + a.m[7];
-	tmp.m[8] = m[8] + a.m[8];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator+=(const Matrix3x3& a)
-{
-	m[0] = m[0] + a.m[0];
-	m[1] = m[1] + a.m[1];
-	m[2] = m[2] + a.m[2];
-	m[3] = m[3] + a.m[3];
-	m[4] = m[4] + a.m[4];
-	m[5] = m[5] + a.m[5];
-	m[6] = m[6] + a.m[6];
-	m[7] = m[7] + a.m[7];
-	m[8] = m[8] + a.m[8];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::operator-(const Matrix3x3& a) const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0] - a.m[0];
-	tmp.m[1] = m[1] - a.m[1];
-	tmp.m[2] = m[2] - a.m[2];
-	tmp.m[3] = m[3] - a.m[3];
-	tmp.m[4] = m[4] - a.m[4];
-	tmp.m[5] = m[5] - a.m[5];
-	tmp.m[6] = m[6] - a.m[6];
-	tmp.m[7] = m[7] - a.m[7];
-	tmp.m[8] = m[8] - a.m[8];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& a)
-{
-	m[0] = m[0] - a.m[0];
-	m[1] = m[1] - a.m[1];
-	m[2] = m[2] - a.m[2];
-	m[3] = m[3] - a.m[3];
-	m[4] = m[4] - a.m[4];
-	m[5] = m[5] - a.m[5];
-	m[6] = m[6] - a.m[6];
-	m[7] = m[7] - a.m[7];
-	m[8] = m[8] - a.m[8];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::operator*(float k) const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0] * k;
-	tmp.m[1] = m[1] * k;
-	tmp.m[2] = m[2] * k;
-	tmp.m[3] = m[3] * k;
-	tmp.m[4] = m[4] * k;
-	tmp.m[5] = m[5] * k;
-	tmp.m[6] = m[6] * k;
-	tmp.m[7] = m[7] * k;
-	tmp.m[8] = m[8] * k;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator*=(float k)
-{
-	m[0] *= k;
-	m[1] *= k;
-	m[2] *= k;
-	m[3] *= k;
-	m[4] *= k;
-	m[5] *= k;
-	m[6] *= k;
-	m[7] *= k;
-	m[8] *= k;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::operator/(float k) const
-{
-	Matrix3x3 tmp;
-
-	k = (float)1.0 / k;
-
-	tmp.m[0] = m[0] * k;
-	tmp.m[1] = m[1] * k;
-	tmp.m[2] = m[2] * k;
-	tmp.m[3] = m[3] * k;
-	tmp.m[4] = m[4] * k;
-	tmp.m[5] = m[5] * k;
-	tmp.m[6] = m[6] * k;
-	tmp.m[7] = m[7] * k;
-	tmp.m[8] = m[8] * k;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator/=(float k)
-{
-	k = (float)1.0 / k;
-
-	m[0] *= k;
-	m[1] *= k;
-	m[2] *= k;
-	m[3] *= k;
-	m[4] *= k;
-	m[5] *= k;
-	m[6] *= k;
-	m[7] *= k;
-	m[8] *= k;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix3x3::operator*(const Vector3& v) const
-{
-	Vector3 tmp;
-
-	tmp.x = m[0] * v.x + m[3] * v.y + m[6] * v.z;
-	tmp.y = m[1] * v.x + m[4] * v.y + m[7] * v.z;
-	tmp.z = m[2] * v.x + m[5] * v.y + m[8] * v.z;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::operator*(const Matrix3x3& a) const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0] * a.m[0] + m[3] * a.m[1] + m[6] * a.m[2];
-	tmp.m[1] = m[1] * a.m[0] + m[4] * a.m[1] + m[7] * a.m[2];
-	tmp.m[2] = m[2] * a.m[0] + m[5] * a.m[1] + m[8] * a.m[2];
-
-	tmp.m[3] = m[0] * a.m[3] + m[3] * a.m[4] + m[6] * a.m[5];
-	tmp.m[4] = m[1] * a.m[3] + m[4] * a.m[4] + m[7] * a.m[5];
-	tmp.m[5] = m[2] * a.m[3] + m[5] * a.m[4] + m[8] * a.m[5];
-
-	tmp.m[6] = m[0] * a.m[6] + m[3] * a.m[7] + m[6] * a.m[8];
-	tmp.m[7] = m[1] * a.m[6] + m[4] * a.m[7] + m[7] * a.m[8];
-	tmp.m[8] = m[2] * a.m[6] + m[5] * a.m[7] + m[8] * a.m[8];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& a)
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0] * a.m[0] + m[3] * a.m[1] + m[6] * a.m[2];
-	tmp.m[1] = m[1] * a.m[0] + m[4] * a.m[1] + m[7] * a.m[2];
-	tmp.m[2] = m[2] * a.m[0] + m[5] * a.m[1] + m[8] * a.m[2];
-
-	tmp.m[3] = m[0] * a.m[3] + m[3] * a.m[4] + m[6] * a.m[5];
-	tmp.m[4] = m[1] * a.m[3] + m[4] * a.m[4] + m[7] * a.m[5];
-	tmp.m[5] = m[2] * a.m[3] + m[5] * a.m[4] + m[8] * a.m[5];
-
-	tmp.m[6] = m[0] * a.m[6] + m[3] * a.m[7] + m[6] * a.m[8];
-	tmp.m[7] = m[1] * a.m[6] + m[4] * a.m[7] + m[7] * a.m[8];
-	tmp.m[8] = m[2] * a.m[6] + m[5] * a.m[7] + m[8] * a.m[8];
-
-	*this = tmp;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 operator*(float k, const Matrix3x3& a)
-{
-	return a * k;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::build_rotation_x(float radians)
-{
-	m[0] = 1.0;
-	m[1] = 0.0;
-	m[2] = 0.0;
-	m[3] = 0.0;
-	m[4] = math::cos(radians);
-	m[5] = math::sin(radians);
-	m[6] = 0.0;
-	m[7] = -math::sin(radians);
-	m[8] = math::cos(radians);
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::build_rotation_y(float radians)
-{
-	m[0] = math::cos(radians);
-	m[1] = 0.0;
-	m[2] = -math::sin(radians);
-	m[3] = 0.0;
-	m[4] = 1.0;
-	m[5] = 0.0;
-	m[6] = math::sin(radians);
-	m[7] = 0.0;
-	m[8] = math::cos(radians);
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::build_rotation_z(float radians)
-{
-	m[0] = math::cos(radians);
-	m[1] = math::sin(radians);
-	m[2] = 0.0;
-	m[3] = -math::sin(radians);
-	m[4] = math::cos(radians);
-	m[5] = 0.0;
-	m[6] = 0.0;
-	m[7] = 0.0;
-	m[8] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::build_rotation(const Vector3& n, float radians)
-{
-	float a = (float)1.0 - math::cos(radians);
-	float sin_a = math::sin(radians);
-	float cos_a = math::cos(radians);
-
-	m[0] = n.x * n.x * a + cos_a;
-	m[1] = n.x * n.y * a + n.z * sin_a;
-	m[2] = n.x * n.z * a - n.y * sin_a;
-	m[3] = n.x * n.y * a - n.z * sin_a;
-	m[4] = n.y * n.y * a + cos_a;
-	m[5] = n.y * n.z * a + n.x * sin_a;
-	m[6] = n.x * n.z * a + n.y * sin_a;
-	m[7] = n.y * n.z * a - n.x * sin_a;
-	m[8] = n.z * n.z * a + cos_a;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::transpose()
-{
-	float tmp;
-
-	tmp = m[1];
-	m[1] = m[3];
-	m[3] = tmp;
-
-	tmp = m[2];
-	m[2] = m[6];
-	m[6] = tmp;
-
-	tmp = m[5];
-	m[5] = m[7];
-	m[7] = tmp;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix3x3::get_transposed() const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0];
-	tmp.m[1] = m[3];
-	tmp.m[2] = m[6];
-	tmp.m[3] = m[1];
-	tmp.m[4] = m[4];
-	tmp.m[5] = m[7];
-	tmp.m[6] = m[2];
-	tmp.m[7] = m[5];
-	tmp.m[8] = m[8];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-float Matrix3x3::get_determinant() const
-{
-	float det;
-
-	det =	m[0] * (m[4] * m[8] - m[7] * m[5]) -
-			m[3] * (m[1] * m[8] - m[7] * m[2]) +
-			m[6] * (m[1] * m[5] - m[4] * m[2]);
-
-	return det;
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3& Matrix3x3::invert()
-{
-	Matrix3x3 mat;
-	float det;
-
-	mat.m[0] = (m[4] * m[8] - m[7] * m[5]);
-	mat.m[1] = (m[1] * m[8] - m[7] * m[2]);
-	mat.m[2] = (m[1] * m[5] - m[4] * m[2]);
-
-	det = m[0] * mat.m[0] - m[3] * mat.m[1] + m[6] * mat.m[2];
-	det = (float)1.0 / det;
-
-	mat.m[3] = (m[3] * m[8] - m[6] * m[5]);
-	mat.m[4] = (m[0] * m[8] - m[6] * m[2]);
-	mat.m[5] = (m[0] * m[5] - m[3] * m[2]);
-	mat.m[6] = (m[3] * m[7] - m[6] * m[4]);
-	mat.m[7] = (m[0] * m[7] - m[6] * m[1]);
-	mat.m[8] = (m[0] * m[4] - m[3] * m[1]);
-
-	m[0] = + mat.m[0] * det;
-	m[1] = - mat.m[1] * det;
-	m[2] = + mat.m[2] * det;
-	m[3] = - mat.m[3] * det;
-	m[4] = + mat.m[4] * det;
-	m[5] = - mat.m[5] * det;
-	m[6] = + mat.m[6] * det;
-	m[7] = - mat.m[7] * det;
-	m[8] = + mat.m[8] * det;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-inline Matrix3x3 Matrix3x3::get_inverted() const
-{
-	Matrix3x3 tmp(*this);
-
-	return tmp.invert();
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::load_identity()
-{
-	m[0] = m[4] = m[8] = 1.0;
-	m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix3x3::x() const
-{
-	return Vector3(m[0], m[1], m[2]);
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix3x3::y() const
-{
-	return Vector3(m[3], m[4], m[5]);
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix3x3::z() const
-{
-	return Vector3(m[6], m[7], m[8]);
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::set_x(const Vector3& x)
-{
-	m[0] = x.x;
-	m[1] = x.y;
-	m[2] = x.z;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::set_y(const Vector3& y)
-{
-	m[3] = y.x;
-	m[4] = y.y;
-	m[5] = y.z;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::set_z(const Vector3& z)
-{
-	m[6] = z.x;
-	m[7] = z.y;
-	m[8] = z.z;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix3x3::get_scale() const
-{
-	Vector3 tmp;
-
-	tmp.x = m[0];
-	tmp.y = m[4];
-	tmp.z = m[8];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix3x3::set_scale(const Vector3& scale)
-{
-	m[0] = scale.x;
-	m[4] = scale.y;
-	m[8] = scale.z;
-}
-
-//-----------------------------------------------------------------------------
-float* Matrix3x3::to_float_ptr()
-{
-	return &m[0];
-}
-
-//-----------------------------------------------------------------------------
-const float* Matrix3x3::to_float_ptr() const
-{
-	return &m[0];
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix3x3::to_matrix4x4() const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0];
-	tmp.m[1] = m[1];
-	tmp.m[2] = m[2];
-	tmp.m[3] = 0.0;
-	tmp.m[4] = m[3];
-	tmp.m[5] = m[4];
-	tmp.m[6] = m[5];
-	tmp.m[7] = 0.0;
-	tmp.m[8] = m[6];
-	tmp.m[9] = m[7];
-	tmp.m[10] = m[8];
-	tmp.m[11] = 0.0;
-	tmp.m[12] = 0.0;
-	tmp.m[13] = 0.0;
-	tmp.m[14] = 0.0;
-	tmp.m[15] = 1.0;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Matrix3x3::to_quaternion() const
-{
-	Quaternion tmp;
-
-	float fourWSquaredMinusOne = m[0] + m[4] + m[8];
-	float fourXSquaredMinusOne = m[0] - m[4] - m[8];
-	float fourYSquaredMinusOne = -m[0] + m[4] - m[8];
-	float fourZSquaredMinusOne = -m[0] - m[4] + m[8];
-	float fourMaxSquaredMinusOne = fourWSquaredMinusOne;
-	uint32_t index = 0;
-
-	if (fourXSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourXSquaredMinusOne;
-		index = 1;
-	}
-
-	if (fourYSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourYSquaredMinusOne;
-		index = 2;
-	}
-
-	if (fourZSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourZSquaredMinusOne;
-		index = 3;
-	}
-
-	float biggest = math::sqrt(fourMaxSquaredMinusOne + (float)1.0) * (float)0.5;
-	float mult = (float)0.25 / biggest;
-
-	switch (index)
-	{
-		case 0:
-			tmp.w = biggest;
-			tmp.x = (-m[7] + m[5]) * mult;
-			tmp.y = (-m[2] + m[6]) * mult;
-			tmp.z = (-m[3] + m[1]) * mult;
-			break;
-		case 1:
-			tmp.x = biggest;
-			tmp.w = (-m[7] + m[5]) * mult;
-			tmp.y = (-m[3] - m[1]) * mult;
-			tmp.z = (-m[2] - m[6]) * mult;
-			break;
-		case 2:
-			tmp.y = biggest;
-			tmp.w = (-m[2] + m[6]) * mult;
-			tmp.x = (-m[3] - m[1]) * mult;
-			tmp.z = (-m[7] - m[5]) * mult;
-			break;
-		case 3:
-			tmp.z = biggest;
-			tmp.w = (-m[3] + m[1]) * mult;
-			tmp.x = (-m[2] - m[6]) * mult;
-			tmp.y = (-m[7] - m[5]) * mult;
-			break;
-	}
-
-	return tmp;
-}
-
-} // namespace crown
-

+ 367 - 103
engine/core/math/Matrix3x3.h

@@ -26,138 +26,402 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include "Types.h"
+#include "MathTypes.h"
+#include "Vector3.h"
+#include "Assert.h"
 
 namespace crown
 {
 
-struct Matrix4x4;
-struct Quaternion;
-struct Vector3;
-
-/// Column major 3x3 matrix.
-/// 
-/// The engine uses column vectors for coordinate space transformations
-/// so you'll have to specify transformations in reverse order.
-/// e.g. (rotation translation vector) will produce the result of first translating
-/// and then rotating the vector.
-/// Also note that a column major matrix needs to be placed to the left of a
-/// vector by matrix multiplication, so, to multiply a vector by a matrix you'll have
-/// to write something like: matrix vector. Since we are also using column vectors, inverting
-/// the operands would result in an impossible operation.
-/// 
-/// @a verbatim:
-///   X base vector
-///     | Y base vector
-///     |   | Z base vector
-///     |   |   |
-/// 1 [ Xx  Yx  Zx ]
-/// 2 | Xy  Yy  Zy |
-/// 3 [ Xz  Yz  Zz ]
-///     1   2   3
-struct Matrix3x3
-{
-
-public:
-
-	float				m[9];
-
-	/// Does nothing for efficiency.
-						Matrix3x3();			
-
-	/// Constructs from a set of float
-						Matrix3x3(float r1c1, float r2c1, float r3c1, float r1c2, float r2c2, float r3c2, float r1c3, float r2c3, float r3c3);
+/// Adds the matrix @a a to @a b and returns the result.
+Matrix3x3 operator+(Matrix3x3 a, const Matrix3x3& b);
+
+/// Subtracts the matrix @a b from @a a and returns the result.
+Matrix3x3 operator-(Matrix3x3 a, const Matrix3x3& b);
+
+/// Multiplies the matrix @a a by the scalar @a k and returns the result.
+Matrix3x3 operator*(Matrix3x3 a, float k);
+
+/// @copydoc operator*(Matrix3x3, float)
+Matrix3x3 operator*(float k, Matrix3x3 a);
+
+/// Divides the matrix @a a by the scalar @a k.
+Matrix3x3 operator/(Matrix3x3 a, float k);
+
+/// Multiplies the matrix @a a by the vector @a v and returns the result.
+Vector3 operator*(const Matrix3x3& a, const Vector3& v);
+
+/// Multiplies the matrix @a a by @a b and returns the result. (i.e. transforms first by @a b then by @a a)
+Matrix3x3 operator*(Matrix3x3 a, const Matrix3x3& b);
+
+/// Functions to manipulate Matrix3x3
+///
+/// @ingroup Math
+namespace matrix3x3
+{
+	const Matrix3x3 IDENTITY = Matrix3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
 	
-	/// Constructs from the @a v array
-						Matrix3x3(const float v[9]);						
-						Matrix3x3(const Matrix3x3& a);	
+	/// Transposes the matrix @a m and returns the result.
+	Matrix3x3& transpose(Matrix3x3& m);
 
-	/// Assignment operator (copies the data)
-	Matrix3x3&			operator=(const Matrix3x3& a);					
+	/// Returns the transposed of the matrix @a m.
+	Matrix3x3 get_transposed(Matrix3x3 m);
 
-	/// Random access by index
-	float				operator[](uint32_t i) const;		
+	/// Returns the determinant of the matrix @a m.
+	float determinant(const Matrix3x3& m);
 
-	/// Random access by index			
-	float&				operator[](uint32_t i);							
+	/// Inverts the matrix @a m and returns the result.
+	Matrix3x3& invert(Matrix3x3& m);
 
-	/// Random access by row/column pair
-	float				operator()(uint32_t row, uint32_t column) const;	
+	/// Returns the inverse of the matrix @a m.
+	Matrix3x3 get_inverted(Matrix3x3 m);
 
-	Matrix3x3			operator+(const Matrix3x3& a) const;				
-	Matrix3x3&			operator+=(const Matrix3x3& a);					
-	Matrix3x3			operator-(const Matrix3x3& a) const;				
-	Matrix3x3&			operator-=(const Matrix3x3& a);					
-	Matrix3x3			operator*(float k) const;					
-	Matrix3x3&			operator*=(float k);						
-	Matrix3x3			operator/(float k) const;					
-	Matrix3x3&			operator/=(float k);							
-	Vector3				operator*(const Vector3& v) const;			
-	Matrix3x3			operator*(const Matrix3x3& a) const;				
-	Matrix3x3&			operator*=(const Matrix3x3& a);			
+	/// Sets the matrix @a m to identity.
+	void set_identity(Matrix3x3& m);							
 
-	/// For simmetry
-	friend Matrix3x3		operator*(float k, const Matrix3x3& a);			
+	/// Returns the pointer to the matrix's data
+	float* to_float_ptr(Matrix3x3& m);
 
-	/// Builds a rotation matrix about the X axis of @a radians radians
-	void				build_rotation_x(float radians);			
+	/// Returns the pointer to the matrix's data				
+	const float* to_float_ptr(const Matrix3x3& m);
 
-	/// Builds a rotation matrix about the Y axis of @a radians radians	
-	void				build_rotation_y(float radians);	
+	/// Returns a 4x4 matrix according to the matrix's rotation portion						
+	Matrix4x4 to_matrix4x4(const Matrix3x3& m);
 
-	/// Builds a rotation matrix about the Z axis of @a radians radians			
-	void				build_rotation_z(float radians);	
+	/// Returns a quaternion according to the matrix's rotation portion							
+	Quaternion to_quaternion(const Matrix3x3& m);
+} // namespace matrix3x3
 
-	/// Builds a rotation matrix about an arbitrary axis of "radians" radians			
-	void				build_rotation(const Vector3& n, float radians);
+inline Matrix3x3 operator+(Matrix3x3 a, const Matrix3x3& b)
+{
+	a += b;
+	return a;
+}
 
-	Matrix3x3&			transpose();								
-	Matrix3x3			get_transposed() const;						
-	float				get_determinant() const;					
-	Matrix3x3&			invert();									
-	Matrix3x3			get_inverted() const;						
+inline Matrix3x3 operator-(Matrix3x3 a, const Matrix3x3& b)
+{
+	a -= b;
+	return a;
+}
 
-	/// Builds the identity matrix
-	void				load_identity();							
+inline Matrix3x3 operator*(Matrix3x3 a, float k)
+{
+	a *= k;
+	return a;
+}
 
-	/// Returns a Vector3 containing the matrix's x base vector.
-	Vector3				x() const;
+inline Matrix3x3 operator*(float k, Matrix3x3 a)
+{
+	a *= k;
+	return a;
+}
 
-	/// Returns a Vector3 containing the matrix's y base vector.
-	Vector3				y() const;
+inline Matrix3x3 operator/(Matrix3x3 a, float k)
+{
+	a /= k;
+	return a;
+}
 
-	/// Returns a Vector3 containing the matrix's z base vector.
-	Vector3				z() const;
+inline Vector3 operator*(const Matrix3x3& a, const Vector3& v)
+{
+	Vector3 tmp;
 
-	/// Sets the matrix's x base vector.
-	void				set_x(const Vector3& x);
+	tmp.x = a.x.x * v.x + a.y.x * v.y + a.z.x * v.z;
+	tmp.y = a.x.y * v.x + a.y.y * v.y + a.z.y * v.z;
+	tmp.z = a.x.z * v.x + a.y.z * v.y + a.z.z * v.z;
 
-	/// Sets the matrix's y base vector.
-	void				set_y(const Vector3& y);
+	return tmp;
+}
 
-	/// Sets the matrix's z base vector.
-	void				set_z(const Vector3& z);
+inline Matrix3x3 operator*(Matrix3x3 a, const Matrix3x3& b)
+{
+	a *= b;
+	return a;
+}
 
-	/// Returns a Vector3 containing the matrix's scale portion
-	Vector3				get_scale() const;	
+namespace matrix3x3
+{
+	//-----------------------------------------------------------------------------
+	inline Matrix3x3& transpose(Matrix3x3& m)
+	{
+		float tmp;
+
+		tmp = m.x.y;
+		m.x.y = m.y.x;
+		m.y.x = tmp;
+
+		tmp = m.x.z;
+		m.x.z = m.z.x;
+		m.z.x = tmp;
+
+		tmp = m.y.z;
+		m.y.z = m.z.y;
+		m.z.y = tmp;
+
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix3x3 get_transposed(Matrix3x3 m)
+	{
+		transpose(m);
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline float determinant(const Matrix3x3& m)
+	{
+		return	m.x.x * (m.y.y * m.z.z - m.z.y * m.y.z) -
+				m.y.x * (m.x.y * m.z.z - m.z.y * m.x.z) +
+				m.z.x * (m.x.y * m.y.z - m.y.y * m.x.z);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix3x3& invert(Matrix3x3& m)
+	{
+		Matrix3x3 mat;
+
+		mat.x.x = (m.y.y * m.z.z - m.z.y * m.y.z);
+		mat.x.y = (m.x.y * m.z.z - m.z.y * m.x.z);
+		mat.x.z = (m.x.y * m.y.z - m.y.y * m.x.z);
+
+		const float inv_det = 1.0 / (m.x.x * mat.x.x - m.y.x * mat.x.y + m.z.x * mat.x.z);
+
+		mat.y.x = (m.y.x * m.z.z - m.z.x * m.y.z);
+		mat.y.y = (m.x.x * m.z.z - m.z.x * m.x.z);
+		mat.y.z = (m.x.x * m.y.z - m.y.x * m.x.z);
+		mat.z.x = (m.y.x * m.z.y - m.z.x * m.y.y);
+		mat.z.y = (m.x.x * m.z.y - m.z.x * m.x.y);
+		mat.z.z = (m.x.x * m.y.y - m.y.x * m.x.y);
+
+		m.x.x = + mat.x.x * inv_det;
+		m.x.y = - mat.x.y * inv_det;
+		m.x.z = + mat.x.z * inv_det;
+		m.y.x = - mat.y.x * inv_det;
+		m.y.y = + mat.y.y * inv_det;
+		m.y.z = - mat.y.z * inv_det;
+		m.z.x = + mat.z.x * inv_det;
+		m.z.y = - mat.z.y * inv_det;
+		m.z.z = + mat.z.z * inv_det;
+
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix3x3 get_inverted(Matrix3x3 m)
+	{
+		invert(m);
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_identity(Matrix3x3& m)
+	{
+		m.x = Vector3(1, 0, 0);
+		m.y = Vector3(0, 1, 0);
+		m.z = Vector3(0, 0, 1);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix4x4 to_matrix4x4(const Matrix3x3& m)
+	{
+		return Matrix4x4(m);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Quaternion to_quaternion(const Matrix3x3& m)
+	{
+		const float fourWSquaredMinusOne = m.x.x + m.y.y + m.z.z;
+		const float fourXSquaredMinusOne = m.x.x - m.y.y - m.z.z;
+		const float fourYSquaredMinusOne = -m.x.x + m.y.y - m.z.z;
+		const float fourZSquaredMinusOne = -m.x.x - m.y.y + m.z.z;
+		float fourMaxSquaredMinusOne = fourWSquaredMinusOne;
+		uint32_t index = 0;
+
+		if (fourXSquaredMinusOne > fourMaxSquaredMinusOne)
+		{
+			fourMaxSquaredMinusOne = fourXSquaredMinusOne;
+			index = 1;
+		}
+
+		if (fourYSquaredMinusOne > fourMaxSquaredMinusOne)
+		{
+			fourMaxSquaredMinusOne = fourYSquaredMinusOne;
+			index = 2;
+		}
+
+		if (fourZSquaredMinusOne > fourMaxSquaredMinusOne)
+		{
+			fourMaxSquaredMinusOne = fourZSquaredMinusOne;
+			index = 3;
+		}
+
+		const float biggest = math::sqrt(fourMaxSquaredMinusOne + (float)1.0) * (float)0.5;
+		const float mult = (float)0.25 / biggest;
+
+		Quaternion tmp;
+		switch (index)
+		{
+			case 0:
+			{
+				tmp.w = biggest;
+				tmp.x = (-m.z.y + m.y.z) * mult;
+				tmp.y = (-m.x.z + m.z.x) * mult;
+				tmp.z = (-m.y.x + m.x.y) * mult;
+				break;
+			}
+			case 1:
+			{
+				tmp.x = biggest;
+				tmp.w = (-m.z.y + m.y.z) * mult;
+				tmp.y = (-m.y.x - m.x.y) * mult;
+				tmp.z = (-m.x.z - m.z.x) * mult;
+				break;
+			}
+			case 2:
+			{
+				tmp.y = biggest;
+				tmp.w = (-m.x.z + m.z.x) * mult;
+				tmp.x = (-m.y.x - m.x.y) * mult;
+				tmp.z = (-m.z.y - m.y.z) * mult;
+				break;
+			}
+			case 3:
+			{
+				tmp.z = biggest;
+				tmp.w = (-m.y.x + m.x.y) * mult;
+				tmp.x = (-m.x.z - m.z.x) * mult;
+				tmp.y = (-m.z.y - m.y.z) * mult;
+				break;
+			}
+			default:
+			{
+				CE_FATAL("You should not be here");
+				break;
+			}
+		}
+
+		return tmp;
+	}
+} // namespace matrix3x3
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3::Matrix3x3()
+{
+	// Do not initialize
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3::Matrix3x3(const Vector3& x, const Vector3& y, const Vector3& z)
+	: x(x)
+	, y(y)
+	, z(z)
+{
+}
 
-	/// Fills the matrix's scale portion with the values contained in @a scale				
-	void				set_scale(const Vector3& scale);				
+//-----------------------------------------------------------------------------
+inline Matrix3x3::Matrix3x3(const Quaternion& r)
+	: x(1.0 - 2.0 * r.y * r.y - 2.0 * r.z * r.z, 2.0 * r.x * r.y + 2.0 * r.w * r.z, 2.0 * r.x * r.z - 2.0 * r.w * r.y)
+	, y(2.0 * r.x * r.y - 2.0 * r.w * r.z, 1.0 - 2.0 * r.x * r.x - 2.0 * r.z * r.z, 2.0 * r.y * r.z + 2.0 * r.w * r.x)
+	, z(2.0 * r.x * r.z + 2.0 * r.w * r.y, 2.0 * r.y * r.z - 2.0 * r.w * r.x, 1.0 - 2.0 * r.x * r.x - 2.0 * r.y * r.y)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3::Matrix3x3(float r1c1, float r2c1, float r3c1, float r1c2, float r2c2, float r3c2,
+						float r1c3, float r2c3, float r3c3)
+	: x(r1c1, r2c1, r3c1)
+	, y(r1c2, r2c2, r3c2)
+	, z(r1c3, r2c3, r3c3)
+{
+}
 
-	/// Returns the pointer to the matrix's data
-	float*				to_float_ptr();				
+//-----------------------------------------------------------------------------
+inline Matrix3x3::Matrix3x3(const float v[9])
+	: x(v[0], v[1], v[2])
+	, y(v[3], v[4], v[5])
+	, z(v[6], v[7], v[8])
+{
+}
 
-	/// Returns the pointer to the matrix's data				
-	const float*		to_float_ptr() const;
+//-----------------------------------------------------------------------------
+inline float& Matrix3x3::operator[](uint32_t i)
+{
+	CE_ASSERT(i < 9, "Index out of bounds");
 
-	/// Returns a 4x4 matrix according to the matrix's rotation portion						
-	Matrix4x4			to_matrix4x4() const;
+	return vector3::to_float_ptr(x)[i];
+}
 
-	/// Returns a quaternion according to the matrix's rotation portion							
-	Quaternion			to_quaternion() const;							
+//-----------------------------------------------------------------------------
+inline const float& Matrix3x3::operator[](uint32_t i) const
+{
+	CE_ASSERT(i < 9, "Index out of bounds");
 
-	static const Matrix3x3	IDENTITY;
-};
+	return vector3::to_float_ptr(x)[i];
+}
 
-} // namespace crown
+//-----------------------------------------------------------------------------
+inline Matrix3x3& Matrix3x3::operator+=(const Matrix3x3& a)
+{
+	x += a.x;
+	y += a.y;
+	z += a.z;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& a)
+{
+	x -= a.x;
+	y -= a.y;
+	z -= a.z;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3& Matrix3x3::operator*=(float k)
+{
+	x *= k;
+	y *= k;
+	z *= k;
 
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3& Matrix3x3::operator/=(float k)
+{
+	const float inv_k = 1.0 / k;
+
+	x *= inv_k;
+	y *= inv_k;
+	z *= inv_k;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& a)
+{
+	Matrix3x3 tmp;
+
+	tmp.x.x = x.x * a.x.x + y.x * a.x.y + z.x * a.x.z;
+	tmp.x.y = x.y * a.x.x + y.y * a.x.y + z.y * a.x.z;
+	tmp.x.z = x.z * a.x.x + y.z * a.x.y + z.z * a.x.z;
+
+	tmp.y.x = x.x * a.y.x + y.x * a.y.y + z.x * a.y.z;
+	tmp.y.y = x.y * a.y.x + y.y * a.y.y + z.y * a.y.z;
+	tmp.y.z = x.z * a.y.x + y.z * a.y.y + z.z * a.y.z;
+
+	tmp.z.x = x.x * a.z.x + y.x * a.z.y + z.x * a.z.z;
+	tmp.z.y = x.y * a.z.x + y.y * a.z.y + z.y * a.z.z;
+	tmp.z.z = x.z * a.z.x + y.z * a.z.y + z.z * a.z.z;
+
+	*this = tmp;
+
+	return *this;
+}
+
+} // namespace crown

+ 0 - 1043
engine/core/math/Matrix4x4.cpp

@@ -1,1043 +0,0 @@
-/*
-Copyright (c) 2013 Daniele Bartolini, Michele Rossi
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "Assert.h"
-#include "Matrix3x3.h"
-#include "Types.h"
-#include "Matrix4x4.h"
-#include "MathUtils.h"
-#include "Quaternion.h"
-#include "Vector3.h"
-#include "Vector4.h"
-
-namespace crown
-{
-
-const Matrix4x4 Matrix4x4::IDENTITY = Matrix4x4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
-
-//-----------------------------------------------------------------------------
-Matrix4x4::Matrix4x4()
-{
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4::Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
-						float r1c2, float r2c2, float r3c2, float r4c2,
-						float r1c3, float r2c3, float r3c3, float r4c3,
-						float r1c4, float r2c4, float r3c4, float r4c4)
-{
-	m[0] = r1c1;
-	m[1] = r2c1;
-	m[2] = r3c1;
-	m[3] = r4c1;
-	m[4] = r1c2;
-	m[5] = r2c2;
-	m[6] = r3c2;
-	m[7] = r4c2;
-	m[8] = r1c3;
-	m[9] = r2c3;
-	m[10] = r3c3;
-	m[11] = r4c3;
-	m[12] = r1c4;
-	m[13] = r2c4;
-	m[14] = r3c4;
-	m[15] = r4c4;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4::Matrix4x4(const Quaternion& r, const Vector3& p)
-{
-	const float rx = r.x;
-	const float ry = r.y;
-	const float rz = r.z;
-	const float rw = r.w;
-
-	m[0] = 1.0 - 2.0 * ry * ry - 2.0 * rz * rz;
-	m[1] = 2.0 * rx * ry + 2.0 * rw * rz;
-	m[2] = 2.0 * rx * rz - 2.0 * rw * ry;
-	m[3] = 0;
-	m[4] = 2.0 * rx * ry - 2.0 * rw * rz;
-	m[5] = 1.0 - 2.0 * rx * rx - 2.0 * rz * rz;
-	m[6] = 2.0 * ry * rz + 2.0 * rw * rx;
-	m[7] = 0.0;
-	m[8] = 2.0 * rx * rz + 2.0 * rw * ry;
-	m[9] = 2.0 * ry * rz - 2.0 * rw * rx;
-	m[10] = 1.0 - 2.0 * rx * rx - 2.0 * ry * ry;
-	m[11] = 0.0;
-	m[12] = p.x;
-	m[13] = p.y;
-	m[14] = p.z;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4::Matrix4x4(const float v[16])
-{
-	m[0] = v[0];
-	m[1] = v[1];
-	m[2] = v[2];
-	m[3] = v[3];
-	m[4] = v[4];
-	m[5] = v[5];
-	m[6] = v[6];
-	m[7] = v[7];
-	m[8] = v[8];
-	m[9] = v[9];
-	m[10] = v[10];
-	m[11] = v[11];
-	m[12] = v[12];
-	m[13] = v[13];
-	m[14] = v[14];
-	m[15] = v[15];
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4::Matrix4x4(const Matrix4x4& a)
-{
-	m[0] = a.m[0];
-	m[1] = a.m[1];
-	m[2] = a.m[2];
-	m[3] = a.m[3];
-	m[4] = a.m[4];
-	m[5] = a.m[5];
-	m[6] = a.m[6];
-	m[7] = a.m[7];
-	m[8] = a.m[8];
-	m[9] = a.m[9];
-	m[10] = a.m[10];
-	m[11] = a.m[11];
-	m[12] = a.m[12];
-	m[13] = a.m[13];
-	m[14] = a.m[14];
-	m[15] = a.m[15];
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator=(const Matrix4x4& a)
-{
-	m[0] = a.m[0];
-	m[1] = a.m[1];
-	m[2] = a.m[2];
-	m[3] = a.m[3];
-	m[4] = a.m[4];
-	m[5] = a.m[5];
-	m[6] = a.m[6];
-	m[7] = a.m[7];
-	m[8] = a.m[8];
-	m[9] = a.m[9];
-	m[10] = a.m[10];
-	m[11] = a.m[11];
-	m[12] = a.m[12];
-	m[13] = a.m[13];
-	m[14] = a.m[14];
-	m[15] = a.m[15];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-float Matrix4x4::operator[](uint32_t i) const
-{
-	CE_ASSERT(i < 16, "Index must be < 16");
-
-	return m[i];
-}
-
-//-----------------------------------------------------------------------------
-float& Matrix4x4::operator[](uint32_t i)
-{
-	CE_ASSERT(i < 16, "Index must be < 16");
-
-	return m[i];
-}
-
-//-----------------------------------------------------------------------------
-float Matrix4x4::operator()(uint32_t row, uint32_t column) const
-{
-	CE_ASSERT(row < 4 && column < 4, "Row and column must be < 4");
-
-	return m[row + column * 4];
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::operator+(const Matrix4x4& a) const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0] + a.m[0];
-	tmp.m[1] = m[1] + a.m[1];
-	tmp.m[2] = m[2] + a.m[2];
-	tmp.m[3] = m[3] + a.m[3];
-	tmp.m[4] = m[4] + a.m[4];
-	tmp.m[5] = m[5] + a.m[5];
-	tmp.m[6] = m[6] + a.m[6];
-	tmp.m[7] = m[7] + a.m[7];
-	tmp.m[8] = m[8] + a.m[8];
-	tmp.m[9] = m[9] + a.m[9];
-	tmp.m[10] = m[10] + a.m[10];
-	tmp.m[11] = m[11] + a.m[11];
-	tmp.m[12] = m[12] + a.m[12];
-	tmp.m[13] = m[13] + a.m[13];
-	tmp.m[14] = m[14] + a.m[14];
-	tmp.m[14] = m[15] + a.m[15];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& a)
-{
-	m[0] = m[0] + a.m[0];
-	m[1] = m[1] + a.m[1];
-	m[2] = m[2] + a.m[2];
-	m[3] = m[3] + a.m[3];
-	m[4] = m[4] + a.m[4];
-	m[5] = m[5] + a.m[5];
-	m[6] = m[6] + a.m[6];
-	m[7] = m[7] + a.m[7];
-	m[8] = m[8] + a.m[8];
-	m[9] = m[9] + a.m[9];
-	m[10] = m[10] + a.m[10];
-	m[11] = m[11] + a.m[11];
-	m[12] = m[12] + a.m[12];
-	m[13] = m[13] + a.m[13];
-	m[14] = m[14] + a.m[14];
-	m[14] = m[15] + a.m[15];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::operator-(const Matrix4x4& a) const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0] - a.m[0];
-	tmp.m[1] = m[1] - a.m[1];
-	tmp.m[2] = m[2] - a.m[2];
-	tmp.m[3] = m[3] - a.m[3];
-	tmp.m[4] = m[4] - a.m[4];
-	tmp.m[5] = m[5] - a.m[5];
-	tmp.m[6] = m[6] - a.m[6];
-	tmp.m[7] = m[7] - a.m[7];
-	tmp.m[8] = m[8] - a.m[8];
-	tmp.m[9] = m[9] - a.m[9];
-	tmp.m[10] = m[10] - a.m[10];
-	tmp.m[11] = m[11] - a.m[11];
-	tmp.m[12] = m[12] - a.m[12];
-	tmp.m[13] = m[13] - a.m[13];
-	tmp.m[14] = m[14] - a.m[14];
-	tmp.m[14] = m[15] - a.m[15];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& a)
-{
-	m[0] = m[0] - a.m[0];
-	m[1] = m[1] - a.m[1];
-	m[2] = m[2] - a.m[2];
-	m[3] = m[3] - a.m[3];
-	m[4] = m[4] - a.m[4];
-	m[5] = m[5] - a.m[5];
-	m[6] = m[6] - a.m[6];
-	m[7] = m[7] - a.m[7];
-	m[8] = m[8] - a.m[8];
-	m[9] = m[9] - a.m[9];
-	m[10] = m[10] - a.m[10];
-	m[11] = m[11] - a.m[11];
-	m[12] = m[12] - a.m[12];
-	m[13] = m[13] - a.m[13];
-	m[14] = m[14] - a.m[14];
-	m[14] = m[15] - a.m[15];
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::operator*(float k) const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0] * k;
-	tmp.m[1] = m[1] * k;
-	tmp.m[2] = m[2] * k;
-	tmp.m[3] = m[3] * k;
-	tmp.m[4] = m[4] * k;
-	tmp.m[5] = m[5] * k;
-	tmp.m[6] = m[6] * k;
-	tmp.m[7] = m[7] * k;
-	tmp.m[8] = m[8] * k;
-	tmp.m[9] = m[9] * k;
-	tmp.m[10] = m[10] * k;
-	tmp.m[11] = m[11] * k;
-	tmp.m[12] = m[12] * k;
-	tmp.m[13] = m[13] * k;
-	tmp.m[14] = m[14] * k;
-	tmp.m[15] = m[15] * k;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator*=(float k)
-{
-	m[0] *= k;
-	m[1] *= k;
-	m[2] *= k;
-	m[3] *= k;
-	m[4] *= k;
-	m[5] *= k;
-	m[6] *= k;
-	m[7] *= k;
-	m[8] *= k;
-	m[9] *= k;
-	m[10] *= k;
-	m[11] *= k;
-	m[12] *= k;
-	m[13] *= k;
-	m[14] *= k;
-	m[15] *= k;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::operator/(float k) const
-{
-	Matrix4x4 tmp;
-
-	k = (float)1.0 / k;
-
-	tmp.m[0] = m[0] * k;
-	tmp.m[1] = m[1] * k;
-	tmp.m[2] = m[2] * k;
-	tmp.m[3] = m[3] * k;
-	tmp.m[4] = m[4] * k;
-	tmp.m[5] = m[5] * k;
-	tmp.m[6] = m[6] * k;
-	tmp.m[7] = m[7] * k;
-	tmp.m[8] = m[8] * k;
-	tmp.m[9] = m[9] * k;
-	tmp.m[10] = m[10] * k;
-	tmp.m[11] = m[11] * k;
-	tmp.m[12] = m[12] * k;
-	tmp.m[13] = m[13] * k;
-	tmp.m[14] = m[14] * k;
-	tmp.m[15] = m[15] * k;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator/=(float k)
-{
-	k = (float)1.0 / k;
-
-	m[0] *= k;
-	m[1] *= k;
-	m[2] *= k;
-	m[3] *= k;
-	m[4] *= k;
-	m[5] *= k;
-	m[6] *= k;
-	m[7] *= k;
-	m[8] *= k;
-	m[9] *= k;
-	m[10] *= k;
-	m[11] *= k;
-	m[12] *= k;
-	m[13] *= k;
-	m[14] *= k;
-	m[15] *= k;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::operator*(const Vector3& v) const
-{
-	Vector3 tmp;
-
-	tmp.x = m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12];
-	tmp.y = m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13];
-	tmp.z = m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Vector4 Matrix4x4::operator*(const Vector4& v) const
-{
-	Vector4 tmp;
-
-	tmp.x = m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12] * v.w;
-	tmp.y = m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13] * v.w;
-	tmp.z = m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14] * v.w;
-	tmp.w = m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15] * v.w;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::operator*(const Matrix4x4& a) const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0] * a.m[0] + m[4] * a.m[1] + m[8] * a.m[2] + m[12] * a.m[3];
-	tmp.m[1] = m[1] * a.m[0] + m[5] * a.m[1] + m[9] * a.m[2] + m[13] * a.m[3];
-	tmp.m[2] = m[2] * a.m[0] + m[6] * a.m[1] + m[10] * a.m[2] + m[14] * a.m[3];
-	tmp.m[3] = m[3] * a.m[0] + m[7] * a.m[1] + m[11] * a.m[2] + m[15] * a.m[3];
-
-	tmp.m[4] = m[0] * a.m[4] + m[4] * a.m[5] + m[8] * a.m[6] + m[12] * a.m[7];
-	tmp.m[5] = m[1] * a.m[4] + m[5] * a.m[5] + m[9] * a.m[6] + m[13] * a.m[7];
-	tmp.m[6] = m[2] * a.m[4] + m[6] * a.m[5] + m[10] * a.m[6] + m[14] * a.m[7];
-	tmp.m[7] = m[3] * a.m[4] + m[7] * a.m[5] + m[11] * a.m[6] + m[15] * a.m[7];
-
-	tmp.m[8] = m[0] * a.m[8] + m[4] * a.m[9] + m[8] * a.m[10] + m[12] * a.m[11];
-	tmp.m[9] = m[1] * a.m[8] + m[5] * a.m[9] + m[9] * a.m[10] + m[13] * a.m[11];
-	tmp.m[10] = m[2] * a.m[8] + m[6] * a.m[9] + m[10] * a.m[10] + m[14] * a.m[11];
-	tmp.m[11] = m[3] * a.m[8] + m[7] * a.m[9] + m[11] * a.m[10] + m[15] * a.m[11];
-
-	tmp.m[12] = m[0] * a.m[12] + m[4] * a.m[13] + m[8] * a.m[14] + m[12] * a.m[15];
-	tmp.m[13] = m[1] * a.m[12] + m[5] * a.m[13] + m[9] * a.m[14] + m[13] * a.m[15];
-	tmp.m[14] = m[2] * a.m[12] + m[6] * a.m[13] + m[10] * a.m[14] + m[14] * a.m[15];
-	tmp.m[15] = m[3] * a.m[12] + m[7] * a.m[13] + m[11] * a.m[14] + m[15] * a.m[15];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::operator*=(const Matrix4x4& a)
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0] * a.m[0] + m[4] * a.m[1] + m[8] * a.m[2] + m[12] * a.m[3];
-	tmp.m[1] = m[1] * a.m[0] + m[5] * a.m[1] + m[9] * a.m[2] + m[13] * a.m[3];
-	tmp.m[2] = m[2] * a.m[0] + m[6] * a.m[1] + m[10] * a.m[2] + m[14] * a.m[3];
-	tmp.m[3] = m[3] * a.m[0] + m[7] * a.m[1] + m[11] * a.m[2] + m[15] * a.m[3];
-
-	tmp.m[4] = m[0] * a.m[4] + m[4] * a.m[5] + m[8] * a.m[6] + m[12] * a.m[7];
-	tmp.m[5] = m[1] * a.m[4] + m[5] * a.m[5] + m[9] * a.m[6] + m[13] * a.m[7];
-	tmp.m[6] = m[2] * a.m[4] + m[6] * a.m[5] + m[10] * a.m[6] + m[14] * a.m[7];
-	tmp.m[7] = m[3] * a.m[4] + m[7] * a.m[5] + m[11] * a.m[6] + m[15] * a.m[7];
-
-	tmp.m[8] = m[0] * a.m[8] + m[4] * a.m[9] + m[8] * a.m[10] + m[12] * a.m[11];
-	tmp.m[9] = m[1] * a.m[8] + m[5] * a.m[9] + m[9] * a.m[10] + m[13] * a.m[11];
-	tmp.m[10] = m[2] * a.m[8] + m[6] * a.m[9] + m[10] * a.m[10] + m[14] * a.m[11];
-	tmp.m[11] = m[3] * a.m[8] + m[7] * a.m[9] + m[11] * a.m[10] + m[15] * a.m[11];
-
-	tmp.m[12] = m[0] * a.m[12] + m[4] * a.m[13] + m[8] * a.m[14] + m[12] * a.m[15];
-	tmp.m[13] = m[1] * a.m[12] + m[5] * a.m[13] + m[9] * a.m[14] + m[13] * a.m[15];
-	tmp.m[14] = m[2] * a.m[12] + m[6] * a.m[13] + m[10] * a.m[14] + m[14] * a.m[15];
-	tmp.m[15] = m[3] * a.m[12] + m[7] * a.m[13] + m[11] * a.m[14] + m[15] * a.m[15];
-
-	*this = tmp;
-
-	return *this;
-}
-
-Matrix4x4 operator*(float k, const Matrix4x4& a)
-{
-	return a * k;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_rotation_x(float radians)
-{
-	m[0] = 1.0;
-	m[1] = 0.0;
-	m[2] = 0.0;
-	m[3] = 0.0;
-	m[4] = 0.0;
-	m[5] = math::cos(radians);
-	m[6] = math::sin(radians);
-	m[7] = 0.0;
-	m[8] = 0.0;
-	m[9] = -math::sin(radians);
-	m[10] = math::cos(radians);
-	m[11] = 0.0;
-	m[12] = 0.0;
-	m[13] = 0.0;
-	m[14] = 0.0;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_rotation_y(float radians)
-{
-	m[0] = math::cos(radians);
-	m[1] = 0.0;
-	m[2] = -math::sin(radians);
-	m[3] = 0.0;
-	m[4] = 0.0;
-	m[5] = 1.0;
-	m[6] = 0.0;
-	m[7] = 0.0;
-	m[8] = math::sin(radians);
-	m[9] = 0.0;
-	m[10] = math::cos(radians);
-	m[11] = 0.0;
-	m[12] = 0.0;
-	m[13] = 0.0;
-	m[14] = 0.0;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_rotation_z(float radians)
-{
-	m[0] = math::cos(radians);
-	m[1] = math::sin(radians);
-	m[2] = 0.0;
-	m[3] = 0.0;
-	m[4] = -math::sin(radians);
-	m[5] = math::cos(radians);
-	m[6] = 0.0;
-	m[7] = 0.0;
-	m[8] = 0.0;
-	m[9] = 0.0;
-	m[10] = 1.0;
-	m[11] = 0.0;
-	m[12] = 0.0;
-	m[13] = 0.0;
-	m[14] = 0.0;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_rotation(const Vector3& n, float radians)
-{
-	float a = (float)1.0 - math::cos(radians);
-	float sin_a = math::sin(radians);
-	float cos_a = math::cos(radians);
-
-	m[0] = n.x * n.x * a + cos_a;
-	m[1] = n.x * n.y * a + n.z * sin_a;
-	m[2] = n.x * n.z * a - n.y * sin_a;
-	m[3] = 0.0;
-	m[4] = n.x * n.y * a - n.z * sin_a;
-	m[5] = n.y * n.y * a + cos_a;
-	m[6] = n.y * n.z * a + n.x * sin_a;
-	m[7] = 0.0;
-	m[8] = n.x * n.z * a + n.y * sin_a;
-	m[9] = n.y * n.z * a - n.x * sin_a;
-	m[10] = n.z * n.z * a + cos_a;
-	m[11] = 0.0;
-	m[12] = 0.0;
-	m[13] = 0.0;
-	m[14] = 0.0;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_rotation(const Quaternion& rot)
-{
-	set_rotation(quaternion::to_matrix3x3(rot));
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_rotation(const Matrix3x3& rot)
-{
-	m[0] = rot.m[0];
-	m[1] = rot.m[1];
-	m[2] = rot.m[2];
-	m[4] = rot.m[3];
-	m[5] = rot.m[4];
-	m[6] = rot.m[5];
-	m[8] = rot.m[6];
-	m[9] = rot.m[7];
-	m[10] = rot.m[8];
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_projection_perspective_rh(float fovy, float aspect, float near, float far)
-{
-	double top, right;
-
-	top = math::tan((float)((double)fovy / 360.0 * math::PI)) * (double)near;
-	right = top * aspect;
-
-	m[0] = (float)(near / right);
-	m[1] = 0.0;
-	m[2] = 0.0;
-	m[3] = 0.0;
-	m[4] = 0.0;
-	m[5] = (float)(near / top);
-	m[6] = 0.0;
-	m[7] = 0.0;
-	m[8] = 0.0;
-	m[9] = 0.0;
-	m[10] = (float)((far + near) / (near - far));
-	m[11] = -1.0;
-	m[12] = 0.0;
-	m[13] = 0.0;
-	m[14] = (float)((2.0 * far * near) / (near - far));
-	m[15] = 0.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_projection_ortho_rh(float left, float right, float bottom, float top, float near, float far)
-{
-	m[0] = 2.0 / (right - left);
-	m[1] = 0.0;
-	m[2] = 0.0;
-	m[3] = 0.0;
-	m[4] = 0.0;
-	m[5] = 2.0 / (top - bottom);
-	m[6] = 0.0;
-	m[7] = 0.0;
-	m[8] = 0.0;
-	m[9] = 0.0;
-	m[10] = -2.0 / (far - near);
-	m[11] = 0.0;
-	m[12] = -((right + left) / (right - left));
-	m[13] = -((top + bottom) / (top - bottom));
-	m[14] = -((far + near) / (far - near));
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::transpose()
-{
-	float tmp;
-
-	tmp = m[1];
-	m[1] = m[4];
-	m[4] = tmp;
-
-	tmp = m[2];
-	m[2] = m[8];
-	m[8] = tmp;
-
-	tmp = m[3];
-	m[3] = m[12];
-	m[12] = tmp;
-
-	tmp = m[6];
-	m[6] = m[9];
-	m[9] = tmp;
-
-	tmp = m[7];
-	m[7] = m[13];
-	m[13] = tmp;
-
-	tmp = m[11];
-	m[11] = m[14];
-	m[14] = tmp;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Matrix4x4::get_transposed() const
-{
-	Matrix4x4 tmp;
-
-	tmp.m[0] = m[0];
-	tmp.m[1] = m[4];
-	tmp.m[2] = m[8];
-	tmp.m[3] = m[12];
-	tmp.m[4] = m[1];
-	tmp.m[5] = m[5];
-	tmp.m[6] = m[9];
-	tmp.m[7] = m[13];
-	tmp.m[8] = m[2];
-	tmp.m[9] = m[6];
-	tmp.m[10] = m[10];
-	tmp.m[11] = m[14];
-	tmp.m[12] = m[3];
-	tmp.m[13] = m[7];
-	tmp.m[14] = m[11];
-	tmp.m[15] = m[15];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_look_at_rh(const Vector3& pos, const Vector3& target, const Vector3& up)
-{
-	Vector3 zAxis =  pos - target;
-	vector3::normalize(zAxis);
-
-	Vector3 xAxis = vector3::cross(up, zAxis);
-	Vector3 yAxis = vector3::cross(zAxis, xAxis);
-
-	m[0] = xAxis.x;
-	m[1] = yAxis.x;
-	m[2] = zAxis.x;
-	m[3] = 0.0;
-	m[4] = xAxis.y;
-	m[5] = yAxis.y;
-	m[6] = zAxis.y;
-	m[7] = 0.0;
-	m[8] = xAxis.z;
-	m[9] = yAxis.z;
-	m[10] = zAxis.z;
-	m[11] = 0.0;
-	m[12] = -vector3::dot(pos, xAxis);
-	m[13] = -vector3::dot(pos, yAxis);
-	m[14] = -vector3::dot(pos, zAxis);
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_viewpoint_billboard(const Vector3& pos, const Vector3& target, const Vector3& up)
-{
-	Vector3 zAxis = target - pos;
-	vector3::normalize(zAxis);
-
-	Vector3 xAxis = vector3::cross(up, zAxis);
-	Vector3 yAxis = vector3::cross(zAxis, xAxis);
-	vector3::normalize(xAxis);
-	vector3::normalize(yAxis);
-
-	m[0] = xAxis.x;
-	m[1] = xAxis.y;
-	m[2] = xAxis.z;
-	m[3] = 0.0;
-	m[4] = yAxis.x;
-	m[5] = yAxis.y;
-	m[6] = yAxis.z;
-	m[7] = 0.0;
-	m[8] = zAxis.x;
-	m[9] = zAxis.y;
-	m[10] = zAxis.z;
-	m[11] = 0.0;
-	m[12] = pos.x;
-	m[13] = pos.y;
-	m[14] = pos.z;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::build_axis_billboard(const Vector3& pos, const Vector3& target, const Vector3& axis)
-{
-	Vector3 zAxis = target - pos;
-
-	Vector3 xAxis = vector3::cross(axis, zAxis);
-	zAxis = vector3::cross(axis, xAxis);
-	vector3::normalize(xAxis);
-	vector3::normalize(zAxis);
-	const Vector3& yAxis = axis;
-
-	m[0] = xAxis.x;
-	m[1] = xAxis.y;
-	m[2] = xAxis.z;
-	m[3] = 0.0;
-	m[4] = yAxis.x;
-	m[5] = yAxis.y;
-	m[6] = yAxis.z;
-	m[7] = 0.0;
-	m[8] = zAxis.x;
-	m[9] = zAxis.y;
-	m[10] = zAxis.z;
-	m[11] = 0.0;
-	m[12] = pos.x;
-	m[13] = pos.y;
-	m[14] = pos.z;
-	m[15] = 1.0;
-}
-
-//-----------------------------------------------------------------------------
-float Matrix4x4::get_determinant() const
-{
-	float det;
-
-	float m02m07_m06m03 = m[2] * m[7] - m[6] * m[3];
-	float m02m11_m10m03 = m[2] * m[11] - m[10] * m[3];
-	float m02m15_m14m03 = m[2] * m[15] - m[14] * m[3];
-	float m06m11_m10m07 = m[6] * m[11] - m[10] * m[7];
-	float m06m15_m14m07 = m[6] * m[15] - m[14] * m[7];
-	float m10m15_m14m11 = m[10] * m[15] - m[14] * m[11];
-
-	det = 	+ m[0] * (m[5] * m10m15_m14m11 - m[9] * m06m15_m14m07 + m[13] * m06m11_m10m07)
-			- m[4] * (m[1] * m10m15_m14m11 - m[9] * m02m15_m14m03 + m[13] * m02m11_m10m03)
-			+ m[8] * (m[1] * m06m15_m14m07 - m[5] * m02m15_m14m03 + m[13] * m02m07_m06m03)
-			- m[12] * (m[1] * m06m11_m10m07 - m[5] * m02m11_m10m03 + m[9] * m02m07_m06m03);
-
-	return det;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4& Matrix4x4::invert()
-{
-	Matrix4x4 mat;
-	float det;
-
-	float m01m06_m05m02 = m[1] * m[6] - m[5] * m[2];
-	float m01m07_m05m03 = m[1] * m[7] - m[5] * m[3];
-	float m01m10_m09m02 = m[1] * m[10] - m[9] * m[2];
-	float m01m11_m09m03 = m[1] * m[11] - m[9] * m[3];
-	float m01m14_m13m02 = m[1] * m[14] - m[13] * m[2];
-	float m01m15_m13m03 = m[1] * m[15] - m[13] * m[3];
-	float m02m07_m06m03 = m[2] * m[7] - m[6] * m[3];
-	float m02m11_m10m03 = m[2] * m[11] - m[10] * m[3];
-	float m02m15_m14m03 = m[2] * m[15] - m[14] * m[3];
-	float m05m10_m09m06 = m[5] * m[10] - m[9] * m[6];
-	float m05m11_m09m07 = m[5] * m[11] - m[9] * m[7];
-	float m05m14_m13m06 = m[5] * m[14] - m[13] * m[6];
-	float m05m15_m13m07 = m[5] * m[15] - m[13] * m[7];
-	float m06m11_m10m07 = m[6] * m[11] - m[10] * m[7];
-	float m06m15_m14m07 = m[6] * m[15] - m[14] * m[7];
-	float m09m14_m13m10 = m[9] * m[14] - m[13] * m[10];
-	float m09m15_m13m11 = m[9] * m[15] - m[13] * m[11];
-	float m10m15_m14m11 = m[10] * m[15] - m[14] * m[11];
-
-	mat.m[0] = (+ m[5] * m10m15_m14m11 - m[9] * m06m15_m14m07 + m[13] * m06m11_m10m07);
-	mat.m[1] = (+ m[1] * m10m15_m14m11 - m[9] * m02m15_m14m03 + m[13] * m02m11_m10m03);
-	mat.m[2] = (+ m[1] * m06m15_m14m07 - m[5] * m02m15_m14m03 + m[13] * m02m07_m06m03);
-	mat.m[3] = (+ m[1] * m06m11_m10m07 - m[5] * m02m11_m10m03 + m[9] * m02m07_m06m03);
-
-	det = m[0] * mat.m[0] - m[4] * mat.m[1] + m[8] * mat.m[2] - m[12] * mat.m[3];
-	det = (float)1.0 / det;
-
-	mat.m[4] = (+ m[4] * m10m15_m14m11 - m[8] * m06m15_m14m07 + m[12] * m06m11_m10m07);
-	mat.m[5] = (+ m[0] * m10m15_m14m11 - m[8] * m02m15_m14m03 + m[12] * m02m11_m10m03);
-	mat.m[6] = (+ m[0] * m06m15_m14m07 - m[4] * m02m15_m14m03 + m[12] * m02m07_m06m03);
-	mat.m[7] = (+ m[0] * m06m11_m10m07 - m[4] * m02m11_m10m03 + m[8] * m02m07_m06m03);
-	mat.m[8] = (+ m[4] * m09m15_m13m11 - m[8] * m05m15_m13m07 + m[12] * m05m11_m09m07);
-	mat.m[9] = (+ m[0] * m09m15_m13m11 - m[8] * m01m15_m13m03 + m[12] * m01m11_m09m03);
-	mat.m[10] = (+ m[0] * m05m15_m13m07 - m[4] * m01m15_m13m03 + m[12] * m01m07_m05m03);
-	mat.m[11] = (+ m[0] * m05m11_m09m07 - m[4] * m01m11_m09m03 + m[8] * m01m07_m05m03);
-	mat.m[12] = (+ m[4] * m09m14_m13m10 - m[8] * m05m14_m13m06 + m[12] * m05m10_m09m06);
-	mat.m[13] = (+ m[0] * m09m14_m13m10 - m[8] * m01m14_m13m02 + m[12] * m01m10_m09m02);
-	mat.m[14] = (+ m[0] * m05m14_m13m06 - m[4] * m01m14_m13m02 + m[12] * m01m06_m05m02);
-	mat.m[15] = (+ m[0] * m05m10_m09m06 - m[4] * m01m10_m09m02 + m[8] * m01m06_m05m02);
-
-	m[0] = + mat.m[0] * det;
-	m[1] = - mat.m[1] * det;
-	m[2] = + mat.m[2] * det;
-	m[3] = - mat.m[3] * det;
-	m[4] = - mat.m[4] * det;
-	m[5] = + mat.m[5] * det;
-	m[6] = - mat.m[6] * det;
-	m[7] = + mat.m[7] * det;
-	m[8] = + mat.m[8] * det;
-	m[9] = - mat.m[9] * det;
-	m[10] = + mat.m[10] * det;
-	m[11] = - mat.m[11] * det;
-	m[12] = - mat.m[12] * det;
-	m[13] = + mat.m[13] * det;
-	m[14] = - mat.m[14] * det;
-	m[15] = + mat.m[15] * det;
-
-	return *this;
-}
-
-//-----------------------------------------------------------------------------
-inline Matrix4x4 Matrix4x4::get_inverted() const
-{
-	Matrix4x4 tmp(*this);
-
-	return tmp.invert();
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::load_identity()
-{
-	m[0] = m[5] = m[10] = m[15] = 1.0;
-	m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::x() const
-{
-	return Vector3(m[0], m[1], m[2]);
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::y() const
-{
-	return Vector3(m[4], m[5], m[6]);
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::z() const
-{
-	return Vector3(m[8], m[9], m[10]);
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_x(const Vector3& x)
-{
-	m[0] = x.x;
-	m[1] = x.y;
-	m[2] = x.z;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_y(const Vector3& y)
-{
-	m[4] = y.x;
-	m[5] = y.y;
-	m[6] = y.z;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_z(const Vector3& z)
-{
-	m[8] = z.x;
-	m[9] = z.y;
-	m[10] = z.z;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::translation() const
-{
-	Vector3 tmp;
-
-	tmp.x = m[12];
-	tmp.y = m[13];
-	tmp.z = m[14];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_translation(const Vector3& trans)
-{
-	m[12] = trans.x;
-	m[13] = trans.y;
-	m[14] = trans.z;
-}
-
-//-----------------------------------------------------------------------------
-Vector3 Matrix4x4::get_scale() const
-{
-	Vector3 tmp;
-
-	tmp.x = m[0];
-	tmp.y = m[5];
-	tmp.z = m[10];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-void Matrix4x4::set_scale(const Vector3& scale)
-{
-	m[0] = scale.x;
-	m[5] = scale.y;
-	m[10] = scale.z;
-}
-
-//-----------------------------------------------------------------------------
-float* Matrix4x4::to_float_ptr()
-{
-	return &m[0];
-}
-
-//-----------------------------------------------------------------------------
-const float* Matrix4x4::to_float_ptr() const
-{
-	return &m[0];
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Matrix4x4::to_matrix3x3() const
-{
-	Matrix3x3 tmp;
-
-	tmp.m[0] = m[0];
-	tmp.m[1] = m[1];
-	tmp.m[2] = m[2];
-	tmp.m[3] = m[4];
-	tmp.m[4] = m[5];
-	tmp.m[5] = m[6];
-	tmp.m[6] = m[8];
-	tmp.m[7] = m[9];
-	tmp.m[8] = m[10];
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Matrix4x4::to_quaternion() const
-{
-	Quaternion tmp;
-	float fourWSquaredMinusOne = m[0] + m[5] + m[10];
-	float fourXSquaredMinusOne = m[0] - m[5] - m[10];
-	float fourYSquaredMinusOne = -m[0] + m[5] - m[10];
-	float fourZSquaredMinusOne = -m[0] - m[5] + m[10];
-	float fourMaxSquaredMinusOne = fourWSquaredMinusOne;
-	uint32_t index = 0;
-
-	if (fourXSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourXSquaredMinusOne;
-		index = 1;
-	}
-
-	if (fourYSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourYSquaredMinusOne;
-		index = 2;
-	}
-
-	if (fourZSquaredMinusOne > fourMaxSquaredMinusOne)
-	{
-		fourMaxSquaredMinusOne = fourZSquaredMinusOne;
-		index = 3;
-	}
-
-	float biggest = math::sqrt(fourMaxSquaredMinusOne + (float)1.0) * (float)0.5;
-	float mult = (float)0.25 / biggest;
-
-	switch (index)
-	{
-		case 0:
-			tmp.w = biggest;
-			tmp.x = (-m[9] + m[6]) * mult;
-			tmp.y = (-m[2] + m[8]) * mult;
-			tmp.z = (-m[4] + m[1]) * mult;
-			break;
-		case 1:
-			tmp.x = biggest;
-			tmp.w = (-m[9] + m[6]) * mult;
-			tmp.y = (-m[4] - m[1]) * mult;
-			tmp.z = (-m[2] - m[8]) * mult;
-			break;
-		case 2:
-			tmp.y = biggest;
-			tmp.w = (-m[2] + m[8]) * mult;
-			tmp.x = (-m[4] - m[1]) * mult;
-			tmp.z = (-m[9] - m[6]) * mult;
-			break;
-		case 3:
-			tmp.z = biggest;
-			tmp.w = (-m[4] + m[1]) * mult;
-			tmp.x = (-m[2] - m[8]) * mult;
-			tmp.y = (-m[9] - m[6]) * mult;
-			break;
-	}
-
-	return tmp;
-}
-
-} // namespace crown
-

+ 559 - 130
engine/core/math/Matrix4x4.h

@@ -26,174 +26,603 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+#include "MathTypes.h"
+#include "Matrix3x3.h"
+#include "Quaternion.h"
+#include "Vector4.h"
 #include "Types.h"
 
 namespace crown
 {
 
-struct Matrix3x3;
-struct Quaternion;
-struct Vector3;
-struct Vector4;
-
-/// Column-major 4x4 matrix.
-/// 
-/// The engine uses column vectors for coordinate space transformations
-/// so you'll have to specify transformations in reverse order.
-/// e.g. (rotation * translation * vector) will produce the result of first translating
-/// and then rotating the vector.
-/// Also note that a column major matrix needs to be placed to the left of a
-/// vector by matrix multiplication, so, to multiply a vector by a matrix you'll have
-/// to write something like: matrix * vector. Since we are also using column vectors, inverting
-/// the operands would result in an impossible operation.
-/// 
-/// @a verbatim:
-///   X base vector
-///     | Y base vector
-///     |   | Z base vector
-///     |   |   | Translation vector
-///     |   |   |   |
-/// 1 [ Xx  Yx  Zx  Tx ]
-/// 2 | Xy  Yy  Zy  Ty |
-/// 3 | Xz  Yz  Zz  Tz |
-/// 4 [ 0   0   0   1  ]
-///     1   2   3   4
-struct Matrix4x4
-{
-
-public:
-
-	float				m[16];
-
-	/// Does nothing for efficiency.
-						Matrix4x4();	
-
-	/// Constructs from a set of float
-						Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
-									float r1c2, float r2c2, float r3c2, float r4c2,
-									float r1c3, float r2c3, float r3c3, float r4c3,
-									float r1c4, float r2c4, float r3c4, float r4c4);
-
-	/// Constructs from rotation @a r and position @a p.
-						Matrix4x4(const Quaternion& r, const Vector3& p);
-	
-	/// Contructs from the @a v array
-						Matrix4x4(const float v[16]);						
-						Matrix4x4(const Matrix4x4& a);					
+/// Adds the matrix @a a to @a b and returns the result.
+Matrix4x4 operator+(Matrix4x4 a, const Matrix4x4& b);
 
-	/// Assignment operator (copies the data)
-	Matrix4x4&			operator=(const Matrix4x4& a);					
+/// Subtracts the matrix @a b from @a a and returns the result.
+Matrix4x4 operator-(Matrix4x4 a, const Matrix4x4& b);
 
-	/// Random access by index
-	float				operator[](uint32_t i) const;
+/// Multiplies the matrix @a a by the scalar @a k and returns the result.
+Matrix4x4 operator*(Matrix4x4 a, float k);
 
-	/// Random access by index					
-	float&				operator[](uint32_t i);							
+/// @copydoc operator*(Matrix4x4, float)
+Matrix4x4 operator*(float k, Matrix4x4 a);
 
-	float				operator()(uint32_t row, uint32_t column) const;	//!< Random access by row/column pair
+/// Divides the matrix @a a by the scalar @a k and returns the result.
+Matrix4x4 operator/(Matrix4x4 a, float k);
 
-	Matrix4x4			operator+(const Matrix4x4& a) const;
-	Matrix4x4&			operator+=(const Matrix4x4& a);					
-	Matrix4x4			operator-(const Matrix4x4& a) const;				
-	Matrix4x4&			operator-=(const Matrix4x4& a);					
-	Matrix4x4			operator*(float k) const;				
-	Matrix4x4&			operator*=(float k);							
-	Matrix4x4			operator/(float k) const;					
-	Matrix4x4&			operator/=(float k);							
-	Vector3				operator*(const Vector3& v) const;				
-	Vector4				operator*(const Vector4& v) const;				
-	Matrix4x4			operator*(const Matrix4x4& a) const;			
-	Matrix4x4&			operator*=(const Matrix4x4& a);
+/// Multiplies the matrix @a a by the vector @a v and returns the result.
+Vector3 operator*(const Matrix4x4& a, const Vector3& v);
 
-	/// For simmetry
-	friend Matrix4x4	operator*(float k, const Matrix4x4& a);			
+/// Multiplies the matrix @a by the vector @a v and returns the result.
+Vector4 operator*(const Matrix4x4& a, const Vector4& v);
 
-	/// Builds a rotation matrix about the X axis of @a radians radians
-	void				build_rotation_x(float radians);
+/// Multiplies the matrix @a a by @a b and returns the result. (i.e. transforms first by @a b then by @a a)
+Matrix4x4 operator*(Matrix4x4 a, const Matrix4x4& b);
 
-	/// Builds a rotation matrix about the Y axis of "radians" radians	
-	void				build_rotation_y(float radians);	
+/// Functions to manipulate Matrix4x4.
+///
+/// @ingroup Math
+namespace matrix4x4
+{
+	const Matrix4x4 IDENTITY = Matrix4x4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
 
-	/// Builds a rotation matrix about the Z axis of @a radians radians			
-	void				build_rotation_z(float radians);		
+	/// Sets the rotation portion of the matrix @a m.
+	void set_rotation(Matrix4x4& m, const Quaternion& rot);
 
-	/// Builds a rotation matrix about an arbitrary axis of "radians" radians		
-	void				build_rotation(const Vector3& n, float radians);
+	/// Sets the rotation portion of the matrix @a m.
+	void set_rotation(Matrix4x4& m, const Matrix3x3& rot);
 
-	/// Sets the rotation portion to the rotation described by @a rot.
-	void				set_rotation(const Quaternion& rot);
+	/// Sets the matrix @a m to perspective. (Right-Handed coordinate systems)
+	void set_perspective_rh(Matrix4x4& m, float fovy, float aspect, float near, float far);
 
-	/// Sets the rotation portion to the rotation described by @a rot.
-	void				set_rotation(const Matrix3x3& rot);
+	/// Sets the matrix @a m to orthographic. (Right-Handed coordinate systems)
+	void set_orthographic_rh(Matrix4x4& m, float left, float right, float bottom, float top, float near, float far);
 
-	/// Builds a perspetive projection matrix suited to Right-Handed coordinate systems
-	void				build_projection_perspective_rh(float fovy, float aspect, float near, float far);
+	/// Sets the matrix @a m to look. (Right-Handed coordinate systems)
+	void set_look_rh(Matrix4x4& m, const Vector3& pos, const Vector3& target, const Vector3& up);
 
-	/// Builds an orthographic projection matrix suited to Right-Handed coordinate systems	
-	void				build_projection_ortho_rh(float left, float right, float bottom, float top, float near, float far);
+	/// Transposes the matrix @a m and returns the result.
+	Matrix4x4& transpose(Matrix4x4& m);					
 
-	/// Builds a "Righ-Handed look-at" matrix from a position, a target, and an up vector
-	void				build_look_at_rh(const Vector3& pos, const Vector3& target, const Vector3& up);
+	/// Returns the transposed of the matrix @a m.			
+	Matrix4x4 get_transposed(Matrix4x4 m);
 
-	/// Builds a "Viewpoint-Oriented billboard" matrix which can be used to make an object face a specific point in space	
-	void				build_viewpoint_billboard(const Vector3& pos, const Vector3& target, const Vector3& up);	
+	/// Returns the determinant of the matrix @a m.						
+	float determinant(const Matrix4x4& m);
 
-	/// Builds a "Arbitrary-Axis billboard" matrix which can be used to make an object face a specific point in space
-	void				build_axis_billboard(const Vector3& pos, const Vector3& target, const Vector3& axis);	
+	/// Inverts the matrix @a m and returns the result.
+	Matrix4x4& invert(Matrix4x4& m);
 
-	Matrix4x4&			transpose();								
-	Matrix4x4			get_transposed() const;						
-	float				get_determinant() const;					
-	Matrix4x4&			invert();									
-	Matrix4x4			get_inverted() const;						
+	/// Returns the inverse of the matrix @a m.				
+	Matrix4x4 get_inverted(Matrix4x4 m);
 
-	/// Builds the identity matrix
-	void				load_identity();							
+	/// Sets the matrix @a m to identity.
+	void set_identity(Matrix4x4& m);
 
-	/// Returns a Vector3 containing the matrix's x base vector.
-	Vector3				x() const;
+	/// Returns the x asis of the matrix @a m.
+	Vector3 x(const Matrix4x4& m);
 
-	/// Returns a Vector3 containing the matrix's y base vector.
-	Vector3				y() const;
+	/// Returns the y axis of the matrix @a m.
+	Vector3 y(const Matrix4x4& m);
 
-	/// Returns a Vector3 containing the matrix's z base vector.
-	Vector3				z() const;
+	/// Returns the z axis of the matrix @a m.
+	Vector3 z(const Matrix4x4& m);
 
-	/// Sets the matrix's x base vector.
-	void				set_x(const Vector3& x);
+	/// Sets the x axis of the matrix @a m.
+	void set_x(Matrix4x4& m, const Vector3& x);
 
-	/// Sets the matrix's y base vector.
-	void				set_y(const Vector3& y);
+	/// Sets the y axis of the matrix @a m.
+	void set_y(Matrix4x4& m, const Vector3& y);
 
-	/// Sets the matrix's z base vector.
-	void				set_z(const Vector3& z);
+	/// Sets the z axis of the matrix @a m.
+	void set_z(Matrix4x4& m, const Vector3& z);
 
-	/// Returns a Vector3 containing the matrix's translation portion
-	Vector3				translation() const;	
+	/// Returns the translation portion of the matrix @a m.
+	Vector3 translation(const Matrix4x4& m);	
 
-	/// Fills the matrix's translation portion values contained in @a trans				
-	void				set_translation(const Vector3& trans);			
+	/// Sets the translation portion of the matrix @a m.
+	void set_translation(Matrix4x4& m, const Vector3& trans);
 
-	/// Returns a Vector3 containing the matrix's scale portion
-	Vector3				get_scale() const;
+	/// Returns the pointer to the matrix's data
+	float* to_float_ptr(Matrix4x4& m);
 
-	/// Fills the matrix's scale portion with the values contained in @a scale							
-	void				set_scale(const Vector3& scale);				
+	/// Returns the pointer to the first elemento of the matrix @a m.
+	const float* to_float_ptr(const Matrix4x4& m);
 
-	/// Returns the pointer to the matrix's data
-	float*				to_float_ptr();
+	/// Returns the rotation portion of the matrix @a m as a Matrix3x3.
+	Matrix3x3 to_matrix3x3(const Matrix4x4& m);
 
-	/// Returns the pointer to the matrix's data
-	const float*		to_float_ptr() const;
+	/// Returns the rotation portion of the matrix @a m as a Quaternion.
+	Quaternion to_quaternion(const Matrix4x4& m);
+} // namespace matrix4x4
 
-	/// Returns a 3x3 matrix according to the matrix's rotation portion
-	Matrix3x3			to_matrix3x3() const;
+inline Matrix4x4 operator+(Matrix4x4 a, const Matrix4x4& b)
+{
+	a += b;
+	return a;
+}
 
-	/// Returns a quaternion according to the matrix's rotation portion
-	Quaternion			to_quaternion() const;
+inline Matrix4x4 operator-(Matrix4x4 a, const Matrix4x4& b)
+{
+	a -= b;
+	return a;
+}
 
-	static const Matrix4x4	IDENTITY;
-};
+inline Matrix4x4 operator*(Matrix4x4 a, float k)
+{
+	a *= k;
+	return a;
+}
 
-} // namespace crown
+inline Matrix4x4 operator*(float k, Matrix4x4 a)
+{
+	a *= k;
+	return a;
+}
+
+inline Matrix4x4 operator/(Matrix4x4 a, float k)
+{
+	a /= k;
+	return a;
+}
+
+inline Vector3 operator*(const Matrix4x4& a, const Vector3& v)
+{
+	Vector3 tmp;
+
+	tmp.x = a.x.x * v.x + a.y.x * v.y + a.z.x * v.z + a.t.x;
+	tmp.y = a.x.y * v.x + a.y.y * v.y + a.z.y * v.z + a.t.y;
+	tmp.z = a.x.z * v.x + a.y.z * v.y + a.z.z * v.z + a.t.z;
 
+	return tmp;
+}
+
+inline Vector4 operator*(const Matrix4x4& a, const Vector4& v)
+{
+	Vector4 tmp;
+
+	tmp.x = a.x.x * v.x + a.y.x * v.y + a.z.x * v.z + a.t.x * v.w;
+	tmp.y = a.x.y * v.x + a.y.y * v.y + a.z.y * v.z + a.t.y * v.w;
+	tmp.z = a.x.z * v.x + a.y.z * v.y + a.z.z * v.z + a.t.z * v.w;
+	tmp.w = a.x.w * v.x + a.y.w * v.y + a.z.w * v.z + a.t.w * v.w;
+
+	return tmp;
+}
+
+inline Matrix4x4 operator*(Matrix4x4 a, const Matrix4x4& b)
+{
+	a *= b;
+	return a;
+}
+
+namespace matrix4x4
+{
+	//-----------------------------------------------------------------------------
+	inline void set_rotation(Matrix4x4& m, const Quaternion& rot)
+	{
+		set_rotation(m, quaternion::to_matrix3x3(rot));
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_rotation(Matrix4x4& m, const Matrix3x3& rot)
+	{
+		m.x.x = rot.x.x;
+		m.x.y = rot.x.y;
+		m.x.z = rot.x.z;
+		m.y.x = rot.y.x;
+		m.y.y = rot.y.y;
+		m.y.y = rot.y.z;
+		m.z.x = rot.z.x;
+		m.z.y = rot.z.y;
+		m.z.z = rot.z.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_perspective_rh(Matrix4x4& m, float fovy, float aspect, float near, float far)
+	{
+		const double top = math::tan(((double)fovy / 360.0 * math::PI)) * (double)near;
+		const double right = top * aspect;
+
+		m.x = Vector4(near / right, 0, 0, 0);
+		m.y = Vector4(0, near / top, 0, 0);
+		m.z = Vector4(0, 0, (far + near) / (near - far), -1);
+		m.t = Vector4(0, 0, (2.0 * far * near) / (near - far), 0);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_orthographic_rh(Matrix4x4& m, float left, float right, float bottom, float top, float near, float far)
+	{
+		m.x = Vector4(2.0 / (right - left), 0, 0, 0);
+		m.y = Vector4(0, 2.0 / (top - bottom), 0, 0);
+		m.z = Vector4(0, 0, -2.0 / (far - near), 0);
+		m.t = Vector4(-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((far + near) / (far - near)), 1.0);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix4x4& transpose(Matrix4x4& m)
+	{
+		float tmp;
+
+		tmp = m.x.y;
+		m.x.y = m.y.x;
+		m.y.x = tmp;
+
+		tmp = m.x.z;
+		m.x.z = m.z.x;
+		m.z.x = tmp;
+
+		tmp = m.x.w;
+		m.x.w = m.t.x;
+		m.t.x = tmp;
+
+		tmp = m.y.z;
+		m.y.z = m.z.y;
+		m.z.y = tmp;
+
+		tmp = m.y.w;
+		m.y.w = m.t.y;
+		m.t.y = tmp;
+
+		tmp = m.z.w;
+		m.z.w = m.t.z;
+		m.t.z = tmp;
+
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix4x4 get_transposed(Matrix4x4 m)
+	{
+		transpose(m);
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_look_rh(Matrix4x4& m, const Vector3& pos, const Vector3& target, const Vector3& up)
+	{
+		Vector3 zAxis = pos - target;
+		vector3::normalize(zAxis);
+		const Vector3 xAxis = vector3::cross(up, zAxis);
+		const Vector3 yAxis = vector3::cross(zAxis, xAxis);
+
+		m.x.x= xAxis.x;
+		m.x.y= yAxis.x;
+		m.x.z= zAxis.x;
+		m.x.w= 0;
+
+		m.y.x= xAxis.y;
+		m.y.y= yAxis.y;
+		m.y.z= zAxis.y;
+		m.y.w= 0;
+
+		m.z.x= xAxis.z;
+		m.z.y= yAxis.z;
+		m.z.z= zAxis.z;
+		m.z.w= 0;
+
+		m.t.x= -vector3::dot(pos, xAxis);
+		m.t.y= -vector3::dot(pos, yAxis);
+		m.t.z= -vector3::dot(pos, zAxis);
+		m.t.w= 1;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline float determinant(const Matrix4x4& m)
+	{
+		const float m02m07_m06m03 = m.x.z * m.y.w - m.y.z * m.x.w;
+		const float m02m11_m10m03 = m.x.z * m.z.w - m.z.z * m.x.w;
+		const float m02m15_m14m03 = m.x.z * m.t.w - m.t.z * m.x.w;
+		const float m06m11_m10m07 = m.y.z * m.z.w - m.z.z * m.y.w;
+		const float m06m15_m14m07 = m.y.z * m.t.w - m.t.z * m.y.w;
+		const float m10m15_m14m11 = m.z.z * m.t.w - m.t.z * m.z.w;
+
+		return 	+ m.x.x * (m.y.y * m10m15_m14m11 - m.z.y * m06m15_m14m07 + m.t.y * m06m11_m10m07)
+				- m.y.x * (m.x.y * m10m15_m14m11 - m.z.y * m02m15_m14m03 + m.t.y * m02m11_m10m03)
+				+ m.z.x * (m.x.y * m06m15_m14m07 - m.y.y * m02m15_m14m03 + m.t.y * m02m07_m06m03)
+				- m.t.x * (m.x.y * m06m11_m10m07 - m.y.y * m02m11_m10m03 + m.z.y * m02m07_m06m03);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix4x4& invert(Matrix4x4& m)
+	{
+		Matrix4x4 mat;
+
+		const float m01m06_m05m02 = m.x.y * m.y.z - m.y.y * m.x.z;
+		const float m01m07_m05m03 = m.x.y * m.y.w - m.y.y * m.x.w;
+		const float m01m10_m09m02 = m.x.y * m.z.z - m.z.y * m.x.z;
+		const float m01m11_m09m03 = m.x.y * m.z.w - m.z.y * m.x.w;
+		const float m01m14_m13m02 = m.x.y * m.t.z - m.t.y * m.x.z;
+		const float m01m15_m13m03 = m.x.y * m.t.w - m.t.y * m.x.w;
+		const float m02m07_m06m03 = m.x.z * m.y.w - m.y.z * m.x.w;
+		const float m02m11_m10m03 = m.x.z * m.z.w - m.z.z * m.x.w;
+		const float m02m15_m14m03 = m.x.z * m.t.w - m.t.z * m.x.w;
+		const float m05m10_m09m06 = m.y.y * m.z.z - m.z.y * m.y.z;
+		const float m05m11_m09m07 = m.y.y * m.z.w - m.z.y * m.y.w;
+		const float m05m14_m13m06 = m.y.y * m.t.z - m.t.y * m.y.z;
+		const float m05m15_m13m07 = m.y.y * m.t.w - m.t.y * m.y.w;
+		const float m06m11_m10m07 = m.y.z * m.z.w - m.z.z * m.y.w;
+		const float m06m15_m14m07 = m.y.z * m.t.w - m.t.z * m.y.w;
+		const float m09m14_m13m10 = m.z.y * m.t.z - m.t.y * m.z.z;
+		const float m09m15_m13m11 = m.z.y * m.t.w - m.t.y * m.z.w;
+		const float m10m15_m14m11 = m.z.z * m.t.w - m.t.z * m.z.w;
+
+		mat.x.x = (+ m.y.y * m10m15_m14m11 - m.z.y * m06m15_m14m07 + m.t.y * m06m11_m10m07);
+		mat.x.y = (+ m.x.y * m10m15_m14m11 - m.z.y * m02m15_m14m03 + m.t.y * m02m11_m10m03);
+		mat.x.z = (+ m.x.y * m06m15_m14m07 - m.y.y * m02m15_m14m03 + m.t.y * m02m07_m06m03);
+		mat.x.w = (+ m.x.y * m06m11_m10m07 - m.y.y * m02m11_m10m03 + m.z.y * m02m07_m06m03);
+
+		const float inv_det = 1.0 / (m.x.x * mat.x.x - m.y.x * mat.x.y + m.z.x * mat.x.z - m.t.x * mat.x.w);
+
+		mat.y.x = (+ m.y.x * m10m15_m14m11 - m.z.x * m06m15_m14m07 + m.t.x * m06m11_m10m07);
+		mat.y.y = (+ m.x.x * m10m15_m14m11 - m.z.x * m02m15_m14m03 + m.t.x * m02m11_m10m03);
+		mat.y.z = (+ m.x.x * m06m15_m14m07 - m.y.x * m02m15_m14m03 + m.t.x * m02m07_m06m03);
+		mat.y.w = (+ m.x.x * m06m11_m10m07 - m.y.x * m02m11_m10m03 + m.z.x * m02m07_m06m03);
+		mat.z.x = (+ m.y.x * m09m15_m13m11 - m.z.x * m05m15_m13m07 + m.t.x * m05m11_m09m07);
+		mat.z.y = (+ m.x.x * m09m15_m13m11 - m.z.x * m01m15_m13m03 + m.t.x * m01m11_m09m03);
+		mat.z.z = (+ m.x.x * m05m15_m13m07 - m.y.x * m01m15_m13m03 + m.t.x * m01m07_m05m03);
+		mat.z.w = (+ m.x.x * m05m11_m09m07 - m.y.x * m01m11_m09m03 + m.z.x * m01m07_m05m03);
+		mat.t.x = (+ m.y.x * m09m14_m13m10 - m.z.x * m05m14_m13m06 + m.t.x * m05m10_m09m06);
+		mat.t.y = (+ m.x.x * m09m14_m13m10 - m.z.x * m01m14_m13m02 + m.t.x * m01m10_m09m02);
+		mat.t.z = (+ m.x.x * m05m14_m13m06 - m.y.x * m01m14_m13m02 + m.t.x * m01m06_m05m02);
+		mat.t.w = (+ m.x.x * m05m10_m09m06 - m.y.x * m01m10_m09m02 + m.z.x * m01m06_m05m02);
+
+		m.x.x = + mat.x.x * inv_det;
+		m.x.y = - mat.x.y * inv_det;
+		m.x.z = + mat.x.z * inv_det;
+		m.x.w = - mat.x.w * inv_det;
+		m.y.x = - mat.y.x * inv_det;
+		m.y.y = + mat.y.y * inv_det;
+		m.y.z = - mat.y.z * inv_det;
+		m.y.w = + mat.y.w * inv_det;
+		m.z.x = + mat.z.x * inv_det;
+		m.z.y = - mat.z.y * inv_det;
+		m.z.z = + mat.z.z * inv_det;
+		m.z.w = - mat.z.w * inv_det;
+		m.t.x = - mat.t.x * inv_det;
+		m.t.y = + mat.t.y * inv_det;
+		m.t.z = - mat.t.z * inv_det;
+		m.t.w = + mat.t.w * inv_det;
+
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix4x4 get_inverted(Matrix4x4 m)
+	{
+		invert(m);
+		return m;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_identity(Matrix4x4& m)
+	{
+		m.x = Vector4(1, 0, 0, 0);
+		m.y = Vector4(0, 1, 0, 0);
+		m.z = Vector4(0, 0, 1, 0);
+		m.t = Vector4(0, 0, 0, 1);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Vector3 x(const Matrix4x4& m)
+	{
+		return Vector3(m.x.x, m.x.y, m.x.z);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Vector3 y(const Matrix4x4& m)
+	{
+		return Vector3(m.y.x, m.y.y, m.y.z);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Vector3 z(const Matrix4x4& m)
+	{
+		return Vector3(m.z.x, m.z.y, m.z.z);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_x(Matrix4x4& m, const Vector3& x)
+	{
+		m.x.x = x.x;
+		m.x.y = x.y;
+		m.x.z = x.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_y(Matrix4x4& m, const Vector3& y)
+	{
+		m.y.x = y.x;
+		m.y.y = y.y;
+		m.y.z = y.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_z(Matrix4x4& m, const Vector3& z)
+	{
+		m.z.x = z.x;
+		m.z.y = z.y;
+		m.z.z = z.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Vector3 translation(const Matrix4x4& m)
+	{
+		return Vector3(m.t.x, m.t.y, m.t.z);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline void set_translation(Matrix4x4& m, const Vector3& trans)
+	{
+		m.t.x = trans.x;
+		m.t.y = trans.y;
+		m.t.z = trans.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline float* to_float_ptr(Matrix4x4& m)
+	{
+		return vector4::to_float_ptr(m.x);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline const float* to_float_ptr(const Matrix4x4& m)
+	{
+		return vector4::to_float_ptr(m.x);
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Matrix3x3 to_matrix3x3(const Matrix4x4& m)
+	{
+		return Matrix3x3(x(m), y(m), z(m));
+	}
+
+	//-----------------------------------------------------------------------------
+	inline Quaternion to_quaternion(const Matrix4x4& m)
+	{
+		return matrix3x3::to_quaternion(to_matrix3x3(m));
+	}
+} // namespace matrix4x4
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4::Matrix4x4()
+{
+	// Do not initialize
+}
+
+inline Matrix4x4::Matrix4x4(const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& t)
+	: x(x, 0), y(y, 0), z(z, 0), t(t, 1)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4::Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
+							float r1c2, float r2c2, float r3c2, float r4c2,
+							float r1c3, float r2c3, float r3c3, float r4c3,
+							float r1c4, float r2c4, float r3c4, float r4c4)
+	: x(r1c1, r2c1, r3c1, r4c1)
+	, y(r1c2, r2c2, r3c2, r4c2)
+	, z(r1c3, r2c3, r3c3, r4c3)
+	, t(r1c4, r2c4, r3c4, r4c4)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4::Matrix4x4(const Quaternion& r, const Vector3& p)
+	: x(1.0 - 2.0 * r.y * r.y - 2.0 * r.z * r.z, 2.0 * r.x * r.y + 2.0 * r.w * r.z, 2.0 * r.x * r.z - 2.0 * r.w * r.y, 0)
+	, y(2.0 * r.x * r.y - 2.0 * r.w * r.z, 1.0 - 2.0 * r.x * r.x - 2.0 * r.z * r.z, 2.0 * r.y * r.z + 2.0 * r.w * r.x, 0)
+	, z(2.0 * r.x * r.z + 2.0 * r.w * r.y, 2.0 * r.y * r.z - 2.0 * r.w * r.x, 1.0 - 2.0 * r.x * r.x - 2.0 * r.y * r.y, 0)
+	, t(p, 1)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4::Matrix4x4(const Matrix3x3& m)
+	: x(m.x, 0)
+	, y(m.y, 0)
+	, z(m.z, 0)
+	, t(0, 0, 0, 1)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4::Matrix4x4(const float v[16])
+	: x(v[0], v[1], v[2], v[3])
+	, y(v[4], v[5], v[6], v[7])
+	, z(v[8], v[9], v[10], v[11])
+	, t(v[12], v[13], v[14], v[15])
+{
+}
+
+//-----------------------------------------------------------------------------
+inline float& Matrix4x4::operator[](uint32_t i)
+{
+	CE_ASSERT(i < 16, "Index out of bounds");
+
+	return vector4::to_float_ptr(x)[i];
+}
+
+//-----------------------------------------------------------------------------
+inline const float& Matrix4x4::operator[](uint32_t i) const
+{
+	CE_ASSERT(i < 16, "Index out of bounds");
+
+	return vector4::to_float_ptr(x)[i];
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& a)
+{
+	x += a.x;
+	y += a.y;
+	z += a.z;
+	t += a.t;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& a)
+{
+	x -= a.x;
+	y -= a.y;
+	z -= a.z;
+	t -= a.t;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4& Matrix4x4::operator*=(float k)
+{
+	x *= k;
+	y *= k;
+	z *= k;
+	t *= k;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4& Matrix4x4::operator/=(float k)
+{
+	const float inv_k = 1.0 / k;
+	
+	x *= inv_k;
+	y *= inv_k;
+	z *= inv_k;
+	t *= inv_k;
+
+	return *this;
+}
+
+//-----------------------------------------------------------------------------
+inline Matrix4x4& Matrix4x4::operator*=(const Matrix4x4& a)
+{
+	Matrix4x4 tmp;
+
+	tmp.x.x = x.x * a.x.x + y.x * a.x.y + z.x * a.x.z + t.x * a.x.w;
+	tmp.x.y = x.y * a.x.x + y.y * a.x.y + z.y * a.x.z + t.y * a.x.w;
+	tmp.x.z = x.z * a.x.x + y.z * a.x.y + z.z * a.x.z + t.z * a.x.w;
+	tmp.x.w = x.w * a.x.x + y.w * a.x.y + z.w * a.x.z + t.w * a.x.w;
+
+	tmp.y.x = x.x * a.y.x + y.x * a.y.y + z.x * a.y.z + t.x * a.y.w;
+	tmp.y.y = x.y * a.y.x + y.y * a.y.y + z.y * a.y.z + t.y * a.y.w;
+	tmp.y.z = x.z * a.y.x + y.z * a.y.y + z.z * a.y.z + t.z * a.y.w;
+	tmp.y.w = x.w * a.y.x + y.w * a.y.y + z.w * a.y.z + t.w * a.y.w;
+
+	tmp.z.x = x.x * a.z.x + y.x * a.z.y + z.x * a.z.z + t.x * a.z.w;
+	tmp.z.y = x.y * a.z.x + y.y * a.z.y + z.y * a.z.z + t.y * a.z.w;
+	tmp.z.z = x.z * a.z.x + y.z * a.z.y + z.z * a.z.z + t.z * a.z.w;
+	tmp.z.w = x.w * a.z.x + y.w * a.z.y + z.w * a.z.z + t.w * a.z.w;
+
+	tmp.t.x = x.x * a.t.x + y.x * a.t.y + z.x * a.t.z + t.x * a.t.w;
+	tmp.t.y = x.y * a.t.x + y.y * a.t.y + z.y * a.t.z + t.y * a.t.w;
+	tmp.t.z = x.z * a.t.x + y.z * a.t.y + z.z * a.t.z + t.z * a.t.w;
+	tmp.t.w = x.w * a.t.x + y.w * a.t.y + z.w * a.t.z + t.w * a.t.w;
+
+	*this = tmp;
+
+	return *this;
+}
+
+} // namespace crown

+ 0 - 6
engine/core/math/Plane.h

@@ -85,12 +85,6 @@ inline Plane::Plane()
 	// Do not initialize
 }
 
-//-----------------------------------------------------------------------------
-inline Plane::Plane(const Plane& p)
-	: n(p.n), d(p.d)
-{
-}
-
 //-----------------------------------------------------------------------------
 inline Plane::Plane(const Vector3& normal, float dist)
 	: n(normal), d(dist)

+ 2 - 44
engine/core/math/Quaternion.h

@@ -30,7 +30,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Vector3.h"
 #include "MathTypes.h"
 #include "Matrix3x3.h"
-#include "Matrix4x4.h"
 
 namespace crown
 {
@@ -134,53 +133,12 @@ namespace quaternion
 
 	inline Matrix3x3 to_matrix3x3(const Quaternion& q)
 	{
-		const float x = q.x;
-		const float y = q.y;
-		const float z = q.z;
-		const float w = q.w;
-
-		Matrix3x3 tmp;
-
-		tmp.m[0] = (float)(1.0 - 2.0*y*y - 2.0*z*z);
-		tmp.m[1] = (float)(2.0*x*y + 2.0*w*z);
-		tmp.m[2] = (float)(2.0*x*z - 2.0*w*y);
-		tmp.m[3] = (float)(2.0*x*y - 2.0*w*z);
-		tmp.m[4] = (float)(1.0 - 2.0*x*x - 2.0*z*z);
-		tmp.m[5] = (float)(2.0*y*z + 2.0*w*x);
-		tmp.m[6] = (float)(2.0*x*z + 2.0*w*y);
-		tmp.m[7] = (float)(2.0*y*z - 2.0*w*x);
-		tmp.m[8] = (float)(1.0 - 2.0*x*x - 2.0*y*y);
-
-		return tmp;
+		return Matrix3x3(q);
 	}
 
 	inline Matrix4x4 to_matrix4x4(const Quaternion& q)
 	{
-		const float x = q.x;
-		const float y = q.y;
-		const float z = q.z;
-		const float w = q.w;
-
-		Matrix4x4 tmp;
-
-		tmp.m[0] = (float)(1.0 - 2.0*y*y - 2.0*z*z);
-		tmp.m[1] = (float)(2.0*x*y + 2.0*w*z);
-		tmp.m[2] = (float)(2.0*x*z - 2.0*w*y);
-		tmp.m[3] = 0;
-		tmp.m[4] = (float)(2.0*x*y - 2.0*w*z);
-		tmp.m[5] = (float)(1.0 - 2.0*x*x - 2.0*z*z);
-		tmp.m[6] = (float)(2.0*y*z + 2.0*w*x);
-		tmp.m[7] = 0.0;
-		tmp.m[8] = (float)(2.0*x*z + 2.0*w*y);
-		tmp.m[9] = (float)(2.0*y*z - 2.0*w*x);
-		tmp.m[10] = (float)(1.0 - 2.0*x*x - 2.0*y*y);
-		tmp.m[11] = 0.0;
-		tmp.m[12] = 0.0;
-		tmp.m[13] = 0.0;
-		tmp.m[14] = 0.0;
-		tmp.m[15] = 1.0;
-
-		return tmp;
+		return Matrix4x4(q, Vector3(0, 0, 0));
 	}
 } // namespace quaternion
 

+ 0 - 5
engine/core/math/Vector2.h

@@ -217,11 +217,6 @@ inline Vector2::Vector2(const float a[2]) : x(a[0]), y(a[1])
 {
 }
 
-//-----------------------------------------------------------------------------
-inline Vector2::Vector2(const Vector2& a) : x(a.x), y(a.y)
-{
-}
-
 //-----------------------------------------------------------------------------
 inline float Vector2::operator[](uint32_t i) const
 {

+ 0 - 5
engine/core/math/Vector3.h

@@ -240,11 +240,6 @@ inline Vector3::Vector3(const float v[3]) : x(v[0]), y(v[1]), z(v[2])
 {
 }
 
-//-----------------------------------------------------------------------------
-inline Vector3::Vector3(const Vector3& a) : x(a.x), y(a.y), z(a.z)
-{
-}
-
 //-----------------------------------------------------------------------------
 inline float Vector3::operator[](uint32_t i) const
 {

+ 5 - 4
engine/core/math/Vector4.h

@@ -215,25 +215,26 @@ namespace vector4
 //-----------------------------------------------------------------------------
 inline Vector4::Vector4()
 {
+	// Do not initialize
 }
 
 //-----------------------------------------------------------------------------
-inline Vector4::Vector4(float val) : x(val), y(val), z(val), w(val)
+inline Vector4::Vector4(const Vector3& a, float w) : x(a.x), y(a.y), z(a.z), w(w)
 {
 }
 
 //-----------------------------------------------------------------------------
-inline Vector4::Vector4(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw)
+inline Vector4::Vector4(float val) : x(val), y(val), z(val), w(val)
 {
 }
 
 //-----------------------------------------------------------------------------
-inline Vector4::Vector4(const float a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3])
+inline Vector4::Vector4(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw)
 {
 }
 
 //-----------------------------------------------------------------------------
-inline Vector4::Vector4(const Vector4& a) : x(a.x), y(a.y), z(a.z), w(a.w)
+inline Vector4::Vector4(const float a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3])
 {
 }
 

+ 10 - 8
engine/gui/Gui.cpp

@@ -47,6 +47,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+using namespace matrix4x4;
+
 ShaderId			gui_default_vs;
 ShaderId			gui_default_fs;
 ShaderId			gui_texture_fs;
@@ -143,12 +145,12 @@ Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
 	, m_text_pool(default_allocator(), CE_MAX_GUI_TEXTS, sizeof(GuiText), CE_ALIGNOF(GuiText))
 {
 	// orthographic projection
-	m_projection.build_projection_ortho_rh(0, m_resolution.x, m_resolution.y, 0, -0.01f, 100.0f);
+	set_orthographic_rh(m_projection, 0, m_resolution.x, m_resolution.y, 0, -0.01f, 100.0f);
 
 	// pose
 	Vector3 pos = m_resource->gui_position();
-	m_pose.load_identity();
-	m_pose.set_translation(pos);
+	set_identity(m_pose);
+	set_translation(m_pose, pos);
 
 	create_gfx();
 
@@ -234,8 +236,8 @@ Vector2 Gui::resolution() const
 //-----------------------------------------------------------------------------
 void Gui::move(const Vector3& pos)
 {
-	m_pose.load_identity();
-	m_pose.set_translation(pos);
+	set_identity(m_pose);
+	set_translation(m_pose, pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -364,9 +366,9 @@ void Gui::render()
 	m_resolution.x = width;
 	m_resolution.y = height;
 
-	m_r.set_layer_view(1, Matrix4x4::IDENTITY);
+	m_r.set_layer_view(1, matrix4x4::IDENTITY);
 	m_r.set_layer_projection(1, m_projection);
-	m_r.set_layer_viewport(1, m_pose.translation().x, m_pose.translation().y, m_resolution.x, m_resolution.y);
+	m_r.set_layer_viewport(1, translation(m_pose).x, translation(m_pose).y, m_resolution.x, m_resolution.y);
 
 	if (!m_visible) return;
 
@@ -467,4 +469,4 @@ void Gui::destroy_gfx()
 	m_r.destroy_shader(font_fs);
 }
 
-} // namespace crown
+} // namespace crown

+ 49 - 153
engine/lua/LuaMatrix4x4.cpp

@@ -30,9 +30,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "LuaEnvironment.h"
 #include "OS.h"
 
+
 namespace crown
 {
 
+using namespace matrix4x4;
+
 //-----------------------------------------------------------------------------
 static int matrix4x4_new(lua_State* L)
 {
@@ -68,141 +71,77 @@ static int matrix4x4_ctor(lua_State* L)
 	return matrix4x4_new(L);
 }
 
-//-----------------------------------------------------------------------------					
-static int matrix4x4_add(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	Matrix4x4& b = stack.get_matrix4x4(2);
-
-	stack.push_matrix4x4(a + b);
-
-	return 1;
-}
-
 //-----------------------------------------------------------------------------
-static int matrix4x4_subtract(lua_State* L)
+static int matrix4x4_from_quaternion(lua_State* L)
 {
 	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	Matrix4x4& b = stack.get_matrix4x4(2);
-
-	stack.push_matrix4x4(a - b);
-
+	const Quaternion& q = stack.get_quaternion(1);
+	stack.push_matrix4x4(Matrix4x4(q, Vector3(0, 0, 0)));
 	return 1;
 }
 
 //-----------------------------------------------------------------------------
-static int matrix4x4_multiply(lua_State* L)
+static int matrix4x4_from_translation(lua_State* L)
 {
 	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	Matrix4x4& b = stack.get_matrix4x4(2);
-
-	stack.push_matrix4x4(a * b);
-
+	const Vector3& t = stack.get_vector3(1);
+	stack.push_matrix4x4(Matrix4x4(quaternion::IDENTITY, t));
 	return 1;
 }
 
 //-----------------------------------------------------------------------------
-static int matrix4x4_build_rotation_x(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	float k = stack.get_float(2);
-
-	a.build_rotation_x(k);
-
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-static int matrix4x4_build_rotation_y(lua_State* L)
+static int matrix4x4_from_quaternion_translation(lua_State* L)
 {
 	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	float k = stack.get_float(2);
-
-	a.build_rotation_y(k);
-
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-static int matrix4x4_build_rotation_z(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	float k = stack.get_float(2);
-
-	a.build_rotation_z(k);
-
-	return 0;
+	stack.push_matrix4x4(Matrix4x4(stack.get_quaternion(1), stack.get_vector3(2)));
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-static int matrix4x4_build_rotation(lua_State* L)
+static int matrix4x4_from_axes(lua_State* L)
 {
 	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	Vector3& d = stack.get_vector3(2);
-	float k = stack.get_float(3);
-
-	a.build_rotation(d, k);
-
-	return 0;
+	stack.push_matrix4x4(Matrix4x4(stack.get_vector3(1), stack.get_vector3(2), stack.get_vector3(3), stack.get_vector3(4)));
+	return 1;
 }
 
-//-----------------------------------------------------------------------------
-static int matrix4x4_build_look_at_rh(lua_State* L)
+//-----------------------------------------------------------------------------					
+static int matrix4x4_add(lua_State* L)
 {
 	LuaStack stack(L);
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
-	Vector3& pos = stack.get_vector3(2);
-	Vector3& target = stack.get_vector3(3);
-	Vector3& up = stack.get_vector3(4);
+	Matrix4x4& b = stack.get_matrix4x4(2);
 
-	a.build_look_at_rh(pos, target, up);
+	stack.push_matrix4x4(a + b);
 
-	return 0;
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-static int matrix4x4_build_viewpoint_billboard(lua_State* L)
+static int matrix4x4_subtract(lua_State* L)
 {
 	LuaStack stack(L);
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
-	Vector3& pos = stack.get_vector3(2);
-	Vector3& target = stack.get_vector3(3);
-	Vector3& up = stack.get_vector3(4);
+	Matrix4x4& b = stack.get_matrix4x4(2);
 
-	a.build_viewpoint_billboard(pos, target, up);
+	stack.push_matrix4x4(a - b);
 
-	return 0;
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-static int matrix4x4_build_axis_billboard(lua_State* L)
+static int matrix4x4_multiply(lua_State* L)
 {
 	LuaStack stack(L);
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
-	Vector3& pos = stack.get_vector3(2);
-	Vector3& target = stack.get_vector3(3);
-	Vector3& up = stack.get_vector3(4);
+	Matrix4x4& b = stack.get_matrix4x4(2);
 
-	a.build_axis_billboard(pos, target, up);
+	stack.push_matrix4x4(a * b);
 
-	return 0;
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
@@ -212,7 +151,7 @@ static int matrix4x4_transpose(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_matrix4x4(a.transpose());
+	stack.push_matrix4x4(transpose(a));
 
 	return 1;
 }
@@ -224,7 +163,7 @@ static int matrix4x4_determinant(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_float(a.get_determinant());
+	stack.push_float(determinant(a));
 
 	return 1;
 }
@@ -236,23 +175,11 @@ static int matrix4x4_invert(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_matrix4x4(a.invert());
+	stack.push_matrix4x4(invert(a));
 
 	return 1;
 }
 
-//-----------------------------------------------------------------------------
-static int matrix4x4_load_identity(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-
-	a.load_identity();
-
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 static int matrix4x4_x(lua_State* L)
 {	
@@ -260,7 +187,7 @@ static int matrix4x4_x(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_vector3(a.x());
+	stack.push_vector3(x(a));
 
 	return 1;
 }
@@ -272,7 +199,7 @@ static int matrix4x4_y(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_vector3(a.y());
+	stack.push_vector3(y(a));
 
 	return 1;
 }
@@ -284,7 +211,7 @@ static int matrix4x4_z(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_vector3(a.z());
+	stack.push_vector3(z(a));
 
 	return 1;
 }
@@ -297,7 +224,7 @@ static int matrix4x4_set_x(lua_State* L)
 	Matrix4x4& a = stack.get_matrix4x4(1);
 	Vector3& x = stack.get_vector3(2);
 
-	a.set_x(x);
+	set_x(a, x);
 
 	return 0;
 }
@@ -310,7 +237,7 @@ static int matrix4x4_set_y(lua_State* L)
 	Matrix4x4& a = stack.get_matrix4x4(1);
 	Vector3& y = stack.get_vector3(2);
 
-	a.set_y(y);
+	set_y(a, y);
 
 	return 0;
 }
@@ -323,7 +250,7 @@ static int matrix4x4_set_z(lua_State* L)
 	Matrix4x4& a = stack.get_matrix4x4(1);
 	Vector3& z = stack.get_vector3(2);
 
-	a.set_z(z);
+	set_z(a, z);
 
 	return 0;
 }
@@ -335,7 +262,7 @@ static int matrix4x4_translation(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	stack.push_vector3(a.translation());
+	stack.push_vector3(translation(a));
 
 	return 1;
 }
@@ -348,32 +275,7 @@ static int matrix4x4_set_translation(lua_State* L)
 	Matrix4x4& a = stack.get_matrix4x4(1);
 	Vector3& trans = stack.get_vector3(2);
 
-	a.set_translation(trans);
-
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-static int matrix4x4_get_scale(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-
-	stack.push_vector3(a.get_scale());
-
-	return 1;
-}
-
-//-----------------------------------------------------------------------------
-static int matrix4x4_set_scale(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Matrix4x4& a = stack.get_matrix4x4(1);
-	Vector3& scale = stack.get_vector3(2);
-
-	a.set_scale(scale);
+	set_translation(a, trans);
 
 	return 0;
 }
@@ -383,7 +285,7 @@ static int matrix4x4_identity(lua_State* L)
 {
 	LuaStack stack(L);
 
-	stack.push_matrix4x4(Matrix4x4::IDENTITY);
+	stack.push_matrix4x4(matrix4x4::IDENTITY);
 
 	return 1;
 }
@@ -395,10 +297,10 @@ static int matrix4x4_print(lua_State* L)
 
 	Matrix4x4& a = stack.get_matrix4x4(1);
 
-	os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[0], a.m[4], a.m[8], a.m[12]);
-	os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[1], a.m[5], a.m[9], a.m[13]);
-	os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[2], a.m[6], a.m[10], a.m[14]);
-	os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[3], a.m[7], a.m[11], a.m[15]);
+	// os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[0], a.m[4], a.m[8], a.m[12]);
+	// os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[1], a.m[5], a.m[9], a.m[13]);
+	// os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[2], a.m[6], a.m[10], a.m[14]);
+	// os::printf("|%.1f|%.1f|%.1f|%.1f|\n", a.m[3], a.m[7], a.m[11], a.m[15]);
 
 	return 0;
 }
@@ -407,20 +309,16 @@ static int matrix4x4_print(lua_State* L)
 void load_matrix4x4(LuaEnvironment& env)
 {
 	env.load_module_function("Matrix4x4", "new", 							matrix4x4_new);
+	env.load_module_function("Matrix4x4", "from_quaternion",				matrix4x4_from_quaternion);
+	env.load_module_function("Matrix4x4", "from_translation",				matrix4x4_from_translation);
+	env.load_module_function("Matrix4x4", "from_quaternion_translation",	matrix4x4_from_quaternion_translation);
+	env.load_module_function("Matrix4x4", "from_axes",						matrix4x4_from_axes);
 	env.load_module_function("Matrix4x4", "add", 							matrix4x4_add);
 	env.load_module_function("Matrix4x4", "subtract", 						matrix4x4_subtract);
 	env.load_module_function("Matrix4x4", "multiply", 						matrix4x4_multiply);
-	env.load_module_function("Matrix4x4", "build_rotation_x", 				matrix4x4_build_rotation_x);
-	env.load_module_function("Matrix4x4", "build_rotation_y", 				matrix4x4_build_rotation_y);
-	env.load_module_function("Matrix4x4", "build_rotation_z", 				matrix4x4_build_rotation_z);
-	env.load_module_function("Matrix4x4", "build_rotation", 				matrix4x4_build_rotation);
-	env.load_module_function("Matrix4x4", "build_look_at_rh", 				matrix4x4_build_look_at_rh);
-	env.load_module_function("Matrix4x4", "build_viewpoint_billboard", 		matrix4x4_build_viewpoint_billboard);
-	env.load_module_function("Matrix4x4", "build_axis_billboard", 			matrix4x4_build_axis_billboard);
 	env.load_module_function("Matrix4x4", "transpose", 						matrix4x4_transpose);
 	env.load_module_function("Matrix4x4", "determinant", 					matrix4x4_determinant);
 	env.load_module_function("Matrix4x4", "invert", 						matrix4x4_invert);
-	env.load_module_function("Matrix4x4", "load_identity", 					matrix4x4_load_identity);
 	env.load_module_function("Matrix4x4", "x",								matrix4x4_x);
 	env.load_module_function("Matrix4x4", "y",								matrix4x4_y);
 	env.load_module_function("Matrix4x4", "z",								matrix4x4_z);
@@ -429,9 +327,7 @@ void load_matrix4x4(LuaEnvironment& env)
 	env.load_module_function("Matrix4x4", "set_z",							matrix4x4_set_z);
 	env.load_module_function("Matrix4x4", "translation", 					matrix4x4_translation);
 	env.load_module_function("Matrix4x4", "set_translation", 				matrix4x4_set_translation);
-	env.load_module_function("Matrix4x4", "get_scale", 						matrix4x4_get_scale);
-	env.load_module_function("Matrix4x4", "set_scale", 						matrix4x4_set_scale);
-	env.load_module_function("Matrix4x4", "identity", 						matrix4x4_identity);	
+	env.load_module_function("Matrix4x4", "identity", 						matrix4x4_identity);
 	env.load_module_function("Matrix4x4", "print", 							matrix4x4_print);
 
 	env.load_module_constructor("Matrix4x4",								matrix4x4_ctor);

+ 8 - 6
engine/physics/Actor.cpp

@@ -40,10 +40,10 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "PhysicsWorld.h"
 #include "Quaternion.h"
 #include "StringUtils.h"
+
 #include "PxCooking.h"
 #include "PxDefaultStreams.h"
 
-
 using physx::PxActorFlag;
 using physx::PxActorType;
 using physx::PxBoxGeometry;
@@ -110,7 +110,7 @@ void Actor::create_objects()
 	const PhysicsActor2& actor_class = config->actor(actor.actor_class);
 
 	// Create rigid body
-	const PxMat44 pose((PxReal*) (m_scene_graph.world_pose(m_node).to_float_ptr()));
+	const PxMat44 pose((PxReal*) matrix4x4::to_float_ptr(m_scene_graph.world_pose(m_node)));
 
 	if (actor_class.flags & PhysicsActor2::DYNAMIC)
 	{
@@ -269,10 +269,12 @@ void Actor::teleport_world_rotation(const Quaternion& r)
 //-----------------------------------------------------------------------------
 void Actor::teleport_world_pose(const Matrix4x4& m)
 {
-	const PxVec3 x(m.x().x, m.x().y, m.x().z);
-	const PxVec3 y(m.y().x, m.y().y, m.y().z);
-	const PxVec3 z(m.z().x, m.z().y, m.z().z);
-	const PxVec3 t(m.translation().x, m.translation().y, m.translation().z);
+	using namespace matrix4x4;
+
+	const PxVec3 x(m.x.x, m.x.y, m.x.z);
+	const PxVec3 y(m.y.x, m.y.y, m.y.z);
+	const PxVec3 z(m.z.x, m.z.y, m.z.z);
+	const PxVec3 t(translation(m).x, translation(m).y, translation(m).z);
 	m_actor->setGlobalPose(PxTransform(PxMat44(x, y, z, t)));
 }
 

+ 1 - 1
engine/renderers/DebugLine.cpp

@@ -124,7 +124,7 @@ void DebugLine::commit()
 	r->set_vertex_buffer(tvb);
 	r->set_index_buffer(tib);
 	//r->set_program(default_program);
-	r->set_pose(Matrix4x4::IDENTITY);
+	r->set_pose(matrix4x4::IDENTITY);
 	r->commit(0);
 }
 

+ 1 - 1
engine/renderers/RenderWorld.cpp

@@ -215,7 +215,7 @@ void RenderWorld::update(const Matrix4x4& view, const Matrix4x4& projection, uin
 	Renderer* r = device()->renderer();
 
 	Matrix4x4 inv_view = view;
-	inv_view.invert();
+	matrix4x4::invert(inv_view);
 
 	r->set_layer_view(0, inv_view);
 	r->set_layer_projection(0, projection);

+ 1 - 1
engine/renderers/backend/RenderContext.h

@@ -175,7 +175,7 @@ struct RenderState
 	{
 		m_flags = STATE_NONE;
 
-		pose = Matrix4x4::IDENTITY;
+		pose = matrix4x4::IDENTITY;
 		program.id = INVALID_ID;
 		vb.id = INVALID_ID;
 		ib.id = INVALID_ID;

+ 4 - 6
engine/renderers/backend/gl/GLRenderer.cpp

@@ -943,24 +943,22 @@ public:
 					{
 						case ShaderUniform::VIEW:
 						{
-							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, view.to_float_ptr()));
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, matrix4x4::to_float_ptr(view)));
 							break;
 						}
 						case ShaderUniform::MODEL:
 						{
-							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, cur_state.pose.to_float_ptr()));
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, matrix4x4::to_float_ptr(cur_state.pose)));
 							break;
 						}
 						case ShaderUniform::MODEL_VIEW:
 						{
-							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (view *
-															cur_state.pose).to_float_ptr()));
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, matrix4x4::to_float_ptr(view * cur_state.pose)));
 							break;
 						}
 						case ShaderUniform::MODEL_VIEW_PROJECTION:
 						{
-							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (projection * view *
-															cur_state.pose).to_float_ptr()));
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, matrix4x4::to_float_ptr(projection * view * cur_state.pose)));
 							break;
 						}
 						case ShaderUniform::TIME_SINCE_START:

+ 9 - 5
engine/world/Camera.cpp

@@ -192,10 +192,12 @@ void Camera::set_viewport_metrics(uint16_t x, uint16_t y, uint16_t width, uint16
 //-----------------------------------------------------------------------------
 Vector3 Camera::screen_to_world(const Vector3& pos)
 {
+	using namespace matrix4x4;
+
 	Matrix4x4 world_inv = world_pose();
-	world_inv.invert();
+	invert(world_inv);
 	Matrix4x4 mvp = m_projection * world_inv;
-	mvp.invert();
+	invert(mvp);
 
 	Vector4 ndc( (2 * (pos.x - 0)) / m_view_width - 1,
 				 (2 * (m_view_height - pos.y)) / m_view_height - 1,
@@ -210,8 +212,10 @@ Vector3 Camera::screen_to_world(const Vector3& pos)
 //-----------------------------------------------------------------------------
 Vector3 Camera::world_to_screen(const Vector3& pos)
 {
+	using namespace matrix4x4;
+
 	Matrix4x4 world_inv = world_pose();
-	world_inv.invert();
+	invert(world_inv);
 
 	Vector3 ndc = (m_projection * world_inv) * pos;
 
@@ -227,12 +231,12 @@ void Camera::update_projection_matrix()
 	{
 		case ProjectionType::ORTHOGRAPHIC:
 		{
-			m_projection.build_projection_ortho_rh(m_left, m_right, m_bottom, m_top, m_near, m_far);
+			matrix4x4::set_orthographic_rh(m_projection, m_left, m_right, m_bottom, m_top, m_near, m_far);
 			break;
 		}
 		case ProjectionType::PERSPECTIVE:
 		{
-			m_projection.build_projection_perspective_rh(m_FOV, m_aspect, m_near, m_far);
+			matrix4x4::set_perspective_rh(m_projection, m_FOV, m_aspect, m_near, m_far);
 			break;
 		}
 		default:

+ 12 - 10
engine/world/SceneGraph.cpp

@@ -40,6 +40,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+using namespace matrix4x4;
+
 //-----------------------------------------------------------------------------
 SceneGraph::SceneGraph(Allocator& a, uint32_t index)
 	: m_allocator(&a)
@@ -144,8 +146,8 @@ void SceneGraph::link(int32_t child, int32_t parent)
 	CE_ASSERT(parent < (int32_t) m_num_nodes, "Parent node does not exist");
 	CE_ASSERT(parent < child, "Parent must be < child");
 
-	m_world_poses[child] = Matrix4x4::IDENTITY;
-	m_local_poses[child] = Matrix4x4::IDENTITY;
+	m_world_poses[child] = matrix4x4::IDENTITY;
+	m_local_poses[child] = matrix4x4::IDENTITY;
 	m_parents[child] = parent;
 }
 
@@ -168,7 +170,7 @@ void SceneGraph::set_local_position(int32_t node, const Vector3& pos)
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
 	m_flags[node] |= LOCAL_DIRTY;
-	m_local_poses[node].set_translation(pos);
+	set_translation(m_local_poses[node], pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -177,7 +179,7 @@ void SceneGraph::set_local_rotation(int32_t node, const Quaternion& rot)
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
 	m_flags[node] |= LOCAL_DIRTY;
-	m_local_poses[node].set_rotation(rot);
+	set_rotation(m_local_poses[node], rot);
 }
 
 //-----------------------------------------------------------------------------
@@ -194,7 +196,7 @@ Vector3 SceneGraph::local_position(int32_t node) const
 {
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
-	return m_local_poses[node].translation();
+	return translation(m_local_poses[node]);
 }
 
 //-----------------------------------------------------------------------------
@@ -202,7 +204,7 @@ Quaternion SceneGraph::local_rotation(int32_t node) const
 {
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
-	return m_local_poses[node].to_quaternion();
+	return to_quaternion(m_local_poses[node]);
 }
 
 //-----------------------------------------------------------------------------
@@ -219,7 +221,7 @@ void SceneGraph::set_world_position(int32_t node, const Vector3& pos)
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
 	m_flags[node] |= WORLD_DIRTY;
-	m_world_poses[node].set_translation(pos);
+	set_translation(m_world_poses[node], pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -228,7 +230,7 @@ void SceneGraph::set_world_rotation(int32_t node, const Quaternion& rot)
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
 	m_flags[node] |= WORLD_DIRTY;
-	m_world_poses[node].set_rotation(rot);
+	set_rotation(m_world_poses[node], rot);
 }
 
 //-----------------------------------------------------------------------------
@@ -245,7 +247,7 @@ Vector3 SceneGraph::world_position(int32_t node) const
 {
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
-	return m_world_poses[node].translation();
+	return translation(m_world_poses[node]);
 }
 
 //-----------------------------------------------------------------------------
@@ -253,7 +255,7 @@ Quaternion SceneGraph::world_rotation(int32_t node) const
 {
 	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
 
-	return m_world_poses[node].to_quaternion();
+	return to_quaternion(m_world_poses[node]);
 }
 
 //-----------------------------------------------------------------------------