diff --git a/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx b/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx index 960ad2e..0198266 100644 --- a/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx +++ b/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx @@ -24,6 +24,7 @@ #include "vtkMRMLVirtualRealityViewNode.h" // MRML includes +#include "vtkMRMLApplicationLogic.h" #include "vtkMRMLScene.h" #include "vtkMRMLModelNode.h" #include "vtkMRMLModelDisplayNode.h" @@ -38,10 +39,13 @@ // VTK includes #include #include +#include #include #include #include +#include #include +#include #include #include #include @@ -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); @@ -203,6 +208,7 @@ vtkVirtualRealityViewInteractorStyle::vtkVirtualRealityViewInteractorStyle() vtkVirtualRealityViewInteractorStyle::~vtkVirtualRealityViewInteractorStyle() { this->SetDisplayableManagerGroup(nullptr); + this->FocusedDisplayableManager = nullptr; delete this->Internal; } @@ -311,6 +317,7 @@ void vtkVirtualRealityViewInteractorStyle::OnMove3D(vtkEventData* edata) // this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); // break; } + this->UpdateLaser(edd->GetDevice()); //// Update rays //if (this->HoverPick) @@ -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(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(dev)] = VTKIS_NONE; +} + + //---------------------------------------------------------------------------- // Interaction methods //---------------------------------------------------------------------------- @@ -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(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 //---------------------------------------------------------------------------- @@ -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; @@ -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); @@ -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() { @@ -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::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 lines; + lines->InsertNextCell(2); + lines->InsertCellPoint(0); + lines->InsertCellPoint(1); + + vtkNew path; + path->SetPoints(this->LaserPoints); + path->SetLines(lines); + + vtkNew pathModel; + pathModel->SetSelectable(false); + pathModel->HideFromEditorsOn(); + pathModel->SetScene(this->GetMRMLScene()); + pathModel->SetName("Laser"); + pathModel->SetAndObservePolyData(path); + + this->LaserModelDisplay = vtkSmartPointer::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(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 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(); +} \ No newline at end of file diff --git a/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.h b/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.h index da62946..6a52ed6 100644 --- a/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.h +++ b/VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.h @@ -23,6 +23,8 @@ // MRML includes #include "vtkMRMLDisplayableManagerGroup.h" +#include "vtkMRMLInteractionEventData.h" +#include "vtkMRMLModelDisplayNode.h" // VTK includes #include "vtkObject.h" @@ -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 *); @@ -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 *); @@ -124,8 +126,8 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract //int GetInteractionState(vtkEventDataDevice device) { // return this->InteractionState[static_cast(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(); @@ -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 Menu; //vtkNew MenuRepresentation; @@ -192,6 +195,9 @@ class VTK_SLICER_VIRTUALREALITY_MODULE_MRML_EXPORT vtkVirtualRealityViewInteract //vtkNew HardwarePicker; vtkMRMLDisplayableManagerGroup* DisplayableManagerGroup; + vtkMRMLAbstractDisplayableManager* FocusedDisplayableManager; + vtkSmartPointer LaserPoints; + vtkSmartPointer LaserModelDisplay; protected: vtkVirtualRealityViewInteractorStyle();