Sfoglia il codice sorgente

Port Quaternion to NMF

Daniele Bartolini 12 anni fa
parent
commit
b2b756c017

+ 0 - 1
engine/CMakeLists.txt

@@ -149,7 +149,6 @@ set (MATH_SRC
 	core/math/Matrix3x3.cpp
 	core/math/Matrix4x4.cpp
 	core/math/Plane.cpp
-	core/math/Quaternion.cpp
 )
 
 set (MATH_HEADERS

+ 11 - 0
engine/core/math/MathTypes.h

@@ -86,4 +86,15 @@ struct Vector4
 	float x, y, z, w;
 };
 
+struct Quaternion
+{
+	Quaternion();
+	Quaternion(float nx, float ny, float nz, float nw);
+	Quaternion(const Vector3& axis, float angle);
+
+	Quaternion& operator*=(const Quaternion& a);
+
+	float x, y, z, w;
+};
+
 } // namespace crown

+ 12 - 12
engine/core/math/Matrix3x3.cpp

@@ -619,27 +619,27 @@ Quaternion Matrix3x3::to_quaternion() const
 	{
 		case 0:
 			tmp.w = biggest;
-			tmp.v.x = (-m[7] + m[5]) * mult;
-			tmp.v.y = (-m[2] + m[6]) * mult;
-			tmp.v.z = (-m[3] + m[1]) * mult;
+			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.v.x = biggest;
+			tmp.x = biggest;
 			tmp.w = (-m[7] + m[5]) * mult;
-			tmp.v.y = (-m[3] - m[1]) * mult;
-			tmp.v.z = (-m[2] - m[6]) * mult;
+			tmp.y = (-m[3] - m[1]) * mult;
+			tmp.z = (-m[2] - m[6]) * mult;
 			break;
 		case 2:
-			tmp.v.y = biggest;
+			tmp.y = biggest;
 			tmp.w = (-m[2] + m[6]) * mult;
-			tmp.v.x = (-m[3] - m[1]) * mult;
-			tmp.v.z = (-m[7] - m[5]) * mult;
+			tmp.x = (-m[3] - m[1]) * mult;
+			tmp.z = (-m[7] - m[5]) * mult;
 			break;
 		case 3:
-			tmp.v.z = biggest;
+			tmp.z = biggest;
 			tmp.w = (-m[3] + m[1]) * mult;
-			tmp.v.x = (-m[2] - m[6]) * mult;
-			tmp.v.y = (-m[7] - m[5]) * mult;
+			tmp.x = (-m[2] - m[6]) * mult;
+			tmp.y = (-m[7] - m[5]) * mult;
 			break;
 	}
 

+ 17 - 17
engine/core/math/Matrix4x4.cpp

