Browse Source

Improved math operation with epsilon support

Léo Terziman 12 năm trước cách đây
mục cha
commit
365b3aa412

+ 5 - 15
code/ColladaExporter.cpp

@@ -115,21 +115,11 @@ void ColladaExporter::WriteFile()
 	mOutput << "</COLLADA>" << endstr;
 }
 
-// ------------------------------------------------------------------------------------------------
-// Utility function to test equality of scalars and quaternions 
-inline bool equal(double a, double b, double epsilon) {
-	return std::abs(a - b) <= epsilon;
-}
-
-inline bool equal(aiQuaternion a, aiQuaternion b, double epsilon) {
-	return equal(a.x, b.x, epsilon) && equal(a.y, b.y, epsilon) && equal(a.z, b.z, epsilon) && equal(a.w, b.w, epsilon);
-}
-
 // ------------------------------------------------------------------------------------------------
 // Writes the asset header
 void ColladaExporter::WriteHeader()
 {
-	static const double epsilon = 0.000001;
+	static const float epsilon = 0.000001f;
 	static const aiQuaternion x_rot(aiMatrix3x3( 
 		0, -1,  0,
 		1,  0,  0,
@@ -156,18 +146,18 @@ void ColladaExporter::WriteHeader()
 	mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
 
 	float scale = 1.0;
-	if(equal(scaling.x, scaling.y, epsilon) && equal(scaling.x, scaling.z, epsilon) && equal(scaling.y, scaling.z, epsilon)) {
+	if(std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
 		scale = scaling.x;
 	} else {
 		DefaultLogger::get()->warn("Collada: Unable to compute the global scale of the scene " + scene_name);
 	}
 
 	std::string up_axis = "Y_UP";
-	if(equal(rotation, x_rot, epsilon)) {
+	if(rotation.Equal(x_rot, epsilon)) {
 		up_axis = "X_UP";
-	} else if(equal(rotation, y_rot, epsilon)) {
+	} else if(rotation.Equal(y_rot, epsilon)) {
 		up_axis = "Y_UP";
-	} else if(equal(rotation, z_rot, epsilon)) {
+	} else if(rotation.Equal(z_rot, epsilon)) {
 		up_axis = "Z_UP";
 	} else {
 		DefaultLogger::get()->warn("Collada: Unable to compute the up axis of the scene " + scene_name);

+ 4 - 2
include/assimp/matrix3x3.h

@@ -90,8 +90,10 @@ public:
 	const TReal* operator[] (unsigned int p_iIndex) const;
 
 	// comparison operators
-	bool operator== (const aiMatrix4x4t<TReal> m) const;
-	bool operator!= (const aiMatrix4x4t<TReal> m) const;
+	bool operator== (const aiMatrix4x4t<TReal>& m) const;
+	bool operator!= (const aiMatrix4x4t<TReal>& m) const;
+
+	bool Equal(const aiMatrix4x4t<TReal>& m, float epsilon = 1e-6) const;
 
 	template <typename TOther>
 	operator aiMatrix3x3t<TOther> () const;

+ 17 - 2
include/assimp/matrix3x3.inl

@@ -113,7 +113,7 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
+inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
 {
 	return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
 		   b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
@@ -122,11 +122,26 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
+inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
 {
 	return !(*this == m);
 }
 
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, float epsilon) const {
+	return
+		std::abs(a1 - m.a1) <= epsilon &&
+		std::abs(a2 - m.a2) <= epsilon &&
+		std::abs(a3 - m.a3) <= epsilon &&
+		std::abs(b1 - m.b1) <= epsilon &&
+		std::abs(b2 - m.b2) <= epsilon &&
+		std::abs(b3 - m.b3) <= epsilon &&
+		std::abs(c1 - m.c1) <= epsilon &&
+		std::abs(c2 - m.c2) <= epsilon &&
+		std::abs(c3 - m.c3) <= epsilon;
+}
+
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()

+ 4 - 2
include/assimp/matrix4x4.h

@@ -94,8 +94,10 @@ public:
 	const TReal* operator[] (unsigned int p_iIndex) const;
 
 	// comparison operators
-	bool operator== (const aiMatrix4x4t m) const;
-	bool operator!= (const aiMatrix4x4t m) const;
+	bool operator== (const aiMatrix4x4t& m) const;
+	bool operator!= (const aiMatrix4x4t& m) const;
+
+	bool Equal(const aiMatrix4x4t& m, float epsilon = 1e-6) const;
 
 	// matrix multiplication. 
 	aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);

+ 24 - 2
include/assimp/matrix4x4.inl

@@ -254,7 +254,7 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
+inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
 {
 	return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
 			b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
@@ -264,11 +264,33 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
+inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
 {
 	return !(*this == m);
 }
 
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, float epsilon) const {
+	return
+		std::abs(a1 - m.a1) <= epsilon &&
+		std::abs(a2 - m.a2) <= epsilon &&
+		std::abs(a3 - m.a3) <= epsilon &&
+		std::abs(a4 - m.a4) <= epsilon &&
+		std::abs(b1 - m.b1) <= epsilon &&
+		std::abs(b2 - m.b2) <= epsilon &&
+		std::abs(b3 - m.b3) <= epsilon &&
+		std::abs(b4 - m.b4) <= epsilon &&
+		std::abs(c1 - m.c1) <= epsilon &&
+		std::abs(c2 - m.c2) <= epsilon &&
+		std::abs(c3 - m.c3) <= epsilon &&
+		std::abs(c4 - m.c4) <= epsilon &&
+		std::abs(d1 - m.d1) <= epsilon &&
+		std::abs(d2 - m.d2) <= epsilon &&
+		std::abs(d3 - m.d3) <= epsilon &&
+		std::abs(d4 - m.d4) <= epsilon;
+}
+
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
 inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,

+ 2 - 0
include/assimp/quaternion.h

@@ -79,6 +79,8 @@ public:
 	bool operator== (const aiQuaterniont& o) const;
 	bool operator!= (const aiQuaterniont& o) const;
 
+	bool Equal(const aiQuaterniont& o, float epsilon = 1e-6) const;
+
 public:
 
 	/** Normalize the quaternion */

+ 9 - 1
include/assimp/quaternion.inl

@@ -62,7 +62,15 @@ bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
 	return !(*this == o);
 }
 
-
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, float epsilon) const {
+	return
+		std::abs(x - o.x) <= epsilon &&
+		std::abs(y - o.y) <= epsilon &&
+		std::abs(z - o.z) <= epsilon &&
+		std::abs(w - o.w) <= epsilon;
+}
 
 // ---------------------------------------------------------------------------
 // Constructs a quaternion from a rotation matrix

+ 2 - 0
include/assimp/vector2.h

@@ -83,6 +83,8 @@ public:
 	bool operator== (const aiVector2t& other) const;
 	bool operator!= (const aiVector2t& other) const;
 
+	bool Equal(const aiVector2t& other, float epsilon = 1e-6) const;
+
 	aiVector2t& operator= (TReal f);
 	const aiVector2t SymMul(const aiVector2t& o);
 

+ 8 - 0
include/assimp/vector2.inl

@@ -131,6 +131,14 @@ bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const {
 	return x != other.x || y != other.y;
 }
 
+// ---------------------------------------------------------------------------
+template<typename TReal>
+bool aiVector2t<TReal>::Equal(const aiVector2t& other, float epsilon) const {
+	return
+		std::abs(x - other.x) <= epsilon &&
+		std::abs(y - other.y) <= epsilon;
+}
+
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
 aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f)	{

+ 2 - 0
include/assimp/vector3.h

@@ -86,6 +86,8 @@ public:
 	bool operator== (const aiVector3t& other) const;
 	bool operator!= (const aiVector3t& other) const;
 
+	bool Equal(const aiVector3t& other, float epsilon = 1e-6) const;
+
 	template <typename TOther>
 	operator aiVector3t<TOther> () const;
 

+ 8 - 0
include/assimp/vector3.inl

@@ -147,6 +147,14 @@ template <typename TReal>
 AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const {
 	return x != other.x || y != other.y || z != other.z;
 }
+// ---------------------------------------------------------------------------
+template<typename TReal>
+AI_FORCE_INLINE bool aiVector3t<TReal>::Equal(const aiVector3t<TReal>& other, float epsilon) const {
+	return
+		std::abs(x - other.x) <= epsilon &&
+		std::abs(y - other.y) <= epsilon &&
+		std::abs(z - other.z) <= epsilon;
+}
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
 AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {