Added DOFTransform, MatrixTransform and PositionAttitudeTransform to NodeVisitor.

Added osg::Matrix/Quat::makeRotate(angle1,axis1,angle2,axis2,angle3,axis3) and
osg::Matrix::rotate(angle1,axis1,angle2,axis2,angle3,axis3) method.

Made osg::Matrix/Quat::makeRotate(heading,pitch,roll) and
osg::Matrix::rotate(heading,pitch,roll) all deprecated API.

Fixed the Quat*Quat & Quat*=Quat multiplication methods so that they multiplied
in the correct order - they were reversed originally due to the Quat code being
based on code example which used the v' = M v ordering, rather than the OSG's
v' = v M ordering.
This commit is contained in:
Robert Osfield 2002-08-18 14:42:43 +00:00
parent a9732aa046
commit 22d54f05e4
6 changed files with 121 additions and 39 deletions

View File

@ -95,14 +95,10 @@ class SG_EXPORT Matrix : public Object
void makeRotate( float angle, const Vec3& axis ); void makeRotate( float angle, const Vec3& axis );
void makeRotate( float angle, float x, float y, float z ); void makeRotate( float angle, float x, float y, float z );
void makeRotate( const Quat& ); void makeRotate( const Quat& );
void makeRotate( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3);
/** make a rotation Matrix from euler angles.
* assume Z up, Y north, X east and euler convention
* as per Open Flight & Performer.
* Applies a positive rotation about Y axis for roll,
* then applies a positive roation about X for pitch,
* and finally a negative rotation about the Z axis.*/
void makeRotate( float heading, float pitch, float roll); //Euler angles
/** Set to a orthographic projection. See glOrtho for further details.*/ /** Set to a orthographic projection. See glOrtho for further details.*/
@ -142,8 +138,9 @@ class SG_EXPORT Matrix : public Object
inline static Matrix rotate( const Vec3& from, const Vec3& to); inline static Matrix rotate( const Vec3& from, const Vec3& to);
inline static Matrix rotate( float angle, float x, float y, float z); inline static Matrix rotate( float angle, float x, float y, float z);
inline static Matrix rotate( float angle, const Vec3& axis); inline static Matrix rotate( float angle, const Vec3& axis);
/** construct rotation matrix from euler angles, for conventions see makeRotate().*/ inline static Matrix rotate( float angle1, const Vec3& axis1,
inline static Matrix rotate( float heading, float pitch, float roll); float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3);
inline static Matrix rotate( const Quat& quat); inline static Matrix rotate( const Quat& quat);
inline static Matrix inverse( const Matrix& matrix); inline static Matrix inverse( const Matrix& matrix);
@ -170,6 +167,19 @@ class SG_EXPORT Matrix : public Object
inline static Matrix lookAt(const Vec3& eye,const Vec3& center,const Vec3& up); inline static Matrix lookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
#ifdef USE_DEPRECATED_API
/** make a rotation Matrix from euler angles.
* assume Z up, Y north, X east and euler convention
* as per Open Flight & Performer.
* Applies a positive rotation about Y axis for roll,
* then applies a positive roation about X for pitch,
* and finally a negative rotation about the Z axis.*/
void makeRotate( float heading, float pitch, float roll); //Euler angles
inline static Matrix rotate( float heading, float pitch, float roll);
#endif
inline Vec3 preMult( const Vec3& v ) const; inline Vec3 preMult( const Vec3& v ) const;
inline Vec3 postMult( const Vec3& v ) const; inline Vec3 postMult( const Vec3& v ) const;
inline Vec3 operator* ( const Vec3& v ) const; inline Vec3 operator* ( const Vec3& v ) const;
@ -289,12 +299,22 @@ inline Matrix Matrix::rotate(float angle, const Vec3& axis )
m.makeRotate(angle,axis); m.makeRotate(angle,axis);
return m; return m;
} }
#ifdef USE_DEPRECATED_API
inline Matrix Matrix::rotate(float heading, float pitch, float roll) inline Matrix Matrix::rotate(float heading, float pitch, float roll)
{ {
Matrix m; Matrix m;
m.makeRotate(heading,pitch,roll); m.makeRotate(heading,pitch,roll);
return m; return m;
} }
#endif
inline Matrix Matrix::rotate( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3)
{
Matrix m;
m.makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
return m;
}
inline Matrix Matrix::rotate(const Vec3& from, const Vec3& to ) inline Matrix Matrix::rotate(const Vec3& from, const Vec3& to )
{ {
Matrix m; Matrix m;

View File

@ -17,6 +17,9 @@ class LightSource;
class ClipNode; class ClipNode;
class Group; class Group;
class Transform; class Transform;
class DOFTransform;
class MatrixTransform;
class PositionAttitudeTransform;
class Projection; class Projection;
class LOD; class LOD;
class Switch; class Switch;
@ -187,22 +190,28 @@ class SG_EXPORT NodeVisitor : public Referenced
const bool getWorldToLocalMatrix(Matrix& matrix, Node* node); const bool getWorldToLocalMatrix(Matrix& matrix, Node* node);
virtual void apply(Node& node) { traverse(node);} virtual void apply(Node& node) { traverse(node);}
virtual void apply(Geode& node) { apply((Node&)node); } virtual void apply(Geode& node) { apply((Node&)node); }
virtual void apply(Billboard& node) { apply((Geode&)node); } virtual void apply(Billboard& node) { apply((Geode&)node); }
virtual void apply(LightSource& node) { apply((Node&)node); } virtual void apply(LightSource& node) { apply((Node&)node); }
virtual void apply(ClipNode& node) { apply((Node&)node); } virtual void apply(ClipNode& node) { apply((Node&)node); }
virtual void apply(Group& node) { apply((Node&)node); } virtual void apply(Group& node) { apply((Node&)node); }
virtual void apply(Projection& node) { apply((Group&)node); }
virtual void apply(Transform& node) { apply((Group&)node); } virtual void apply(Projection& node) { apply((Group&)node); }
virtual void apply(Switch& node) { apply((Group&)node); }
virtual void apply(Sequence& node) { apply((Switch&)node); } virtual void apply(Transform& node) { apply((Group&)node); }
virtual void apply(LOD& node) { apply((Group&)node); } virtual void apply(DOFTransform& node) { apply((Transform&)node); }
virtual void apply(Impostor& node) { apply((LOD&)node); } virtual void apply(MatrixTransform& node) { apply((Transform&)node); }
virtual void apply(EarthSky& node) { apply((Group&)node); } virtual void apply(PositionAttitudeTransform& node) { apply((Transform&)node); }
virtual void apply(OccluderNode& node) { apply((Group&)node); }
virtual void apply(Switch& node) { apply((Group&)node); }
virtual void apply(Sequence& node) { apply((Switch&)node); }
virtual void apply(LOD& node) { apply((Group&)node); }
virtual void apply(Impostor& node) { apply((LOD&)node); }
virtual void apply(EarthSky& node) { apply((Group&)node); }
virtual void apply(OccluderNode& node) { apply((Group&)node); }
protected: protected:

View File

@ -85,19 +85,19 @@ class SG_EXPORT Quat
/// Binary multiply /// Binary multiply
inline const Quat operator*(const Quat& rhs) const inline const Quat operator*(const Quat& rhs) const
{ {
return Quat( _fv[3]*rhs._fv[0] + _fv[0]*rhs._fv[3] + _fv[1]*rhs._fv[2] - _fv[2]*rhs._fv[1], return Quat( rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1],
_fv[3]*rhs._fv[1] - _fv[0]*rhs._fv[2] + _fv[1]*rhs._fv[3] + _fv[2]*rhs._fv[0], rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0],
_fv[3]*rhs._fv[2] + _fv[0]*rhs._fv[1] - _fv[1]*rhs._fv[0] + _fv[2]*rhs._fv[3], rhs._fv[3]*_fv[2] + rhs._fv[0]*_fv[1] - rhs._fv[1]*_fv[0] + rhs._fv[2]*_fv[3],
_fv[3]*rhs._fv[3] - _fv[0]*rhs._fv[0] - _fv[1]*rhs._fv[1] - _fv[2]*rhs._fv[2] ); rhs._fv[3]*_fv[3] - rhs._fv[0]*_fv[0] - rhs._fv[1]*_fv[1] - rhs._fv[2]*_fv[2] );
} }
/// Unary multiply /// Unary multiply
inline Quat& operator*=(const Quat& rhs) inline Quat& operator*=(const Quat& rhs)
{ {
float x = _fv[3]*rhs._fv[0] + _fv[0]*rhs._fv[3] + _fv[1]*rhs._fv[2] - _fv[2]*rhs._fv[1]; float x = rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1];
float y = _fv[3]*rhs._fv[1] - _fv[0]*rhs._fv[2] + _fv[1]*rhs._fv[3] + _fv[2]*rhs._fv[0]; float y = rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0];
float z = _fv[3]*rhs._fv[2] + _fv[0]*rhs._fv[1] - _fv[1]*rhs._fv[0] + _fv[2]*rhs._fv[3]; float z = rhs._fv[3]*_fv[2] + rhs._fv[0]*_fv[1] - rhs._fv[1]*_fv[0] + rhs._fv[2]*_fv[3];
_fv[3] = _fv[3]*rhs._fv[3] - _fv[0]*rhs._fv[0] - _fv[1]*rhs._fv[1] - _fv[2]*rhs._fv[2]; _fv[3] = rhs._fv[3]*_fv[3] - rhs._fv[0]*_fv[0] - rhs._fv[1]*_fv[1] - rhs._fv[2]*_fv[2];
_fv[2] = z; _fv[2] = z;
_fv[1] = y; _fv[1] = y;
@ -105,6 +105,29 @@ class SG_EXPORT Quat
return (*this); // enable nesting return (*this); // enable nesting
} }
// /// Binary multiply
// inline const Quat operator*(const Quat& rhs) const
// {
// return Quat( _fv[3]*rhs._fv[0] + _fv[0]*rhs._fv[3] + _fv[1]*rhs._fv[2] - _fv[2]*rhs._fv[1],
// _fv[3]*rhs._fv[1] - _fv[0]*rhs._fv[2] + _fv[1]*rhs._fv[3] + _fv[2]*rhs._fv[0],
// _fv[3]*rhs._fv[2] + _fv[0]*rhs._fv[1] - _fv[1]*rhs._fv[0] + _fv[2]*rhs._fv[3],
// _fv[3]*rhs._fv[3] - _fv[0]*rhs._fv[0] - _fv[1]*rhs._fv[1] - _fv[2]*rhs._fv[2] );
// }
//
// /// Unary multiply
// inline Quat& operator*=(const Quat& rhs)
// {
// float x = _fv[3]*rhs._fv[0] + _fv[0]*rhs._fv[3] + _fv[1]*rhs._fv[2] - _fv[2]*rhs._fv[1];
// float y = _fv[3]*rhs._fv[1] - _fv[0]*rhs._fv[2] + _fv[1]*rhs._fv[3] + _fv[2]*rhs._fv[0];
// float z = _fv[3]*rhs._fv[2] + _fv[0]*rhs._fv[1] - _fv[1]*rhs._fv[0] + _fv[2]*rhs._fv[3];
// _fv[3] = _fv[3]*rhs._fv[3] - _fv[0]*rhs._fv[0] - _fv[1]*rhs._fv[1] - _fv[2]*rhs._fv[2];
//
// _fv[2] = z;
// _fv[1] = y;
// _fv[0] = x;
//
// return (*this); // enable nesting
// }
/// Divide by scalar /// Divide by scalar
inline const Quat operator / (const float& rhs) const inline const Quat operator / (const float& rhs) const
@ -203,6 +226,10 @@ class SG_EXPORT Quat
const float x, const float y, const float z ); const float x, const float y, const float z );
void makeRotate ( const float angle, const Vec3& vec ); void makeRotate ( const float angle, const Vec3& vec );
void makeRotate ( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3);
/** Make a rotation Quat which will rotate vec1 to vec2. /** Make a rotation Quat which will rotate vec1 to vec2.
Generally take adot product to get the angle between these Generally take adot product to get the angle between these
and then use a cross product to get the rotation axis and then use a cross product to get the rotation axis
@ -210,6 +237,7 @@ class SG_EXPORT Quat
are co-incident or opposite in direction.*/ are co-incident or opposite in direction.*/
void makeRotate( const Vec3& vec1, const Vec3& vec2 ); void makeRotate( const Vec3& vec1, const Vec3& vec2 );
#ifdef USE_DEPRECATED_API
/** make a rotation Quat from euler angles. /** make a rotation Quat from euler angles.
* assume Z up, Y north, X east and euler convention * assume Z up, Y north, X east and euler convention
* as per Open Flight & Performer. * as per Open Flight & Performer.
@ -217,7 +245,7 @@ class SG_EXPORT Quat
* then applies a positive roation about X for pitch, * then applies a positive roation about X for pitch,
* and finally a negative rotation about the Z axis.*/ * and finally a negative rotation about the Z axis.*/
void makeRotate( float heading, float pitch, float roll); void makeRotate( float heading, float pitch, float roll);
#endif
/** Return the angle and vector components represented by the quaternion.*/ /** Return the angle and vector components represented by the quaternion.*/
void getRotate ( float& angle, float& x, float& y, float& z ) const; void getRotate ( float& angle, float& x, float& y, float& z ) const;

