Skip to content

Commit 803d3a3

Browse files
committed
ENH: Use pose matrices instead of camera parameters for VR controllers
It is easier to manage controller pose as a matrix instead of the (pos,wxyz,ppos,wdir) variables that the ConvertPoseToWorldCoordinates function calculates. A function called ConvertOpenVRPoseToMatrices was added that calculates the matrix. It is used in various places in addition or instead of those variables. A PhysicalToWorldMatrixModified event is added to vtkOpenVRRenderWindow to enable notifications to the application when the physical scaling, translation, etc. changes. Small changes: - Fix incorrect sign of VR physical to world matrix translation - Fix gesture end event invocation (Trigger button release was checked instead of Grip, as it is done for press) - Add comments for physical to world ivars and controller pose camera style variables for easier understanding - Remove unused PoseTransform member variable from vtkOpenVRRenderWindowInteractor
1 parent 6fd6d25 commit 803d3a3

9 files changed

+371
-98
lines changed

Rendering/Core/vtkRenderWindowInteractor3D.cxx

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@
2525
#include "vtkActor.h"
2626
#include "vtkObjectFactory.h"
2727
#include "vtkCommand.h"
28-
#include "vtkNew.h"
29-
// #include "vtkPropPicker.h"
3028
#include "vtkMath.h"
29+
#include "vtkMatrix4x4.h"
3130

3231
vtkStandardNewMacro(vtkRenderWindowInteractor3D);
3332

@@ -345,3 +344,113 @@ void vtkRenderWindowInteractor3D::RightButtonReleaseEvent()
345344
}
346345
this->InvokeEvent(vtkCommand::RightButtonReleaseEvent, nullptr);
347346
}
347+
348+
//------------------------------------------------------------------
349+
void vtkRenderWindowInteractor3D::SetPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
350+
{
351+
if (!poseMatrix || pointerIndex < 0 || pointerIndex >= VTKI_MAX_POINTERS)
352+
{
353+
return;
354+
}
355+
356+
bool poseDifferent = false;
357+
for (int i = 0; i < 4; i++)
358+
{
359+
for (int j = 0; j < 4; j++)
360+
{
361+
if ( fabs(this->PhysicalEventPoses[pointerIndex]->GetElement(i, j) - poseMatrix->GetElement(i, j)) >= 1e-3 )
362+
{
363+
poseDifferent = true;
364+
break;
365+
}
366+
}
367+
}
368+
369+
370+
if (poseDifferent)
371+
{
372+
this->LastPhysicalEventPoses[pointerIndex]->DeepCopy(PhysicalEventPoses[pointerIndex]);
373+
this->PhysicalEventPoses[pointerIndex]->DeepCopy(poseMatrix);
374+
this->Modified();
375+
}
376+
}
377+
378+
//------------------------------------------------------------------
379+
void vtkRenderWindowInteractor3D::SetWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
380+
{
381+
if (!poseMatrix || pointerIndex < 0 || pointerIndex >= VTKI_MAX_POINTERS)
382+
{
383+
return;
384+
}
385+
386+
bool poseDifferent = false;
387+
for (int i = 0; i < 4; i++)
388+
{
389+
for (int j = 0; j < 4; j++)
390+
{
391+
if ( fabs(this->WorldEventPoses[pointerIndex]->GetElement(i, j) - poseMatrix->GetElement(i, j)) >= 1e-3 )
392+
{
393+
poseDifferent = true;
394+
break;
395+
}
396+
}
397+
}
398+
399+
400+
if (poseDifferent)
401+
{
402+
this->LastWorldEventPoses[pointerIndex]->DeepCopy(WorldEventPoses[pointerIndex]);
403+
this->WorldEventPoses[pointerIndex]->DeepCopy(poseMatrix);
404+
this->Modified();
405+
}
406+
}
407+
408+
//------------------------------------------------------------------
409+
void vtkRenderWindowInteractor3D::GetWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
410+
{
411+
if (pointerIndex >= VTKI_MAX_POINTERS || !poseMatrix)
412+
{
413+
return;
414+
}
415+
poseMatrix->DeepCopy(WorldEventPoses[pointerIndex]);
416+
}
417+
418+
//------------------------------------------------------------------
419+
void vtkRenderWindowInteractor3D::GetLastWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
420+
{
421+
if (pointerIndex >= VTKI_MAX_POINTERS || !poseMatrix)
422+
{
423+
return;
424+
}
425+
poseMatrix->DeepCopy(LastWorldEventPoses[pointerIndex]);
426+
}
427+
428+
//------------------------------------------------------------------
429+
void vtkRenderWindowInteractor3D::GetPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
430+
{
431+
if (pointerIndex >= VTKI_MAX_POINTERS || !poseMatrix)
432+
{
433+
return;
434+
}
435+
poseMatrix->DeepCopy(PhysicalEventPoses[pointerIndex]);
436+
}
437+
438+
//------------------------------------------------------------------
439+
void vtkRenderWindowInteractor3D::GetLastPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
440+
{
441+
if (pointerIndex >= VTKI_MAX_POINTERS || !poseMatrix)
442+
{
443+
return;
444+
}
445+
poseMatrix->DeepCopy(LastPhysicalEventPoses[pointerIndex]);
446+
}
447+
448+
//------------------------------------------------------------------
449+
void vtkRenderWindowInteractor3D::GetStartingPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex)
450+
{
451+
if (pointerIndex >= VTKI_MAX_POINTERS || !poseMatrix)
452+
{
453+
return;
454+
}
455+
poseMatrix->DeepCopy(StartingPhysicalEventPoses[pointerIndex]);
456+
}

