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, float x, float y, float z );
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.*/
@ -140,10 +136,11 @@ class SG_EXPORT Matrix : public Object
inline static Matrix translate( const Vec3& dv);
inline static Matrix translate( float x, float y, float z);
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);
/** construct rotation matrix from euler angles, for conventions see makeRotate().*/
inline static Matrix rotate( float heading, float pitch, float roll);
inline static Matrix rotate( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3);
inline static Matrix rotate( const Quat& quat);
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);
#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 postMult( 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);
return m;
}
#ifdef USE_DEPRECATED_API
inline Matrix Matrix::rotate(float heading, float pitch, float roll)
{
Matrix m;
m.makeRotate(heading,pitch,roll);
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 )
{
Matrix m;

View File

@ -17,6 +17,9 @@ class LightSource;
class ClipNode;
class Group;
class Transform;
class DOFTransform;
class MatrixTransform;
class PositionAttitudeTransform;
class Projection;
class LOD;
class Switch;
@ -187,22 +190,28 @@ class SG_EXPORT NodeVisitor : public Referenced
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(Billboard& node) { apply((Geode&)node); }
virtual void apply(LightSource& node) { apply((Node&)node); }
virtual void apply(ClipNode& node) { apply((Node&)node); }
virtual void apply(Geode& node) { apply((Node&)node); }
virtual void apply(Billboard& node) { apply((Geode&)node); }
virtual void apply(LightSource& node) { apply((Node&)node); }
virtual void apply(ClipNode& 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(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); }
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(DOFTransform& node) { apply((Transform&)node); }
virtual void apply(MatrixTransform& node) { apply((Transform&)node); }
virtual void apply(PositionAttitudeTransform& node) { apply((Transform&)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:

View File

@ -85,19 +85,19 @@ class SG_EXPORT Quat
/// 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] );
return Quat( rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1],
rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0],
rhs._fv[3]*_fv[2] + rhs._fv[0]*_fv[1] - rhs._fv[1]*_fv[0] + 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] );
}
/// 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];
float x = rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1];
float y = rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0];
float z = 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[3] - rhs._fv[0]*_fv[0] - rhs._fv[1]*_fv[1] - rhs._fv[2]*_fv[2];
_fv[2] = z;
_fv[1] = y;
@ -105,6 +105,29 @@ class SG_EXPORT Quat
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
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 );
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.
Generally take adot product to get the angle between these
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.*/
void makeRotate( const Vec3& vec1, const Vec3& vec2 );
#ifdef USE_DEPRECATED_API
/** make a rotation Quat from euler angles.
* assume Z up, Y north, X east and euler convention
* as per Open Flight & Performer.
@ -217,7 +245,7 @@ class SG_EXPORT Quat
* 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);
#endif
/** Return the angle and vector components represented by the quaternion.*/
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
}
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
#endif

View File

@ -136,12 +136,25 @@ void Matrix::makeRotate( const Quat& q )
q.get(*this);
}
#ifdef USE_DEPRECATED_API
void Matrix::makeRotate( float heading, float pitch, float roll)
{
Quat quat;
quat.makeRotate(heading,pitch,roll);
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 )
{

View File

@ -36,6 +36,7 @@ void Quat::makeRotate( const float angle, const Vec3& vec )
makeRotate( angle, vec[0], vec[1], vec[2] );
}
#ifdef USE_DEPRECATED_API
// assume Z up, Y north, X east and euler convention
// as per Open Flight & Performer.
@ -48,13 +49,20 @@ void Quat::makeRotate( float heading, float pitch, float roll)
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);
// note reverse order than would be done using matrices
// which raises the interesting question whether the definition
// of Quat*Quat should be changed to fit with the v' = v x M
// convention of Matrix. Will investigate further later on.
// Robert Osfield. April 2002.
*this = q_heading*q_pitch*q_roll;
*this = q_roll*q_pitch*q_heading;
}
#endif
void Quat::makeRotate ( float angle1, const Vec3& axis1,
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
// Generally take adot product to get the angle between these