Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create PolyData laser on the tip of the left controller #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 199 additions & 7 deletions VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "vtkMRMLVirtualRealityViewNode.h"

// MRML includes
#include "vtkMRMLApplicationLogic.h"
#include "vtkMRMLScene.h"
#include "vtkMRMLModelNode.h"
#include "vtkMRMLModelDisplayNode.h"
Expand All @@ -38,10 +39,13 @@
// VTK includes
#include <vtkCamera.h>
#include <vtkCellPicker.h>
#include <vtkCellArray.h>
#include <vtkCallbackCommand.h>
#include <vtkMath.h>
#include <vtkObjectFactory.h>
#include <vtkOpenVRModel.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkQuaternion.h>
#include <vtkTimerLog.h>
Expand Down Expand Up @@ -192,7 +196,8 @@ vtkVirtualRealityViewInteractorStyle::vtkVirtualRealityViewInteractorStyle()
vtkEventDataDeviceInput::Grip, VTKIS_POSITION_PROP);
this->MapInputToAction(vtkEventDataDevice::RightController,
vtkEventDataDeviceInput::TrackPad, VTKIS_DOLLY);

this->MapInputToAction(vtkEventDataDevice::LeftController,
vtkEventDataDeviceInput::TrackPad, VTKIS_PICK);
this->MapInputToAction(vtkEventDataDevice::LeftController,
vtkEventDataDeviceInput::Grip, VTKIS_POSITION_PROP);

Expand All @@ -203,6 +208,7 @@ vtkVirtualRealityViewInteractorStyle::vtkVirtualRealityViewInteractorStyle()
vtkVirtualRealityViewInteractorStyle::~vtkVirtualRealityViewInteractorStyle()
{
this->SetDisplayableManagerGroup(nullptr);
this->FocusedDisplayableManager = nullptr;
delete this->Internal;
}

Expand Down Expand Up @@ -311,6 +317,7 @@ void vtkVirtualRealityViewInteractorStyle::OnMove3D(vtkEventData* edata)
// this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
// break;
}
this->UpdateLaser(edd->GetDevice());

//// Update rays
//if (this->HoverPick)
Expand Down Expand Up @@ -349,6 +356,32 @@ void vtkVirtualRealityViewInteractorStyle::OnButton3D(vtkEventData* edata)
}
}

//----------------------------------------------------------------------------
// Interaction entry points
//----------------------------------------------------------------------------
void vtkVirtualRealityViewInteractorStyle::StartPick(vtkEventDataDevice3D *ed)
{
// turn on laser and update length
this->ShowLaser(ed->GetDevice());
this->UpdateLaser(ed->GetDevice());

vtkEventDataDevice dev = ed->GetDevice();
this->Internal->InteractionState[static_cast<int>(dev)] = VTKIS_PICK;
}
//----------------------------------------------------------------------------
void vtkVirtualRealityViewInteractorStyle::EndPick(vtkEventDataDevice3D *ed)
{
// turn off ray
this->HideLaser(ed->GetDevice());

// perform probe
this->ProbeData(ed->GetDevice());

vtkEventDataDevice dev = ed->GetDevice();
this->Internal->InteractionState[static_cast<int>(dev)] = VTKIS_NONE;
}


//----------------------------------------------------------------------------
// Interaction methods
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -557,6 +590,59 @@ void vtkVirtualRealityViewInteractorStyle::EndDolly3D(vtkEventDataDevice3D* ed)
this->LastDolly3DEventTime->StopTimer();
}

//----------------------------------------------------------------------------
// Interaction methods
//----------------------------------------------------------------------------
void vtkVirtualRealityViewInteractorStyle::ProbeData(vtkEventDataDevice controller)
{
vtkRenderer *ren = this->CurrentRenderer;
vtkOpenVRRenderWindow* renWin = vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
vtkOpenVRRenderWindowInteractor *iren =
static_cast<vtkOpenVRRenderWindowInteractor *>(this->Interactor);

if (!ren || !renWin || !iren)
{
return;
}

vtkOpenVRModel *cmodel =
renWin->GetTrackedDeviceModel(controller);
if (!cmodel)
{
return;
}

// Invoke start pick method if defined
this->InvokeEvent(vtkCommand::StartPickEvent, nullptr);

cmodel->SetVisibility(false);

// Compute controller position and world orientation
double p0[3]; //Ray start point
double wxyz[4];// Controller orientation
double dummy_ppos[3];
double wdir[3];
vr::TrackedDevicePose_t &tdPose = renWin->GetTrackedDevicePose(cmodel->TrackedDevice);
iren->ConvertPoseToWorldCoordinates(tdPose, p0, wxyz, dummy_ppos, wdir);

// TO DO
//this->HardwarePicker->PickProp(p0, wxyz, ren, ren->GetViewProps());

cmodel->SetVisibility(true);

// // Invoke end pick method if defined
// if (this->HandleObservers &&
// this->HasObserver(vtkCommand::EndPickEvent))
// {
// // TO DO
// // this->InvokeEvent(vtkCommand::EndPickEvent, this->HardwarePicker->GetSelection());
// }
// else
// {
// this->EndPickCallback(this->HardwarePicker->GetSelection());
// }
}

