Commit 8d628796 authored by hybrid's avatar hybrid

Added default parameter to getMatrix

Change matrix pointer access to direct array operator access.
Add some test cases for quaternion methods.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4280 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 86bd1032
...@@ -104,7 +104,7 @@ class quaternion ...@@ -104,7 +104,7 @@ class quaternion
#endif #endif
//! Creates a matrix from this quaternion //! Creates a matrix from this quaternion
void getMatrix( matrix4 &dest, const core::vector3df &translation ) const; void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
/*! /*!
Creates a matrix from this quaternion Creates a matrix from this quaternion
...@@ -233,55 +233,55 @@ inline quaternion& quaternion::operator=(const quaternion& other) ...@@ -233,55 +233,55 @@ inline quaternion& quaternion::operator=(const quaternion& other)
// matrix assignment operator // matrix assignment operator
inline quaternion& quaternion::operator=(const matrix4& m) inline quaternion& quaternion::operator=(const matrix4& m)
{ {
const f32 diag = m(0,0) + m(1,1) + m(2,2) + 1; const f32 diag = m[0] + m[5] + m[10] + 1;
if( diag > 0.0f ) if( diag > 0.0f )
{ {
const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal
// TODO: speed this up // TODO: speed this up
X = ( m(1,2) - m(2,1)) / scale; X = (m[6] - m[9]) / scale;
Y = ( m(2,0) - m(0,2)) / scale; Y = (m[8] - m[2]) / scale;
Z = ( m(0,1) - m(1,0)) / scale; Z = (m[1] - m[4]) / scale;
W = 0.25f * scale; W = 0.25f * scale;
} }
else else
{ {
if ( m(0,0) > m(1,1) && m(0,0) > m(2,2)) if (m[0]>m[5] && m[0]>m[10])
{ {
// 1st element of diag is greatest value // 1st element of diag is greatest value
// find scale according to 1st element, and double it // find scale according to 1st element, and double it
const f32 scale = sqrtf( 1.0f + m(0,0) - m(1,1) - m(2,2)) * 2.0f; const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f;
// TODO: speed this up // TODO: speed this up
X = 0.25f * scale; X = 0.25f * scale;
Y = (m(1,0) + m(0,1)) / scale; Y = (m[4] + m[1]) / scale;
Z = (m(0,2) + m(2,0)) / scale; Z = (m[2] + m[8]) / scale;
W = (m(1,2) - m(2,1)) / scale; W = (m[6] - m[9]) / scale;
} }
else if ( m(1,1) > m(2,2)) else if (m[5]>m[10])
{ {
// 2nd element of diag is greatest value // 2nd element of diag is greatest value
// find scale according to 2nd element, and double it // find scale according to 2nd element, and double it
const f32 scale = sqrtf( 1.0f + m(1,1) - m(0,0) - m(2,2)) * 2.0f; const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f;
// TODO: speed this up // TODO: speed this up
X = (m(1,0) + m(0,1) ) / scale; X = (m[4] + m[1]) / scale;
Y = 0.25f * scale; Y = 0.25f * scale;
Z = (m(2,1) + m(1,2) ) / scale; Z = (m[9] + m[6]) / scale;
W = (m(2,0) - m(0,2) ) / scale; W = (m[8] - m[2]) / scale;
} }
else else
{ {
// 3rd element of diag is greatest value // 3rd element of diag is greatest value
// find scale according to 3rd element, and double it // find scale according to 3rd element, and double it
const f32 scale = sqrtf( 1.0f + m(2,2) - m(0,0) - m(1,1)) * 2.0f; const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f;
// TODO: speed this up // TODO: speed this up
X = (m(2,0) + m(0,2)) / scale; X = (m[8] + m[2]) / scale;
Y = (m(2,1) + m(1,2)) / scale; Y = (m[9] + m[6]) / scale;
Z = 0.25f * scale; Z = 0.25f * scale;
W = (m(0,1) - m(1,0)) / scale; W = (m[1] - m[4]) / scale;
} }
} }
...@@ -289,6 +289,7 @@ inline quaternion& quaternion::operator=(const matrix4& m) ...@@ -289,6 +289,7 @@ inline quaternion& quaternion::operator=(const matrix4& m)
} }
#endif #endif
// multiplication operator // multiplication operator
inline quaternion quaternion::operator*(const quaternion& other) const inline quaternion quaternion::operator*(const quaternion& other) const
{ {
...@@ -309,6 +310,7 @@ inline quaternion quaternion::operator*(f32 s) const ...@@ -309,6 +310,7 @@ inline quaternion quaternion::operator*(f32 s) const
return quaternion(s*X, s*Y, s*Z, s*W); return quaternion(s*X, s*Y, s*Z, s*W);
} }
// multiplication operator // multiplication operator
inline quaternion& quaternion::operator*=(f32 s) inline quaternion& quaternion::operator*=(f32 s)
{ {
...@@ -336,7 +338,7 @@ inline quaternion quaternion::operator+(const quaternion& b) const ...@@ -336,7 +338,7 @@ inline quaternion quaternion::operator+(const quaternion& b) const
inline matrix4 quaternion::getMatrix() const inline matrix4 quaternion::getMatrix() const
{ {
core::matrix4 m; core::matrix4 m;
getMatrix(m, core::vector3df(0,0,0)); getMatrix(m);
return m; return m;
} }
#endif #endif
...@@ -344,74 +346,69 @@ inline matrix4 quaternion::getMatrix() const ...@@ -344,74 +346,69 @@ inline matrix4 quaternion::getMatrix() const
/*! /*!
Creates a matrix from this quaternion Creates a matrix from this quaternion
*/ */
inline void quaternion::getMatrix( matrix4 &dest, const core::vector3df &center ) const inline void quaternion::getMatrix(matrix4 &dest,
const core::vector3df &center) const
{ {
f32 * m = dest.pointer(); dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
m[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; dest[2] = 2.0f*X*Z - 2.0f*Y*W;
m[1] = 2.0f*X*Y + 2.0f*Z*W; dest[3] = 0.0f;
m[2] = 2.0f*X*Z - 2.0f*Y*W;
m[3] = 0.0f;
m[4] = 2.0f*X*Y - 2.0f*Z*W; dest[4] = 2.0f*X*Y - 2.0f*Z*W;
m[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
m[6] = 2.0f*Z*Y + 2.0f*X*W; dest[6] = 2.0f*Z*Y + 2.0f*X*W;
m[7] = 0.0f; dest[7] = 0.0f;
m[8] = 2.0f*X*Z + 2.0f*Y*W; dest[8] = 2.0f*X*Z + 2.0f*Y*W;
m[9] = 2.0f*Z*Y - 2.0f*X*W; dest[9] = 2.0f*Z*Y - 2.0f*X*W;
m[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
m[11] = 0.0f; dest[11] = 0.0f;
m[12] = center.X; dest[12] = center.X;
m[13] = center.Y; dest[13] = center.Y;
m[14] = center.Z; dest[14] = center.Z;
m[15] = 1.f; dest[15] = 1.f;
//dest.setDefinitelyIdentityMatrix ( matrix4::BIT_IS_NOT_IDENTITY );
dest.setDefinitelyIdentityMatrix ( false ); dest.setDefinitelyIdentityMatrix ( false );
} }
/*! /*!
Creates a matrix from this quaternion Creates a matrix from this quaternion
Rotate about a center point Rotate about a center point
shortcut for shortcut for
core::quaternion q; core::quaternion q;
q.rotationFromTo ( vin[i].Normal, forward ); q.rotationFromTo(vin[i].Normal, forward);
q.getMatrix ( lookat, center ); q.getMatrix(lookat, center);
core::matrix4 m2; core::matrix4 m2;
m2.setInverseTranslation ( center ); m2.setInverseTranslation(center);
lookat *= m2; lookat *= m2;
*/ */
inline void quaternion::getMatrixCenter(matrix4 &dest, inline void quaternion::getMatrixCenter(matrix4 &dest,
const core::vector3df &center, const core::vector3df &center,
const core::vector3df &translation) const const core::vector3df &translation) const
{ {
f32 * m = dest.pointer(); dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
m[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; dest[2] = 2.0f*X*Z - 2.0f*Y*W;
m[1] = 2.0f*X*Y + 2.0f*Z*W; dest[3] = 0.0f;
m[2] = 2.0f*X*Z - 2.0f*Y*W;
m[3] = 0.0f;
m[4] = 2.0f*X*Y - 2.0f*Z*W; dest[4] = 2.0f*X*Y - 2.0f*Z*W;
m[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
m[6] = 2.0f*Z*Y + 2.0f*X*W; dest[6] = 2.0f*Z*Y + 2.0f*X*W;
m[7] = 0.0f; dest[7] = 0.0f;
m[8] = 2.0f*X*Z + 2.0f*Y*W; dest[8] = 2.0f*X*Z + 2.0f*Y*W;
m[9] = 2.0f*Z*Y - 2.0f*X*W; dest[9] = 2.0f*Z*Y - 2.0f*X*W;
m[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
m[11] = 0.0f; dest[11] = 0.0f;
dest.setRotationCenter ( center, translation ); dest.setRotationCenter ( center, translation );
} }
// Creates a matrix from this quaternion // Creates a matrix from this quaternion
inline void quaternion::getMatrix_transposed( matrix4 &dest ) const inline void quaternion::getMatrix_transposed(matrix4 &dest) const
{ {
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
dest[4] = 2.0f*X*Y + 2.0f*Z*W; dest[4] = 2.0f*X*Y + 2.0f*Z*W;
...@@ -432,10 +429,9 @@ inline void quaternion::getMatrix_transposed( matrix4 &dest ) const ...@@ -432,10 +429,9 @@ inline void quaternion::getMatrix_transposed( matrix4 &dest ) const
dest[7] = 0.f; dest[7] = 0.f;
dest[11] = 0.f; dest[11] = 0.f;
dest[15] = 1.f; dest[15] = 1.f;
//dest.setDefinitelyIdentityMatrix ( matrix4::BIT_IS_NOT_IDENTITY );
dest.setDefinitelyIdentityMatrix ( false );
}
dest.setDefinitelyIdentityMatrix(false);
}
// Inverts this quaternion // Inverts this quaternion
...@@ -445,6 +441,7 @@ inline quaternion& quaternion::makeInverse() ...@@ -445,6 +441,7 @@ inline quaternion& quaternion::makeInverse()
return *this; return *this;
} }
// sets new quaternion // sets new quaternion
inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w) inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w)
{ {
......
...@@ -85,6 +85,57 @@ const core::vector3df vals[] = { ...@@ -85,6 +85,57 @@ const core::vector3df vals[] = {
core::vector3df(-57.187481f,-90.f,0.f) core::vector3df(-57.187481f,-90.f,0.f)
}; };
bool testQuatEulerMatrix()
{
// Test fromAngleAxis
core::vector3df v4;
core::quaternion q1;
f32 angle = 60.f;
q1.fromAngleAxis(angle*core::DEGTORAD, core::vector3df(1, 0, 0));
q1.toEuler(v4);
bool result = v4.equals(core::vector3df(angle*core::DEGTORAD,0,0));
// Test maxtrix constructor
core::vector3df v5;
core::matrix4 mx4;
mx4.setRotationDegrees(core::vector3df(angle,0,0));
core::quaternion q2(mx4);
q2.toEuler(v5);
result &= q1.equals(q2);
result &= v4.equals(v5);
// Test matrix conversion via getMatrix
core::matrix4 mat;
mat.setRotationDegrees(core::vector3df(angle,0,0));
core::vector3df v6 = mat.getRotationDegrees()*core::DEGTORAD;
// make sure comparison matrix is correct
result &= v4.equals(v6);
core::matrix4 mat2 = q1.getMatrix();
result &= mat.equals(mat2, 0.0005f);
// test for proper handedness
angle=90;
q1.fromAngleAxis(angle*core::DEGTORAD, core::vector3df(0,0,1));
// check we have the correct quat
result &= q1.equals(core::quaternion(0,0,sqrtf(2)/2,sqrtf(2)/2));
q1.toEuler(v4);
// and the correct rotation vector
result &= v4.equals(core::vector3df(0,0,90*core::DEGTORAD));
mat.setRotationRadians(v4);
mat2=q1.getMatrix();
// check matrix
result &= mat.equals(mat2, 0.0005f);
// and to be absolutely sure, check rotation results
v5.set(1,0,0);
mat.transformVect(v5);
v6.set(1,0,0);
mat2.transformVect(v6);
result &= v5.equals(v6);
return result;
}
bool testEulerConversion() bool testEulerConversion()
{ {
bool result = true; bool result = true;
...@@ -94,6 +145,7 @@ bool testEulerConversion() ...@@ -94,6 +145,7 @@ bool testEulerConversion()
result &= compareQ(vals[i]) && compareQ(vals[i], core::vector3df(1,2,3)) && result &= compareQ(vals[i]) && compareQ(vals[i], core::vector3df(1,2,3)) &&
compareQ(vals[i], core::vector3df(0,1,0)); compareQ(vals[i], core::vector3df(0,1,0));
} }
result &= testQuatEulerMatrix();
return result; return result;
} }
......
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