Rendering/Core/vtkRenderWindowInteractor3D.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
#include "vtkRenderingCoreModule.h" // For export macro
3333
#include "vtkRenderWindowInteractor.h"
3434

35+
#include "vtkNew.h" // ivars
36+
3537
class vtkCamera;
38+
class vtkMatrix4x4;
3639
enum class vtkEventDataDevice;
3740
enum class vtkEventDataDeviceInput;
3841

@@ -70,11 +73,9 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor3D : public vtkRenderWind
7073

7174
//@{
7275
/**
73-
* With VR we know the world coordinate positions
74-
* and orientations of events. These methods
75-
* support querying them instead of going through
76-
* a display X,Y coordinate approach as is standard
77-
* for mouse/touch events
76+
* With VR we know the world coordinate positions and orientations of events.
77+
* These methods support querying them instead of going through a display X,Y
78+
* coordinate approach as is standard for mouse/touch events
7879
*/
7980
virtual double *GetWorldEventPosition(int pointerIndex)
8081
{
@@ -108,13 +109,15 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor3D : public vtkRenderWind
108109
}
109110
return this->LastWorldEventOrientations[pointerIndex];
110111
}
112+
virtual void GetWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
113+
virtual void GetLastWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
111114
//@}
112115

113116
//@{
114117
/**
115118
* With VR we know the physical/room coordinate positions
116-
* and orientations of events. These methods
117-
* support setting them.
119+
* and orientations of events.
120+
* These methods support setting them.
118121
*/
119122
virtual void SetPhysicalEventPosition(double x, double y, double z, int pointerIndex)
120123
{
@@ -143,6 +146,18 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor3D : public vtkRenderWind
143146
this->Modified();
144147
}
145148
}
149+
virtual void SetPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
150+
//@}
151+
152+
//@{
153+
/**
154+
* With VR we know the physical/room coordinate positions
155+
* and orientations of events.
156+
* These methods support getting them.
157+
*/
158+
virtual void GetPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
159+
virtual void GetLastPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
160+
virtual void GetStartingPhysicalEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
146161
//@}
147162

148163
//@{
@@ -209,6 +224,7 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor3D : public vtkRenderWind
209224
this->Modified();
210225
}
211226
}
227+
virtual void SetWorldEventPose(vtkMatrix4x4* poseMatrix, int pointerIndex);
212228
//@}
213229

214230
//@{
@@ -280,6 +296,11 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindowInteractor3D : public vtkRenderWind
280296
double StartingPhysicalEventPositions[VTKI_MAX_POINTERS][3];
281297
double WorldEventOrientations[VTKI_MAX_POINTERS][4];
282298
double LastWorldEventOrientations[VTKI_MAX_POINTERS][4];
299+
vtkNew<vtkMatrix4x4> WorldEventPoses[VTKI_MAX_POINTERS];
300+
vtkNew<vtkMatrix4x4> LastWorldEventPoses[VTKI_MAX_POINTERS];
301+
vtkNew<vtkMatrix4x4> PhysicalEventPoses[VTKI_MAX_POINTERS];
302+
vtkNew<vtkMatrix4x4> LastPhysicalEventPoses[VTKI_MAX_POINTERS];
303+
vtkNew<vtkMatrix4x4> StartingPhysicalEventPoses[VTKI_MAX_POINTERS];
283304
void RecognizeGesture(vtkCommand::EventIds) override;
284305

285306
private:

Rendering/OpenVR/vtkOpenVRControlsHelper.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ PURPOSE. See the above copyright notice for more information.
3030
#include "vtkWindow.h"
3131
#include "vtkCamera.h"
3232
#include "vtkLineSource.h"
33-
33+
#include "vtkTransform.h"
3434
#include "vtkSmartPointer.h"
3535

