From 9c8c73c77ff218c7aa270dfbb031b0decd9bd767 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 23 Jan 2002 15:42:36 +0000 Subject: [PATCH] Updates to osg::Transform to allow it subclassed more easily. --- include/osg/Transform | 49 +++++++++++++++++++++++++++++++++++++++---- src/osg/Transform.cpp | 12 +++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/include/osg/Transform b/include/osg/Transform index e62b18233..0b2926303 100644 --- a/include/osg/Transform +++ b/include/osg/Transform @@ -31,7 +31,7 @@ class SG_EXPORT Transform : public Group META_Node(Transform); - /** Range of type that the Transform can be.*/ + /** Range of types that the Transform can be.*/ enum Type { DYNAMIC, @@ -49,12 +49,26 @@ class SG_EXPORT Transform : public Group /** Get the Transform Type.*/ inline const Type getType() const { return _type; } + + + + /** Get the transform's matrix. */ + inline const Matrix& getMatrix() const { if (_matrixDirty) computeMatrix(); return *_matrix; } - inline const Matrix& getMatrix() const { return *_matrix; } + /** Get the inverse of the transform's matrix. + * Automatically compute the inverse if it is not up to date. */ + inline const Matrix& getInverse() const { if (_inverseDirty) computeInverse(); return *_inverse; } + + + /** Set the transform's matrix.*/ inline void setMatrix(const Matrix& mat ) { (*_matrix) = mat; + + _matrixDirty = false; // matrix is valid, so no need to compute + _inverseDirty = true; // inverse is now invalid, so will need to recompute. + dirtyBound(); } @@ -62,6 +76,10 @@ class SG_EXPORT Transform : public Group inline void preMult( const Matrix& mat ) { (*_matrix) = mat * (*_matrix); + + _matrixDirty = false; // matrix is valid, so no need to compute + _inverseDirty = true; // inverse is now invalid, so will need to recompute. + dirtyBound(); } @@ -69,6 +87,10 @@ class SG_EXPORT Transform : public Group inline void postMult( const Matrix& mat ) { (*_matrix) = (*_matrix) * mat; + + _matrixDirty = false; // matrix is valid, so no need to compute + _inverseDirty = true; // inverse is now invalid, so will need to recompute. + dirtyBound(); } @@ -76,10 +98,29 @@ class SG_EXPORT Transform : public Group virtual ~Transform(); + /** Override's Group's computeBound. + * There is no need to override in subclasses from osg::Transform since this computeBound() uses + * the underlying matrix (calling computeMatrix if required.) */ virtual const bool computeBound() const; + + /** If you subclass from osg::Transform you must override computeMatrix() to provide your own mechanism for + * setting up the 4x4 matrix. An example of a subclass might a PositionAttitudeTransfrom which is its own + * Vec3 and Quat to calculate the matrix.*/ + virtual void computeMatrix() const { _matrixDirty = false; } - Type _type; - ref_ptr _matrix; + /** If you subclass from osg::Transform it is safe to rely on this default implementation which uses osg::Matrix::invert(getMatrix()) + * to compute the inverse. However, you may wish to override this method too since there may well be a more optimal way to + * compute the inverse rather than rely on the brute force method of osg::Matrix::invert(..).*/ + virtual void computeInverse() const { if (_inverseDirty) _inverse->invert(getMatrix()); _inverseDirty = false; } + + Type _type; + + mutable bool _matrixDirty; + mutable ref_ptr _matrix; + + mutable bool _inverseDirty; + mutable ref_ptr _inverse; + }; }; diff --git a/src/osg/Transform.cpp b/src/osg/Transform.cpp index 89c6a495c..1c3fd35fe 100644 --- a/src/osg/Transform.cpp +++ b/src/osg/Transform.cpp @@ -5,15 +5,25 @@ using namespace osg; Transform::Transform() { _type = DYNAMIC; + _matrix = new Matrix; _matrix->makeIdentity(); + _matrixDirty = false; + + _inverse = new Matrix; + _inverse->makeIdentity(); + _inverseDirty = false; } Transform::Transform(const Matrix& mat ) { _type = DYNAMIC; + _matrix = new Matrix(mat); + _matrixDirty = false; + + _inverseDirty = true; // will neeed to recompute. } @@ -25,6 +35,8 @@ const bool Transform::computeBound() const { if (!Group::computeBound()) return false; + if (_matrixDirty) computeMatrix(); + Vec3 xdash = _bsphere._center; xdash.x() += _bsphere._radius; xdash = xdash*(*_matrix);