From 0acbe077faef818783c9a132c67b75fdaa61da9f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 12 Jul 2004 19:54:54 +0000 Subject: [PATCH] Added support for matix manipulator setHomePosition(,,) --- include/osgGA/DriveManipulator | 2 ++ include/osgGA/KeySwitchMatrixManipulator | 6 ++++ include/osgGA/MatrixManipulator | 40 ++++++++++++++++++++++++ src/osgGA/DriveManipulator.cpp | 33 +++++++++++-------- src/osgGA/FlightManipulator.cpp | 29 +++++++---------- src/osgGA/KeySwitchMatrixManipulator.cpp | 39 ++++++++++++++++++++++- src/osgGA/MatrixManipulator.cpp | 6 ++++ src/osgGA/TerrainManipulator.cpp | 22 +++++-------- src/osgGA/TrackballManipulator.cpp | 16 +++------- 9 files changed, 135 insertions(+), 58 deletions(-) diff --git a/include/osgGA/DriveManipulator b/include/osgGA/DriveManipulator index 1b83c5821..41198d87a 100644 --- a/include/osgGA/DriveManipulator +++ b/include/osgGA/DriveManipulator @@ -52,6 +52,8 @@ class OSGGA_EXPORT DriveManipulator : public MatrixManipulator virtual osg::Node* getNode(); + virtual void computeHomePosition(); + virtual void home(const GUIEventAdapter& ea,GUIActionAdapter& us); virtual void init(const GUIEventAdapter& ea,GUIActionAdapter& us); diff --git a/include/osgGA/KeySwitchMatrixManipulator b/include/osgGA/KeySwitchMatrixManipulator index fca0b7ba7..b76f587e8 100644 --- a/include/osgGA/KeySwitchMatrixManipulator +++ b/include/osgGA/KeySwitchMatrixManipulator @@ -109,6 +109,12 @@ public: virtual osg::Node* getNode() { return _current->getNode(); } + virtual void setHomePosition(const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up); + + virtual void setAutoComputeHomePosition(bool flag); + + virtual void computeHomePosition(); + virtual void home(const GUIEventAdapter& ee,GUIActionAdapter& aa) { _current->home(ee,aa); } virtual void init(const GUIEventAdapter& ee,GUIActionAdapter& aa) { _current->init(ee,aa); } diff --git a/include/osgGA/MatrixManipulator b/include/osgGA/MatrixManipulator index 60bbd3797..4b6c30453 100644 --- a/include/osgGA/MatrixManipulator +++ b/include/osgGA/MatrixManipulator @@ -27,6 +27,8 @@ namespace osgGA{ +#define NEW_HOME_POSITION + /** MatrixManipulator is an abstract base class defining the interface, and a certain @@ -50,6 +52,7 @@ public: virtual ~CoordinateFrameCallback() {} }; + /** set the minimum distance (as ratio) the eye point can be zoomed in towards the center before the center is pushed forward.*/ @@ -111,6 +114,37 @@ public: /** Return node if attached.*/ virtual osg::Node* getNode() { return NULL; } + virtual void setHomePosition(const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up) + { + _homeEye = eye; + _homeCenter = center; + _homeUp = up; + } + + virtual void getHomePosition(osg::Vec3d& eye, osg::Vec3d& center, osg::Vec3d& up) + { + _homeEye = eye; + _homeCenter = center; + _homeUp = up; + } + + virtual void setAutoComputeHomePosition(bool flag) { _autoComputeHomePosition = flag; } + + bool getAutoComputeHomePosition() const { return _autoComputeHomePosition; } + + virtual void computeHomePosition() + { + if(getNode()) + { + const osg::BoundingSphere& boundingSphere=getNode()->getBound(); + + setHomePosition(boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius,0.0f), + boundingSphere._center, + osg::Vec3(0.0f,0.0f,1.0f)); + } + } + + /** Move the camera to the default position. May be ignored by manipulators if home functionality is not appropriate. @@ -135,6 +169,12 @@ protected: virtual ~MatrixManipulator(); double _minimumDistance; + + bool _autoComputeHomePosition; + + osg::Vec3d _homeEye; + osg::Vec3d _homeCenter; + osg::Vec3d _homeUp; osg::ref_ptr _coordinateFrameCallback; }; diff --git a/src/osgGA/DriveManipulator.cpp b/src/osgGA/DriveManipulator.cpp index c972add7e..d825c5679 100644 --- a/src/osgGA/DriveManipulator.cpp +++ b/src/osgGA/DriveManipulator.cpp @@ -51,6 +51,7 @@ void DriveManipulator::setNode(osg::Node* node) _height = getHeightOfDriver(); _buffer = _height*1.3; } + if (getAutoComputeHomePosition()) computeHomePosition(); } @@ -65,13 +66,10 @@ osg::Node* DriveManipulator::getNode() return _node.get(); } -void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) +void DriveManipulator::computeHomePosition() { - if(_node.get()) { - - const osg::BoundingSphere& boundingSphere=_node->getBound(); osg::Vec3d ep = boundingSphere._center; @@ -110,7 +108,7 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) ep += getUpVector(cf)*_height; osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0); - computePosition(ep,lv,uv); + setHomePosition(ep,ep+lv,uv); positionSet = true; @@ -145,7 +143,7 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) ep = ip; ep += getUpVector(cf)*_height; osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0); - computePosition(ep,lv,uv); + setHomePosition(ep,ep+lv,uv); positionSet = true; @@ -156,14 +154,21 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) if (!positionSet) { - computePosition( + setHomePosition( boundingSphere._center+osg::Vec3d( 0.0,-2.0 * boundingSphere._radius,0.0), - osg::Vec3d(0.0,1.0,0.0), + boundingSphere._center+osg::Vec3d( 0.0,-2.0 * boundingSphere._radius,0.0)+osg::Vec3d(0.0,1.0,0.0), osg::Vec3d(0.0,0.0,1.0)); } } +} +void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) +{ + if (getAutoComputeHomePosition()) computeHomePosition(); + + computePosition(_homeEye, _homeCenter, _homeUp); + _velocity = 0.0; us.requestRedraw(); @@ -218,7 +223,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) ep = ip+uv*_height; osg::Vec3d lv = uv^sv; - computePosition(ep,lv,uv); + computePosition(ep,ep+lv,uv); positionSet = true; } @@ -252,7 +257,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) ep = ip+uv*_height; osg::Vec3 lv = uv^sv; - computePosition(ep,lv,uv); + computePosition(ep,ep+lv,uv); positionSet = true; } @@ -386,8 +391,10 @@ osg::Matrixd DriveManipulator::getInverseMatrix() const return osg::Matrixd::translate(-_eye)*osg::Matrixd::rotate(_rotation.inverse()); } -void DriveManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& lv,const osg::Vec3d& up) +void DriveManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up) { + osg::Vec3d lv = center-eye; + osg::Vec3d f(lv); f.normalize(); osg::Vec3d s(f^up); @@ -532,7 +539,7 @@ bool DriveManipulator::calcMovement() lv = up^sv; - computePosition(_eye,lv,up); + computePosition(_eye,_eye+lv,up); return true; @@ -570,7 +577,7 @@ bool DriveManipulator::calcMovement() lv = up^sv; - computePosition(_eye,lv,up); + computePosition(_eye,_eye+lv,up); return true; } diff --git a/src/osgGA/FlightManipulator.cpp b/src/osgGA/FlightManipulator.cpp index 910ff5867..bb36cee28 100644 --- a/src/osgGA/FlightManipulator.cpp +++ b/src/osgGA/FlightManipulator.cpp @@ -28,6 +28,8 @@ void FlightManipulator::setNode(osg::Node* node) const osg::BoundingSphere& boundingSphere=_node->getBound(); _modelScale = boundingSphere._radius; } + + if (getAutoComputeHomePosition()) computeHomePosition(); } @@ -45,26 +47,17 @@ osg::Node* FlightManipulator::getNode() void FlightManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) { - if(_node.get()) - { + if (getAutoComputeHomePosition()) computeHomePosition(); - const osg::BoundingSphere& boundingSphere=_node->getBound(); + computePosition(_homeEye, _homeCenter, _homeUp); + + _velocity = 0.0; - computePosition( - boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius,0.0f), - osg::Vec3(0.0f,1.0f,0.0f), - osg::Vec3(0.0f,0.0f,1.0f)); + us.requestRedraw(); - _velocity = 0.0f; - - us.requestRedraw(); - - us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2.0f,(ea.getYmin()+ea.getYmax())/2.0f); - - flushMouseEventStack(); - - } + us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2.0f,(ea.getYmin()+ea.getYmax())/2.0f); + flushMouseEventStack(); } @@ -198,8 +191,10 @@ osg::Matrixd FlightManipulator::getInverseMatrix() const return osg::Matrixd::translate(-_eye)*osg::Matrixd::rotate(_rotation.inverse()); } -void FlightManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& lv,const osg::Vec3& up) +void FlightManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up) { + osg::Vec3d lv = center-eye; + osg::Vec3 f(lv); f.normalize(); osg::Vec3 s(f^up); diff --git a/src/osgGA/KeySwitchMatrixManipulator.cpp b/src/osgGA/KeySwitchMatrixManipulator.cpp index 3e16627e0..d9d644f44 100644 --- a/src/osgGA/KeySwitchMatrixManipulator.cpp +++ b/src/osgGA/KeySwitchMatrixManipulator.cpp @@ -10,7 +10,9 @@ void KeySwitchMatrixManipulator::addMatrixManipulator(int key, std::string name, _manips[key]=std::make_pair(name,osg::ref_ptr(cm)); if(!_current.valid()){ _current=cm; - _current->setNode(getNode()); + _current->setAutoComputeHomePosition(_autoComputeHomePosition); + _current->setHomePosition(_homeEye,_homeCenter,_homeUp); + _current->setNode(0); _current->setCoordinateFrameCallback(getCoordinateFrameCallback()); _current->setByMatrix(getMatrix()); } @@ -34,6 +36,9 @@ void KeySwitchMatrixManipulator::selectMatrixManipulator(unsigned int num) if (itr!=_manips.end()) { + itr->second.second->setAutoComputeHomePosition(_autoComputeHomePosition); + itr->second.second->setHomePosition(_homeEye,_homeCenter,_homeUp); + if (_current.valid()) { if ( !itr->second.second->getCoordinateFrameCallback() ) @@ -61,6 +66,28 @@ void KeySwitchMatrixManipulator::setNode(osg::Node* node) } } +void KeySwitchMatrixManipulator::setHomePosition(const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up) +{ + MatrixManipulator::setHomePosition(eye, center, up); + for(KeyManipMap::iterator itr=_manips.begin(); + itr!=_manips.end(); + ++itr) + { + itr->second.second->setHomePosition(eye, center, up); + } +} + +void KeySwitchMatrixManipulator::setAutoComputeHomePosition(bool flag) +{ + _autoComputeHomePosition = flag; + for(KeyManipMap::iterator itr=_manips.begin(); + itr!=_manips.end(); + ++itr) + { + itr->second.second->setAutoComputeHomePosition(flag); + } +} + void KeySwitchMatrixManipulator::setMinimumDistance(float minimumDistance) { _minimumDistance = minimumDistance; @@ -72,6 +99,16 @@ void KeySwitchMatrixManipulator::setMinimumDistance(float minimumDistance) } } +void KeySwitchMatrixManipulator::computeHomePosition() +{ + for(KeyManipMap::iterator itr=_manips.begin(); + itr!=_manips.end(); + ++itr) + { + itr->second.second->computeHomePosition(); + } +} + void KeySwitchMatrixManipulator::setCoordinateFrameCallback(CoordinateFrameCallback* cb) { _coordinateFrameCallback = cb; diff --git a/src/osgGA/MatrixManipulator.cpp b/src/osgGA/MatrixManipulator.cpp index f6134fd0f..2c226cc85 100644 --- a/src/osgGA/MatrixManipulator.cpp +++ b/src/osgGA/MatrixManipulator.cpp @@ -8,6 +8,12 @@ using namespace osgGA; MatrixManipulator::MatrixManipulator() { _minimumDistance = 0.001; + + _autoComputeHomePosition = true; + + _homeEye.set(0.0,-1.0,0.0); + _homeCenter.set(0.0,0.0,0.0); + _homeUp.set(0.0,0.0,1.0); } diff --git a/src/osgGA/TerrainManipulator.cpp b/src/osgGA/TerrainManipulator.cpp index 46c7e474b..156ce1150 100644 --- a/src/osgGA/TerrainManipulator.cpp +++ b/src/osgGA/TerrainManipulator.cpp @@ -42,7 +42,7 @@ void TerrainManipulator::setNode(osg::Node* node) osg::notify(osg::INFO)<<"Setting terrain manipulator _minimumDistance to "<<_minimumDistance<getBound(); - - computePosition(boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius,0.0f), - boundingSphere._center, - osg::Vec3(0.0f,0.0f,1.0f)); - - us.requestRedraw(); - } + if (getAutoComputeHomePosition()) computeHomePosition(); + computePosition(_homeEye, _homeCenter, _homeUp); + us.requestRedraw(); } @@ -243,7 +235,7 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix) osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get()); if (!hitList.empty()) { - notify(INFO) << "Hit terrain ok"<< std::endl; + notify(INFO) << "Hit terrain ok A"<< std::endl; osg::Vec3d ip = hitList.front().getWorldIntersectPoint(); _center = ip; @@ -280,7 +272,7 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix) osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get()); if (!hitList.empty()) { - notify(INFO) << "Hit terrain ok"<< std::endl; + notify(INFO) << "Hit terrain ok B"<< std::endl; osg::Vec3d ip = hitList.front().getWorldIntersectPoint(); _center = ip; @@ -336,7 +328,7 @@ void TerrainManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get()); if (!hitList.empty()) { - osg::notify(osg::INFO) << "Hit terrain ok"<< std::endl; + osg::notify(osg::INFO) << "Hit terrain ok C"<< std::endl; osg::Vec3d ip = hitList.front().getWorldIntersectPoint(); _center = ip; diff --git a/src/osgGA/TrackballManipulator.cpp b/src/osgGA/TrackballManipulator.cpp index 03a444617..51b42ba98 100644 --- a/src/osgGA/TrackballManipulator.cpp +++ b/src/osgGA/TrackballManipulator.cpp @@ -28,6 +28,7 @@ void TrackballManipulator::setNode(osg::Node* node) const osg::BoundingSphere& boundingSphere=_node->getBound(); _modelScale = boundingSphere._radius; } + if (getAutoComputeHomePosition()) computeHomePosition(); } @@ -43,21 +44,12 @@ osg::Node* TrackballManipulator::getNode() } - /*ea*/ void TrackballManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us) { - if(_node.get()) - { - - const osg::BoundingSphere& boundingSphere=_node->getBound(); - - computePosition(boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius,0.0f), - boundingSphere._center, - osg::Vec3(0.0f,0.0f,1.0f)); - - us.requestRedraw(); - } + if (getAutoComputeHomePosition()) computeHomePosition(); + computePosition(_homeEye, _homeCenter, _homeUp); + us.requestRedraw(); }