From 22d54f05e48c513bf67720ae4503a9de132f490a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 18 Aug 2002 14:42:43 +0000 Subject: [PATCH] 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. --- include/osg/Matrix | 40 ++++++++++++++++++++++++++--------- include/osg/NodeVisitor | 37 ++++++++++++++++++++------------- include/osg/Quat | 46 +++++++++++++++++++++++++++++++++-------- include/osg/Vec3 | 4 ++++ src/osg/Matrix.cpp | 13 ++++++++++++ src/osg/Quat.cpp | 20 ++++++++++++------ 6 files changed, 121 insertions(+), 39 deletions(-) diff --git a/include/osg/Matrix b/include/osg/Matrix index c77fe0c9d..5ff9af97f 100644 --- a/include/osg/Matrix +++ b/include/osg/Matrix @@ -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; diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 368c54ab3..e810eec3d 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -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: diff --git a/include/osg/Quat b/include/osg/Quat index 55e9e7ed5..29738d63e 100644 --- a/include/osg/Quat +++ b/include/osg/Quat @@ -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; diff --git a/include/osg/Vec3 b/include/osg/Vec3 index 8caa57f0c..92ca76fc0 100644 --- a/include/osg/Vec3 +++ b/include/osg/Vec3 @@ -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 diff --git a/src/osg/Matrix.cpp b/src/osg/Matrix.cpp index 210e57919..e384057d2 100644 --- a/src/osg/Matrix.cpp +++ b/src/osg/Matrix.cpp @@ -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 ) { diff --git a/src/osg/Quat.cpp b/src/osg/Quat.cpp index ddafb2e48..479deeca9 100644 --- a/src/osg/Quat.cpp +++ b/src/osg/Quat.cpp @@ -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