Improved the panning support, and added s/getRotationMode(..) to allow

users flip between a trackball rotation style and an azim,elevation style.
This commit is contained in:
Robert Osfield
2004-05-17 15:50:44 +00:00
parent 867a1ae105
commit a62699b015
2 changed files with 112 additions and 24 deletions

View File

@@ -27,6 +27,17 @@ class OSGGA_EXPORT TerrainManipulator : public MatrixManipulator
virtual const char* className() const { return "Terrain"; }
enum RotationMode
{
ELEVATION_AZIM_ROLL,
ELEVATION_AZIM,
};
void setRotationMode(RotationMode mode);
RotationMode getRotationMode() const { return _rotationMode; }
/** set the minimum distance (as ratio) the eye point can be zoomed in towards the
center before the center is pushed forward.*/
void setMinimumZoomScale(float minimumZoomScale) { _minimumZoomScale=minimumZoomScale; }
@@ -34,6 +45,7 @@ class OSGGA_EXPORT TerrainManipulator : public MatrixManipulator
/** get the minimum distance (as ratio) the eye point can be zoomed in */
float getMinimumZoomScale() const { return _minimumZoomScale; }
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByMatrix(const osg::Matrixd& matrix);
@@ -100,20 +112,26 @@ class OSGGA_EXPORT TerrainManipulator : public MatrixManipulator
If speed is below a threshold then return false, otherwise return true.*/
bool isMouseMoving();
void clampOrientation();
// Internal event stack comprising last three mouse events.
osg::ref_ptr<const GUIEventAdapter> _ga_t1;
osg::ref_ptr<const GUIEventAdapter> _ga_t0;
osg::ref_ptr<osg::Node> _node;
osg::ref_ptr<osg::Node> _node;
float _modelScale;
float _minimumZoomScale;
float _modelScale;
bool _thrown;
RotationMode _rotationMode;
float _minimumZoomScale;
bool _thrown;
osg::CoordinateFrame _coordinateFrame;
osg::Quat _rotation;
float _distance;
osg::CoordinateFrame _coordinateFrame;
osg::Quat _rotation;
float _distance;
};

View File

@@ -9,10 +9,13 @@ using namespace osgGA;
TerrainManipulator::TerrainManipulator()
{
_modelScale = 0.01f;
_rotationMode =ELEVATION_AZIM;
_minimumZoomScale = 0.0005f;
_distance = 1.0f;
_thrown = false;
_distance = 1.0f;
}
@@ -21,6 +24,13 @@ TerrainManipulator::~TerrainManipulator()
}
void TerrainManipulator::setRotationMode(RotationMode mode)
{
_rotationMode = mode;
// need to correct rotation.
}
void TerrainManipulator::setNode(osg::Node* node)
{
_node = node;
@@ -268,6 +278,8 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix)
}
}
clampOrientation();
}
osg::Matrixd TerrainManipulator::getMatrix() const
@@ -326,6 +338,8 @@ void TerrainManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& c
rotation_matrix.get(_rotation);
_rotation = _rotation.inverse();
clampOrientation();
}
@@ -345,25 +359,50 @@ bool TerrainManipulator::calcMovement()
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
// rotate camera.
if (_rotationMode==ELEVATION_AZIM_ROLL)
{
// rotate camera.
osg::Vec3 axis;
float angle;
osg::Vec3 axis;
float angle;
float px0 = _ga_t0->getXnormalized();
float py0 = _ga_t0->getYnormalized();
float px0 = _ga_t0->getXnormalized();
float py0 = _ga_t0->getYnormalized();
float px1 = _ga_t1->getXnormalized();
float py1 = _ga_t1->getYnormalized();
trackball(axis,angle,px1,py1,px0,py0);
osg::Quat new_rotate;
new_rotate.makeRotate(angle,axis);
_rotation = _rotation*new_rotate;
}
else
{
osg::Matrix rotation_matrix;
rotation_matrix.set(_rotation);
osg::Vec3 lookVector = -getUpVector(rotation_matrix);
osg::Vec3 sideVector = getSideVector(rotation_matrix);
osg::Vec3 upVector = getFrontVector(rotation_matrix);
osg::Vec3 forwardVector =osg::Vec3(0.0f,0.0f,1.0f)^sideVector;
sideVector = forwardVector^osg::Vec3(0.0f,0.0f,1.0f);
forwardVector.normalize();
sideVector.normalize();
osg::Quat rotate_elevation;
rotate_elevation.makeRotate(dy,sideVector);
osg::Quat rotate_azim;
rotate_azim.makeRotate(-dx,osg::Vec3(0.0f,0.0f,1.0f));
_rotation = _rotation * rotate_elevation * rotate_azim;
}
float px1 = _ga_t1->getXnormalized();
float py1 = _ga_t1->getYnormalized();
trackball(axis,angle,px1,py1,px0,py0);
osg::Quat new_rotate;
new_rotate.makeRotate(angle,axis);
_rotation = _rotation*new_rotate;
return true;
}
@@ -457,6 +496,37 @@ bool TerrainManipulator::calcMovement()
return false;
}
void TerrainManipulator::clampOrientation()
{
if (_rotationMode==ELEVATION_AZIM)
{
osg::Matrix rotation_matrix;
rotation_matrix.set(_rotation);
osg::Vec3 lookVector = -getUpVector(rotation_matrix);
osg::Vec3 upVector = getFrontVector(rotation_matrix);
osg::Vec3 sideVector = lookVector ^ osg::Vec3(0.0f,0.0f,1.0f);
if (sideVector.length()<0.1)
{
osg::notify(osg::NOTICE)<<"Side vector short "<<sideVector.length()<<std::endl;
sideVector = upVector^osg::Vec3(0.0f,0.0f,1.0f);
sideVector.normalize();
}
Vec3 newUpVector = sideVector^lookVector;
newUpVector.normalize();
osg::Quat rotate_roll;
rotate_roll.makeRotate(upVector,newUpVector);
_rotation = _rotation * rotate_roll;
}
}
/*
* This size should really be based on the distance from the center of