3636
vtkStandardNewMacro(vtkOpenVRControlsHelper);

Rendering/OpenVR/vtkOpenVRHardwarePicker.cxx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,7 @@ PURPOSE. See the above copyright notice for more information.
2323
#include "vtkOpenVRRenderWindowInteractor.h"
2424
#include "vtkRenderer.h"
2525
#include "vtkSelection.h"
26-
27-
// #include "vtkAssemblyNode.h"
28-
// #include "vtkAssemblyPath.h"
29-
// #include "vtkRenderer.h"
30-
// #include "vtkMath.h"
31-
// #include "vtkCamera.h"
32-
// #include "vtkBox.h"
33-
// #include "vtkRenderWindow.h"
34-
// #include "vtkRenderWindowInteractor3D.h"
35-
// #include "vtkTransform.h"
26+
#include "vtkTransform.h"
3627

3728
vtkStandardNewMacro(vtkOpenVRHardwarePicker);
3829

Rendering/OpenVR/vtkOpenVRPanelRepresentation.cxx

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -394,21 +394,10 @@ void vtkOpenVRPanelRepresentation::ComputeMatrix(vtkRenderer *ren)
394394
rw->GetTrackedDevicePose(vtkEventDataDevice::LeftController, &tdPose);
395395
if (tdPose && tdPose->bPoseIsValid)
396396
{
397-
double pos[3];
398-
double ppos[3];
399-
double wxyz[4];
400-
double wdir[3];
397+
vtkNew<vtkMatrix4x4> poseMatrixWorld;
401398
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
402-
->ConvertPoseToWorldCoordinates(*tdPose, pos, wxyz, ppos, wdir);
403-
404-
double scale = rw->GetPhysicalScale();
405-
406-
this->TempTransform->Identity();
407-
this->TempTransform->PreMultiply();
408-
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
409-
this->TempTransform->Scale(scale, scale, scale);
410-
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
411-
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
399+
->ConvertOpenVRPoseToMatrices(*tdPose, poseMatrixWorld);
400+
this->TextActor->GetUserMatrix()->DeepCopy(poseMatrixWorld);
412401
}
413402
}
414403

@@ -418,21 +407,10 @@ void vtkOpenVRPanelRepresentation::ComputeMatrix(vtkRenderer *ren)
418407
rw->GetTrackedDevicePose(vtkEventDataDevice::RightController, &tdPose);
419408
if (tdPose && tdPose->bPoseIsValid)
420409
{
421-
double pos[3];
422-
double ppos[3];
423-
double wxyz[4];
424-
double wdir[3];
410+
vtkNew<vtkMatrix4x4> poseMatrixWorld;
425411
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
426-
->ConvertPoseToWorldCoordinates(*tdPose, pos, wxyz, ppos, wdir);
427-
428-
double scale = rw->GetPhysicalScale();
429-
430-
this->TempTransform->Identity();
431-
this->TempTransform->PreMultiply();
432-
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
433-
this->TempTransform->Scale(scale, scale, scale);
434-
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
435-
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
412+
->ConvertOpenVRPoseToMatrices(*tdPose, poseMatrixWorld);
413+
this->TextActor->GetUserMatrix()->DeepCopy(poseMatrixWorld);
436414
}
437415
}
438416
}

Rendering/OpenVR/vtkOpenVRRenderWindow.cxx

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,6 @@ void vtkOpenVRRenderWindow::UpdateHMDMatrixPose()
425425
double hmdY_Physical[3] = { tdPose.mDeviceToAbsoluteTracking.m[0][1],
426426
tdPose.mDeviceToAbsoluteTracking.m[1][1],
427427
tdPose.mDeviceToAbsoluteTracking.m[2][1] };
428-
double hmdZ_Physical[3] = {0.0};
429428
double hmdPosition_Physical[3] = { tdPose.mDeviceToAbsoluteTracking.m[0][3],
430429
tdPose.mDeviceToAbsoluteTracking.m[1][3],
431430
tdPose.mDeviceToAbsoluteTracking.m[2][3] };
@@ -787,6 +786,73 @@ void vtkOpenVRRenderWindow::GetTrackedDevicePose(
787786
}
788787
}
789788

