Commit 6f1532e2 authored by hybrid's avatar hybrid

Added orthogonality check in matrix class, based on a patch by Halifax. Also...

Added orthogonality check in matrix class, based on a patch by Halifax. Also added some (rather trivial) testcases, corner cases have to be identified...

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2029 dfc29bdd-3216-0410-991c-e03cc46cb475
parent b95c2fcb
...@@ -195,10 +195,16 @@ namespace core ...@@ -195,10 +195,16 @@ namespace core
} }
//! returns if a equals zero, taking rounding errors into account
inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_64)
{
return fabs(a) <= tolerance;
}
//! returns if a equals zero, taking rounding errors into account //! returns if a equals zero, taking rounding errors into account
inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_32) inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_32)
{ {
return fabsf ( a ) <= tolerance; return fabsf(a) <= tolerance;
} }
//! returns if a equals zero, taking rounding errors into account //! returns if a equals zero, taking rounding errors into account
...@@ -213,21 +219,21 @@ namespace core ...@@ -213,21 +219,21 @@ namespace core
return a <= tolerance; return a <= tolerance;
} }
inline s32 s32_min ( s32 a, s32 b) inline s32 s32_min(s32 a, s32 b)
{ {
s32 mask = (a - b) >> 31; const s32 mask = (a - b) >> 31;
return (a & mask) | (b & ~mask); return (a & mask) | (b & ~mask);
} }
inline s32 s32_max ( s32 a, s32 b) inline s32 s32_max(s32 a, s32 b)
{ {
s32 mask = (a - b) >> 31; const s32 mask = (a - b) >> 31;
return (b & mask) | (a & ~mask); return (b & mask) | (a & ~mask);
} }
inline s32 s32_clamp (s32 value, s32 low, s32 high) inline s32 s32_clamp (s32 value, s32 low, s32 high)
{ {
return s32_min (s32_max(value,low), high); return s32_min(s32_max(value,low), high);
} }
/* /*
......
...@@ -110,6 +110,9 @@ namespace core ...@@ -110,6 +110,9 @@ namespace core
//! Returns true if the matrix is the identity matrix //! Returns true if the matrix is the identity matrix
inline bool isIdentity() const; inline bool isIdentity() const;
//! Returns true if the matrix is orthogonal
inline bool isOrthogonal() const;
//! Returns true if the matrix is the identity matrix //! Returns true if the matrix is the identity matrix
bool isIdentity_integer_base () const; bool isIdentity_integer_base () const;
...@@ -818,6 +821,31 @@ namespace core ...@@ -818,6 +821,31 @@ namespace core
return true; return true;
} }
/* Check orthogonality of matrix. */
template <class T>
inline bool CMatrix4<T>::isOrthogonal() const
{
T dp = M[0] * M[4 ] + M[1] * M[5 ] + M[2 ] * M[6 ] + M[3 ] * M[7 ];
if (!iszero(dp))
return false;
dp = M[0] * M[8 ] + M[1] * M[9 ] + M[2 ] * M[10] + M[3 ] * M[11];
if (!iszero(dp))
return false;
dp = M[0] * M[12] + M[1] * M[13] + M[2 ] * M[14] + M[3 ] * M[15];
if (!iszero(dp))
return false;
dp = M[4] * M[8 ] + M[5] * M[9 ] + M[6 ] * M[10] + M[7 ] * M[11];
if (!iszero(dp))
return false;
dp = M[4] * M[12] + M[5] * M[13] + M[6 ] * M[14] + M[7 ] * M[15];
if (!iszero(dp))
return false;
dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15];
return (iszero(dp));
}
/* /*
doesn't solve floating range problems.. doesn't solve floating range problems..
but takes care on +/- 0 on translation because we are changing it.. but takes care on +/- 0 on translation because we are changing it..
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
bool irrCoreEquals(void) bool irrCoreEquals(void)
{ {
// float tests
if(!irr::core::equals(99.f, 99.f)) if(!irr::core::equals(99.f, 99.f))
{ {
logTestString("irr::core::equals(f32, f32 (, default)) failed.\n"); logTestString("irr::core::equals(f32, f32 (, default)) failed.\n");
...@@ -19,6 +20,7 @@ bool irrCoreEquals(void) ...@@ -19,6 +20,7 @@ bool irrCoreEquals(void)
return false; return false;
} }
// double tests
if(!irr::core::equals(99.0, 99.0)) if(!irr::core::equals(99.0, 99.0))
{ {
logTestString("irr::core::equals(f64, f64 (,default)) failed.\n"); logTestString("irr::core::equals(f64, f64 (,default)) failed.\n");
...@@ -31,6 +33,7 @@ bool irrCoreEquals(void) ...@@ -31,6 +33,7 @@ bool irrCoreEquals(void)
return false; return false;
} }
// int tests
if(!irr::core::equals(99, 99)) if(!irr::core::equals(99, 99))
{ {
logTestString("irr::core::equals(s32, s32 (,default)) failed.\n"); logTestString("irr::core::equals(s32, s32 (,default)) failed.\n");
...@@ -79,6 +82,65 @@ bool irrCoreEquals(void) ...@@ -79,6 +82,65 @@ bool irrCoreEquals(void)
return false; return false;
} }
// iszero is a specialized equals method
// float tests
if(!irr::core::iszero(.0f))
{
logTestString("irr::core::iszero(f32 (,default)) failed.\n");
return false;
}
if(irr::core::iszero(-1.0f))
{
logTestString("irr::core::iszero(f32 (,default)) failed.\n");
return false;
}
if(!irr::core::iszero(1.0f, 1.0f))
{
logTestString("irr::core::iszero(f32, f32) failed.\n");
return false;
}
// double tests
if(!irr::core::iszero(0.0))
{
logTestString("irr::core::iszero(f64 (,default)) failed.\n");
return false;
}
if(irr::core::iszero(-1.0))
{
logTestString("irr::core::iszero(f64 (,default)) failed.\n");
return false;
}
if(!irr::core::iszero(-2.0, -2.0))
{
logTestString("irr::core::iszero(f64, f64) failed.\n");
return false;
}
// int tests
if(!irr::core::iszero(0))
{
logTestString("irr::core::iszero(s32 (,default)) failed.\n");
return false;
}
if(irr::core::iszero(-1))
{
logTestString("irr::core::iszero(s32 (,default)) failed.\n");
return false;
}
if(!irr::core::iszero(1, 1))
{
logTestString("irr::core::iszero(s32, s32) failed.\n");
return false;
}
return true; return true;
} }
\ No newline at end of file
...@@ -56,6 +56,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -56,6 +56,7 @@ int main(int argumentCount, char * arguments[])
extern bool textureRenderStates(void); extern bool textureRenderStates(void);
extern bool burningsVideo(void); extern bool burningsVideo(void);
extern bool makeColorKeyTexture(void); extern bool makeColorKeyTexture(void);
extern bool matrixOps(void);
typedef struct _STest typedef struct _STest
{ {
...@@ -71,6 +72,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -71,6 +72,7 @@ int main(int argumentCount, char * arguments[])
TEST(exports), TEST(exports),
TEST(testVector3d), TEST(testVector3d),
TEST(testVector2d), TEST(testVector2d),
TEST(matrixOps),
TEST(planeMatrix), TEST(planeMatrix),
TEST(fast_atof), TEST(fast_atof),
TEST(line2dIntersectWith), TEST(line2dIntersectWith),
......
// Copyright (C) 2008 Colin MacDonald
// No rights reserved: this software is in the public domain.
#include "testUtils.h"
#include "irrlicht.h"
#include <assert.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
// Test some matrix ops.
bool matrixOps(void)
{
matrix4 rotationMatrix;
if (!rotationMatrix.isOrthogonal())
{
logTestString("irr::core::matrix4::isOrthogonal() failed with Identity.\n");
return false;
}
rotationMatrix.setRotationDegrees(vector3df(90, 0, 0));
if (rotationMatrix.isOrthogonal())
{
logTestString("irr::core::matrix4::isOrthogonal() failed with rotation.\n");
return false;
}
matrix4 translationMatrix;
translationMatrix.setTranslation(vector3df(0, 3, 0));
if (translationMatrix.isOrthogonal())
{
logTestString("irr::core::matrix4::isOrthogonal() failed with translation.\n");
return false;
}
matrix4 scaleMatrix;
scaleMatrix.setScale(vector3df(1, 2, 3));
if (scaleMatrix.isOrthogonal())
{
logTestString("irr::core::matrix4::isOrthogonal() failed with scale.\n");
return false;
}
return true;
}
Test suite pass at GMT Sat Jan 03 23:29:59 2009 Test suite pass at GMT Sun Jan 04 14:29:01 2009
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
<Unit filename="line2dIntersectWith.cpp" /> <Unit filename="line2dIntersectWith.cpp" />
<Unit filename="main.cpp" /> <Unit filename="main.cpp" />
<Unit filename="makeColorKeyTexture.cpp" /> <Unit filename="makeColorKeyTexture.cpp" />
<Unit filename="matrixOps.cpp" />
<Unit filename="md2Animation.cpp" /> <Unit filename="md2Animation.cpp" />
<Unit filename="planeMatrix.cpp" /> <Unit filename="planeMatrix.cpp" />
<Unit filename="sceneCollisionManager.cpp" /> <Unit filename="sceneCollisionManager.cpp" />
......
...@@ -217,6 +217,10 @@ ...@@ -217,6 +217,10 @@
RelativePath=".\makeColorKeyTexture.cpp" RelativePath=".\makeColorKeyTexture.cpp"
> >
</File> </File>
<File
RelativePath=".\matrixOps.cpp"
>
</File>
<File <File
RelativePath=".\md2Animation.cpp" RelativePath=".\md2Animation.cpp"
> >
......
...@@ -196,11 +196,11 @@ ...@@ -196,11 +196,11 @@
> >
</File> </File>
<File <File
RelativePath=".\irrCoreEquals.cpp" RelativePath=".\guiDisabledMenu.cpp"
> >
</File> </File>
<File <File
RelativePath=".\guiDisabledMenu.cpp" RelativePath=".\irrCoreEquals.cpp"
> >
</File> </File>
<File <File
...@@ -215,6 +215,10 @@ ...@@ -215,6 +215,10 @@
RelativePath=".\makeColorKeyTexture.cpp" RelativePath=".\makeColorKeyTexture.cpp"
> >
</File> </File>
<File
RelativePath=".\matrixOps.cpp"
>
</File>
<File <File
RelativePath=".\md2Animation.cpp" RelativePath=".\md2Animation.cpp"
> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment