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
#endif
//! 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
......@@ -233,55 +233,55 @@ inline quaternion& quaternion::operator=(const quaternion& other)
// matrix assignment operator
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 )
{
const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal
// TODO: speed this up
X = ( m(1,2) - m(2,1)) / scale;
Y = ( m(2,0) - m(0,2)) / scale;
Z = ( m(0,1) - m(1,0)) / scale;
X = (m[6] - m[9]) / scale;
Y = (m[8] - m[2]) / scale;
Z = (m[1] - m[4]) / scale;
W = 0.25f * scale;
}
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
// 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
X = 0.25f * scale;
Y = (m(1,0) + m(0,1)) / scale;
Z = (m(0,2) + m(2,0)) / scale;
W = (m(1,2) - m(2,1)) / scale;
Y = (m[4] + m[1]) / scale;
Z = (m[2] + m[8]) / 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
// 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
X = (m(1,0) + m(0,1) ) / scale;
X = (m[4] + m[1]) / scale;
Y = 0.25f * scale;
Z = (m(2,1) + m(1,2) ) / scale;
W = (m(2,0) - m(0,2) ) / scale;
Z = (m[9] + m[6]) / scale;
W = (m[8] - m[2]) / scale;
}
else
{
// 3rd element of diag is greatest value
// 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
X = (m(2,0) + m(0,2)) / scale;
Y = (m(2,1) + m(1,2)) / scale;
X = (m[8] + m[2]) / scale;
Y = (m[9] + m[6]) / 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)
}
#endif
// multiplication operator
inline quaternion quaternion::operator*(const quaternion& other) const
{
......@@ -309,6 +310,7 @@ inline quaternion quaternion::operator*(f32 s) const
return quaternion(s*X, s*Y, s*Z, s*W);
}
// multiplication operator
inline quaternion& quaternion::operator*=(f32 s)
{
......@@ -336,7 +338,7 @@ inline quaternion quaternion::operator+(const quaternion& b) const
inline matrix4 quaternion::getMatrix() const
{
core::matrix4 m;
getMatrix(m, core::vector3df(0,0,0));
getMatrix(m);
return m;
}
#endif
......@@ -344,74 +346,69 @@ inline matrix4 quaternion::getMatrix() const
/*!
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();
m[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
m[1] = 2.0f*X*Y + 2.0f*Z*W;
m[2] = 2.0f*X*Z - 2.0f*Y*W;
m[3] = 0.0f;
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
dest[3] = 0.0f;
m[4] = 2.0f*X*Y - 2.0f*Z*W;
m[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
m[6] = 2.0f*Z*Y + 2.0f*X*W;
m[7] = 0.0f;
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
dest[7] = 0.0f;
m[8] = 2.0f*X*Z + 2.0f*Y*W;
m[9] = 2.0f*Z*Y - 2.0f*X*W;
m[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
m[11] = 0.0f;
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
dest[11] = 0.0f;
m[12] = center.X;
m[13] = center.Y;
m[14] = center.Z;
m[15] = 1.f;
dest[12] = center.X;
dest[13] = center.Y;
dest[14] = center.Z;
dest[15] = 1.f;
//dest.setDefinitelyIdentityMatrix ( matrix4::BIT_IS_NOT_IDENTITY );
dest.setDefinitelyIdentityMatrix ( false );
}
/*!
Creates a matrix from this quaternion
Rotate about a center point
shortcut for
core::quaternion q;
q.rotationFromTo ( vin[i].Normal, forward );
q.getMatrix ( lookat, center );
q.rotationFromTo(vin[i].Normal, forward);
q.getMatrix(lookat, center);
core::matrix4 m2;
m2.setInverseTranslation ( center );
m2.setInverseTranslation(center);
lookat *= m2;
*/
inline void quaternion::getMatrixCenter(matrix4 &dest,
const core::vector3df &center,
const core::vector3df &translation) const
{
f32 * m = dest.pointer();
m[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
m[1] = 2.0f*X*Y + 2.0f*Z*W;
m[2] = 2.0f*X*Z - 2.0f*Y*W;
m[3] = 0.0f;
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
dest[3] = 0.0f;
m[4] = 2.0f*X*Y - 2.0f*Z*W;
m[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
m[6] = 2.0f*Z*Y + 2.0f*X*W;
m[7] = 0.0f;
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
dest[7] = 0.0f;
m[8] = 2.0f*X*Z + 2.0f*Y*W;
m[9] = 2.0f*Z*Y - 2.0f*X*W;
m[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
m[11] = 0.0f;
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
dest[11] = 0.0f;
dest.setRotationCenter ( center, translation );
}
// 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[4] = 2.0f*X*Y + 2.0f*Z*W;
......@@ -432,10 +429,9 @@ inline void quaternion::getMatrix_transposed( matrix4 &dest ) const
dest[7] = 0.f;
dest[11] = 0.f;
dest[15] = 1.f;
//dest.setDefinitelyIdentityMatrix ( matrix4::BIT_IS_NOT_IDENTITY );
dest.setDefinitelyIdentityMatrix ( false );
}
dest.setDefinitelyIdentityMatrix(false);
}
// Inverts this quaternion
......@@ -445,6 +441,7 @@ inline quaternion& quaternion::makeInverse()
return *this;
}
// sets new quaternion
inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w)
{
......
......@@ -85,6 +85,57 @@ const core::vector3df vals[] = {
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 result = true;
......@@ -94,6 +145,7 @@ bool testEulerConversion()
result &= compareQ(vals[i]) && compareQ(vals[i], core::vector3df(1,2,3)) &&
compareQ(vals[i], core::vector3df(0,1,0));
}
result &= testQuatEulerMatrix();
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