789+
void vtkOpenVRRenderWindow::SetPhysicalViewDirection(double x, double y, double z)
790+
{
791+
if ( this->PhysicalViewDirection[0] != x
792+
|| this->PhysicalViewDirection[1] != y
793+
|| this->PhysicalViewDirection[2] != z )
794+
{
795+
this->PhysicalViewDirection[0] = x;
796+
this->PhysicalViewDirection[1] = y;
797+
this->PhysicalViewDirection[2] = z;
798+
this->InvokeEvent(vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified);
799+
this->Modified();
800+
}
801+
}
802+
803+
void vtkOpenVRRenderWindow::SetPhysicalViewDirection(double dir[3])
804+
{
805+
this->SetPhysicalViewDirection(dir[0], dir[1], dir[2]);
806+
}
807+
808+
void vtkOpenVRRenderWindow::SetPhysicalViewUp(double x, double y, double z)
809+
{
810+
if ( this->PhysicalViewUp[0] != x
811+
|| this->PhysicalViewUp[1] != y
812+
|| this->PhysicalViewUp[2] != z )
813+
{
814+
this->PhysicalViewUp[0] = x;
815+
this->PhysicalViewUp[1] = y;
816+
this->PhysicalViewUp[2] = z;
817+
this->InvokeEvent(vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified);
818+
this->Modified();
819+
}
820+
}
821+
822+
void vtkOpenVRRenderWindow::SetPhysicalViewUp(double dir[3])
823+
{
824+
this->SetPhysicalViewUp(dir[0], dir[1], dir[2]);
825+
}
826+
827+
void vtkOpenVRRenderWindow::SetPhysicalTranslation(double x, double y, double z)
828+
{
829+
if ( this->PhysicalTranslation[0] != x
830+
|| this->PhysicalTranslation[1] != y
831+
|| this->PhysicalTranslation[2] != z )
832+
{
833+
this->PhysicalTranslation[0] = x;
834+
this->PhysicalTranslation[1] = y;
835+
this->PhysicalTranslation[2] = z;
836+
this->InvokeEvent(vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified);
837+
this->Modified();
838+
}
839+
}
840+
841+
void vtkOpenVRRenderWindow::SetPhysicalTranslation(double trans[3])
842+
{
843+
this->SetPhysicalTranslation(trans[0], trans[1], trans[2]);
844+
}
845+
846+
void vtkOpenVRRenderWindow::SetPhysicalScale(double scale)
847+
{
848+
if (this->PhysicalScale != scale)
849+
{
850+
this->PhysicalScale = scale;
851+
this->InvokeEvent(vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified);
852+
this->Modified();
853+
}
854+
}
855+
790856
void vtkOpenVRRenderWindow::SetPhysicalToWorldMatrix(vtkMatrix4x4* matrix)
791857
{
792858
if (!matrix)
@@ -797,7 +863,11 @@ void vtkOpenVRRenderWindow::SetPhysicalToWorldMatrix(vtkMatrix4x4* matrix)
797863
vtkNew<vtkTransform> hmdToWorldTransform;
798864
hmdToWorldTransform->SetMatrix(matrix);
799865

800-
hmdToWorldTransform->GetPosition(this->PhysicalTranslation);
866+
double translation[3] = {0.0};
867+
hmdToWorldTransform->GetPosition(translation);
868+
this->PhysicalTranslation[0] = (-1.0) * translation[0];
869+
this->PhysicalTranslation[1] = (-1.0) * translation[1];
870+
this->PhysicalTranslation[2] = (-1.0) * translation[2];
801871

802872
double scale[3] = {0.0};
803873
hmdToWorldTransform->GetScale(scale);
@@ -811,6 +881,9 @@ void vtkOpenVRRenderWindow::SetPhysicalToWorldMatrix(vtkMatrix4x4* matrix)
811881
this->PhysicalViewDirection[1] = (-1.0) * matrix->GetElement(1,2);
812882
this->PhysicalViewDirection[2] = (-1.0) * matrix->GetElement(2,2);
813883
vtkMath::Normalize(this->PhysicalViewDirection);
884+
885+
this->InvokeEvent(vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified);
886+
this->Modified();
814887
}
815888

816889
void vtkOpenVRRenderWindow::GetPhysicalToWorldMatrix(vtkMatrix4x4* physicalToWorldMatrix)
@@ -835,6 +908,6 @@ void vtkOpenVRRenderWindow::GetPhysicalToWorldMatrix(vtkMatrix4x4* physicalToWor
835908
physicalToWorldMatrix->SetElement(row, 0, physicalX_NonscaledWorld[row]*this->PhysicalScale);
836909
physicalToWorldMatrix->SetElement(row, 1, physicalY_NonscaledWorld[row]*this->PhysicalScale);
837910
physicalToWorldMatrix->SetElement(row, 2, physicalZ_NonscaledWorld[row]*this->PhysicalScale);
838-
physicalToWorldMatrix->SetElement(row, 3, this->PhysicalTranslation[row]);
911+
physicalToWorldMatrix->SetElement(row, 3, -this->PhysicalTranslation[row]);
839912
}
840913
}

0 commit comments

Comments
 (0)