From e9f4ed87bc28921fcddb5fa45378910756857f39 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Aug 2004 15:15:51 +0000 Subject: [PATCH] From Jay Zuckerman, fixes to AutoTransform so that it includes checking of previous position value. --- include/osg/AutoTransform | 148 ++++++++++---------- src/osg/AutoTransform.cpp | 274 +++++++++++++++++++------------------- 2 files changed, 215 insertions(+), 207 deletions(-) diff --git a/include/osg/AutoTransform b/include/osg/AutoTransform index 954eee3fa..1a136f9d6 100644 --- a/include/osg/AutoTransform +++ b/include/osg/AutoTransform @@ -1,106 +1,108 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. -*/ + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ -#ifndef OSG_AUTOTRANSFORM -#define OSG_AUTOTRANSFORM 1 +#ifndef OSG_AUTOTRANSFORM +#define OSG_AUTOTRANSFORM 1 #include -#include -#include -#include +#include +#include +#include -namespace osg { +namespace osg { /** AutoTransform - is Transform the automatically scales or rotates - * to keep its children relative to screen space coordinates. -*/ -class SG_EXPORT AutoTransform : public Transform -{ - public : - AutoTransform(); + * to keep its children relative to screen space coordinates. +*/ +class SG_EXPORT AutoTransform : public Transform +{ + public : + AutoTransform(); - AutoTransform(const AutoTransform& pat,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + AutoTransform(const AutoTransform& pat,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - virtual osg::Object* cloneType() const { return new AutoTransform (); } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new AutoTransform (*this,copyop); } - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } - virtual const char* className() const { return "AutoTransform"; } - virtual const char* libraryName() const { return "osg"; } + virtual osg::Object* cloneType() const { return new AutoTransform (); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new AutoTransform (*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "AutoTransform"; } + virtual const char* libraryName() const { return "osg"; } - virtual void accept(NodeVisitor& nv); + virtual void accept(NodeVisitor& nv); - virtual AutoTransform* asAutoTransform() { return this; } - virtual const AutoTransform* asAutoTransform() const { return this; } + virtual AutoTransform* asAutoTransform() { return this; } + virtual const AutoTransform* asAutoTransform() const { return this; } inline void setPosition(const Vec3& pos) { _position = pos; _matrixDirty=true; dirtyBound(); } - inline const Vec3& getPosition() const { return _position; } + inline const Vec3& getPosition() const { return _position; } inline void setRotation(const Quat& quat) { _rotation = quat; _matrixDirty=true; dirtyBound(); } - inline const Quat& getRotation() const { return _rotation; } - + inline const Quat& getRotation() const { return _rotation; } + inline void setScale(float scale) { _scale.set(scale,scale,scale); _matrixDirty=true; dirtyBound(); } - inline void setScale(const Vec3& scale) { _scale = scale; dirtyBound(); } - inline const Vec3& getScale() const { return _scale; } - + inline void setScale(const Vec3& scale) { _scale = scale; dirtyBound(); } + inline const Vec3& getScale() const { return _scale; } + inline void setPivotPoint(const Vec3& pivot) { _pivotPoint = pivot; _matrixDirty=true; dirtyBound(); } - inline const Vec3& getPivotPoint() const { return _pivotPoint; } - + inline const Vec3& getPivotPoint() const { return _pivotPoint; } + - void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } - float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } + void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } + float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } void setAutoRotateToScreen(bool autoRotateToScreen) { _autoRotateToScreen = autoRotateToScreen; _matrixDirty=true; } - bool getAutoRotateToScreen() const { return _autoRotateToScreen; } + bool getAutoRotateToScreen() const { return _autoRotateToScreen; } void setAutoScaleToScreen(bool autoScaleToScreen) { _autoScaleToScreen = autoScaleToScreen; _matrixDirty=true; } - bool getAutoScaleToScreen() const { return _autoScaleToScreen; } + bool getAutoScaleToScreen() const { return _autoScaleToScreen; } - virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const; + virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const; - virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const; + virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const; - protected : - - virtual ~AutoTransform() {} + protected : + + virtual ~AutoTransform() {} + + + Vec3 _position; + Vec3 _pivotPoint; + float _autoUpdateEyeMovementTolerance; + bool _autoRotateToScreen; + bool _autoScaleToScreen; + + mutable Quat _rotation; + mutable Vec3 _scale; + mutable bool _firstTimeToInitEyePoint; + mutable osg::Vec3 _previousEyePoint; + mutable int _previousWidth; + mutable int _previousHeight; + mutable osg::Matrix _previousProjection; + mutable osg::Vec3 _previousPosition; + + + void computeMatrix() const; + + mutable bool _matrixDirty; + mutable osg::Matrix _cachedMatrix; + + +}; - Vec3 _position; - Vec3 _pivotPoint; - float _autoUpdateEyeMovementTolerance; - bool _autoRotateToScreen; - bool _autoScaleToScreen; - - mutable Quat _rotation; - mutable Vec3 _scale; - mutable bool _firstTimeToInitEyePoint; - mutable osg::Vec3 _previousEyePoint; - mutable int _previousWidth; - mutable int _previousHeight; - mutable osg::Matrix _previousProjection; +} - void computeMatrix() const; - - mutable bool _matrixDirty; - mutable osg::Matrix _cachedMatrix; - - - -}; - -} - -#endif +#endif diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp index 496054ba3..1a5de9a5c 100644 --- a/src/osg/AutoTransform.cpp +++ b/src/osg/AutoTransform.cpp @@ -1,33 +1,33 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. -*/ -#include -#include + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include +#include -using namespace osg; +using namespace osg; -AutoTransform::AutoTransform(): - _autoUpdateEyeMovementTolerance(0.0f), - _autoRotateToScreen(false), - _autoScaleToScreen(false), - _scale(1.0f,1.0f,1.0f), - _firstTimeToInitEyePoint(true), - _matrixDirty(true) -{ -// setNumChildrenRequiringUpdateTraversal(1); -} +AutoTransform::AutoTransform(): + _autoUpdateEyeMovementTolerance(0.0f), + _autoRotateToScreen(false), + _autoScaleToScreen(false), + _scale(1.0f,1.0f,1.0f), + _firstTimeToInitEyePoint(true), + _matrixDirty(true) +{ +// setNumChildrenRequiringUpdateTraversal(1); +} -AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop): - Transform(pat,copyop), +AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop): + Transform(pat,copyop), _position(pat._position), _pivotPoint(pat._pivotPoint), _autoUpdateEyeMovementTolerance(pat._autoUpdateEyeMovementTolerance), @@ -37,131 +37,137 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop): _scale(pat._scale), _firstTimeToInitEyePoint(true), _matrixDirty(true) -{ -// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); -} +{ +// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); +} -bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const -{ - if (_matrixDirty) computeMatrix(); - - if (_referenceFrame==RELATIVE_TO_PARENTS) - { - matrix.preMult(_cachedMatrix); - } - else // absolute - { - matrix = _cachedMatrix; - } - return true; -} +bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const +{ + if (_matrixDirty) computeMatrix(); + + if (_referenceFrame==RELATIVE_TO_PARENTS) + { + matrix.preMult(_cachedMatrix); + } + else // absolute + { + matrix = _cachedMatrix; + } + return true; +} -bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const -{ - if (_referenceFrame==RELATIVE_TO_PARENTS) - { - matrix.postMult(osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_rotation.inverse())* - osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* - osg::Matrix::translate(_pivotPoint)); - } - else // absolute - { - matrix = osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_rotation.inverse())* - osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* - osg::Matrix::translate(_pivotPoint); - } - return true; -} +bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const +{ + if (_referenceFrame==RELATIVE_TO_PARENTS) + { + matrix.postMult(osg::Matrix::translate(-_position)* + osg::Matrix::rotate(_rotation.inverse())* + osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* + osg::Matrix::translate(_pivotPoint)); + } + else // absolute + { + matrix = osg::Matrix::translate(-_position)* + osg::Matrix::rotate(_rotation.inverse())* + osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* + osg::Matrix::translate(_pivotPoint); + } + return true; +} -void AutoTransform::computeMatrix() const -{ - if (!_matrixDirty) return; - - _cachedMatrix.set(osg::Matrix::translate(-_pivotPoint)* - osg::Matrix::scale(_scale)* - osg::Matrix::rotate(_rotation)* - osg::Matrix::translate(_position)); - - _matrixDirty = false; -} +void AutoTransform::computeMatrix() const +{ + if (!_matrixDirty) return; + + _cachedMatrix.set(osg::Matrix::translate(-_pivotPoint)* + osg::Matrix::scale(_scale)* + osg::Matrix::rotate(_rotation)* + osg::Matrix::translate(_position)); + + _matrixDirty = false; +} -void AutoTransform::accept(NodeVisitor& nv) -{ - // if app traversal update the frame count. - if (nv.getVisitorType()==NodeVisitor::UPDATE_VISITOR) - { - } - else - if (nv.getVisitorType()==NodeVisitor::CULL_VISITOR) - { +void AutoTransform::accept(NodeVisitor& nv) +{ + // if app traversal update the frame count. + if (nv.getVisitorType()==NodeVisitor::UPDATE_VISITOR) + { + } + else + if (nv.getVisitorType()==NodeVisitor::CULL_VISITOR) + { - CullStack* cs = dynamic_cast(&nv); - if (cs) - { + CullStack* cs = dynamic_cast(&nv); + if (cs) + { - int width = _previousWidth; - int height = _previousHeight; + int width = _previousWidth; + int height = _previousHeight; - osg::Viewport* viewport = cs->getViewport(); - if (viewport) - { - width = viewport->width(); - height = viewport->height(); - } + osg::Viewport* viewport = cs->getViewport(); + if (viewport) + { + width = viewport->width(); + height = viewport->height(); + } - const osg::Vec3& eyePoint = cs->getEyeLocal(); + osg::Vec3 eyePoint = cs->getEyeLocal(); + osg::Vec3 position = getPosition(); const osg::Matrix& projection = cs->getProjectionMatrix(); - bool doUpdate = _firstTimeToInitEyePoint; - if (!_firstTimeToInitEyePoint) - { - osg::Vec3 dv = _previousEyePoint-eyePoint; - if (dv.length2()>getAutoUpdateEyeMovementTolerance()*(eyePoint-getPosition()).length2()) - { - doUpdate = true; - } - else if (width!=_previousWidth || height!=_previousHeight) - { - doUpdate = true; - } + bool doUpdate = _firstTimeToInitEyePoint; + if (!_firstTimeToInitEyePoint) + { + osg::Vec3 dv = _previousEyePoint-eyePoint; + if (dv.length2()>getAutoUpdateEyeMovementTolerance()*(eyePoint-getPosition()).length2()) + { + doUpdate = true; + } + else if (width!=_previousWidth || height!=_previousHeight) + { + doUpdate = true; + } else if (projection != _previousProjection) - { - doUpdate = true; - } - } - _firstTimeToInitEyePoint = false; + { + doUpdate = true; + } + else if (position != _previousPosition) + { + doUpdate = true; + } + } + _firstTimeToInitEyePoint = false; - if (doUpdate) - { + if (doUpdate) + { - if (getAutoScaleToScreen()) - { - float size = 1.0f/cs->pixelSize(getPosition(),1.0f); - setScale(size); - } + if (getAutoScaleToScreen()) + { + float size = 1.0f/cs->pixelSize(getPosition(),1.0f); + setScale(size); + } - if (getAutoRotateToScreen()) - { - osg::Quat rotation; - cs->getModelViewMatrix().get(rotation); - setRotation(rotation.inverse()); - } + if (getAutoRotateToScreen()) + { + osg::Quat rotation; + cs->getModelViewMatrix().get(rotation); + setRotation(rotation.inverse()); + } - _previousEyePoint = eyePoint; - _previousWidth = width; - _previousHeight = height; - _previousProjection = projection; + _previousEyePoint = eyePoint; + _previousWidth = width; + _previousHeight = height; + _previousProjection = projection; + _previousPosition = position; - _matrixDirty = true; - } + _matrixDirty = true; + } - } - } - - // now do the proper accept - Transform::accept(nv); -} + } + } + + // now do the proper accept + Transform::accept(nv); +}