From Lee Bulter, "I noticed that when "throwing" things the rate of motion once thrown was
dependent on the complexity of the geometry. For complex scenes this meant that it looked like you were "throwing" the display into molasses. For simple geometry things get over-excited once thrown. The fix is to factor in the frame rendering time to the caluclated motion. I've implemented this for rotation and panning. Now when things are thrown they maintain a rate very close to what was happening when the mouse button was released."
This commit is contained in:
parent
44a8e850f4
commit
b1a99ba25f
@ -149,6 +149,24 @@ class OSGGA_EXPORT TrackballManipulator : public MatrixManipulator
|
||||
bool _allowThrow;
|
||||
bool _thrown;
|
||||
|
||||
|
||||
/** Indicates whether "thrown" display should match rate of motion at time of throw.
|
||||
* This is significant on systems where the delta between mouse events can be radically different
|
||||
* from the delta in display update events.
|
||||
*/
|
||||
bool _rate_sensitive;
|
||||
|
||||
/** The approximate amount of time it is currently taking to draw a frame.
|
||||
* This is used to compute the delta in translation/rotation during a thrown display update.
|
||||
* It allows us to match an delta in position/rotation independent of the rendering frame rate.
|
||||
*/
|
||||
double _delta_frame_time;
|
||||
|
||||
/** The time the last frame started.
|
||||
* Used when _rate_sensitive is true so that we can match display update rate to rotation/translation rate.
|
||||
*/
|
||||
double _last_frame_time;
|
||||
|
||||
osg::Vec3d _center;
|
||||
osg::Quat _rotation;
|
||||
double _distance;
|
||||
|
@ -12,6 +12,7 @@ TrackballManipulator::TrackballManipulator()
|
||||
_minimumZoomScale = 0.05f;
|
||||
_allowThrow = true;
|
||||
_thrown = false;
|
||||
_rate_sensitive = true;
|
||||
|
||||
_distance = 1.0f;
|
||||
_trackballSize = 0.8f;
|
||||
@ -81,11 +82,18 @@ bool TrackballManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(GUIEventAdapter::FRAME):
|
||||
{
|
||||
double current_frame_time = ea.getTime();
|
||||
|
||||
_delta_frame_time = current_frame_time - _last_frame_time;
|
||||
_last_frame_time = current_frame_time;
|
||||
|
||||
if (_thrown && _allowThrow)
|
||||
{
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -321,7 +329,15 @@ bool TrackballManipulator::calcMovement()
|
||||
trackball(axis,angle,px1,py1,px0,py0);
|
||||
|
||||
osg::Quat new_rotate;
|
||||
|
||||
if (_thrown && _rate_sensitive && _ga_t0.valid() && _ga_t1.valid())
|
||||
{
|
||||
// frame_time / delta_event_time
|
||||
double rate = _delta_frame_time / (_ga_t0->getTime() - _ga_t1->getTime());
|
||||
new_rotate.makeRotate(angle * rate,axis);
|
||||
} else {
|
||||
new_rotate.makeRotate(angle,axis);
|
||||
}
|
||||
|
||||
_rotation = _rotation*new_rotate;
|
||||
|
||||
@ -339,6 +355,13 @@ bool TrackballManipulator::calcMovement()
|
||||
osg::Matrix rotation_matrix;
|
||||
rotation_matrix.makeRotate(_rotation);
|
||||
|
||||
if (_thrown && _rate_sensitive && _ga_t0.valid() && _ga_t1.valid())
|
||||
{
|
||||
// frame_time / delta_event_time
|
||||
double rate = _delta_frame_time / (_ga_t0->getTime() - _ga_t1->getTime());
|
||||
scale *= rate;
|
||||
}
|
||||
|
||||
osg::Vec3 dv(dx*scale,dy*scale,0.0f);
|
||||
|
||||
_center += dv*rotation_matrix;
|
||||
|
Loading…
Reference in New Issue
Block a user