Commit 74d94885 authored by Ken Martin's avatar Ken Martin Committed by Kitware Robot

Merge topic 'vr-dolly-speed-fix'

8272090e ENH: Add timer in vtkInteractorStyle3D to allow for smooth flying
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Ken Martin's avatarKen Martin <ken.martin@kitware.com>
Merge-request: !4726
parents 7e3f6029 8272090e
......@@ -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 = 1.6666;
}
//----------------------------------------------------------------------------
......@@ -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,38 @@ 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
// scale speed by thumb position on the touchpad along Y axis
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;
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)
double physicalScale = rwi->GetPhysicalScale();
this->LastDolly3DEventTime->StopTimer();
double distanceTravelled_World =
speedScaleFactor * this->DollyPhysicalSpeed /* m/sec */ *
physicalScale * /* world/physical */
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]*distanceTravelled_World,
trans[1]-vdir[1]*distanceTravelled_World,
trans[2]-vdir[2]*distanceTravelled_World);
if (this->AutoAdjustCameraClippingRange)
{
......
......@@ -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,14 +80,12 @@ 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 meters per second.
* Default is 1.6666, 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);
//@}
/**
......@@ -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);
}
};
......
......@@ -859,6 +859,24 @@ void vtkOpenVRRenderWindow::SetPhysicalToWorldMatrix(vtkMatrix4x4* matrix)
{
return;
}
vtkNew<vtkMatrix4x4> currentPhysicalToWorldMatrix;
this->GetPhysicalToWorldMatrix(currentPhysicalToWorldMatrix);
bool matrixDifferent = false;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if ( fabs(matrix->GetElement(i, j) - currentPhysicalToWorldMatrix->GetElement(i, j)) >= 1e-3 )
{
matrixDifferent = true;
break;
}
}
}
if (!matrixDifferent)
{
return;
}
vtkNew<vtkTransform> hmdToWorldTransform;
hmdToWorldTransform->SetMatrix(matrix);
......
......@@ -34,6 +34,18 @@ PURPOSE. See the above copyright notice for more information.
* made to work with this but consider how overlays will appear in a
* HMD if they do not track the viewpoint etc. This class is based on
* sample code from the OpenVR project.
*
* OpenVR provides HMD and controller positions in "Physical" coordinate
* system.
* Origin: user's eye position at the time of calibration.
* Axis directions: x = user's right; y = user's up; z = user's back.
* Unit: meter.
*
* Renderer shows actors in World coordinate system. Transformation between
* Physical and World coordinate systems is defined by PhysicalToWorldMatrix.
* This matrix determines the user's position and orientation in the rendered
* scene and scaling (magnification) of rendered actors.
*
*/
#ifndef vtkOpenVRRenderWindow_h
......@@ -148,19 +160,56 @@ public:
//@{
/**
* Control the HMD to World transformations. In
* some cases users may not want the Y axis to be up
* and these methods allow them to control it.
* Set/get physical coordinate system in world coordinate system.
*
* View direction is the -Z axis of the physical coordinate system
* in world coordinate system.
* \sa SetPhysicalViewUp, \sa SetPhysicalTranslation,
* \sa SetPhysicalScale, \sa SetPhysicalToWorldMatrix
*/
virtual void SetPhysicalViewDirection(double,double,double);
virtual void SetPhysicalViewDirection(double[3]);
vtkGetVector3Macro(PhysicalViewDirection, double);
//@}
//@{
/**
* Set/get physical coordinate system in world coordinate system.
*
* View up is the +Y axis of the physical coordinate system
* in world coordinate system.
* \sa SetPhysicalViewDirection, \sa SetPhysicalTranslation,
* \sa SetPhysicalScale, \sa SetPhysicalToWorldMatrix
*/
virtual void SetPhysicalViewUp(double,double,double);
virtual void SetPhysicalViewUp(double[3]);
vtkGetVector3Macro(PhysicalViewUp, double);
//@}
//@{
/**
* Set/get physical coordinate system in world coordinate system.
*
* Position of the physical coordinate system origin
* in world coordinates.
* \sa SetPhysicalViewDirection, \sa SetPhysicalViewUp,
* \sa SetPhysicalScale, \sa SetPhysicalToWorldMatrix
*/
virtual void SetPhysicalTranslation(double,double,double);
virtual void SetPhysicalTranslation(double[3]);
vtkGetVector3Macro(PhysicalTranslation, double);
//@}
//@{
/**
* Set/get physical coordinate system in world coordinate system.
*
* Ratio of distance in world coordinate and physical and system
* (PhysicalScale = distance_World / distance_Physical).
* Example: if world coordinate system is in mm then
* PhysicalScale = 1000.0 makes objects appear in real size.
* PhysicalScale = 100.0 makes objects appear 10x larger than real size.
*/
virtual void SetPhysicalScale(double);
vtkGetMacro(PhysicalScale, double);
//@}
......
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