//----------------------------------------------------------------------------
// Multitouch interaction methods
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -730,9 +816,9 @@ void vtkVirtualRealityViewInteractorStyle::StartAction(int state, vtkEventDataDe
//case VTKIS_CLIP:
// this->StartClip(edata);
// break;
//case VTKIS_PICK:
// this->StartPick(edata);
// break;
case VTKIS_PICK:
this->StartPick(edata);
break;
//case VTKIS_LOAD_CAMERA_POSE:
// this->StartLoadCamPose(edata);
// break;
Expand All @@ -753,9 +839,9 @@ void vtkVirtualRealityViewInteractorStyle::EndAction(int state, vtkEventDataDevi
//case VTKIS_CLIP:
// this->EndClip(edata);
// break;
//case VTKIS_PICK:
// this->EndPick(edata);
// break;
case VTKIS_PICK:
this->EndPick(edata);
break;
//case VTKIS_MENU:
// this->Menu->SetInteractor(this->Interactor);
// this->Menu->Show(edata);
Expand Down Expand Up @@ -788,6 +874,24 @@ void vtkVirtualRealityViewInteractorStyle::EndAction(int state, vtkEventDataDevi
//}
}

//----------------------------------------------------------------------------
// Handle Laser drawing and update
//----------------------------------------------------------------------------
void vtkVirtualRealityViewInteractorStyle::ShowLaser(vtkEventDataDevice controller)
{
if (!this->LaserPoints)
{
this->CreateLaser();
}
this->LaserModelDisplay->VisibilityOn();
}

//----------------------------------------------------------------------------
void vtkVirtualRealityViewInteractorStyle::HideLaser(vtkEventDataDevice controller)
{
this->LaserModelDisplay->VisibilityOff();
}

//---------------------------------------------------------------------------
vtkMRMLScene* vtkVirtualRealityViewInteractorStyle::GetMRMLScene()
{
Expand Down Expand Up @@ -883,3 +987,91 @@ double vtkVirtualRealityViewInteractorStyle::GetMagnification()

return 1000.0 / rw->GetPhysicalScale();
}

void vtkVirtualRealityViewInteractorStyle::CreateLaser()
{
vtkRenderer *ren = this->CurrentRenderer;
if (!ren)
{
return;
}

this->LaserPoints = vtkSmartPointer<vtkPoints>::New();
this->LaserPoints->SetNumberOfPoints(2);
this->LaserPoints->SetPoint(0, 0.0, 0.0, 0.0);
this->LaserPoints->SetPoint(1, 0.0, 0.0, -ren->GetActiveCamera()->GetClippingRange()[1]);

vtkNew<vtkCellArray> lines;
lines->InsertNextCell(2);
lines->InsertCellPoint(0);
lines->InsertCellPoint(1);

vtkNew<vtkPolyData> path;
path->SetPoints(this->LaserPoints);
path->SetLines(lines);

vtkNew<vtkMRMLModelNode> pathModel;
pathModel->SetSelectable(false);
pathModel->HideFromEditorsOn();
pathModel->SetScene(this->GetMRMLScene());
pathModel->SetName("Laser");
pathModel->SetAndObservePolyData(path);

this->LaserModelDisplay = vtkSmartPointer<vtkMRMLModelDisplayNode>::New();
this->LaserModelDisplay->SetColor(1,0,0);
this->LaserModelDisplay->SetScene(this->GetMRMLScene());
this->GetMRMLScene()->AddNode(this->LaserModelDisplay);
pathModel->SetAndObserveDisplayNodeID(this->LaserModelDisplay->GetID());

this->GetMRMLScene()->AddNode(pathModel);

this->LaserModelDisplay->AddViewNodeID("vtkMRMLVirtualRealityViewNodeActive");
}

void vtkVirtualRealityViewInteractorStyle::UpdateLaser(vtkEventDataDevice controller)
{
if (!this->LaserPoints)
{
return;
}

if (!this->LaserModelDisplay->GetVisibility())
{
return;
}

vtkRenderer *ren = this->CurrentRenderer;
vtkOpenVRRenderWindow* renWin = vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
vtkOpenVRRenderWindowInteractor *iren =
static_cast<vtkOpenVRRenderWindowInteractor *>(this->Interactor);
if (!ren || !renWin || !iren)
{
return;
}

vr::TrackedDeviceIndex_t idx = renWin->GetTrackedDeviceIndexForDevice(controller);
if (idx == vr::k_unTrackedDeviceIndexInvalid)
{
return;
}
vtkOpenVRModel* mod = renWin->GetTrackedDeviceModel(idx);
if (!mod)
{
return;
}

// Compute controller position and world orientation
vr::TrackedDevicePose_t &tdPose = renWin->GetTrackedDevicePose(mod->TrackedDevice);
vtkNew<vtkMatrix4x4> leftControllerWorldPose;
iren->ConvertOpenVRPoseToMatrices(tdPose, leftControllerWorldPose);

double p0[4] = { 0.0, 0.0, 0.0, 1.0 };
double* LaserClose = leftControllerWorldPose->MultiplyDoublePoint(p0);
this->LaserPoints->SetPoint(0, LaserClose[0], LaserClose[1], LaserClose[2]);

double p1[4] = { 0.0, 0.0, -ren->GetActiveCamera()->GetClippingRange()[1], 1.0 };
double* LaserFar = leftControllerWorldPose->MultiplyDoublePoint(p1);
this->LaserPoints->SetPoint(1, LaserFar[0], LaserFar[1], LaserFar[2]);

this->LaserPoints->Modified();
}
20 changes: 13 additions & 7 deletions VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

// MRML includes
#include "vtkMRMLDisplayableManagerGroup.h"
#include "vtkMRMLInteractionEventData.h"
#include "vtkMRMLModelDisplayNode.h"

// VTK includes
#include "vtkObject.h"
Expand Down Expand Up @@ -65,8 +67,8 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract
/**
* Interaction mode entry points.
*/
//virtual void StartPick(vtkEventDataDevice3D *);
//virtual void EndPick(vtkEventDataDevice3D *);
virtual void StartPick(vtkEventDataDevice3D *);
virtual void EndPick(vtkEventDataDevice3D *);
//virtual void StartLoadCamPose(vtkEventDataDevice3D *);
//virtual void EndLoadCamPose(vtkEventDataDevice3D *);
virtual void StartPositionProp(vtkEventDataDevice3D *);
Expand All @@ -93,7 +95,7 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract
/**
* Methods for interaction.
*/
//void ProbeData(vtkEventDataDevice controller);
void ProbeData(vtkEventDataDevice controller);
//void LoadNextCameraPose();
virtual void PositionProp(vtkEventData *);
//virtual void Clip(vtkEventDataDevice3D *);
Expand Down Expand Up @@ -124,8 +126,8 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract
//int GetInteractionState(vtkEventDataDevice device) {
// return this->InteractionState[static_cast<int>(device)]; }

//void ShowRay(vtkEventDataDevice controller);
//void HideRay(vtkEventDataDevice controller);
void ShowLaser(vtkEventDataDevice controller);
void HideLaser(vtkEventDataDevice controller);

//void ShowBillboard(const std::string &text);
//void HideBillboard();
Expand Down Expand Up @@ -153,8 +155,9 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract
protected:
//void EndPickCallback(vtkSelection *sel);

////Ray drawing
//void UpdateRay(vtkEventDataDevice controller);
////Laser drawing
void CreateLaser();
void UpdateLaser(vtkEventDataDevice controller);

//vtkNew<vtkOpenVRMenuWidget> Menu;
//vtkNew<vtkOpenVRMenuRepresentation> MenuRepresentation;
Expand Down Expand Up @@ -192,6 +195,9 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract
//vtkNew<vtkOpenVRHardwarePicker> HardwarePicker;

vtkMRMLDisplayableManagerGroup* DisplayableManagerGroup;
vtkMRMLAbstractDisplayableManager* FocusedDisplayableManager;
vtkSmartPointer<vtkPoints> LaserPoints;
vtkSmartPointer<vtkMRMLModelDisplayNode> LaserModelDisplay;

protected:
vtkVirtualRealityViewInteractorStyle();
Expand Down