Replacing matrix4::setRotationRadiansLH and setRotationRadiansRH by setRotationRadians. Old functions had left handed and right handed just the wrong way round and contained an additional bug that did lead to wrong rotations (mixing up y,z). A single function for this is enough (people can just flip the axis) and this way people who already used the old functions (which only got added in trunk) don't just get new behavior but some compile error. Thanks to Randajad for finding the error with the wrong results, giving a testcase and insisting that there's really a bug when I didn't see it on first try :-)

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4295 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2012-08-20 11:22:05 +00:00
parent efa93883e2
commit a83a87594a
3 changed files with 140 additions and 57 deletions

View File

@ -1,5 +1,7 @@
Changes in 1.8 (??.??.2011)
- matrix4::setRotationAxisRadians added
- quaternion conversions to and from matrix4 no longer invert rotations.
To test if your code was affected by this you can set IRR_TEST_BROKEN_QUATERNION_USE in quaternion.h and try to compile your application.
Then on all compile-errors when you pass the matrix to the quaternion you can replace the matrix transposed matrix.

View File

@ -185,13 +185,9 @@ namespace core
/** The 4th row and column are unmodified. */
inline CMatrix4<T>& setInverseRotationDegrees( const vector3d<T>& rotation );
//! Make a rotation matrix from angle and axis using LH rotation.
//! Make a rotation matrix from angle and axis, assuming left handed rotation.
/** The 4th row and column are unmodified. */
inline CMatrix4<T>& setRotationAxisRadiansLH(const T& angle, const vector3d<T>& axis);
//! Make a rotation matrix from angle and axis using RH rotation.
/** The 4th row and column are unmodified. */
inline CMatrix4<T>& setRotationAxisRadiansRH(const T& angle, const vector3d<T>& axis);
inline CMatrix4<T>& setRotationAxisRadians(const T& angle, const vector3d<T>& axis);
//! Set Scale
CMatrix4<T>& setScale( const vector3d<T>& scale );
@ -947,65 +943,32 @@ namespace core
return *this;
}
//! Sets matrix to rotation matrix defined by axis and angle, assuming LH rotation
template <class T>
inline CMatrix4<T>& CMatrix4<T>::setRotationAxisRadiansLH( const T& angle, const vector3d<T>& axis )
{
const f64 c = cos( angle );
const f64 s = sin( angle );
const f64 t = 1.0 - c;
const f64 tx = t * axis.X;
M[0] = (T)(tx * axis.X + c);
M[1] = (T)(tx * axis.Y - s * axis.Z);
M[2] = (T)(tx * axis.Z + s * axis.Y);
const f64 ty = t * axis.Y;
M[4] = (T)(ty * axis.X + s * axis.Z);
M[5] = (T)(ty * axis.Y + c);
M[6] = (T)(ty * axis.Z - s * axis.X);
const f64 tz = t * axis.Z;
M[8] = (T)(tz * axis.X - s * axis.Y);
M[9] = (T)(tz * axis.Z + s * axis.X);
M[10] = (T)(tz * axis.Z + c);
#if defined ( USE_MATRIX_TEST )
definitelyIdentityMatrix=false;
#endif
return *this;
}
//! Sets matrix to rotation matrix defined by axis and angle, assuming RH rotation
template <class T>
inline CMatrix4<T>& CMatrix4<T>::setRotationAxisRadiansRH( const T& angle, const vector3d<T>& axis )
inline CMatrix4<T>& CMatrix4<T>::setRotationAxisRadians( const T& angle, const vector3d<T>& axis )
{
const f64 c = cos(angle);
const f64 s = sin(angle);
const f64 t = 1.0 - c;
const f64 tx = t * axis.X;
M[0] = (T)(tx * axis.X + c);
M[1] = (T)(tx * axis.Y + s * axis.Z);
M[2] = (T)(tx * axis.Z - s * axis.Y);
const f64 ty = t * axis.Y;
M[4] = (T)(ty * axis.X - s * axis.Z);
M[5] = (T)(ty * axis.Y + c);
M[6] = (T)(ty * axis.Z + s * axis.X);
const f64 ty = t * axis.Y;
const f64 tz = t * axis.Z;
M[8] = (T)(tz * axis.X + s * axis.Y);
M[9] = (T)(tz * axis.Z - s * axis.X);
const f64 sx = s * axis.X;
const f64 sy = s * axis.Y;
const f64 sz = s * axis.Z;
M[0] = (T)(tx * axis.X + c);
M[1] = (T)(tx * axis.Y + sz);
M[2] = (T)(tx * axis.Z - sy);
M[4] = (T)(ty * axis.X - sz);
M[5] = (T)(ty * axis.Y + c);
M[6] = (T)(ty * axis.Z + sx);
M[8] = (T)(tz * axis.X + sy);
M[9] = (T)(tz * axis.Y - sx);
M[10] = (T)(tz * axis.Z + c);
#if defined ( USE_MATRIX_TEST )

View File

@ -236,6 +236,124 @@ bool isOrthogonal(void)
return true;
}
bool checkMatrixRotation(irr::core::matrix4& m, const vector3df& vector, const vector3df& expectedResult)
{
vector3df v(vector);
m.rotateVect(v);
if ( expectedResult.equals(v) )
return true;
logTestString("checkMatrixRotation failed for vector %f %f %f. Expected %f %f %f, got %f %f %f \n"
, vector.X, vector.Y, vector.Z, expectedResult.X, expectedResult.Y, expectedResult.Z, v.X, v.Y, v.Z);
logTestString("matrix: ");
for ( int i=0; i<16; ++i )
logTestString("%.2f ", m[i]);
logTestString("\n");
return false;
}
bool setRotationAxis()
{
matrix4 m;
vector3df v;
// y up, x right, z depth (as usual)
// y rotated around x-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(1,0,0)), vector3df(0,1,0), vector3df(0, 0, 1)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(1,0,0)), vector3df(0,1,0), vector3df(0, -1, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// y rotated around negative x-axis
m.makeIdentity();
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(-1,0,0)), vector3df(0,1,0), vector3df(0, 0, -1)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// x rotated around x-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(1,0,0)), vector3df(1,0,0), vector3df(1, 0, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// x rotated around y-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,1,0)), vector3df(1,0,0), vector3df(0, 0, -1)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,1,0)), vector3df(1,0,0), vector3df(-1, 0, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// x rotated around negative y-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,-1,0)), vector3df(1,0,0), vector3df(0, 0, 1)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// y rotated around y-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,1,0)), vector3df(0,1,0), vector3df(0, 1, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// x rotated around z-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(1,0,0), vector3df(0, 1, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,0,1)), vector3df(1,0,0), vector3df(-1, 0, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// x rotated around negative z-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,-1)), vector3df(1,0,0), vector3df(0, -1, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// y rotated around z-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,1,0), vector3df(-1, 0, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,1,0), vector3df(0, -1, 0)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
// z rotated around z-axis
if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,0,1), vector3df(0, 0, 1)) )
{
logTestString("%s:%d", __FILE__, __LINE__);
return false;
}
return true;
}
// just calling each function once to find compile problems
void calltest()
{
@ -273,8 +391,7 @@ void calltest()
vector3df v2 = mat.getRotationDegrees();
mat.setInverseRotationRadians(vector3df(1.f, 1.f, 1.f) );
mat.setInverseRotationDegrees(vector3df(1.f, 1.f, 1.f) );
mat.setRotationAxisRadiansLH(1.f, vector3df(1.f, 1.f, 1.f) );
mat.setRotationAxisRadiansRH(1.f, vector3df(1.f, 1.f, 1.f) );
mat.setRotationAxisRadians(1.f, vector3df(1.f, 1.f, 1.f) );
mat.setScale(vector3df(1.f, 1.f, 1.f) );
mat.setScale(1.f);
vector3df v3 = mat.getScale();
@ -342,6 +459,7 @@ bool matrixOps(void)
result &= rotations();
result &= isOrthogonal();
result &= transformations();
result &= setRotationAxis();
return result;
}