diff --git a/MixedReality/MRML/CMakeLists.txt b/MixedReality/MRML/CMakeLists.txt index 77bdd02..b8fc2d3 100644 --- a/MixedReality/MRML/CMakeLists.txt +++ b/MixedReality/MRML/CMakeLists.txt @@ -2,6 +2,9 @@ project(vtkSlicer${MODULE_NAME}ModuleMRML) set(KIT ${PROJECT_NAME}) +#----------------------------------------------------------------------------- +find_package(vtkRenderingOpenXR REQUIRED) + #----------------------------------------------------------------------------- set(${KIT}_EXPORT_DIRECTIVE "VTK_SLICER_${MODULE_NAME_UPPER}_MODULE_MRML_EXPORT") @@ -16,11 +19,16 @@ set(${KIT}_SRCS vtkMRML${MODULE_NAME}ViewNode.h # vtkMRML${MODULE_NAME}LayoutNode.cxx # vtkMRML${MODULE_NAME}LayoutNode.h + vtk${MODULE_NAME}ViewInteractor.cxx + vtk${MODULE_NAME}ViewInteractor.h + vtk${MODULE_NAME}ViewInteractorStyle.cxx + vtk${MODULE_NAME}ViewInteractorStyle.h ) set(${KIT}_TARGET_LIBRARIES ${VTK_LIBRARIES} ${MRML_LIBRARIES} + VTK::RenderingOpenXR ) #----------------------------------------------------------------------------- diff --git a/MixedReality/MRML/vtkMRMLMixedRealityViewNode.h b/MixedReality/MRML/vtkMRMLMixedRealityViewNode.h index 8715448..e9922ca 100644 --- a/MixedReality/MRML/vtkMRMLMixedRealityViewNode.h +++ b/MixedReality/MRML/vtkMRMLMixedRealityViewNode.h @@ -75,14 +75,23 @@ class VTK_SLICER_MIXEDREALITY_MODULE_MRML_EXPORT vtkMRMLMixedRealityViewNode vtkSetMacro(PlayerIPAddress, const std::string); vtkGetMacro(PlayerIPAddress, std::string); + /// Magnification of world [0.01, 100]. + /// Value greater than 1 means that objects appear larger in VR than their real world size. + /// Translated to physical scale of the VR render window + vtkGetMacro(Magnification, double); + vtkSetMacro(Magnification, double); + protected: vtkMRMLMixedRealityViewNode(); ~vtkMRMLMixedRealityViewNode() override; vtkMRMLMixedRealityViewNode(const vtkMRMLMixedRealityViewNode&); void operator=(const vtkMRMLMixedRealityViewNode&); + // Connection std::string PlayerIPAddress; + // Display + double Magnification; static const char* ReferenceViewNodeReferenceRole; }; diff --git a/MixedReality/MRML/vtkMixedRealityViewInteractor.cxx b/MixedReality/MRML/vtkMixedRealityViewInteractor.cxx new file mode 100644 index 0000000..8657e80 --- /dev/null +++ b/MixedReality/MRML/vtkMixedRealityViewInteractor.cxx @@ -0,0 +1,38 @@ +/*============================================================================== + + Copyright (c) Laboratory for Percutaneous Surgery (PerkLab) + Queen's University, Kingston, ON, Canada. All Rights Reserved. + + See COPYRIGHT.txt + or http://www.slicer.org/copyright/copyright.txt for details. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + This file was originally developed by Csaba Pinter, PerkLab, Queen's University + and was supported through CANARIE's Research Software Program, and Cancer + Care Ontario. + +==============================================================================*/ + +#include "vtkMixedRealityViewInteractor.h" + +// VTK includes +#include + +// SlicerMixedReality includes +#include "vtkMixedRealityViewInteractorStyle.h" + +vtkStandardNewMacro(vtkMixedRealityViewInteractor); + +vtkMixedRealityViewInteractor::vtkMixedRealityViewInteractor() = default; +vtkMixedRealityViewInteractor::~vtkMixedRealityViewInteractor() = default; + +//---------------------------------------------------------------------------- +void vtkMixedRealityViewInteractor::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); +} diff --git a/MixedReality/MRML/vtkMixedRealityViewInteractor.h b/MixedReality/MRML/vtkMixedRealityViewInteractor.h new file mode 100644 index 0000000..3614b8a --- /dev/null +++ b/MixedReality/MRML/vtkMixedRealityViewInteractor.h @@ -0,0 +1,55 @@ +/*============================================================================== + + Copyright (c) Laboratory for Percutaneous Surgery (PerkLab) + Queen's University, Kingston, ON, Canada. All Rights Reserved. + + See COPYRIGHT.txt + or http://www.slicer.org/copyright/copyright.txt for details. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + This file was originally developed by Csaba Pinter, PerkLab, Queen's University + and was supported through CANARIE's Research Software Program, and Cancer + Care Ontario. + +==============================================================================*/ + +#ifndef vtkMixedRealityViewInteractor_h +#define vtkMixedRealityViewInteractor_h + +#include "vtkSlicerMixedRealityModuleMRMLExport.h" + +#include + +#include + +// vtkRenderingOpenXR is not python wrapped, so wrapping New causes linking error //TODO: +#ifndef __VTK_WRAP__ + +class VTK_SLICER_MIXEDREALITY_MODULE_MRML_EXPORT vtkMixedRealityViewInteractor : public vtkOpenXRRenderWindowInteractor +{ +public: + static vtkMixedRealityViewInteractor *New(); + + typedef vtkMixedRealityViewInteractor Self; + + vtkTypeMacro(vtkMixedRealityViewInteractor,vtkOpenXRRenderWindowInteractor); + void PrintSelf(ostream& os, vtkIndent indent) override; + +protected: + +private: + vtkMixedRealityViewInteractor(); + ~vtkMixedRealityViewInteractor() override; + + vtkMixedRealityViewInteractor(const vtkMixedRealityViewInteractor&) = delete; + void operator=(const vtkMixedRealityViewInteractor&) = delete; +}; + +#endif // __VTK_WRAP__ + +#endif diff --git a/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.cxx b/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.cxx new file mode 100644 index 0000000..39b2497 --- /dev/null +++ b/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.cxx @@ -0,0 +1,196 @@ +/*============================================================================== + + Copyright (c) Laboratory for Percutaneous Surgery (PerkLab) + Queen's University, Kingston, ON, Canada. All Rights Reserved. + + See COPYRIGHT.txt + or http://www.slicer.org/copyright/copyright.txt for details. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + This file was originally developed by Csaba Pinter, PerkLab, Queen's University + and was supported through CANARIE's Research Software Program, and Cancer + Care Ontario. + +==============================================================================*/ + +#include "vtkMixedRealityViewInteractorStyle.h" + +// VR MRML includes +//#include "vtkMRMLMixedRealityViewNode.h" + +// MRML includes +//#include "vtkMRMLAbstractThreeDViewDisplayableManager.h" +//#include "vtkMRMLDisplayableManagerGroup.h" +//#include "vtkMRMLScene.h" + +// VTK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VTK OpenXR +#include +#include + + +vtkStandardNewMacro(vtkMixedRealityViewInteractorStyle); + +//---------------------------------------------------------------------------- +class vtkMixedRealityViewInteractorStyle::vtkInternal +{ +public: + vtkInternal() = default; + ~vtkInternal() = default; +public: +}; + +//--------------------------------------------------------------------------- +// vtkMixedRealityViewInteractorStyle methods + +//---------------------------------------------------------------------------- +vtkMixedRealityViewInteractorStyle::vtkMixedRealityViewInteractorStyle() +{ + this->Internal = new vtkInternal(); +} + +//---------------------------------------------------------------------------- +vtkMixedRealityViewInteractorStyle::~vtkMixedRealityViewInteractorStyle() +{ + delete this->Internal; +} + +//---------------------------------------------------------------------------- +void vtkMixedRealityViewInteractorStyle::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os,indent); +} + +//---------------------------------------------------------------------------- +// Generic events binding +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Interaction methods +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Interaction entry points +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Multitouch interaction methods +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Utility routines +//---------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +//vtkMRMLScene* vtkMixedRealityViewInteractorStyle::GetMRMLScene() +//{ +// if (!this->DisplayableManagers +// || this->DisplayableManagers->GetDisplayableManagerCount() == 0) +// { +// return nullptr; +// } + +// return this->DisplayableManagers->GetNthDisplayableManager(0)->GetMRMLScene(); +//} + +//--------------------------------------------------------------------------- +void vtkMixedRealityViewInteractorStyle::SetMagnification(double magnification) +{ + if (this->CurrentRenderer == nullptr) + { + return; + } + + vtkOpenXRRenderWindowInteractor* rwi = static_cast(this->Interactor); + vtkOpenXRRenderWindow* rw = static_cast(rwi->GetRenderWindow()); + + double currentPhysicalScale = rw->GetPhysicalScale(); + double newPhysicalScale = 1000.0 / magnification; + double scaleFactor = newPhysicalScale / currentPhysicalScale; + if (fabs(scaleFactor - 1.0) < 0.001) + { + return; + } + + // Get Physical to World_Origin matrix + vtkNew physicalToWorldOriginMatrix; + rw->GetPhysicalToWorldMatrix(physicalToWorldOriginMatrix); + + // Calculate World_Origin to World_FocusPoint matrix + double bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + this->CurrentRenderer->ComputeVisiblePropBounds(bounds); + double focusPoint_World[3] = { (bounds[1] + bounds[0]) / 2.0, + (bounds[3] + bounds[2]) / 2.0, + (bounds[5] + bounds[4]) / 2.0 }; + vtkNew worldOriginToWorldFocusPointMatrix; + for (int i=0; i<3; ++i) + { + worldOriginToWorldFocusPointMatrix->SetElement(i,3, -focusPoint_World[i]); + } + + // Calculate World_FocusPoint to World_ScaledFocusPoint matrix + vtkNew worldFocusPointToWorldScaledFocusPointMatrix; + for (int i=0; i<3; ++i) + { + worldFocusPointToWorldScaledFocusPointMatrix->SetElement(i,i, scaleFactor); + } + + // Calculate World_ScaledFocusPoint to World_ScaledOrigin matrix + vtkNew worldScaledFocusPointToWorldScaledOriginMatrix; + for (int i=0; i<3; ++i) + { + worldScaledFocusPointToWorldScaledOriginMatrix->SetElement(i,3, focusPoint_World[i]); + } + + // Calculate Physical to World_ScaledOrigin matrix + vtkNew worldFocusPointToWorldScaledOriginMatrix; + vtkMatrix4x4::Multiply4x4( worldScaledFocusPointToWorldScaledOriginMatrix, worldFocusPointToWorldScaledFocusPointMatrix, + worldFocusPointToWorldScaledOriginMatrix ); + + vtkNew worldOriginToWorldScaledOriginMatrix; + vtkMatrix4x4::Multiply4x4( worldFocusPointToWorldScaledOriginMatrix, worldOriginToWorldFocusPointMatrix, + worldOriginToWorldScaledOriginMatrix ); + + // Physical to World_ScaledOrigin + vtkNew physicalToWorldScaledOriginMatrix; + vtkMatrix4x4::Multiply4x4( worldOriginToWorldScaledOriginMatrix, physicalToWorldOriginMatrix, + physicalToWorldScaledOriginMatrix ); + + rw->SetPhysicalToWorldMatrix(physicalToWorldScaledOriginMatrix); + + if (this->AutoAdjustCameraClippingRange) + { + this->CurrentRenderer->ResetCameraClippingRange(); + } + if (this->Interactor->GetLightFollowCamera()) + { + this->CurrentRenderer->UpdateLightsGeometryToFollowCamera(); + } +} + +//--------------------------------------------------------------------------- +double vtkMixedRealityViewInteractorStyle::GetMagnification() +{ + vtkOpenXRRenderWindowInteractor* rwi = static_cast(this->Interactor); + vtkOpenXRRenderWindow* rw = static_cast(rwi->GetRenderWindow()); + + return 1000.0 / rw->GetPhysicalScale(); +} diff --git a/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.h b/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.h new file mode 100644 index 0000000..cc35d6e --- /dev/null +++ b/MixedReality/MRML/vtkMixedRealityViewInteractorStyle.h @@ -0,0 +1,66 @@ +/*============================================================================== + + Copyright (c) Laboratory for Percutaneous Surgery (PerkLab) + Queen's University, Kingston, ON, Canada. All Rights Reserved. + + See COPYRIGHT.txt + or http://www.slicer.org/copyright/copyright.txt for details. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + This file was originally developed by Csaba Pinter, PerkLab, Queen's University + and was supported through CANARIE's Research Software Program, and Cancer + Care Ontario. + +==============================================================================*/ + +#ifndef __vtkMixedRealityViewInteractorStyle_h +#define __vtkMixedRealityViewInteractorStyle_h + +// MRML includes +//#include "vtkMRMLViewInteractorStyle.h" +#include +//class vtkMRMLScene; + +// VTK includes +#include +#include + +#include "vtkSlicerMixedRealityModuleMRMLExport.h" + +/// \brief Mixed reality interactions +class VTK_SLICER_MIXEDREALITY_MODULE_MRML_EXPORT vtkMixedRealityViewInteractorStyle : +// public vtkMRMLViewInteractorStyle + public vtkOpenXRInteractorStyle +{ +public: + static vtkMixedRealityViewInteractorStyle *New(); +// vtkTypeMacro(vtkMixedRealityViewInteractorStyle,vtkMRMLViewInteractorStyle); + vtkTypeMacro(vtkMixedRealityViewInteractorStyle,vtkOpenXRInteractorStyle); + void PrintSelf(ostream& os, vtkIndent indent) override; + + /// Get MRML scene from the displayable manager group (the first displayable manager's if any) +// vtkMRMLScene* GetMRMLScene(); + + /// Set physical to world magnification. Valid value range is [0.01, 100]. + /// Note: Conversion is physicalScale = 1000 / magnification + void SetMagnification(double magnification); + double GetMagnification(); + +protected: + vtkMixedRealityViewInteractorStyle(); + ~vtkMixedRealityViewInteractorStyle() override; + +private: + vtkMixedRealityViewInteractorStyle(const vtkMixedRealityViewInteractorStyle&); /// Not implemented. + void operator=(const vtkMixedRealityViewInteractorStyle&); /// Not implemented. + + class vtkInternal; + vtkInternal* Internal; +}; + +#endif diff --git a/MixedReality/Resources/UI/qSlicerMixedRealityModuleWidget.ui b/MixedReality/Resources/UI/qSlicerMixedRealityModuleWidget.ui index b26e6e3..cfe204f 100644 --- a/MixedReality/Resources/UI/qSlicerMixedRealityModuleWidget.ui +++ b/MixedReality/Resources/UI/qSlicerMixedRealityModuleWidget.ui @@ -33,6 +33,67 @@ + + + + Advanced + + + + + + Magnification: + + + + + + + + + <html><head/><body><p>Scale of the world in VR view.</p><p><br/></p><p>1x magnification means that objects appear in real size, 10x means they appear ten times larger.</p></body></html> + + + 2 + + + 0.100000000000000 + + + 0.250000000000000 + + + -2.000000000000000 + + + 2.000000000000000 + + + 1.000000000000000 + + + false + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + 10x + + + + + + + + @@ -61,6 +122,11 @@
ctkCollapsibleButton.h
1 + + ctkSliderWidget + QWidget +
ctkSliderWidget.h
+
diff --git a/MixedReality/Widgets/qMRMLMixedRealityView.cxx b/MixedReality/Widgets/qMRMLMixedRealityView.cxx index efc780d..e5eead6 100644 --- a/MixedReality/Widgets/qMRMLMixedRealityView.cxx +++ b/MixedReality/Widgets/qMRMLMixedRealityView.cxx @@ -18,10 +18,10 @@ // Need to be included before qMRMLVRView_p #include -//#include -//#include //TODO: For debugging the original interactor -#include -//#include //TODO: For debugging the original interactor +#include "vtkMixedRealityViewInteractorStyle.h" +//#include //TODO: For debugging the original interactor +#include "vtkMixedRealityViewInteractor.h" +#include //TODO: For debugging the original interactor //#include #include #include @@ -120,6 +120,16 @@ CTK_GET_CPP(qMRMLMixedRealityView, vtkOpenXRRenderWindowInteractor*, interactor, CTK_SET_CPP(qMRMLMixedRealityView, const QString&, setActionManifestPath, ActionManifestPath); CTK_GET_CPP(qMRMLMixedRealityView, QString, actionManifestPath, ActionManifestPath); +//------------------------------------------------------------------------------ +void qMRMLMixedRealityView::onPhysicalToWorldMatrixModified() +{ + Q_D(qMRMLMixedRealityView); + + d->MRMLMixedRealityViewNode->SetMagnification(d->InteractorStyle->GetMagnification()); + + emit physicalToWorldMatrixModified(); +} + //--------------------------------------------------------------------------- void qMRMLMixedRealityViewPrivate::createRenderWindow() { @@ -141,14 +151,14 @@ void qMRMLMixedRealityViewPrivate::createRenderWindow() // this->LastViewPosition[2] = 0.0; this->RenderWindow = vtkSmartPointer::New(); this->Renderer = vtkSmartPointer::New(); -// this->Interactor = vtkSmartPointer::New(); - this->Interactor = vtkSmartPointer::New(); //TODO: For debugging the original interactor + this->Interactor = vtkSmartPointer::New(); +// this->Interactor = vtkSmartPointer::New(); //TODO: For debugging the original interactor this->Interactor->SetActionManifestDirectory(q->actionManifestPath().toStdString()); -// this->InteractorStyle = vtkSmartPointer::New(); + this->InteractorStyle = vtkSmartPointer::New(); //this->InteractorStyle = vtkSmartPointer::New(); //TODO: For debugging the original interactor -// this->Interactor->SetInteractorStyle(this->InteractorStyle); -// this->InteractorStyle->SetInteractor(this->Interactor); -// this->InteractorStyle->SetCurrentRenderer(this->Renderer); + this->Interactor->SetInteractorStyle(this->InteractorStyle); + this->InteractorStyle->SetInteractor(this->Interactor); + this->InteractorStyle->SetCurrentRenderer(this->Renderer); this->Camera = vtkSmartPointer::New(); this->Renderer->SetActiveCamera(this->Camera); @@ -158,13 +168,10 @@ void qMRMLMixedRealityViewPrivate::createRenderWindow() this->RenderWindow->SetRemotingIPAddress(q->mrmlMixedRealityViewNode()->GetPlayerIPAddress().c_str()); // Set default 10x magnification (conversion: PhysicalScale = 1000 / Magnification) -// this->RenderWindow->SetPhysicalScale(100.0); + this->RenderWindow->SetPhysicalScale(100.0); // Observe VR render window event -// qvtkReconnect(this->RenderWindow, vtkOpenVRRenderWindow::PhysicalToWorldMatrixModified, -// q, SLOT(onPhysicalToWorldMatrixModified())); - - // Observe button press event -// qvtkReconnect(this->Interactor, vtkCommand::Button3DEvent, q, SLOT(onButton3DEvent(vtkObject*,void*,unsigned long,void*))); + qvtkReconnect(this->RenderWindow, vtkOpenXRRenderWindow::PhysicalToWorldMatrixModified, + q, SLOT(onPhysicalToWorldMatrixModified())); vtkMRMLMixedRealityViewDisplayableManagerFactory* factory = vtkMRMLMixedRealityViewDisplayableManagerFactory::GetInstance(); @@ -326,23 +333,23 @@ void qMRMLMixedRealityViewPrivate::updateWidgetFromMRML() // this->Renderer->SetUseDepthPeeling(this->MRMLMixedRealityViewNode->GetUseDepthPeeling() != 0); // this->Renderer->SetUseDepthPeelingForVolumes(this->MRMLMixedRealityViewNode->GetUseDepthPeeling() != 0); -// // Render window properties -// if (this->RenderWindow) -// { + // Render window properties + if (this->RenderWindow) + { // // Desired update rate // this->RenderWindow->SetDesiredUpdateRate(this->desiredUpdateRate()); -// // Magnification -// double magnification = this->MRMLMixedRealityViewNode->GetMagnification(); -// if (magnification < 0.01) -// { -// magnification = 0.01; -// } -// else if (magnification > 100.0) -// { -// magnification = 100.0; -// } -// this->InteractorStyle->SetMagnification(magnification); + // Magnification + double magnification = this->MRMLMixedRealityViewNode->GetMagnification(); + if (magnification < 0.01) + { + magnification = 0.01; + } + else if (magnification > 100.0) + { + magnification = 100.0; + } + this->InteractorStyle->SetMagnification(magnification); // // Dolly physical speed // double dollyPhysicalSpeedMps = this ->MRMLMixedRealityViewNode->GetMotionSpeed(); @@ -378,7 +385,7 @@ void qMRMLMixedRealityViewPrivate::updateWidgetFromMRML() // } // } // } -// } + } // if (this->MRMLMixedRealityViewNode->GetActive()) // { diff --git a/MixedReality/Widgets/qMRMLMixedRealityView.h b/MixedReality/Widgets/qMRMLMixedRealityView.h index cd21ac4..8117094 100644 --- a/MixedReality/Widgets/qMRMLMixedRealityView.h +++ b/MixedReality/Widgets/qMRMLMixedRealityView.h @@ -114,10 +114,15 @@ class Q_SLICER_MODULE_MIXEDREALITY_WIDGETS_EXPORT qMRMLMixedRealityView : public QString actionManifestPath() const; ///@} +signals: + void physicalToWorldMatrixModified(); + public slots: /// Set the current \a viewNode to observe void setMRMLMixedRealityViewNode(vtkMRMLMixedRealityViewNode* newViewNode); + void onPhysicalToWorldMatrixModified(); + protected: QScopedPointer d_ptr; diff --git a/MixedReality/Widgets/qMRMLMixedRealityView_p.h b/MixedReality/Widgets/qMRMLMixedRealityView_p.h index f8892a5..d7bc01b 100644 --- a/MixedReality/Widgets/qMRMLMixedRealityView_p.h +++ b/MixedReality/Widgets/qMRMLMixedRealityView_p.h @@ -54,8 +54,8 @@ class vtkObject;; class vtkOpenXRRemotingRenderWindow; class vtkOpenXRRenderWindowInteractor; class vtkTimerLog; -//class vtkMixedRealityViewInteractor; -//class vtkMixedRealityViewInteractorStyle; +class vtkMixedRealityViewInteractor; +class vtkMixedRealityViewInteractorStyle; //----------------------------------------------------------------------------- class qMRMLMixedRealityViewPrivate: public QObject @@ -95,9 +95,9 @@ public slots: vtkWeakPointer MRMLMixedRealityViewNode; vtkSmartPointer Renderer; vtkSmartPointer RenderWindow; - vtkSmartPointer Interactor; + vtkSmartPointer Interactor; //vtkSmartPointer Interactor; //TODO: For debugging the original interactor -// vtkSmartPointer InteractorStyle; + vtkSmartPointer InteractorStyle; //vtkSmartPointer InteractorStyle; //TODO: For debugging the original interactor vtkSmartPointer Camera; // vtkSmartPointer Lights; diff --git a/MixedReality/qSlicerMixedRealityModule.cxx b/MixedReality/qSlicerMixedRealityModule.cxx index c73e70b..bf3313d 100644 --- a/MixedReality/qSlicerMixedRealityModule.cxx +++ b/MixedReality/qSlicerMixedRealityModule.cxx @@ -112,6 +112,14 @@ void qSlicerMixedRealityModulePrivate::addViewWidget() } qDebug() << "actionManifestPath:" << this->MixedRealityViewWidget->actionManifestPath(); + + qSlicerMixedRealityModuleWidget* moduleWidget = + dynamic_cast(q->widgetRepresentation()); + if (moduleWidget) + { + QObject::connect(this->MixedRealityViewWidget, SIGNAL(physicalToWorldMatrixModified()), + moduleWidget, SLOT(onPhysicalToWorldMatrixModified())); + } } //----------------------------------------------------------------------------- diff --git a/MixedReality/qSlicerMixedRealityModuleWidget.cxx b/MixedReality/qSlicerMixedRealityModuleWidget.cxx index 610d758..cfc6b81 100644 --- a/MixedReality/qSlicerMixedRealityModuleWidget.cxx +++ b/MixedReality/qSlicerMixedRealityModuleWidget.cxx @@ -91,3 +91,67 @@ void qSlicerMixedRealityModuleWidget::setPlayerIPAddress(const QString& value) xrViewNode->SetPlayerIPAddress(value.toStdString()); } } + +//---------------------------------------------------------------------------------- +void qSlicerMixedRealityModuleWidget::onMagnificationChanged(double powerOfTen) +{ + Q_D(qSlicerMixedRealityModuleWidget); + + double magnification = this->getMagnificationFromPower(powerOfTen); + + vtkSlicerMixedRealityLogic* vrLogic = vtkSlicerMixedRealityLogic::SafeDownCast(this->logic()); + vtkMRMLMixedRealityViewNode* vrViewNode = vrLogic->GetMixedRealityViewNode(); + if (vrViewNode) + { + vrViewNode->SetMagnification(magnification); + } + + d->MagnificationValueLabel->setText(QString("%1x").arg(magnification, 3, 'f', 2)); +} + +//---------------------------------------------------------------------------------- +void qSlicerMixedRealityModuleWidget::onPhysicalToWorldMatrixModified() +{ + Q_D(qSlicerMixedRealityModuleWidget); + + vtkSlicerMixedRealityLogic* vrLogic = vtkSlicerMixedRealityLogic::SafeDownCast(this->logic()); + vtkMRMLMixedRealityViewNode* vrViewNode = vrLogic->GetMixedRealityViewNode(); + if (vrViewNode) + { + double magnification = vrViewNode->GetMagnification(); + bool wasBlocked = d->MagnificationSlider->blockSignals(true); + d->MagnificationSlider->setValue(this->getPowerFromMagnification(magnification)); + d->MagnificationSlider->blockSignals(wasBlocked); + d->MagnificationValueLabel->setText(QString("%1x").arg(magnification, 3, 'f', 2)); + } +} + +//---------------------------------------------------------------------------------- +double qSlicerMixedRealityModuleWidget::getMagnificationFromPower(double powerOfTen) +{ + if (powerOfTen < -2.0) + { + powerOfTen = -2.0; + } + else if (powerOfTen > 2.0) + { + powerOfTen = 2.0; + } + + return pow(10.0, powerOfTen); +} + +//---------------------------------------------------------------------------------- +double qSlicerMixedRealityModuleWidget::getPowerFromMagnification(double magnification) +{ + if (magnification < 0.01) + { + magnification = 0.01; + } + else if (magnification > 100.0) + { + magnification = 100.0; + } + + return log10(magnification); +} diff --git a/MixedReality/qSlicerMixedRealityModuleWidget.h b/MixedReality/qSlicerMixedRealityModuleWidget.h index a6ba076..7907ed2 100644 --- a/MixedReality/qSlicerMixedRealityModuleWidget.h +++ b/MixedReality/qSlicerMixedRealityModuleWidget.h @@ -41,15 +41,21 @@ class Q_SLICER_QTMODULES_MIXEDREALITY_EXPORT qSlicerMixedRealityModuleWidget : public slots: void setPlayerIPAddress(const QString& value); + void onMagnificationChanged(double); protected slots: void updateWidgetFromMRML(); + void onPhysicalToWorldMatrixModified(); + protected: QScopedPointer d_ptr; void setup() override; + double getMagnificationFromPower(double powerOfTen); + double getPowerFromMagnification(double magnification); + private: Q_DECLARE_PRIVATE(qSlicerMixedRealityModuleWidget); Q_DISABLE_COPY(qSlicerMixedRealityModuleWidget);