Skip to content

Commit

Permalink
Fixed numerical accuracy problem in Trackball manipulator.
Browse files Browse the repository at this point in the history
  • Loading branch information
robertosfield committed Aug 29, 2002
1 parent 20dd09b commit f1ed6fd
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 23 deletions.
8 changes: 8 additions & 0 deletions include/osgGA/TrackballManipulator
Expand Up @@ -49,6 +49,10 @@ class OSGGA_EXPORT TrackballManipulator : public CameraManipulator
/** For the give mouse movement calculate the movement of the camera.
Return true is camera has moved and a redraw is required.*/
bool calcMovement();

void computeLocalDataFromCamera();

void computeCameraFromLocalData();

void trackball(osg::Vec3& axis,float& angle, float p1x, float p1y, float p2x, float p2y);
float tb_project_to_sphere(float r, float x, float y);
Expand All @@ -68,6 +72,10 @@ class OSGGA_EXPORT TrackballManipulator : public CameraManipulator
float _minimumZoomScale;

bool _thrown;

osg::Vec3 _center;
osg::Quat _rotation;
float _distance;

};

Expand Down
75 changes: 52 additions & 23 deletions src/osgGA/TrackballManipulator.cpp
Expand Up @@ -53,6 +53,8 @@ void TrackballManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
boundingSphere._center,
osg::Vec3(0.0f,0.0f,1.0f));

computeLocalDataFromCamera();

us.requestRedraw();
}

Expand All @@ -62,9 +64,10 @@ void TrackballManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
void TrackballManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
{
flushMouseEventStack();

computeLocalDataFromCamera();
}


bool TrackballManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
{
if(!_camera.get()) return false;
Expand Down Expand Up @@ -200,6 +203,41 @@ void TrackballManipulator::addMouseEvent(const GUIEventAdapter& ea)
}



void TrackballManipulator::computeLocalDataFromCamera()
{
// maths from gluLookAt/osg::Matrix::makeLookAt
osg::Vec3 f(_camera->getCenterPoint()-_camera->getEyePoint());
f.normalize();
osg::Vec3 s(f^_camera->getUpVector());
s.normalize();
osg::Vec3 u(s^f);
u.normalize();

osg::Matrix rotation_matrix(s[0], u[0], -f[0], 0.0f,
s[1], u[1], -f[1], 0.0f,
s[2], u[2], -f[2], 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);

_center = _camera->getCenterPoint();
_distance = _camera->getLookDistance();
_rotation.set(rotation_matrix);
_rotation = _rotation.inverse();

}

void TrackballManipulator::computeCameraFromLocalData()
{
osg::Matrix new_rotation;
new_rotation.makeRotate(_rotation);

osg::Vec3 up = osg::Vec3(0.0f,1.0f,0.0) * new_rotation;
osg::Vec3 eye = (osg::Vec3(0.0f,0.0f,_distance) * new_rotation) + _center;

_camera->setLookAt(eye,_center,up);
}


bool TrackballManipulator::calcMovement()
{

Expand All @@ -220,7 +258,6 @@ bool TrackballManipulator::calcMovement()

// rotate camera.

osg::Vec3 center = _camera->getCenterPoint();
osg::Vec3 axis;
float angle;

Expand All @@ -244,12 +281,12 @@ bool TrackballManipulator::calcMovement()

trackball(axis,angle,px1,py1,px0,py0);

osg::Matrix mat;
mat.makeTranslate(-center.x(),-center.y(),-center.z());
mat *= Matrix::rotate(angle,axis.x(),axis.y(),axis.z());
mat *= Matrix::translate(center.x(),center.y(),center.z());
osg::Quat new_rotate;
new_rotate.makeRotate(angle,axis);

_rotation = _rotation*new_rotate;

_camera->transformLookAt(mat);
computeCameraFromLocalData();

return true;

Expand All @@ -259,19 +296,17 @@ bool TrackballManipulator::calcMovement()
{

// pan model.


float scale = 0.0015f*focalLength;

osg::Vec3 uv = _camera->getUpVector();
osg::Vec3 sv = _camera->getSideVector();
osg::Vec3 dv = uv*(dy*scale)-sv*(dx*scale);

osg::Matrix mat;
mat.makeTranslate(dv.x(),dv.y(),dv.z());

_camera->transformLookAt(mat);
_center += dv;

computeCameraFromLocalData();

return true;

}
Expand All @@ -284,29 +319,23 @@ bool TrackballManipulator::calcMovement()
float scale = 1.0f-dy*0.001f;
if (fd*scale>_modelScale*_minimumZoomScale)
{
// zoom camera in.
osg::Vec3 center = _camera->getCenterPoint();

osg::Matrix mat;
mat.makeTranslate(-center.x(),-center.y(),-center.z());
mat *= Matrix::scale(scale,scale,scale);
mat *= Matrix::translate(center.x(),center.y(),center.z());
_distance *= scale;

_camera->transformLookAt(mat);
computeCameraFromLocalData();

}
else
{

// notify(DEBUG_INFO) << "Pushing forward"<<std::endl;
// notify(DEBUG_INFO) << "Pushing forward"<<std::endl;
// push the camera forward.
float scale = 0.0015f*fd;
osg::Vec3 dv = _camera->getLookVector()*(dy*scale);

osg::Matrix mat;
mat.makeTranslate(dv.x(),dv.y(),dv.z());
_center += dv;

_camera->transformLookAt(mat);
computeCameraFromLocalData();

}

Expand Down

0 comments on commit f1ed6fd

Please sign in to comment.