Commit 13ba193c authored by Csaba Pinter's avatar Csaba Pinter

ENH: Add timer in vtkInteractorStyle3D to allow for smooth flying

Dolly translation speed can be specified in mm/s, to achieve a constant flying speed that is not dependent on frame rate or physical scale. Default is 1666.6 m/s, which corresponds to walking speed (6 km/h). Do not dolly if left or right side of the trackpad is pressed instead of up/down.
parent 803d3a32
......@@ -28,6 +28,7 @@
#include "vtkQuaternion.h"
#include "vtkRenderer.h"
#include "vtkMatrix3x3.h"
#include "vtkTimerLog.h"
#include "vtkTransform.h"
#include "vtkCamera.h"
......@@ -44,7 +45,7 @@ vtkInteractorStyle3D::vtkInteractorStyle3D()
this->AppliedTranslation[1] = 0;
this->AppliedTranslation[2] = 0;
this->TempTransform = vtkTransform::New();
this->DollyMotionFactor = 2.0;
this->DollyPhysicalSpeed = 1666.6;
}
//----------------------------------------------------------------------------
......@@ -162,10 +163,10 @@ void vtkInteractorStyle3D::FindPickedActor(double pos[3], double orient[4])
//----------------------------------------------------------------------------
void vtkInteractorStyle3D::Prop3DTransform(vtkProp3D *prop3D,
double *boxCenter,
int numRotation,
double **rotate,
double *scale)
double *boxCenter,
int numRotation,
double **rotate,
double *scale)
{
vtkMatrix4x4 *oldMatrix = this->TempMatrix4;
prop3D->GetMatrix(oldMatrix);
......@@ -241,30 +242,36 @@ void vtkInteractorStyle3D::Dolly3D(vtkEventData *ed)
double elem[3][3];
q1.ToMatrix3x3(elem);
double vdir[3] = {0.0,0.0,-1.0};
vtkMatrix3x3::MultiplyPoint(
elem[0],vdir,vdir);
vtkMatrix3x3::MultiplyPoint(elem[0],vdir,vdir);
double *trans = rwi->GetPhysicalTranslation(
this->CurrentRenderer->GetActiveCamera());
double physicalScale = rwi->GetPhysicalScale();
// The world coordinate speed of
// movement can be determined from the camera scale.
// movement speed is scaled by the touchpad
// y coordinate
float tpos[3];
rwi->GetTouchPadPosition(
edd->GetDevice(),
vtkEventDataDeviceInput::Unknown,
tpos);
// 2.0 so that the max is 2.0 times the average
// motion factor
double factor = tpos[1]*2.0*this->DollyMotionFactor/90.0;
// scale speed by thumb position on the touchpad along Y axis
float tpos[3];
rwi->GetTouchPadPosition(
edd->GetDevice(),
vtkEventDataDeviceInput::Unknown,
tpos);
if (fabs(tpos[0]) > fabs(tpos[1]))
{
// do not dolly if pressed direction is not up or down but left or right
return;
}
double speedScaleFactor = tpos[1]; // -1 to +1 (the Y axis of the trackpad)
this->LastDolly3DEventTime->StopTimer();
double physicalDistanceTravelled =
speedScaleFactor * this->DollyPhysicalSpeed /* mm/sec */ *
this->LastDolly3DEventTime->GetElapsedTime() /* sec */;
this->LastDolly3DEventTime->StartTimer();
rwi->SetPhysicalTranslation(
this->CurrentRenderer->GetActiveCamera(),
trans[0]-vdir[0]*factor*physicalScale,
trans[1]-vdir[1]*factor*physicalScale,
trans[2]-vdir[2]*factor*physicalScale);
trans[0]-vdir[0]*physicalDistanceTravelled,
trans[1]-vdir[1]*physicalDistanceTravelled,
trans[2]-vdir[2]*physicalDistanceTravelled);
if (this->AutoAdjustCameraClippingRange)
{
......@@ -291,8 +298,8 @@ void vtkInteractorStyle3D::SetScale(vtkCamera *camera, double newScale)
newPos[1] = hmd[1]*newScale - trans[1];
newPos[2] = hmd[2]*newScale - trans[2];
// Note: New camera properties are overridden by virtual reality render
// window if head-mounted display is tracked
// Note: New camera properties are overridden by virtual reality render
// window if head-mounted display is tracked
camera->SetFocalPoint(
newPos[0] + dop[0]*newScale,
newPos[1] + dop[1]*newScale,
......
......@@ -53,12 +53,14 @@
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkInteractorStyle.h"
#include "vtkNew.h" // ivars
class vtkCamera;
class vtkPropPicker;
class vtkProp3D;
class vtkMatrix3x3;
class vtkMatrix4x4;
class vtkTimerLog;
class vtkTransform;
class VTKRENDERINGCORE_EXPORT vtkInteractorStyle3D : public vtkInteractorStyle
......@@ -78,22 +80,20 @@ public:
//@{
/**
* Set/Get the dolly motion factor used when flying in 3D.
* Defaults to 2.0 to simulate 2 meters per second
* of movement in physical space. The dolly speed is
* adjusted by the touchpad position as well. The maximum
* rate is twice this setting.
* Set/Get the maximum dolly speed used when flying in 3D, in millimeters per second.
* Default is 1666.6, corresponding to walking speed (= 6 km/h).
* This speed is scaled by the touchpad position as well.
*/
vtkSetMacro(DollyMotionFactor, double);
vtkGetMacro(DollyMotionFactor, double);
vtkSetMacro(DollyPhysicalSpeed, double);
vtkGetMacro(DollyPhysicalSpeed, double);
//@}
/**
* Set the scaling factor from world to physical space.
* In VR when we set it to a new value we also adjust the
* HMD position to maintain the same relative position.
*/
virtual void SetScale(vtkCamera *cam, double newScale);
/**
* Set the scaling factor from world to physical space.
* In VR when we set it to a new value we also adjust the
* HMD position to maintain the same relative position.
*/
virtual void SetScale(vtkCamera *cam, double newScale);
/**
* Get the interaction picker
......@@ -119,10 +119,12 @@ protected:
vtkProp3D *InteractionProp;
vtkMatrix3x3 *TempMatrix3;
vtkMatrix4x4 *TempMatrix4;
vtkTransform *TempTransform;
double AppliedTranslation[3];
double DollyMotionFactor;
double DollyPhysicalSpeed;
vtkNew<vtkTimerLog> LastDolly3DEventTime;
private:
vtkInteractorStyle3D(const vtkInteractorStyle3D&) = delete; // Not implemented.
......
......@@ -21,6 +21,7 @@
#include "vtkOpenGLState.h"
#include "vtkOpenGLError.h"
#include "vtkPerspectiveTransform.h"
#include "vtkTimerLog.h"
#include <cmath>
......
......@@ -49,7 +49,7 @@ void handleMotionFactor(vtkObject *caller, unsigned long eid,
case 3: mf = 10.0; break;
case 4: mf = 100.0; break;
}
is->SetDollyMotionFactor(mf);
is->SetDollyPhysicalSpeed(mf);
// turn off all motion spots
std::vector<vtkOpenVROverlaySpot> &spots = ovl->GetSpots();
......
......@@ -53,6 +53,7 @@ PURPOSE. See the above copyright notice for more information.
#include "vtkSphereSource.h"
#include "vtkStringArray.h"
#include "vtkTextProperty.h"
#include "vtkTimerLog.h"
#include "vtkOpenVRMenuRepresentation.h"
#include "vtkOpenVRMenuWidget.h"
......@@ -440,6 +441,7 @@ void vtkOpenVRInteractorStyle::StartDolly3D(vtkEventDataDevice3D * ed)
}
vtkEventDataDevice dev = ed->GetDevice();
this->InteractionState[static_cast<int>(dev)] = VTKIS_DOLLY;
this->LastDolly3DEventTime->StartTimer();
// this->GrabFocus(this->EventCallbackCommand);
}
......@@ -448,6 +450,8 @@ void vtkOpenVRInteractorStyle::EndDolly3D(vtkEventDataDevice3D * ed)
{
vtkEventDataDevice dev = ed->GetDevice();
this->InteractionState[static_cast<int>(dev)] = VTKIS_NONE;
this->LastDolly3DEventTime->StopTimer();
}
//----------------------------------------------------------------------------
......
......@@ -54,7 +54,7 @@ public:
this->Distance = win->GetPhysicalScale();
vtkInteractorStyle3D *is =
static_cast<vtkInteractorStyle3D *>(win->GetInteractor()->GetInteractorStyle());
this->MotionFactor = is->GetDollyMotionFactor();
this->MotionFactor = is->GetDollyPhysicalSpeed();
cam->GetPosition(this->Position);
......@@ -146,7 +146,7 @@ public:
win->SetPhysicalViewUp(this->PhysicalViewUp);
vtkInteractorStyle3D *is =
static_cast<vtkInteractorStyle3D *>(win->GetInteractor()->GetInteractorStyle());
is->SetDollyMotionFactor(this->MotionFactor);
is->SetDollyPhysicalSpeed(this->MotionFactor);
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment