diff --git a/include/osgGA/KeySwitchMatrixManipulator b/include/osgGA/KeySwitchMatrixManipulator index 50687072b..53db2e7de 100644 --- a/include/osgGA/KeySwitchMatrixManipulator +++ b/include/osgGA/KeySwitchMatrixManipulator @@ -64,6 +64,8 @@ public: // Overrides from MatrixManipulator... + /** set the coordinate frame which tells the manipulator which way is up, east and north.*/ + virtual void setCoordinateFrame(const osg::CoordinateFrame& cf) { _coordinateFrame = cf; _current->setCoordinateFrame(cf); } /** set the position of the matrix manipulator using a 4x4 Matrix.*/ virtual void setByMatrix(const osg::Matrixd& matrix) { _current->setByMatrix(matrix); } diff --git a/include/osgGA/MatrixManipulator b/include/osgGA/MatrixManipulator index 083708e81..b6818bea8 100644 --- a/include/osgGA/MatrixManipulator +++ b/include/osgGA/MatrixManipulator @@ -16,6 +16,7 @@ #include #include +#include #include @@ -39,6 +40,16 @@ public: virtual const char* className() const { return "MatrixManipulator"; } + + /** set the coordinate frame which tells the manipulator which way is up, east and north.*/ + virtual void setCoordinateFrame(const osg::CoordinateFrame& cf) { _coordinateFrame = cf; } + + /** get the coordinate frame.*/ + const osg::CoordinateFrame& getCoordinateFrame() const { return _coordinateFrame; } + + osg::Vec3 getSideVector() const { return osg::Vec3(_coordinateFrame(0,0),_coordinateFrame(1,0),_coordinateFrame(2,0)); } + osg::Vec3 getFromVector() const { return osg::Vec3(_coordinateFrame(0,1),_coordinateFrame(1,1),_coordinateFrame(2,1)); } + osg::Vec3 getUpVector() const { return osg::Vec3(_coordinateFrame(0,2),_coordinateFrame(1,2),_coordinateFrame(2,2)); } /** set the position of the matrix manipulator using a 4x4 Matrix.*/ virtual void setByMatrix(const osg::Matrixd& matrix) = 0; @@ -95,6 +106,7 @@ protected: MatrixManipulator(); virtual ~MatrixManipulator(); + osg::CoordinateFrame _coordinateFrame; }; } diff --git a/src/osgGA/DriveManipulator.cpp b/src/osgGA/DriveManipulator.cpp index 5db1ed423..41c940185 100644 --- a/src/osgGA/DriveManipulator.cpp +++ b/src/osgGA/DriveManipulator.cpp @@ -75,8 +75,8 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) osg::Vec3 ep = boundingSphere._center; osg::Vec3 bp = ep; - ep.z() -= _modelScale*0.0001f; - bp.z() -= _modelScale; + ep -= getUpVector()* _modelScale*0.0001f; + bp -= getUpVector()* _modelScale; // check to see if any obstruction in front. osgUtil::IntersectVisitor iv; @@ -99,11 +99,11 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) osg::Vec3 np = hitList.front().getWorldIntersectNormal(); osg::Vec3 uv; - if (np.z()>0.0f) uv = np; + if (np * getUpVector()>0.0f) uv = np; else uv = -np; ep = ip; - ep.z() += _height; + ep += getUpVector()*_height; osg::Vec3 lv = uv^osg::Vec3(1.0f,0.0f,0.0f); computePosition(ep,lv,uv); @@ -117,7 +117,7 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) if (!positionSet) { bp = ep; - bp.z() += _modelScale; + bp += getUpVector()*_modelScale; osg::ref_ptr segUp = new osg::LineSegment; segUp->set(ep,bp); @@ -135,11 +135,11 @@ void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us) osg::Vec3 np = hitList.front().getWorldIntersectNormal(); osg::Vec3 uv; - if (np.z()>0.0f) uv = np; + if (np*getUpVector()>0.0f) uv = np; else uv = -np; ep = ip; - ep.z() += _height; + ep += getUpVector()*_height; osg::Vec3 lv = uv^osg::Vec3(1.0f,0.0f,0.0f); computePosition(ep,lv,uv); @@ -183,7 +183,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) rotation_matrix.set(_rotation); osg::Vec3 sv = osg::Vec3(1.0f,0.0f,0.0f) * rotation_matrix; osg::Vec3 bp = ep; - bp.z() -= _modelScale; + bp -= getUpVector()*_modelScale; // check to see if any obstruction in front. osgUtil::IntersectVisitor iv; @@ -206,7 +206,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) osg::Vec3 np = hitList.front().getWorldIntersectNormal(); osg::Vec3 uv; - if (np.z()>0.0f) uv = np; + if (np*getUpVector()>0.0f) uv = np; else uv = -np; ep = ip+uv*_height; @@ -222,7 +222,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) if (!positionSet) { bp = ep; - bp.z() += _modelScale; + bp += getUpVector()*_modelScale; osg::ref_ptr segUp = new osg::LineSegment; segUp->set(ep,bp); @@ -240,7 +240,7 @@ void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) osg::Vec3 np = hitList.front().getWorldIntersectNormal(); osg::Vec3 uv; - if (np.z()>0.0f) uv = np; + if (np*getUpVector()>0.0f) uv = np; else uv = -np; ep = ip+uv*_height; @@ -535,7 +535,7 @@ bool DriveManipulator::calcMovement() // no hit on the terrain found therefore resort to a fall under // under the influence of gravity. osg::Vec3 dp = lfp; - dp.z() -= 2*_modelScale; + dp -= getUpVector()* (2*_modelScale); iv.reset(); diff --git a/src/osgGA/FlightManipulator.cpp b/src/osgGA/FlightManipulator.cpp index d0717bbed..51efaabdb 100644 --- a/src/osgGA/FlightManipulator.cpp +++ b/src/osgGA/FlightManipulator.cpp @@ -282,11 +282,15 @@ bool FlightManipulator::calcMovement() if (_yawMode==YAW_AUTOMATICALLY_WHEN_BANKED) { - float bank = asinf(sv.z()); + //float bank = asinf(sv.z()); + float bank = asinf(sv *getUpVector()); float yaw = inRadians(bank)*dt; osg::Quat yaw_rotate; - yaw_rotate.makeRotate(yaw,0.0f,0.0f,1.0f); + //yaw_rotate.makeRotate(yaw,0.0f,0.0f,1.0f); + + yaw_rotate.makeRotate(yaw,getUpVector()); + delta_rotate = delta_rotate*yaw_rotate; } diff --git a/src/osgGA/TrackballManipulator.cpp b/src/osgGA/TrackballManipulator.cpp index ac8209462..f936a8ed1 100644 --- a/src/osgGA/TrackballManipulator.cpp +++ b/src/osgGA/TrackballManipulator.cpp @@ -230,7 +230,6 @@ void TrackballManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& bool TrackballManipulator::calcMovement() { - // return if less then two events have been added. if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;