@@ -70,10 +70,10 @@ Matrix4x4::Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1,
 //-----------------------------------------------------------------------------
 Matrix4x4::Matrix4x4(const Quaternion& r, const Vector3& p)
 {
-	const float& rx = r.v.x;
-	const float& ry = r.v.y;
-	const float& rz = r.v.z;
-	const float& rw = r.w;
+	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;
@@ -557,7 +557,7 @@ void Matrix4x4::build_rotation(const Vector3& n, float radians)
 //-----------------------------------------------------------------------------
 void Matrix4x4::set_rotation(const Quaternion& rot)
 {
-	set_rotation(rot.to_matrix3x3());
+	set_rotation(quaternion::to_matrix3x3(rot));
 }
 
 //-----------------------------------------------------------------------------
@@ -1012,27 +1012,27 @@ Quaternion Matrix4x4::to_quaternion() const
 	{
 		case 0:
 			tmp.w = biggest;
-			tmp.v.x = (-m[9] + m[6]) * mult;
-			tmp.v.y = (-m[2] + m[8]) * mult;
-			tmp.v.z = (-m[4] + m[1]) * mult;
+			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.v.x = biggest;
+			tmp.x = biggest;
 			tmp.w = (-m[9] + m[6]) * mult;
-			tmp.v.y = (-m[4] - m[1]) * mult;
-			tmp.v.z = (-m[2] - m[8]) * mult;
+			tmp.y = (-m[4] - m[1]) * mult;
+			tmp.z = (-m[2] - m[8]) * mult;
 			break;
 		case 2:
-			tmp.v.y = biggest;
+			tmp.y = biggest;
 			tmp.w = (-m[2] + m[8]) * mult;
-			tmp.v.x = (-m[4] - m[1]) * mult;
-			tmp.v.z = (-m[9] - m[6]) * mult;
+			tmp.x = (-m[4] - m[1]) * mult;
+			tmp.z = (-m[9] - m[6]) * mult;
 			break;
 		case 3:
-			tmp.v.z = biggest;
+			tmp.z = biggest;
 			tmp.w = (-m[4] + m[1]) * mult;
-			tmp.v.x = (-m[2] - m[8]) * mult;
-			tmp.v.y = (-m[9] - m[6]) * mult;
+			tmp.x = (-m[2] - m[8]) * mult;
+			tmp.y = (-m[9] - m[6]) * mult;
 			break;
 	}
 

+ 0 - 216
engine/core/math/Quaternion.cpp

@@ -1,216 +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 "Matrix3x3.h"
-#include "Matrix4x4.h"
-#include "Types.h"
-#include "MathUtils.h"
-#include "Quaternion.h"
-#include "Vector3.h"
-
-namespace crown
-{
-
-const Quaternion Quaternion::IDENTITY = Quaternion(0.0, 0.0, 0.0, 1.0);
-
-//-----------------------------------------------------------------------------
-Quaternion::Quaternion()
-{
-}
-
-//-----------------------------------------------------------------------------
-Quaternion::Quaternion(float nx, float ny, float nz, float nw) :
-	v(nx, ny, nz),
-	w(nw)
-{
-}
-
-//-----------------------------------------------------------------------------
-Quaternion::Quaternion(const Vector3& axis, float angle) :
-	v(axis * math::sin(angle * 0.5)),
-	w(math::cos(angle * 0.5))
-{
-}
-
-//-----------------------------------------------------------------------------
-void Quaternion::negate()
-{
-	w = -w;
-	v = -v;
-}
-
-//-----------------------------------------------------------------------------
-void Quaternion::load_identity()
-{
-	w = 1.0;
-	v.x = 0.0;
-	v.y = 0.0;
-	v.z = 0.0;
-}
-
-//-----------------------------------------------------------------------------
-float Quaternion::length() const
-{
-	return math::sqrt(w * w + v.x * v.x + v.y * v.y + v.z * v.z);
-}
-
-//-----------------------------------------------------------------------------
-void Quaternion::conjugate()
-{
-	v = -v;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Quaternion::get_conjugate() const
-{
-	return Quaternion(-v, w);
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Quaternion::get_inverse() const
-{
-	return get_conjugate() * (1.0 / length());
-}
-
-//-----------------------------------------------------------------------------
-Matrix3x3 Quaternion::to_matrix3x3() const
-{
-	const float x = v.x;
-	const float y = v.y;
-	const float z = v.z;
-
-	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;
-}
-
-//-----------------------------------------------------------------------------
-Matrix4x4 Quaternion::to_matrix4x4() const
-{
-	const float x = v.x;
-	const float y = v.y;
-	const float z = v.z;
-
-	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;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Quaternion::operator*(const Quaternion& b) const
-{
-	Quaternion tmp;
-
-	tmp.w = w * b.w - vector3::dot(v, b.v);
-	tmp.v = w * b.v + b.w * v + vector3::cross(b.v, v);
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Quaternion::operator*(const float& k) const
-{
-	Quaternion tmp;
-
-	tmp.w = w * k;
-	tmp.v = v * k;
-
-	return tmp;
-}
-
-//-----------------------------------------------------------------------------
-Quaternion Quaternion::power(float exp)
-{
-	Quaternion tmp;
-
-	if (math::abs(w) < 0.9999)
-	{
-		float alpha = math::acos(w); // alpha = theta/2
-		float newAlpha = alpha * exp;
-		tmp.w = math::cos(newAlpha);
-		float mult = math::sin(newAlpha) / math::sin(alpha);
-		tmp.v.x = v.x * mult;
-		tmp.v.y = v.y * mult;
-		tmp.v.z = v.z * mult;
-		return tmp;
-	}
-
-	tmp.w = w;
-	tmp.v = v;
-
-	return tmp;
-}
-
-/*
-The geometric interpretation of the Quaternion dot product is similar to the interpretation of
-the vector dot product; the larger the absolute value of the Quaternion dot product axb, the more
-"similar" the angular displacements represented by a and b.
-*/
-//-----------------------------------------------------------------------------
-float dot(const Quaternion& a, const Quaternion& b)
-{
-	return a.w * b.w + vector3::dot(a.v, b.v);
-}
-
-// Spherical Linear interpolation
-//-----------------------------------------------------------------------------
-Quaternion slerp(const Quaternion& start, const Quaternion& end, float t)
-{
-	Quaternion delta = end * start.get_inverse();
-	delta = delta.power(t);
-
-	return delta * start;
-}
-
-} // namespace crown
-

+ 165 - 48
engine/core/math/Quaternion.h

@@ -28,75 +28,192 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Types.h"
 #include "Vector3.h"
+#include "MathTypes.h"
+#include "Matrix3x3.h"
+#include "Matrix4x4.h"
 
 namespace crown
 {
 
-struct Matrix3x3;
-struct Matrix4x4;
-
-/// Quaternion.
-///
-/// @a Note:
-/// This implementation uses the standard quaternion
-/// multiplication equation, so, the order of multiplication
-/// for multiple rotations is in a reverse fashion:
-/// p' = qpq^-1 where p is the point and q the rotation quaternion
-/// 
-/// p' = (ba)p(ba)^-1 where p is the point and (ba) the concatenation of two successive rotations
-/// In this case, the point p is first rotated by the quaternion a and then by the quaternion b.
-/// The transformation order is reversed.
-struct Quaternion
-{
-public:
+/// Negates the quaternion @a q and returns the result.
+Quaternion operator-(const Quaternion& q);
 
-	Vector3		v;
-	float		w;
+/// Multiplies the quaternions @a and @a b. (i.e. rotates first by @a a then by @a b).
+Quaternion operator*(Quaternion a, const Quaternion& b);
 
-public:
+/// Multiplies the quaternion @a a by the scalar @a k.
+Quaternion operator*(const Quaternion& a, float k);
 
-	/// Does nothing
-						Quaternion();
+namespace quaternion
+{
+	const Quaternion IDENTITY = Quaternion(0.0, 0.0, 0.0, 1.0);
 
-	/// Constructs from individual components.
-						Quaternion(float nx, float ny, float nz, float nw);
+	/// Returns the dot product between quaternions @a a and @a b.
+	float dot(const Quaternion& a, const Quaternion& b);
 
-	/// Builds the quaternion from an @a axis and a @a angle.							
-						Quaternion(const Vector3& axis, float angle);	
+	/// Returns the length of @a q.
+	float length(const Quaternion& q);
 
-	/// Negates the quaternion.
-	void				negate();
+	/// Returns the conjugate of quaternion @a q.
+	Quaternion conjugate(const Quaternion& q);
 
-	/// Builds the identity quaternion.
-	void				load_identity();
+	/// Returns the inverse of quaternion @a q.
+	Quaternion inverse(const Quaternion& q);
 
-	/// Returns the lenght of the quaternion.
-	float				length() const;		
+	/// Returns the quaternion @a q raised to the power of @a exp.
+	Quaternion power(const Quaternion& q, float exp);
 
-	/// Conjugates the quaternion.
-	void				conjugate();
+	/// Returns the Matrix3x3 representation of the quaternion @a q.
+	Matrix3x3 to_matrix3x3(const Quaternion& q);
 
-	/// Returns the quaternion's conjugate.
-	Quaternion			get_conjugate() const;
+	/// Returns the Matrix4x4 representation of the quaternion @a q.
+	Matrix4x4 to_matrix4x4(const Quaternion& q);
 
-	/// Quaternion's inverse				
-	Quaternion			get_inverse() const;
+} // namespace quaternion
 
-	Matrix3x3			to_matrix3x3() const;
-	Matrix4x4			to_matrix4x4() const;
+inline Quaternion operator-(const Quaternion& q)
+{
+	return Quaternion(-q.x, -q.y, -q.z, -q.w);
+}
 
-	/// Cross product
-	Quaternion			operator*(const Quaternion& b) const;
+inline Quaternion operator*(Quaternion a, const Quaternion& b)
+{
+	a *= b;
+	return a;
+}
 
-	/// Multiplication by a scalar		
-	Quaternion			operator*(const float& k) const;
+inline Quaternion operator*(const Quaternion& a, float k)
+{
+	return Quaternion(a.x * k, a.y * k, a.z * k, a.w * k);
+}
 
-	Quaternion			power(float exp);
+namespace quaternion
+{
+	//-----------------------------------------------------------------------------
+	inline float dot(const Quaternion& a, const Quaternion& b)
+	{
+		return a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z;
+	}
+
+	//-----------------------------------------------------------------------------
+	inline float length(const Quaternion& q)
+	{
+		return math::sqrt(q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z);
+	}
+
+	inline Quaternion conjugate(const Quaternion& q)
+	{
+		return Quaternion(-q.x, -q.y, -q.z, q.w);
+	}
+
+	inline Quaternion inverse(const Quaternion& q)
+	{
+		return conjugate(q) * (1.0 / length(q));
+	}
+
+	inline Quaternion power(const Quaternion& q, float exp)
+	{
+		if (math::abs(q.w) < 0.9999)
+		{
+			Quaternion tmp;
+			float alpha = math::acos(q.w); // alpha = theta/2
+			float new_alpha = alpha * exp;
+			tmp.w = math::cos(new_alpha);
+			float mult = math::sin(new_alpha) / math::sin(alpha);
+			tmp.x = q.x * mult;
+			tmp.y = q.y * mult;
+			tmp.z = q.z * mult;
+			return tmp;
+		}
+
+		return q;
+	}
+
+	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;
+	}
+
+	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;
+	}
+} // namespace quaternion
+
+//-----------------------------------------------------------------------------
+inline Quaternion::Quaternion()
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Quaternion::Quaternion(float nx, float ny, float nz, float nw)
+	: x(nx)
+	, y(ny)
+	, z(nz)
+	, w(nw)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline Quaternion::Quaternion(const Vector3& axis, float angle)
+	: x(axis.x * math::sin(angle * 0.5))
+	, y(axis.y * math::sin(angle * 0.5))
+	, z(axis.z * math::sin(angle * 0.5))
+	, w(math::cos(angle * 0.5))
+{
+}
 
-public:
+//-----------------------------------------------------------------------------
+inline Quaternion& Quaternion::operator*=(const Quaternion& a)
+{
+	w = w * a.w - x * a.x - y * a.y - z * a.z;
+	x = w * a.x + x * a.w + z * a.y - y * a.z;
+	y = w * a.y + y * a.w + x * a.z - z * a.x;
+	z = w * a.z + z * a.w + y * a.x - x * a.y;
 
-	static const Quaternion	IDENTITY;
-};
+	return *this;
+}
 
 } // namespace crown
 

+ 4 - 4
engine/lua/LuaGui.cpp

@@ -98,7 +98,7 @@ CE_EXPORT int gui_create_rect(lua_State* L)
 	const Vector3 pos = stack.get_vector3(2);
 	const Vector2 size = stack.get_vector2(3);
 	const Quaternion col = stack.get_quaternion(4);
-	const Color4 color(col.v.x, col.v.y, col.v.z, col.w);
+	const Color4 color(col.x, col.y, col.z, col.w);
 
 	GuiComponentId rect_id = gui->create_rect(pos, size, color);
 	stack.push_gui_component_id(rect_id);
@@ -116,7 +116,7 @@ CE_EXPORT int gui_update_rect(lua_State* L)
 	const Vector3 pos = stack.get_vector3(3);
 	const Vector2 size = stack.get_vector2(4);
 	const Quaternion col = stack.get_quaternion(4);
-	const Color4 color(col.v.x, col.v.y, col.v.z, col.w);
+	const Color4 color(col.x, col.y, col.z, col.w);
 
 	gui->update_rect(rect_id, pos, size, color);
 
@@ -146,7 +146,7 @@ CE_EXPORT int gui_create_triangle(lua_State* L)
 	const Vector2 p2 = stack.get_vector2(3);
 	const Vector2 p3 = stack.get_vector2(3);
 	const Quaternion col = stack.get_quaternion(4);
-	const Color4 color(col.v.x, col.v.y, col.v.z, col.w);
+	const Color4 color(col.x, col.y, col.z, col.w);
 
 	GuiComponentId triangle_id = gui->create_triangle(p1, p2, p3, color);
 
@@ -166,7 +166,7 @@ CE_EXPORT int gui_update_triangle(lua_State* L)
 	const Vector2 p2 = stack.get_vector2(4);
 	const Vector2 p3 = stack.get_vector2(5);
 	const Quaternion col = stack.get_quaternion(4);
-	const Color4 color(col.v.x, col.v.y, col.v.z, col.w);
+	const Color4 color(col.x, col.y, col.z, col.w);
 
 	gui->update_triangle(triangle_id, p1, p2, p3, color);
 

+ 33 - 36
engine/lua/LuaQuaternion.cpp

@@ -34,12 +34,12 @@ namespace crown
 {
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int quaternion(lua_State* L)
+CE_EXPORT int quaternion_new(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Vector3& v = stack.get_vector3(1);
-	float w = stack.get_float(2);
+	const Vector3& v = stack.get_vector3(1);
+	const float w = stack.get_float(2);
 
 	stack.push_quaternion(Quaternion(v, w));
 
@@ -51,23 +51,20 @@ CE_EXPORT int quaternion_negate(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
+	const Quaternion& q = stack.get_quaternion(1);
 
-	q.negate();
+	stack.push_quaternion(-q);
 
-	return 0;
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int quaternion_load_identity(lua_State* L)
+CE_EXPORT int quaternion_identity(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
-
-	q.load_identity();
-
-	return 0;
+	stack.push_quaternion(quaternion::IDENTITY);
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
@@ -75,9 +72,9 @@ CE_EXPORT int quaternion_length(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
+	const Quaternion& q = stack.get_quaternion(1);
 
-	stack.push_float(q.length());
+	stack.push_float(quaternion::length(q));
 
 	return 1;
 }
@@ -87,9 +84,9 @@ CE_EXPORT int quaternion_conjugate(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
+	const Quaternion& q = stack.get_quaternion(1);
 
-	stack.push_quaternion(q.get_conjugate());
+	stack.push_quaternion(quaternion::conjugate(q));
 
 	return 1;
 }
@@ -99,20 +96,20 @@ CE_EXPORT int quaternion_inverse(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
+	const Quaternion& q = stack.get_quaternion(1);
 
-	stack.push_quaternion(q.get_inverse());
+	stack.push_quaternion(quaternion::inverse(q));
 
 	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int quaternion_cross(lua_State* L)
+CE_EXPORT int quaternion_multiply(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q1 = stack.get_quaternion(1);
-	Quaternion& q2 = stack.get_quaternion(2);
+	const Quaternion& q1 = stack.get_quaternion(1);
+	const Quaternion& q2 = stack.get_quaternion(2);
 
 	stack.push_quaternion(q1 * q2);
 
@@ -120,12 +117,12 @@ CE_EXPORT int quaternion_cross(lua_State* L)
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int quaternion_multiply(lua_State* L)
+CE_EXPORT int quaternion_multiply_by_scalar(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
-	float k = stack.get_float(2);
+	const Quaternion& q = stack.get_quaternion(1);
+	const float k = stack.get_float(2);
 
 	stack.push_quaternion(q * k);
 
@@ -137,10 +134,10 @@ CE_EXPORT int quaternion_power(lua_State* L)
 {
 	LuaStack stack(L);
 
-	Quaternion& q = stack.get_quaternion(1);
-	float k = stack.get_float(2);
+	const Quaternion& q = stack.get_quaternion(1);
+	const float k = stack.get_float(2);
 
-	stack.push_quaternion(q.power(k));
+	stack.push_quaternion(quaternion::power(q, k));
 
 	return 1;
 }
@@ -148,15 +145,15 @@ CE_EXPORT int quaternion_power(lua_State* L)
 //-----------------------------------------------------------------------------
 void load_quaternion(LuaEnvironment& env)
 {
-	env.load_module_function("Quaternion", "new",			quaternion);
-	env.load_module_function("Quaternion", "negate",		quaternion_negate);
-	env.load_module_function("Quaternion", "load_identity",	quaternion_load_identity);
-	env.load_module_function("Quaternion", "length",		quaternion_length);
-	env.load_module_function("Quaternion", "conjugate",		quaternion_conjugate);
-	env.load_module_function("Quaternion", "inverse",		quaternion_inverse);
-	env.load_module_function("Quaternion", "cross",			quaternion_cross);
-	env.load_module_function("Quaternion", "multiply",		quaternion_multiply);
-	env.load_module_function("Quaternion", "pow",			quaternion_power);
+	env.load_module_function("Quaternion", "new",					quaternion_new);
+	env.load_module_function("Quaternion", "negate",				quaternion_negate);
+	env.load_module_function("Quaternion", "identity",				quaternion_identity);
+	env.load_module_function("Quaternion", "multiply",				quaternion_multiply);
+	env.load_module_function("Quaternion", "multiply_by_scalar",	quaternion_multiply_by_scalar);
+	env.load_module_function("Quaternion", "length",				quaternion_length);
+	env.load_module_function("Quaternion", "conjugate",				quaternion_conjugate);
+	env.load_module_function("Quaternion", "inverse",				quaternion_inverse);
+	env.load_module_function("Quaternion", "power",					quaternion_power);
 }
 
 } //namespace crown

+ 2 - 2
engine/lua/LuaSystem.cpp

@@ -54,7 +54,7 @@ extern int vector3_negate(lua_State* L);
 extern int vector2_new(lua_State* L);
 extern int vector3_new(lua_State* L);
 extern int matrix4x4(lua_State* L);
-extern int quaternion(lua_State* L);
+extern int quaternion_new(lua_State* L);
 
 //-----------------------------------------------------------------------------
 static int crown_lua_vector2_call(lua_State* L)
@@ -81,7 +81,7 @@ static int crown_lua_matrix4x4_call(lua_State* L)
 static int crown_lua_quaternion_call(lua_State* L)
 {
 	lua_remove(L, 1);
-	return quaternion(L);
+	return quaternion_new(L);
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 1
engine/lua/LuaWorld.cpp

@@ -42,7 +42,7 @@ CE_EXPORT int world_spawn_unit(lua_State* L)
 	const char* name = stack.get_string(2);
 
 	const Vector3& pos = stack.num_args() > 2 ? stack.get_vector3(3) : vector3::ZERO;
-	const Quaternion& rot = stack.num_args() > 3 ? stack.get_quaternion(4) : Quaternion::IDENTITY;
+	const Quaternion& rot = stack.num_args() > 3 ? stack.get_quaternion(4) : quaternion::IDENTITY;
 
 	UnitId unit = world->spawn_unit(name, pos, rot);
 

+ 2 - 2
engine/physics/PhysicsWorld.cpp

@@ -262,7 +262,7 @@ PhysicsWorld::~PhysicsWorld()
 ActorId	PhysicsWorld::create_actor(const PhysicsResource* res, const uint32_t index, SceneGraph& sg, int32_t node, Unit* unit)
 {
 	PhysicsConfigResource* config = (PhysicsConfigResource*) device()->resource_manager()->lookup("physics_config", "global");
-	Actor* actor = CE_NEW(m_actors_pool, Actor)(res, config, index, physics_system::s_physics, physics_system::s_cooking, m_scene, sg, node, unit, vector3::ZERO, Quaternion::IDENTITY);
+	Actor* actor = CE_NEW(m_actors_pool, Actor)(res, config, index, physics_system::s_physics, physics_system::s_cooking, m_scene, sg, node, unit, vector3::ZERO, quaternion::IDENTITY);
 	return m_actors.create(actor);
 }
 
@@ -389,7 +389,7 @@ void PhysicsWorld::clear_kinematic(ActorId id)
 void PhysicsWorld::overlap_test(const char* callback, CollisionType::Enum filter, ShapeType::Enum type,
 								const Vector3& pos, const Quaternion& rot, const Vector3& size, Array<Actor*>& actors)
 {
-	PxTransform transform(PxVec3(pos.x, pos.y, pos.z), PxQuat(rot.v.x, rot.v.y, rot.v.z, rot.w));
+	PxTransform transform(PxVec3(pos.x, pos.y, pos.z), PxQuat(rot.x, rot.y, rot.z, rot.w));
 
 	switch(type)
 	{

+ 1 - 1
engine/world/World.h

@@ -62,7 +62,7 @@ public:
 	WorldId								id() const;
 	void								set_id(WorldId id);
 
-	UnitId								spawn_unit(const char* name, const Vector3& pos = vector3::ZERO, const Quaternion& rot = Quaternion::IDENTITY);
+	UnitId								spawn_unit(const char* name, const Vector3& pos = vector3::ZERO, const Quaternion& rot = quaternion::IDENTITY);
 	UnitId								spawn_unit(const char* name, UnitResource* ur, const Vector3& pos, const Quaternion& rot);
 	void								destroy_unit(UnitId id);
 	void								reload_units(UnitResource* old_ur, UnitResource* new_ur);