View File

@ -180,6 +180,10 @@ inline std::ostream& operator << (std::ostream& output, const Vec3& vec)
return output; // to enable cascading return output; // to enable cascading
} }
const Vec3 X_AXIS(1.0f,0.0f,0.0f);
const Vec3 Y_AXIS(0.0f,1.0f,0.0f);
const Vec3 Z_AXIS(0.0f,0.0f,1.0f);
} // end of namespace osg } // end of namespace osg
#endif #endif

View File

@ -136,12 +136,25 @@ void Matrix::makeRotate( const Quat& q )
q.get(*this); q.get(*this);
} }
#ifdef USE_DEPRECATED_API
void Matrix::makeRotate( float heading, float pitch, float roll) void Matrix::makeRotate( float heading, float pitch, float roll)
{ {
Quat quat; Quat quat;
quat.makeRotate(heading,pitch,roll); quat.makeRotate(heading,pitch,roll);
quat.get(*this); quat.get(*this);
} }
#endif
void Matrix::makeRotate( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3)
{
Quat quat;
quat.makeRotate(angle1, axis1,
angle2, axis2,
angle3, axis3);
quat.get(*this);
}
void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) void Matrix::mult( const Matrix& lhs, const Matrix& rhs )
{ {

View File

@ -36,6 +36,7 @@ void Quat::makeRotate( const float angle, const Vec3& vec )
makeRotate( angle, vec[0], vec[1], vec[2] ); makeRotate( angle, vec[0], vec[1], vec[2] );
} }
#ifdef USE_DEPRECATED_API
// assume Z up, Y north, X east and euler convention // assume Z up, Y north, X east and euler convention
// as per Open Flight & Performer. // as per Open Flight & Performer.
@ -48,12 +49,19 @@ void Quat::makeRotate( float heading, float pitch, float roll)
Quat q_pitch; q_pitch.makeRotate(pitch,1.0,0.0,0.0); Quat q_pitch; q_pitch.makeRotate(pitch,1.0,0.0,0.0);
Quat q_heading; q_heading.makeRotate(-heading,0.0,0.0,1.0); Quat q_heading; q_heading.makeRotate(-heading,0.0,0.0,1.0);
// note reverse order than would be done using matrices *this = q_roll*q_pitch*q_heading;
// which raises the interesting question whether the definition }
// of Quat*Quat should be changed to fit with the v' = v x M #endif
// convention of Matrix. Will investigate further later on.
// Robert Osfield. April 2002. void Quat::makeRotate ( float angle1, const Vec3& axis1,
*this = q_heading*q_pitch*q_roll; float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3)
{
Quat q1; q1.makeRotate(angle1,axis1);
Quat q2; q2.makeRotate(angle2,axis2);
Quat q3; q3.makeRotate(angle3,axis3);
*this = q1*q2*q3;
} }
// Make a rotation Quat which will rotate vec1 to vec2 // Make a rotation Quat which will rotate vec1 to vec2