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
}
//! 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
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
......@@ -213,21 +219,21 @@ namespace core
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);
}
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);
}
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
//! Returns true if the matrix is the identity matrix
inline bool isIdentity() const;
//! Returns true if the matrix is orthogonal
inline bool isOrthogonal() const;
//! Returns true if the matrix is the identity matrix
bool isIdentity_integer_base () const;
......@@ -818,6 +821,31 @@ namespace core
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..
but takes care on +/- 0 on translation because we are changing it..
......
......@@ -7,6 +7,7 @@
bool irrCoreEquals(void)
{
// float tests
if(!irr::core::equals(99.f, 99.f))
{
logTestString("irr::core::equals(f32, f32 (, default)) failed.\n");
......@@ -19,6 +20,7 @@ bool irrCoreEquals(void)
return false;
}
// double tests
if(!irr::core::equals(99.0, 99.0))
{
logTestString("irr::core::equals(f64, f64 (,default)) failed.\n");
......@@ -31,6 +33,7 @@ bool irrCoreEquals(void)
return false;
}
// int tests
if(!irr::core::equals(99, 99))
{
logTestString("irr::core::equals(s32, s32 (,default)) failed.\n");
......@@ -79,6 +82,65 @@ bool irrCoreEquals(void)
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;
}
\ No newline at end of file
}
......@@ -56,6 +56,7 @@ int main(int argumentCount, char * arguments[])
extern bool textureRenderStates(void);
extern bool burningsVideo(void);
extern bool makeColorKeyTexture(void);
extern bool matrixOps(void);
typedef struct _STest
{
......@@ -71,6 +72,7 @@ int main(int argumentCount, char * arguments[])
TEST(exports),
TEST(testVector3d),
TEST(testVector2d),
TEST(matrixOps),
TEST(planeMatrix),
TEST(fast_atof),
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 @@
<Unit filename="line2dIntersectWith.cpp" />
<Unit filename="main.cpp" />
<Unit filename="makeColorKeyTexture.cpp" />
<Unit filename="matrixOps.cpp" />
<Unit filename="md2Animation.cpp" />
<Unit filename="planeMatrix.cpp" />
<Unit filename="sceneCollisionManager.cpp" />
......
......@@ -217,6 +217,10 @@
RelativePath=".\makeColorKeyTexture.cpp"
>
</File>
<File
RelativePath=".\matrixOps.cpp"
>
</File>
<File
RelativePath=".\md2Animation.cpp"
>
......
......@@ -196,11 +196,11 @@
>
</File>
<File
RelativePath=".\irrCoreEquals.cpp"
RelativePath=".\guiDisabledMenu.cpp"
>
</File>
<File
RelativePath=".\guiDisabledMenu.cpp"
RelativePath=".\irrCoreEquals.cpp"
>
</File>
<File
......@@ -215,6 +215,10 @@
RelativePath=".\makeColorKeyTexture.cpp"
>
</File>
<File
RelativePath=".\matrixOps.cpp"
>
</File>
<File
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