diff --git a/examples/osgautotransform/osgautotransform.cpp b/examples/osgautotransform/osgautotransform.cpp index 292ac4660..9438918fd 100644 --- a/examples/osgautotransform/osgautotransform.cpp +++ b/examples/osgautotransform/osgautotransform.cpp @@ -71,7 +71,7 @@ osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& lab return geode; } -osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps) +osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps, osg::AutoTransform::AutoRotateMode autoRotateMode, const std::string& str) { osg::Group* group = new osg::Group; @@ -80,7 +80,7 @@ osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps) osg::Vec3 pos = s; - bool useAuto = false; + bool useAuto = true; if (useAuto) { osg::Vec3Array* vertices = new osg::Vec3Array; @@ -89,9 +89,8 @@ osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps) { osg::AutoTransform* at = new osg::AutoTransform; at->setPosition(pos); - at->setAutoRotateToScreen(true); - at->setAutoScaleToScreen(true); - at->addChild(createLabel(osg::Vec3(0.0f,0.0f,0.0f),40.0f,"Test 2")); + at->setAutoRotateMode(autoRotateMode); + at->addChild(createLabel(osg::Vec3(0.0f,0.0f,0.0f),dv.length()*0.2f,str)); vertices->push_back(pos); pos += dv; @@ -118,7 +117,7 @@ osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps) for(int i=0;iaddChild(createLabel3(osg::Vec3(pos),dv.length()*0.5f,"Test 2")); + group->addChild(createLabel3(osg::Vec3(pos),dv.length()*0.5f,str)); vertices->push_back(pos); pos += dv; @@ -146,11 +145,11 @@ osg::Node* createScene() { osg::Group* root = new osg::Group; - int numReps = 3333; -// int numReps = 10; - root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(1000.0,0.0,0.0),numReps)); - root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,1000.0,0.0),numReps)); - root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,0.0,1000.0),numReps)); +// int numReps = 3333; + int numReps = 10; + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(1000.0,0.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_CAMERA,"ROTATE_TO_CAMERA")); + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,1000.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_SCREEN,"ROTATE_TO_SCREEN")); + root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,0.0,1000.0),numReps,osg::AutoTransform::NO_ROTATION,"NO_ROTATION")); return root; } diff --git a/include/osg/AutoTransform b/include/osg/AutoTransform index 1a136f9d6..7dc15086b 100644 --- a/include/osg/AutoTransform +++ b/include/osg/AutoTransform @@ -1,108 +1,139 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under + * + * 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. + * (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 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; } + + + + + enum AutoRotateMode + { + NO_ROTATION, + ROTATE_TO_SCREEN, + ROTATE_TO_CAMERA + }; + + void setAutoRotateMode(AutoRotateMode mode) { _autoRotateMode = mode; } + + AutoRotateMode getAutoRotateMode() const { return _autoRotateMode; } + +#ifdef USE_DEPRECATED_API + void setAutoRotateToScreen(bool autoRotateToScreen) + { + setAutoRotateMode(autoRotateToScreen?ROTATE_TO_SCREEN:NO_ROTATION); + } + + bool getAutoRotateToCamera() const { return _autoRotateMode==ROTATE_TO_SCREEN; } + + void setAutoRotateToCamera(bool autoRotateToCamera) + { + setAutoRotateMode(autoRotateToScreen?ROTATE_TO_CAMERA:NO_ROTATION); + } + + bool getAutoRotateToCamera() const { return _autoRotateMode==ROTATE_TO_SCREEN; } +#endif - void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } - float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } - void setAutoRotateToScreen(bool autoRotateToScreen) { _autoRotateToScreen = autoRotateToScreen; _matrixDirty=true; } - 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; + Vec3 _position; + Vec3 _pivotPoint; + float _autoUpdateEyeMovementTolerance; + + AutoRotateMode _autoRotateMode; + + 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; + void computeMatrix() const; - mutable bool _matrixDirty; - mutable osg::Matrix _cachedMatrix; - + mutable bool _matrixDirty; + mutable osg::Matrix _cachedMatrix; - -}; + + +}; -} +} -#endif +#endif diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp index 1a5de9a5c..c98d9ec68 100644 --- a/src/osg/AutoTransform.cpp +++ b/src/osg/AutoTransform.cpp @@ -1,173 +1,182 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under + * + * 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. + * (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 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), + _autoRotateMode(NO_ROTATION), + _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), - _autoRotateToScreen(pat._autoRotateToScreen), + _autoRotateMode(pat._autoRotateMode), _autoScaleToScreen(pat._autoScaleToScreen), _rotation(pat._rotation), _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(); + } osg::Vec3 eyePoint = cs->getEyeLocal(); - osg::Vec3 position = getPosition(); + 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; - } + { + doUpdate = true; + } else if (position != _previousPosition) { doUpdate = true; } - } - _firstTimeToInitEyePoint = false; + } + _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 (_autoRotateMode==ROTATE_TO_SCREEN) + { + osg::Quat rotation; + cs->getModelViewMatrix().get(rotation); + setRotation(rotation.inverse()); + } + else if (_autoRotateMode==ROTATE_TO_CAMERA) + { + osg::Vec3 PosToEye = _position - eyePoint; + osg::Matrix lookto = osg::Matrix::lookAt( + osg::Vec3(0,0,0), PosToEye, cs->getUpLocal()); + Quat q; + q.set(osg::Matrix::inverse(lookto)); + setRotation(q); + } - _previousEyePoint = eyePoint; - _previousWidth = width; - _previousHeight = height; - _previousProjection = projection; - _previousPosition = position; + _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); +} diff --git a/src/osgPlugins/osg/AutoTransform.cpp b/src/osgPlugins/osg/AutoTransform.cpp index 8711df92e..6e247546e 100644 --- a/src/osgPlugins/osg/AutoTransform.cpp +++ b/src/osgPlugins/osg/AutoTransform.cpp @@ -93,7 +93,18 @@ bool AutoTransform_readLocalData(Object& obj, Input& fr) if (fr.matchSequence("autoRotateToScreen %w")) { std::string w(fr[1].getStr()); - transform.setAutoRotateToScreen(w == "TRUE"); + transform.setAutoRotateMode((w == "TRUE") ? osg::AutoTransform::ROTATE_TO_SCREEN : osg::AutoTransform::NO_ROTATION); + fr += 2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("autoRotateMode %w")) + { + std::string w(fr[1].getStr()); + if (w=="ROTATE_TO_SCREEN") transform.setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN); + else if (w=="ROTATE_TO_CAMERA") transform.setAutoRotateMode(osg::AutoTransform::ROTATE_TO_CAMERA); + else if (w=="NO_ROTATION") transform.setAutoRotateMode(osg::AutoTransform::NO_ROTATION); + fr += 2; iteratorAdvanced = true; } @@ -118,9 +129,18 @@ bool AutoTransform_writeLocalData(const Object& obj, Output& fw) fw.indent()<<"rotation "<