- 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
pull/1/head
ulfjorensen 2009-03-05 14:27:06 +00:00
parent c42611ea5e
commit 5c0a259a63
4 changed files with 52 additions and 3 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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)
{}
{}
// -------------------------------------------------------------------

View File

@ -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 &&