Преглед изворни кода

- added proper inversion of 3x3 matrices
- Bugfix: aiMatrix4x4::IsIdentity() had a classical Copy&Paste error. Thanks to Michael Schifferling for pointing it out.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@354 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

ulfjorensen пре 16 година
родитељ
комит
5c0a259a63
4 измењених фајлова са 52 додато и 3 уклоњено
  1. 8 0
      include/aiMatrix3x3.h
  2. 40 0
      include/aiMatrix3x3.inl
  3. 3 2
      include/aiMatrix4x4.h
  4. 1 1
      include/aiMatrix4x4.inl

+ 8 - 0
include/aiMatrix3x3.h

@@ -103,6 +103,14 @@ public:
 	 */
 	aiMatrix3x3& Transpose();
 
+	// -------------------------------------------------------------------
+	/** @brief Invert the matrix.
+	 *  If the matrix is not invertible all elements are set to qnan.
+	 *  Beware, use (f != f) to check whether a float f is qnan.
+	 */
+	aiMatrix3x3& Inverse();
+	float Determinant() const;
+
 public:
 	// -------------------------------------------------------------------
 	/** @brief Returns a rotation matrix for a rotation around z

+ 40 - 0
include/aiMatrix3x3.inl

@@ -9,6 +9,7 @@
 #ifdef __cplusplus
 #include "aiMatrix4x4.h"
 #include <algorithm>
+#include <limits>
 
 // ------------------------------------------------------------------------------------------------
 // Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
@@ -78,6 +79,45 @@ inline aiMatrix3x3& aiMatrix3x3::Transpose()
 	return *this;
 }
 
+// ----------------------------------------------------------------------------------------
+inline float aiMatrix3x3::Determinant() const
+{
+	return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
+}
+
+// ----------------------------------------------------------------------------------------
+inline aiMatrix3x3& aiMatrix3x3::Inverse()
+{
+	// Compute the reciprocal determinant
+	float det = Determinant();
+	if(det == 0.0f) 
+	{
+		// Matrix not invertible. Setting all elements to nan is not really
+		// correct in a mathematical sense but it is easy to debug for the
+		// programmer.
+		const float nan = std::numeric_limits<float>::quiet_NaN();
+		*this = aiMatrix3x3( nan,nan,nan,nan,nan,nan,nan,nan,nan);
+
+		return *this;
+	}
+
+	float invdet = 1.0f / det;
+
+	aiMatrix3x3 res;
+	res.a1 = invdet  * (b2 * c3 - b3 * c2);
+	res.a2 = -invdet * (a2 * c3 - a3 * c2);
+	res.a3 = invdet  * (a2 * b3 - a3 * b2);
+	res.b1 = -invdet * (b1 * c3 - b3 * c1);
+	res.b2 = invdet  * (a1 * c3 - a3 * c1);
+	res.b3 = -invdet * (a1 * b3 - a3 * b1);
+	res.c1 = invdet  * (b1 * c2 - b2 * c1);
+	res.c2 = -invdet * (a1 * c2 - a2 * c1);
+	res.c3 = invdet  * (a1 * b2 - a2 * b1);
+	*this = res;
+
+	return *this;
+}
+
 // ------------------------------------------------------------------------------------------------
 inline aiMatrix3x3& aiMatrix3x3::RotationZ(float a, aiMatrix3x3& out)
 {

+ 3 - 2
include/aiMatrix4x4.h

@@ -70,7 +70,8 @@ struct aiMatrix4x4
 		a1(1.0f), a2(0.0f), a3(0.0f), a4(0.0f), 
 		b1(0.0f), b2(1.0f), b3(0.0f), b4(0.0f), 
 		c1(0.0f), c2(0.0f), c3(1.0f), c4(0.0f),
-		d1(0.0f), d2(0.0f), d3(0.0f), d4(1.0f){}
+		d1(0.0f), d2(0.0f), d3(0.0f), d4(1.0f)
+	{}
 
 		// from single values
 	aiMatrix4x4 (	float _a1, float _a2, float _a3, float _a4,
@@ -81,7 +82,7 @@ struct aiMatrix4x4
 		b1(_b1), b2(_b2), b3(_b3), b4(_b4), 
 		c1(_c1), c2(_c2), c3(_c3), c4(_c4),
 		d1(_d1), d2(_d2), d3(_d3), d4(_d4)
-		{}
+	{}
 
 
 	// -------------------------------------------------------------------

+ 1 - 1
include/aiMatrix4x4.inl

@@ -304,7 +304,7 @@ inline bool aiMatrix4x4::IsIdentity() const
 			b4 <= epsilon && b4 >= -epsilon &&
 			c1 <= epsilon && c1 >= -epsilon &&
 			c2 <= epsilon && c2 >= -epsilon &&
-			c3 <= epsilon && c3 >= -epsilon &&
+			c4 <= epsilon && c4 >= -epsilon &&
 			d1 <= epsilon && d1 >= -epsilon &&
 			d2 <= epsilon && d2 >= -epsilon &&
 			d3 <= epsilon && d3 >= -epsilon &&