Quaternions were assigning inverted values during conversion to matricies.

This is probably due to an error on the gamasutra web page demonstrating this.
It caused left-handed rotations rather than right handed rotations.  Should be
fixed now.
This commit is contained in:
Don BURNS 2001-10-14 04:28:50 +00:00
parent 1e4a0cadf5
commit c6f11afbf6
2 changed files with 35 additions and 17 deletions

View File

@ -188,6 +188,7 @@ void Matrix::makeRot( float angle, float x, float y, float z ) {
angle = DEG2RAD(angle);
#endif
#if 0
float sin_half = sin( angle/2 );
float cos_half = cos( angle/2 );
@ -195,6 +196,9 @@ void Matrix::makeRot( float angle, float x, float y, float z ) {
sin_half * (y/d),
sin_half * (z/d),
cos_half );//NOTE: original used a private quaternion made of doubles
#endif
Quat q;
q.makeRot( angle, x, y, z);
makeRot( q ); // but Quat stores the values in a Vec4 made of floats.
}
@ -216,10 +220,18 @@ void Matrix::makeRot( const Quat& q ) {
double wy = ys * v.w();
double wz = zs * v.w();
/*
* This is inverted - Don Burns
SET_ROW(0, 1.0-(yy+zz), xy - wz, xz + wy, 0.0 )
SET_ROW(1, xy + wz, 1.0-(xx+zz),yz - wx, 0.0 )
SET_ROW(2, xz - wy, yz + wx, 1.0-(xx+yy),0.0 )
SET_ROW(3, 0.0, 0.0, 0.0, 1.0 )
*/
SET_ROW(0, 1.0-(yy+zz), xy + wz, xz - wy, 0.0 )
SET_ROW(1, xy - wz, 1.0-(xx+zz),yz + wx, 0.0 )
SET_ROW(2, xz + wy, yz - wx, 1.0-(xx+yy),0.0 )
SET_ROW(3, 0.0, 0.0, 0.0, 1.0 )
fully_realized = true;
}

View File

@ -1,3 +1,4 @@
#include <stdio.h>
#include "osg/Quat"
#include "osg/Vec4"
#include "osg/Vec3"
@ -19,10 +20,9 @@ const float x,
const float y,
const float z )
{
float _angle = -angle; // Convert to right handed coordinate system
float inversenorm = 1.0/sqrt( x*x + y*y + z*z );
float coshalfangle = cos( 0.5*_angle );
float sinhalfangle = sin( 0.5*_angle );
float coshalfangle = cos( 0.5*angle );
float sinhalfangle = sin( 0.5*angle );
_fv[0] = x * sinhalfangle * inversenorm;
_fv[1] = y * sinhalfangle * inversenorm;
@ -52,8 +52,6 @@ void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
// dot product vec1*vec2
float cosangle = vec1*vec2/(length1*length2);
//cosangle = - cosangle; // Convert to right-handed coordinate system
if ( fabs(cosangle - 1) < epsilon )
{
// cosangle is close to 1, so the vectors are close to being coincident
@ -62,8 +60,10 @@ void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
makeRot( 0.0, 1.0, 0.0, 0.0 );
}
else
#if 0 /// This is broken and entirely unecessary. - Don Burns.
if ( fabs(cosangle + 1) < epsilon )
{
// cosangle is close to -1, so the vectors are close to being opposite
// The angle of rotation is going to be Pi, but around which axis?
// Basically, any one perpendicular to vec1 = (x,y,z) is going to work.
@ -79,6 +79,7 @@ void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
makeRot( (float)M_PI, axis );
}
else
#endif
{
// This is the usual situation - take a cross-product of vec1 and vec2
// and that is the axis around which to rotate.
@ -242,23 +243,28 @@ void Quat::get( Matrix& m ) const
wy = QW * y2;
wz = QW * z2;
// Note. Gamasutra gets the matrix assignments inverted, resulting
// in left-handed rotations, which is contrary to OpenGL and OSG's
// methodology. The matrix assignment has been altered in the next
// few lines of code to do the right thing.
// Don Burns - Oct 13, 2001
m(0,0) = 1.0f - (yy + zz);
m(0,1) = xy - wz;
m(0,2) = xz + wy;
m(0,3) = 0.0f;
m(1,0) = xy - wz;
m(2,0) = xz + wy;
m(3,0) = 0.0f;
m(1,0) = xy + wz;
m(0,1) = xy + wz;
m(1,1) = 1.0f - (xx + zz);
m(1,2) = yz - wx;
m(1,3) = 0.0f;
m(2,1) = yz - wx;
m(3,1) = 0.0f;
m(2,0) = xz - wy;
m(2,1) = yz + wx;
m(0,2) = xz - wy;
m(1,2) = yz + wx;
m(2,2) = 1.0f - (xx + yy);
m(2,3) = 0.0f;
m(3,2) = 0.0f;
m(3,0) = 0;
m(3,1) = 0;
m(3,2) = 0;
m(0,3) = 0;
m(1,3) = 0;
m(2,3) = 0;
m(3,3) = 1;
}