Explorar o código

Math: Refactor the Euler class

Panagiotis Christopoulos Charitos hai 1 semana
pai
achega
3f65d0e22f

+ 1 - 1
AnKi/Editor/EditorUi.cpp

@@ -663,7 +663,7 @@ void EditorUi::sceneNodePropertiesWindow()
 			dummyButton(id++);
 
 			const Euler rot(node.getLocalRotation());
-			F32 localRotation[3] = {toDegrees(rot.x()), toDegrees(rot.y()), toDegrees(rot.z())};
+			F32 localRotation[3] = {toDegrees(rot.x), toDegrees(rot.y), toDegrees(rot.z)};
 			if(ImGui::DragFloat3(ICON_MDI_ROTATE_ORBIT " Rotation", localRotation, 0.25f, -360.0f, 360.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp))
 			{
 				const Euler rot(toRad(localRotation[0]), toRad(localRotation[1]), toRad(localRotation[2]));

+ 73 - 100
AnKi/Math/Euler.h

@@ -9,58 +9,85 @@
 
 namespace anki {
 
-/// @addtogroup math
-/// @{
-
-/// Euler angles. Used for rotations. It cannot describe a rotation accurately though.
-/// The 'x' denotes a rotation around x axis, 'y' around y axis and 'z' around z axis.
+// Euler angles. Used for rotations. It cannot describe a rotation accurately though
 template<typename T>
 class TEuler
 {
 public:
-	/// @name Constructors
-	/// @{
-	TEuler()
+	// Data //
+
+	// Skip some warnings cause we really nead anonymous structs inside unions
+#if ANKI_COMPILER_MSVC
+#	pragma warning(push)
+#	pragma warning(disable : 4201)
+#elif ANKI_COMPILER_GCC_COMPATIBLE
+#	pragma GCC diagnostic push
+#	pragma GCC diagnostic ignored "-Wgnu-anonymous-struct"
+#	pragma GCC diagnostic ignored "-Wnested-anon-types"
+#endif
+	union
+	{
+		struct
+		{
+			T x; // Rotation around the x axiz
+			T y; // Rotation around the y axiz
+			T z; // Rotation around the z axiz
+		};
+
+		Array<T, 3> m_arr;
+	};
+#if ANKI_COMPILER_MSVC
+#	pragma warning(pop)
+#elif ANKI_COMPILER_GCC_COMPATIBLE
+#	pragma GCC diagnostic pop
+#endif
+
+	// Constructors //
+
+	constexpr TEuler()
+		: x(0)
+		, y(0)
+		, z(0)
 	{
 	}
 
 	constexpr TEuler(const T x_, const T y_, const T z_)
+		: x(x_)
+		, y(y_)
+		, z(z_)
 	{
-		m_vec.m_x = x_;
-		m_vec.m_y = y_;
-		m_vec.m_z = z_;
 	}
 
 	constexpr TEuler(const TEuler& b)
+		: x(b.x)
+		, y(b.y)
+		, z(b.z)
 	{
-		x() = b.x();
-		y() = b.y();
-		z() = b.z();
 	}
 
 	explicit TEuler(const TQuat<T>& q)
 	{
-		const T test = q.x() * q.y() + q.z() * q.w();
+		const T test = q.x * q.y + q.z * q.w;
 		if(test > T(0.499))
 		{
-			y() = T(2) * atan2<T>(q.x(), q.w());
-			z() = kPi / T(2);
-			x() = T(0);
+			y = T(2) * atan2<T>(q.x, q.w);
+			z = kPi / T(2);
+			x = T(0);
 		}
 		else if(test < T(-0.499))
 		{
-			y() = -T(2) * atan2<T>(q.x(), q.w());
-			z() = -kPi / T(2);
-			x() = T(0);
+			y = -T(2) * atan2<T>(q.x, q.w);
+			z = -kPi / T(2);
+			x = T(0);
 		}
 		else
 		{
-			const T sqx = q.x() * q.x();
-			const T sqy = q.y() * q.y();
-			const T sqz = q.z() * q.z();
-			y() = atan2<T>(T(2) * q.y() * q.w() - T(2) * q.x() * q.z(), T(1) - T(2) * sqy - T(2) * sqz);
-			z() = asin<T>(T(2) * test);
-			x() = atan2<T>(T(2) * q.x() * q.w() - T(2) * q.y() * q.z(), T(1) - T(2) * sqx - T(2) * sqz);
+			const T sqx = q.x * q.x;
+			const T sqy = q.y * q.y;
+			const T sqz = q.z * q.z;
+			y = atan2<T>(T(2) * q.y * q.w - T(2) * q.x * q.z, T(1) - T(2) * sqy - T(2) * sqz);
+			z = asin<T>(T(2) * test);
+			x = atan2<T>(T(2) * q.x * q.w - T(2) * q.y * q.z, T(1) - T(2) * sqx - T(2) * sqz);
 		}
 	}
 
@@ -69,28 +96,27 @@ public:
 		if(m3(1, 0) > T(0.998))
 		{
 			// Singularity at north pole
-			y() = atan2(m3(0, 2), m3(2, 2));
-			z() = kPi / T(2);
-			x() = T(0);
+			y = atan2(m3(0, 2), m3(2, 2));
+			z = kPi / T(2);
+			x = T(0);
 		}
 		else if(m3(1, 0) < T(-0.998))
 		{
 			// Singularity at south pole
-			y() = atan2(m3(0, 2), m3(2, 2));
-			z() = -kPi / T(2);
-			x() = T(0);
+			y = atan2(m3(0, 2), m3(2, 2));
+			z = -kPi / T(2);
+			x = T(0);
 		}
 		else
 		{
-			y() = atan2(-m3(2, 0), m3(0, 0));
-			z() = asin(m3(1, 0));
-			x() = atan2(-m3(1, 2), m3(1, 1));
+			y = atan2(-m3(2, 0), m3(0, 0));
+			z = asin(m3(1, 0));
+			x = atan2(-m3(1, 2), m3(1, 1));
 		}
 	}
-	/// @}
 
-	/// @name Accessors
-	/// @{
+	// Accessors //
+
 	T& operator[](const U i)
 	{
 		return m_arr[i];
@@ -101,52 +127,19 @@ public:
 		return m_arr[i];
 	}
 
-	T& x()
-	{
-		return m_vec.m_x;
-	}
-
-	T x() const
-	{
-		return m_vec.m_x;
-	}
-
-	T& y()
-	{
-		return m_vec.m_y;
-	}
-
-	T y() const
-	{
-		return m_vec.m_y;
-	}
-
-	T& z()
-	{
-		return m_vec.m_z;
-	}
-
-	T z() const
-	{
-		return m_vec.m_z;
-	}
-	/// @}
+	// Operators with same type //
 
-	/// @name Operators with same type
-	/// @{
 	TEuler& operator=(const TEuler& b)
 	{
-		x() = b.x();
-		y() = b.y();
-		z() = b.z();
+		x = b.x;
+		y = b.y;
+		z = b.z;
 		return *this;
 	}
-	/// @}
 
-	/// @name Other
-	/// @{
+	// Other //
 
-	/// Return lerp(this, v1, t)
+	// Return lerp(this, v1, t)
 	[[nodiscard]] TEuler lerp(const TEuler& v1, T t) const
 	{
 		TEuler out;
@@ -159,36 +152,16 @@ public:
 
 	String toString() const requires(std::is_floating_point<T>::value)
 	{
-		return String().sprintf("%f %f %f", m_vec.m_x, m_vec.m_y, m_vec.m_z);
+		return String().sprintf("%f %f %f", x, y, z);
 	}
 
 	String toStringDegrees() const requires(std::is_floating_point<T>::value)
 	{
-		return String().sprintf("%f %f %f", toDegrees(m_vec.m_x), toDegrees(m_vec.m_y), toDegrees(m_vec.m_z));
+		return String().sprintf("%f %f %f", toDegrees(x), toDegrees(y), toDegrees(z));
 	}
-	/// @}
-
-private:
-	/// @name Data
-	/// @{
-	struct Vec
-	{
-		T m_x, m_y, m_z;
-	};
-
-	union
-	{
-		Vec m_vec;
-		Array<T, 3> m_arr;
-	};
-	/// @}
 };
 
-/// F32 Euler angles
 using Euler = TEuler<F32>;
-
-/// F64 Euler angles
 using DEuler = TEuler<F64>;
-/// @}
 
 } // end namespace anki

+ 0 - 1
AnKi/Math/Functions.h

@@ -7,7 +7,6 @@
 
 #include <AnKi/Util/Functions.h>
 #include <cmath>
-#include <cstdlib>
 
 namespace anki {
 

+ 3 - 3
AnKi/Math/Mat.h

@@ -131,9 +131,9 @@ public:
 	{
 		TMat& m = *this;
 		T ch, sh, ca, sa, cb, sb;
-		sinCos(e.y(), sh, ch);
-		sinCos(e.z(), sa, ca);
-		sinCos(e.x(), sb, cb);
+		sinCos(e.y, sh, ch);
+		sinCos(e.z, sa, ca);
+		sinCos(e.x, sb, cb);
 
 		m(0, 0) = ch * ca;
 		m(0, 1) = sh * sb - ch * sa * cb;

+ 3 - 3
AnKi/Math/Quat.h

@@ -135,13 +135,13 @@ public:
 	explicit TQuat(const TEuler<T>& eu)
 	{
 		T cx, sx;
-		sinCos(eu.y() * T(0.5), sx, cx);
+		sinCos(eu.y * T(0.5), sx, cx);
 
 		T cy, sy;
-		sinCos(eu.z() * T(0.5), sy, cy);
+		sinCos(eu.z * T(0.5), sy, cy);
 
 		T cz, sz;
-		sinCos(eu.x() * T(0.5), sz, cz);
+		sinCos(eu.x * T(0.5), sz, cz);
 
 		const T cxcy = cx * cy;
 		const T sxsy = sx * sy;

+ 4 - 4
AnKi/Scene/EditorUiNode.cpp

@@ -102,10 +102,10 @@ void EditorUiNode::frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_u
 		{
 			const Second dt = crntTime - prevUpdateTime;
 			Euler angles(mover.getLocalRotation().getRotationPart());
-			angles.x() += velocity.y() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
-			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-			angles.y() += -velocity.x() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
-			angles.z() = 0.0f;
+			angles.x += velocity.y() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
+			angles.x = clamp(angles.x, toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y += -velocity.x() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
+			angles.z = 0.0f;
 			mover.setLocalRotation(Mat3(angles));
 		}
 	}

+ 8 - 8
Samples/Common/SampleApp.cpp

@@ -245,10 +245,10 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 		if(velocity != Vec2(0.0))
 		{
 			Euler angles(mover->getLocalRotation().getRotationPart());
-			angles.x() += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-			angles.y() += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.z() = 0.0f;
+			angles.x += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.x = clamp(angles.x, toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.z = 0.0f;
 			mover->setLocalRotation(Mat3(angles));
 		}
 
@@ -275,10 +275,10 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 			velocity *= 0.3f;
 
 			Euler angles(mover->getLocalRotation().getRotationPart());
-			angles.x() += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-			angles.y() += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.z() = 0.0f;
+			angles.x += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.x = clamp(angles.x, toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.z = 0.0f;
 			mover->setLocalRotation(Mat3(angles));
 		}
 

+ 8 - 8
Sandbox/Main.cpp

@@ -263,10 +263,10 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 		if(velocity != Vec2(0.0))
 		{
 			Euler angles(mover->getLocalRotation().getRotationPart());
-			angles.x() += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-			angles.y() += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.z() = 0.0f;
+			angles.x += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.x = clamp(angles.x, toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.z = 0.0f;
 			mover->setLocalRotation(Mat3(angles));
 		}
 
@@ -293,10 +293,10 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 			velocity *= 0.3f;
 
 			Euler angles(mover->getLocalRotation().getRotationPart());
-			angles.x() += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-			angles.y() += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
-			angles.z() = 0.0f;
+			angles.x += velocity.y() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.x = clamp(angles.x, toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * MOUSE_SENSITIVITY;
+			angles.z = 0.0f;
 			mover->setLocalRotation(Mat3(angles));
 		}