1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkOpenVRInteractorStyle.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkOpenVRInteractorStyle.h"
16
17 #include "vtkCompositeDataSet.h"
18 #include "vtkDataObjectTreeIterator.h"
19
20 #include "vtkBillboardTextActor3D.h"
21 #include "vtkCoordinate.h"
22 #include "vtkTextActor.h"
23 #include "vtkTextActor3D.h"
24
25 #include "vtkAssemblyPath.h"
26 #include "vtkCallbackCommand.h"
27 #include "vtkCamera.h"
28 #include "vtkCellData.h"
29 #include "vtkCellPicker.h"
30 #include "vtkDataObject.h"
31 #include "vtkDataSet.h"
32 #include "vtkHardwareSelector.h"
33 #include "vtkIdTypeArray.h"
34 #include "vtkInformation.h"
35 #include "vtkMapper.h"
36 #include "vtkNew.h"
37 #include "vtkObjectFactory.h"
38 #include "vtkOpenVRCamera.h"
39 #include "vtkOpenVRControlsHelper.h"
40 #include "vtkOpenVRModel.h"
41 #include "vtkOpenVROverlay.h"
42 #include "vtkOpenVRRenderWindow.h"
43 #include "vtkOpenVRRenderWindowInteractor.h"
44 #include "vtkPlane.h"
45 #include "vtkPolyData.h"
46 #include "vtkPolyDataMapper.h"
47 #include "vtkPropPicker.h"
48 #include "vtkProperty.h"
49 #include "vtkRenderWindow.h"
50 #include "vtkRenderer.h"
51 #include "vtkSelection.h"
52 #include "vtkSelectionNode.h"
53 #include "vtkSphereSource.h"
54 #include "vtkStringArray.h"
55 #include "vtkTextProperty.h"
56 #include "vtkTimerLog.h"
57 #include "vtkVRHardwarePicker.h"
58 #include "vtkVRModel.h"
59
60 #include "vtkVRMenuRepresentation.h"
61 #include "vtkVRMenuWidget.h"
62
63 #include <sstream>
64
65 // Map controller inputs to interaction states
66 vtkStandardNewMacro(vtkOpenVRInteractorStyle);
67
68 //------------------------------------------------------------------------------
vtkOpenVRInteractorStyle()69 vtkOpenVRInteractorStyle::vtkOpenVRInteractorStyle()
70 {
71 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
72 {
73 this->InteractionState[d] = VTKIS_NONE;
74 this->InteractionProps[d] = nullptr;
75 this->ClippingPlanes[d] = nullptr;
76
77 for (int i = 0; i < vtkEventDataNumberOfInputs; i++)
78 {
79 this->ControlsHelpers[d][i] = nullptr;
80 }
81 }
82
83 // Create default inputs mapping
84 this->MapInputToAction(vtkCommand::ViewerMovement3DEvent, VTKIS_DOLLY);
85 this->MapInputToAction(vtkCommand::Menu3DEvent, VTKIS_MENU);
86 this->MapInputToAction(vtkCommand::NextPose3DEvent, VTKIS_LOAD_CAMERA_POSE);
87 this->MapInputToAction(vtkCommand::Select3DEvent, VTKIS_POSITION_PROP);
88
89 this->MenuCommand = vtkCallbackCommand::New();
90 this->MenuCommand->SetClientData(this);
91 this->MenuCommand->SetCallback(vtkOpenVRInteractorStyle::MenuCallback);
92
93 this->Menu->SetRepresentation(this->MenuRepresentation);
94 this->Menu->PushFrontMenuItem("exit", "Exit", this->MenuCommand);
95 this->Menu->PushFrontMenuItem("clipmode", "Clipping Mode", this->MenuCommand);
96 this->Menu->PushFrontMenuItem("probemode", "Probe Mode", this->MenuCommand);
97 this->Menu->PushFrontMenuItem("grabmode", "Grab Mode", this->MenuCommand);
98
99 vtkNew<vtkPolyDataMapper> pdm;
100 this->PickActor->SetMapper(pdm);
101 this->PickActor->GetProperty()->SetLineWidth(4);
102 this->PickActor->GetProperty()->RenderLinesAsTubesOn();
103 this->PickActor->GetProperty()->SetRepresentationToWireframe();
104 this->PickActor->DragableOff();
105
106 this->HoverPickOff();
107 this->GrabWithRayOff();
108
109 vtkNew<vtkCellPicker> exactPicker;
110 this->SetInteractionPicker(exactPicker);
111 }
112
113 //------------------------------------------------------------------------------
~vtkOpenVRInteractorStyle()114 vtkOpenVRInteractorStyle::~vtkOpenVRInteractorStyle()
115 {
116 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
117 {
118 if (this->ClippingPlanes[d])
119 {
120 this->ClippingPlanes[d]->Delete();
121 this->ClippingPlanes[d] = nullptr;
122 }
123 }
124 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
125 {
126 for (int i = 0; i < vtkEventDataNumberOfInputs; i++)
127 {
128 if (this->ControlsHelpers[d][i])
129 {
130 this->ControlsHelpers[d][i]->Delete();
131 this->ControlsHelpers[d][i] = nullptr;
132 }
133 }
134 }
135 this->MenuCommand->Delete();
136 }
137
SetInteractor(vtkRenderWindowInteractor * iren)138 void vtkOpenVRInteractorStyle::SetInteractor(vtkRenderWindowInteractor* iren)
139 {
140 this->Superclass::SetInteractor(iren);
141
142 // hook up default bindings?
143 auto oiren = vtkOpenVRRenderWindowInteractor::SafeDownCast(iren);
144 if (!oiren)
145 {
146 return;
147 }
148
149 oiren->AddAction("/actions/vtk/in/StartMovement", vtkCommand::ViewerMovement3DEvent, false);
150 oiren->AddAction("/actions/vtk/in/Movement", vtkCommand::ViewerMovement3DEvent, true);
151 oiren->AddAction("/actions/vtk/in/NextCameraPose", vtkCommand::NextPose3DEvent, false);
152 oiren->AddAction("/actions/vtk/in/TriggerAction", vtkCommand::Select3DEvent, false);
153 oiren->AddAction("/actions/vtk/in/PositionProp", vtkCommand::PositionProp3DEvent, false);
154 oiren->AddAction("/actions/vtk/in/ShowMenu", vtkCommand::Menu3DEvent, false);
155 }
156
157 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)158 void vtkOpenVRInteractorStyle::PrintSelf(ostream& os, vtkIndent indent)
159 {
160 this->Superclass::PrintSelf(os, indent);
161 }
162
163 //------------------------------------------------------------------------------
MenuCallback(vtkObject * vtkNotUsed (object),unsigned long,void * clientdata,void * calldata)164 void vtkOpenVRInteractorStyle::MenuCallback(
165 vtkObject* vtkNotUsed(object), unsigned long, void* clientdata, void* calldata)
166 {
167 std::string name = static_cast<const char*>(calldata);
168 vtkOpenVRInteractorStyle* self = static_cast<vtkOpenVRInteractorStyle*>(clientdata);
169
170 if (name == "exit")
171 {
172 if (self->Interactor)
173 {
174 self->Interactor->ExitCallback();
175 }
176 }
177 if (name == "togglelabel")
178 {
179 self->ToggleDrawControls();
180 }
181 if (name == "clipmode")
182 {
183 self->MapInputToAction(vtkCommand::Select3DEvent, VTKIS_CLIP);
184 }
185 if (name == "grabmode")
186 {
187 self->MapInputToAction(vtkCommand::Select3DEvent, VTKIS_POSITION_PROP);
188 }
189 if (name == "probemode")
190 {
191 self->MapInputToAction(vtkCommand::Select3DEvent, VTKIS_PICK);
192 }
193 }
194
OnNextPose3D(vtkEventData * edata)195 void vtkOpenVRInteractorStyle::OnNextPose3D(vtkEventData* edata)
196 {
197 vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
198 if (!edd)
199 {
200 return;
201 }
202 if (edd->GetAction() == vtkEventDataAction::Press)
203 {
204 this->LoadNextCameraPose();
205 }
206 }
207
OnViewerMovement3D(vtkEventData * edata)208 void vtkOpenVRInteractorStyle::OnViewerMovement3D(vtkEventData* edata)
209 {
210 vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
211 if (!edd)
212 {
213 return;
214 }
215
216 // joystick moves?
217 int idev = static_cast<int>(edd->GetDevice());
218
219 // Update current state
220 int x = this->Interactor->GetEventPosition()[0];
221 int y = this->Interactor->GetEventPosition()[1];
222 this->FindPokedRenderer(x, y);
223
224 // Set current state and interaction prop
225 this->InteractionProp = this->InteractionProps[idev];
226
227 double const* pos = edd->GetTrackPadPosition();
228
229 if (edd->GetAction() == vtkEventDataAction::Press)
230 {
231 this->StartAction(VTKIS_DOLLY, edd);
232 this->LastTrackPadPosition[0] = 0.0;
233 this->LastTrackPadPosition[1] = 0.0;
234 return;
235 }
236
237 if (edd->GetAction() == vtkEventDataAction::Release)
238 {
239 this->EndAction(VTKIS_DOLLY, edd);
240 return;
241 }
242
243 // if the event is joystick and it is away from the center then
244 // call start, when returning to center call end
245 if (edd->GetInput() == vtkEventDataDeviceInput::Joystick &&
246 this->InteractionState[idev] != VTKIS_DOLLY && pos[1] != 0.0)
247 {
248 this->StartAction(VTKIS_DOLLY, edd);
249 this->LastTrackPadPosition[0] = 0.0;
250 this->LastTrackPadPosition[1] = 0.0;
251 return;
252 }
253
254 if (this->InteractionState[idev] == VTKIS_DOLLY)
255 {
256 // strop when returning to zero on joystick
257 if (edd->GetInput() == vtkEventDataDeviceInput::Joystick && pos[1] == 0.0)
258 {
259 this->EndAction(VTKIS_DOLLY, edd);
260 return;
261 }
262 this->Dolly3D(edata);
263 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
264 }
265 }
266
267 //------------------------------------------------------------------------------
268 // Generic events binding
269 //------------------------------------------------------------------------------
OnMove3D(vtkEventData * edata)270 void vtkOpenVRInteractorStyle::OnMove3D(vtkEventData* edata)
271 {
272 vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
273 if (!edd)
274 {
275 return;
276 }
277
278 // joystick moves?
279 int idev = static_cast<int>(edd->GetDevice());
280
281 // Update current state
282 int x = this->Interactor->GetEventPosition()[0];
283 int y = this->Interactor->GetEventPosition()[1];
284
285 // Set current state and interaction prop
286 this->InteractionProp = this->InteractionProps[idev];
287
288 switch (this->InteractionState[idev])
289 {
290 case VTKIS_POSITION_PROP:
291 this->FindPokedRenderer(x, y);
292 this->PositionProp(edd);
293 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
294 break;
295 case VTKIS_DOLLY:
296 this->FindPokedRenderer(x, y);
297 this->Dolly3D(edata);
298 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
299 break;
300 case VTKIS_CLIP:
301 this->FindPokedRenderer(x, y);
302 this->Clip(edd);
303 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
304 break;
305 }
306
307 // Update rays
308 this->UpdateRay(edd->GetDevice());
309 }
310
311 //------------------------------------------------------------------------------
OnMenu3D(vtkEventData * edata)312 void vtkOpenVRInteractorStyle::OnMenu3D(vtkEventData* edata)
313 {
314 vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
315 if (!edd)
316 {
317 return;
318 }
319
320 int x = this->Interactor->GetEventPosition()[0];
321 int y = this->Interactor->GetEventPosition()[1];
322 this->FindPokedRenderer(x, y);
323
324 if (edd->GetAction() == vtkEventDataAction::Press)
325 {
326 this->StartAction(VTKIS_MENU, edd);
327 return;
328 }
329
330 if (edd->GetAction() == vtkEventDataAction::Release)
331 {
332 this->EndAction(VTKIS_MENU, edd);
333 return;
334 }
335 }
336
337 //------------------------------------------------------------------------------
OnSelect3D(vtkEventData * edata)338 void vtkOpenVRInteractorStyle::OnSelect3D(vtkEventData* edata)
339 {
340 vtkEventDataDevice3D* bd = edata->GetAsEventDataDevice3D();
341 if (!bd)
342 {
343 return;
344 }
345
346 int x = this->Interactor->GetEventPosition()[0];
347 int y = this->Interactor->GetEventPosition()[1];
348 this->FindPokedRenderer(x, y);
349
350 decltype(this->InputMap)::key_type key(vtkCommand::Select3DEvent, bd->GetAction());
351 auto it = this->InputMap.find(key);
352 if (it == this->InputMap.end())
353 {
354 return;
355 }
356
357 int state = it->second;
358
359 // if grab mode then convert event data into where the ray is intersecting geometry
360
361 if (bd->GetAction() == vtkEventDataAction::Press)
362 {
363 this->StartAction(state, bd);
364 }
365 if (bd->GetAction() == vtkEventDataAction::Release)
366 {
367 this->EndAction(state, bd);
368 }
369 if (bd->GetAction() == vtkEventDataAction::Touch)
370 {
371 this->StartAction(state, bd);
372 }
373 if (bd->GetAction() == vtkEventDataAction::Untouch)
374 {
375 this->EndAction(state, bd);
376 }
377 }
378 //------------------------------------------------------------------------------
379
380 //------------------------------------------------------------------------------
381 // Interaction entry points
382 //------------------------------------------------------------------------------
StartPick(vtkEventDataDevice3D * edata)383 void vtkOpenVRInteractorStyle::StartPick(vtkEventDataDevice3D* edata)
384 {
385 this->HideBillboard();
386 this->HidePickActor();
387
388 this->InteractionState[static_cast<int>(edata->GetDevice())] = VTKIS_PICK;
389
390 // update ray
391 this->UpdateRay(edata->GetDevice());
392 }
393 //------------------------------------------------------------------------------
EndPick(vtkEventDataDevice3D * edata)394 void vtkOpenVRInteractorStyle::EndPick(vtkEventDataDevice3D* edata)
395 {
396 // perform probe
397 this->ProbeData(edata->GetDevice());
398
399 this->InteractionState[static_cast<int>(edata->GetDevice())] = VTKIS_NONE;
400
401 // turn off ray
402 this->UpdateRay(edata->GetDevice());
403 }
404
405 //------------------------------------------------------------------------------
StartLoadCamPose(vtkEventDataDevice3D * edata)406 void vtkOpenVRInteractorStyle::StartLoadCamPose(vtkEventDataDevice3D* edata)
407 {
408 int iDevice = static_cast<int>(edata->GetDevice());
409 this->InteractionState[iDevice] = VTKIS_LOAD_CAMERA_POSE;
410 }
411 //------------------------------------------------------------------------------
EndLoadCamPose(vtkEventDataDevice3D * edata)412 void vtkOpenVRInteractorStyle::EndLoadCamPose(vtkEventDataDevice3D* edata)
413 {
414 this->LoadNextCameraPose();
415
416 int iDevice = static_cast<int>(edata->GetDevice());
417 this->InteractionState[iDevice] = VTKIS_NONE;
418 }
419
420 //------------------------------------------------------------------------------
HardwareSelect(vtkEventDataDevice controller,bool actorPassOnly)421 bool vtkOpenVRInteractorStyle::HardwareSelect(vtkEventDataDevice controller, bool actorPassOnly)
422 {
423 vtkRenderer* ren = this->CurrentRenderer;
424 vtkOpenVRRenderWindow* renWin =
425 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
426 vtkOpenVRRenderWindowInteractor* iren =
427 static_cast<vtkOpenVRRenderWindowInteractor*>(this->Interactor);
428
429 if (!ren || !renWin || !iren)
430 {
431 return false;
432 }
433
434 vtkOpenVRModel* cmodel = vtkOpenVRModel::SafeDownCast(renWin->GetTrackedDeviceModel(controller));
435 if (!cmodel)
436 {
437 return false;
438 }
439
440 cmodel->SetVisibility(false);
441
442 // Compute controller position and world orientation
443 double p0[3]; // Ray start point
444 double wxyz[4]; // Controller orientation
445 double dummy_ppos[3];
446 double wdir[3];
447 vr::TrackedDevicePose_t* tdPose = renWin->GetTrackedDevicePose(cmodel->TrackedDevice);
448 iren->ConvertPoseToWorldCoordinates(*tdPose, p0, wxyz, dummy_ppos, wdir);
449
450 this->HardwarePicker->PickProp(p0, wxyz, ren, ren->GetViewProps(), actorPassOnly);
451
452 cmodel->SetVisibility(true);
453
454 return true;
455 }
456
457 //------------------------------------------------------------------------------
StartPositionProp(vtkEventDataDevice3D * edata)458 void vtkOpenVRInteractorStyle::StartPositionProp(vtkEventDataDevice3D* edata)
459 {
460 if (this->GrabWithRay)
461 {
462 if (!this->HardwareSelect(edata->GetDevice(), true))
463 {
464 return;
465 }
466
467 vtkSelection* selection = this->HardwarePicker->GetSelection();
468
469 if (!selection || selection->GetNumberOfNodes() == 0)
470 {
471 return;
472 }
473
474 vtkSelectionNode* node = selection->GetNode(0);
475 this->InteractionProp =
476 vtkProp3D::SafeDownCast(node->GetProperties()->Get(vtkSelectionNode::PROP()));
477 }
478 else
479 {
480 double pos[3];
481 edata->GetWorldPosition(pos);
482 this->FindPickedActor(pos, nullptr);
483 }
484
485 if (this->InteractionProp == nullptr)
486 {
487 return;
488 }
489
490 this->InteractionState[static_cast<int>(edata->GetDevice())] = VTKIS_POSITION_PROP;
491 this->InteractionProps[static_cast<int>(edata->GetDevice())] = this->InteractionProp;
492
493 // Don't start action if a controller is already positioning the prop
494 int rc = static_cast<int>(vtkEventDataDevice::RightController);
495 int lc = static_cast<int>(vtkEventDataDevice::LeftController);
496 if (this->InteractionProps[rc] == this->InteractionProps[lc])
497 {
498 this->EndPositionProp(edata);
499 return;
500 }
501 }
502
503 //------------------------------------------------------------------------------
EndPositionProp(vtkEventDataDevice3D * edata)504 void vtkOpenVRInteractorStyle::EndPositionProp(vtkEventDataDevice3D* edata)
505 {
506 vtkEventDataDevice dev = edata->GetDevice();
507 this->InteractionState[static_cast<int>(dev)] = VTKIS_NONE;
508 this->InteractionProps[static_cast<int>(dev)] = nullptr;
509 }
510
511 //------------------------------------------------------------------------------
StartClip(vtkEventDataDevice3D * ed)512 void vtkOpenVRInteractorStyle::StartClip(vtkEventDataDevice3D* ed)
513 {
514 if (this->CurrentRenderer == nullptr)
515 {
516 return;
517 }
518
519 vtkEventDataDevice dev = ed->GetDevice();
520 this->InteractionState[static_cast<int>(dev)] = VTKIS_CLIP;
521
522 if (!this->ClippingPlanes[static_cast<int>(dev)])
523 {
524 this->ClippingPlanes[static_cast<int>(dev)] = vtkPlane::New();
525 }
526
527 vtkActorCollection* ac;
528 vtkActor *anActor, *aPart;
529 vtkAssemblyPath* path;
530 if (this->CurrentRenderer != nullptr)
531 {
532 ac = this->CurrentRenderer->GetActors();
533 vtkCollectionSimpleIterator ait;
534 for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait));)
535 {
536 for (anActor->InitPathTraversal(); (path = anActor->GetNextPath());)
537 {
538 aPart = static_cast<vtkActor*>(path->GetLastNode()->GetViewProp());
539 if (aPart->GetMapper())
540 {
541 aPart->GetMapper()->AddClippingPlane(this->ClippingPlanes[static_cast<int>(dev)]);
542 continue;
543 }
544 }
545 }
546 }
547 else
548 {
549 vtkWarningMacro(<< "no current renderer on the interactor style.");
550 }
551 }
552
553 //------------------------------------------------------------------------------
EndClip(vtkEventDataDevice3D * ed)554 void vtkOpenVRInteractorStyle::EndClip(vtkEventDataDevice3D* ed)
555 {
556 vtkEventDataDevice dev = ed->GetDevice();
557 this->InteractionState[static_cast<int>(dev)] = VTKIS_NONE;
558
559 vtkActorCollection* ac;
560 vtkActor *anActor, *aPart;
561 vtkAssemblyPath* path;
562 if (this->CurrentRenderer != nullptr)
563 {
564 ac = this->CurrentRenderer->GetActors();
565 vtkCollectionSimpleIterator ait;
566 for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait));)
567 {
568 for (anActor->InitPathTraversal(); (path = anActor->GetNextPath());)
569 {
570 aPart = static_cast<vtkActor*>(path->GetLastNode()->GetViewProp());
571 if (aPart->GetMapper())
572 {
573 aPart->GetMapper()->RemoveClippingPlane(this->ClippingPlanes[static_cast<int>(dev)]);
574 continue;
575 }
576 }
577 }
578 }
579 else
580 {
581 vtkWarningMacro(<< "no current renderer on the interactor style.");
582 }
583 }
584
585 //------------------------------------------------------------------------------
StartDolly3D(vtkEventDataDevice3D * ed)586 void vtkOpenVRInteractorStyle::StartDolly3D(vtkEventDataDevice3D* ed)
587 {
588 if (this->CurrentRenderer == nullptr)
589 {
590 return;
591 }
592 vtkEventDataDevice dev = ed->GetDevice();
593 this->InteractionState[static_cast<int>(dev)] = VTKIS_DOLLY;
594 this->LastDolly3DEventTime->StartTimer();
595
596 // this->GrabFocus(this->EventCallbackCommand);
597 }
598 //------------------------------------------------------------------------------
EndDolly3D(vtkEventDataDevice3D * ed)599 void vtkOpenVRInteractorStyle::EndDolly3D(vtkEventDataDevice3D* ed)
600 {
601 vtkEventDataDevice dev = ed->GetDevice();
602 this->InteractionState[static_cast<int>(dev)] = VTKIS_NONE;
603
604 this->LastDolly3DEventTime->StopTimer();
605 }
606
607 //------------------------------------------------------------------------------
ToggleDrawControls()608 void vtkOpenVRInteractorStyle::ToggleDrawControls()
609 {
610 if (this->CurrentRenderer == nullptr)
611 {
612 return;
613 }
614
615 // Enable helpers
616 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
617 {
618 // No helper for HMD
619 if (static_cast<vtkEventDataDevice>(d) == vtkEventDataDevice::HeadMountedDisplay)
620 {
621 continue;
622 }
623
624 for (int i = 0; i < vtkEventDataNumberOfInputs; i++)
625 {
626 if (this->ControlsHelpers[d][i])
627 {
628 if (this->ControlsHelpers[d][i]->GetRenderer() != this->CurrentRenderer)
629 {
630 vtkRenderer* ren = this->ControlsHelpers[d][i]->GetRenderer();
631 if (ren)
632 {
633 ren->RemoveViewProp(this->ControlsHelpers[d][i]);
634 }
635 this->ControlsHelpers[d][i]->SetRenderer(this->CurrentRenderer);
636 this->ControlsHelpers[d][i]->BuildRepresentation();
637 // this->ControlsHelpers[iDevice][iInput]->SetEnabled(false);
638 this->CurrentRenderer->AddViewProp(this->ControlsHelpers[d][i]);
639 }
640
641 this->ControlsHelpers[d][i]->SetEnabled(!this->ControlsHelpers[d][i]->GetEnabled());
642 }
643 }
644 }
645 }
646
SetDrawControls(bool val)647 void vtkOpenVRInteractorStyle::SetDrawControls(bool val)
648 {
649 if (this->CurrentRenderer == nullptr)
650 {
651 return;
652 }
653
654 // Enable helpers
655 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
656 {
657 // No helper for HMD
658 if (static_cast<vtkEventDataDevice>(d) == vtkEventDataDevice::HeadMountedDisplay)
659 {
660 continue;
661 }
662
663 for (int i = 0; i < vtkEventDataNumberOfInputs; i++)
664 {
665 if (this->ControlsHelpers[d][i])
666 {
667 if (this->ControlsHelpers[d][i]->GetRenderer() != this->CurrentRenderer)
668 {
669 vtkRenderer* ren = this->ControlsHelpers[d][i]->GetRenderer();
670 if (ren)
671 {
672 ren->RemoveViewProp(this->ControlsHelpers[d][i]);
673 }
674 this->ControlsHelpers[d][i]->SetRenderer(this->CurrentRenderer);
675 this->ControlsHelpers[d][i]->BuildRepresentation();
676 // this->ControlsHelpers[iDevice][iInput]->SetEnabled(false);
677 this->CurrentRenderer->AddViewProp(this->ControlsHelpers[d][i]);
678 }
679
680 this->ControlsHelpers[d][i]->SetEnabled(val);
681 }
682 }
683 }
684 }
685
686 //------------------------------------------------------------------------------
687 // Interaction methods
688 //------------------------------------------------------------------------------
ProbeData(vtkEventDataDevice controller)689 void vtkOpenVRInteractorStyle::ProbeData(vtkEventDataDevice controller)
690 {
691 // Invoke start pick method if defined
692 this->InvokeEvent(vtkCommand::StartPickEvent, nullptr);
693
694 if (!this->HardwareSelect(controller, false))
695 {
696 return;
697 }
698
699 // Invoke end pick method if defined
700 if (this->HandleObservers && this->HasObserver(vtkCommand::EndPickEvent))
701 {
702 this->InvokeEvent(vtkCommand::EndPickEvent, this->HardwarePicker->GetSelection());
703 }
704 else
705 {
706 this->EndPickCallback(this->HardwarePicker->GetSelection());
707 }
708 }
709
EndPickCallback(vtkSelection * sel)710 void vtkOpenVRInteractorStyle::EndPickCallback(vtkSelection* sel)
711 {
712 if (!sel)
713 {
714 return;
715 }
716
717 vtkSelectionNode* node = sel->GetNode(0);
718 if (!node || !node->GetProperties()->Has(vtkSelectionNode::PROP()))
719 {
720 return;
721 }
722
723 vtkProp3D* prop = vtkProp3D::SafeDownCast(node->GetProperties()->Get(vtkSelectionNode::PROP()));
724 if (!prop)
725 {
726 return;
727 }
728 this->ShowPickSphere(prop->GetCenter(), prop->GetLength() / 2.0, nullptr);
729 }
730
731 //------------------------------------------------------------------------------
LoadNextCameraPose()732 void vtkOpenVRInteractorStyle::LoadNextCameraPose()
733 {
734 vtkOpenVRRenderWindow* renWin =
735 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
736 if (!renWin)
737 {
738 return;
739 }
740 vtkOpenVROverlay* ovl = renWin->GetDashboardOverlay();
741 ovl->LoadNextCameraPose();
742 }
743
744 //------------------------------------------------------------------------------
PositionProp(vtkEventData * ed,double * lwpos,double * lwori)745 void vtkOpenVRInteractorStyle::PositionProp(vtkEventData* ed, double* lwpos, double* lwori)
746 {
747 if (this->InteractionProp == nullptr || !this->InteractionProp->GetDragable())
748 {
749 return;
750 }
751 this->Superclass::PositionProp(ed, lwpos, lwori);
752 }
753
754 //------------------------------------------------------------------------------
Clip(vtkEventDataDevice3D * ed)755 void vtkOpenVRInteractorStyle::Clip(vtkEventDataDevice3D* ed)
756 {
757 if (this->CurrentRenderer == nullptr)
758 {
759 return;
760 }
761
762 const double* wpos = ed->GetWorldPosition();
763 const double* wori = ed->GetWorldOrientation();
764
765 double ori[4];
766 ori[0] = vtkMath::RadiansFromDegrees(wori[0]);
767 ori[1] = wori[1];
768 ori[2] = wori[2];
769 ori[3] = wori[3];
770
771 // we have a position and a normal, that defines our plane
772 // plane->SetOrigin(wpos[0], wpos[1], wpos[2]);
773
774 double r[3];
775 double up[3];
776 up[0] = 0;
777 up[1] = -1;
778 up[2] = 0;
779 vtkMath::RotateVectorByWXYZ(up, ori, r);
780 // plane->SetNormal(r);
781
782 vtkEventDataDevice dev = ed->GetDevice();
783 int idev = static_cast<int>(dev);
784 this->ClippingPlanes[idev]->SetNormal(r);
785 this->ClippingPlanes[idev]->SetOrigin(wpos[0], wpos[1], wpos[2]);
786 }
787
788 //------------------------------------------------------------------------------
789
790 //------------------------------------------------------------------------------
791 // Multitouch interaction methods
792 //------------------------------------------------------------------------------
OnPan()793 void vtkOpenVRInteractorStyle::OnPan()
794 {
795 int rc = static_cast<int>(vtkEventDataDevice::RightController);
796 int lc = static_cast<int>(vtkEventDataDevice::LeftController);
797
798 if (!this->InteractionProps[rc] && !this->InteractionProps[lc])
799 {
800 this->InteractionState[rc] = VTKIS_PAN;
801 this->InteractionState[lc] = VTKIS_PAN;
802
803 int pointer = this->Interactor->GetPointerIndex();
804
805 this->FindPokedRenderer(this->Interactor->GetEventPositions(pointer)[0],
806 this->Interactor->GetEventPositions(pointer)[1]);
807
808 if (this->CurrentRenderer == nullptr)
809 {
810 return;
811 }
812
813 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
814 vtkRenderWindowInteractor3D* rwi = static_cast<vtkRenderWindowInteractor3D*>(this->Interactor);
815
816 double t[3] = { rwi->GetTranslation3D()[0] - rwi->GetLastTranslation3D()[0],
817 rwi->GetTranslation3D()[1] - rwi->GetLastTranslation3D()[1],
818 rwi->GetTranslation3D()[2] - rwi->GetLastTranslation3D()[2] };
819
820 double* ptrans = rwi->GetPhysicalTranslation(camera);
821
822 rwi->SetPhysicalTranslation(camera, ptrans[0] + t[0], ptrans[1] + t[1], ptrans[2] + t[2]);
823
824 // clean up
825 if (this->Interactor->GetLightFollowCamera())
826 {
827 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
828 }
829 }
830 }
831 //------------------------------------------------------------------------------
OnPinch()832 void vtkOpenVRInteractorStyle::OnPinch()
833 {
834 int rc = static_cast<int>(vtkEventDataDevice::RightController);
835 int lc = static_cast<int>(vtkEventDataDevice::LeftController);
836
837 if (!this->InteractionProps[rc] && !this->InteractionProps[lc])
838 {
839 this->InteractionState[rc] = VTKIS_ZOOM;
840 this->InteractionState[lc] = VTKIS_ZOOM;
841
842 int pointer = this->Interactor->GetPointerIndex();
843
844 this->FindPokedRenderer(this->Interactor->GetEventPositions(pointer)[0],
845 this->Interactor->GetEventPositions(pointer)[1]);
846
847 if (this->CurrentRenderer == nullptr)
848 {
849 return;
850 }
851
852 double dyf = this->Interactor->GetScale() / this->Interactor->GetLastScale();
853 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
854 vtkRenderWindowInteractor3D* rwi = static_cast<vtkRenderWindowInteractor3D*>(this->Interactor);
855 double physicalScale = rwi->GetPhysicalScale();
856
857 this->SetScale(camera, physicalScale / dyf);
858 }
859 }
860 //------------------------------------------------------------------------------
OnRotate()861 void vtkOpenVRInteractorStyle::OnRotate()
862 {
863 int rc = static_cast<int>(vtkEventDataDevice::RightController);
864 int lc = static_cast<int>(vtkEventDataDevice::LeftController);
865
866 // Rotate only when one controller is not interacting
867 if (!this->InteractionProps[rc] && !this->InteractionProps[lc])
868 {
869 this->InteractionState[rc] = VTKIS_ROTATE;
870 this->InteractionState[lc] = VTKIS_ROTATE;
871
872 double angle = this->Interactor->GetRotation() - this->Interactor->GetLastRotation();
873 if (fabs(angle) > 90)
874 {
875 // return;
876 }
877
878 // rotate the world, aka rotate the physicalViewDirection about the physicalViewUp
879 vtkOpenVRRenderWindow* renWin =
880 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
881 if (!renWin)
882 {
883 return;
884 }
885
886 double* vup = renWin->GetPhysicalViewUp();
887 double* dop = renWin->GetPhysicalViewDirection();
888 double newDOP[3];
889 double wxyz[4];
890 wxyz[0] = vtkMath::RadiansFromDegrees(angle);
891 wxyz[1] = vup[0];
892 wxyz[2] = vup[1];
893 wxyz[3] = vup[2];
894 vtkMath::RotateVectorByWXYZ(dop, wxyz, newDOP);
895 renWin->SetPhysicalViewDirection(newDOP);
896 }
897 }
898 //------------------------------------------------------------------------------
899
900 //------------------------------------------------------------------------------
901 // Utility routines
902 //------------------------------------------------------------------------------
MapInputToAction(vtkCommand::EventIds eid,vtkEventDataAction action,int state)903 void vtkOpenVRInteractorStyle::MapInputToAction(
904 vtkCommand::EventIds eid, vtkEventDataAction action, int state)
905 {
906 if (state < VTKIS_NONE)
907 {
908 return;
909 }
910
911 decltype(this->InputMap)::key_type key(eid, action);
912 auto it = this->InputMap.find(key);
913 if (it != this->InputMap.end())
914 {
915 if (it->second == state)
916 {
917 return;
918 }
919 }
920
921 this->InputMap[key] = state;
922
923 this->Modified();
924 }
925
MapInputToAction(vtkCommand::EventIds eid,int state)926 void vtkOpenVRInteractorStyle::MapInputToAction(vtkCommand::EventIds eid, int state)
927 {
928 this->MapInputToAction(eid, vtkEventDataAction::Press, state);
929 this->MapInputToAction(eid, vtkEventDataAction::Release, state);
930 }
931
932 //------------------------------------------------------------------------------
StartAction(int state,vtkEventDataDevice3D * edata)933 void vtkOpenVRInteractorStyle::StartAction(int state, vtkEventDataDevice3D* edata)
934 {
935 switch (state)
936 {
937 case VTKIS_POSITION_PROP:
938 this->StartPositionProp(edata);
939 break;
940 case VTKIS_DOLLY:
941 this->StartDolly3D(edata);
942 break;
943 case VTKIS_CLIP:
944 this->StartClip(edata);
945 break;
946 case VTKIS_PICK:
947 this->StartPick(edata);
948 break;
949 case VTKIS_LOAD_CAMERA_POSE:
950 this->StartLoadCamPose(edata);
951 break;
952 }
953 }
954 //------------------------------------------------------------------------------
EndAction(int state,vtkEventDataDevice3D * edata)955 void vtkOpenVRInteractorStyle::EndAction(int state, vtkEventDataDevice3D* edata)
956 {
957 switch (state)
958 {
959 case VTKIS_POSITION_PROP:
960 this->EndPositionProp(edata);
961 break;
962 case VTKIS_DOLLY:
963 this->EndDolly3D(edata);
964 break;
965 case VTKIS_CLIP:
966 this->EndClip(edata);
967 break;
968 case VTKIS_PICK:
969 this->EndPick(edata);
970 break;
971 case VTKIS_MENU:
972 this->Menu->SetInteractor(this->Interactor);
973 this->Menu->Show(edata);
974 break;
975 case VTKIS_LOAD_CAMERA_POSE:
976 this->EndLoadCamPose(edata);
977 break;
978 case VTKIS_TOGGLE_DRAW_CONTROLS:
979 this->ToggleDrawControls();
980 break;
981 case VTKIS_EXIT:
982 if (this->Interactor)
983 {
984 this->Interactor->ExitCallback();
985 }
986 break;
987 }
988
989 // Reset multitouch state because a button has been released
990 for (int d = 0; d < vtkEventDataNumberOfDevices; ++d)
991 {
992 switch (this->InteractionState[d])
993 {
994 case VTKIS_PAN:
995 case VTKIS_ZOOM:
996 case VTKIS_ROTATE:
997 this->InteractionState[d] = VTKIS_NONE;
998 break;
999 }
1000 }
1001 }
1002 //------------------------------------------------------------------------------
1003
1004 //------------------------------------------------------------------------------
1005 // Handle Ray drawing and update
1006 //------------------------------------------------------------------------------
ShowRay(vtkEventDataDevice controller)1007 void vtkOpenVRInteractorStyle::ShowRay(vtkEventDataDevice controller)
1008 {
1009 vtkOpenVRRenderWindow* renWin =
1010 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
1011 if (!renWin ||
1012 (controller != vtkEventDataDevice::LeftController &&
1013 controller != vtkEventDataDevice::RightController))
1014 {
1015 return;
1016 }
1017 vtkVRModel* cmodel = renWin->GetTrackedDeviceModel(controller);
1018 if (cmodel)
1019 {
1020 cmodel->SetShowRay(true);
1021 }
1022 }
1023 //------------------------------------------------------------------------------
HideRay(vtkEventDataDevice controller)1024 void vtkOpenVRInteractorStyle::HideRay(vtkEventDataDevice controller)
1025 {
1026 vtkOpenVRRenderWindow* renWin =
1027 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
1028 if (!renWin ||
1029 (controller != vtkEventDataDevice::LeftController &&
1030 controller != vtkEventDataDevice::RightController))
1031 {
1032 return;
1033 }
1034 vtkVRModel* cmodel = renWin->GetTrackedDeviceModel(controller);
1035 if (cmodel)
1036 {
1037 cmodel->SetShowRay(false);
1038 }
1039 }
1040 //------------------------------------------------------------------------------
UpdateRay(vtkEventDataDevice controller)1041 void vtkOpenVRInteractorStyle::UpdateRay(vtkEventDataDevice controller)
1042 {
1043 if (!this->Interactor)
1044 {
1045 return;
1046 }
1047
1048 vtkRenderer* ren = this->CurrentRenderer;
1049 vtkOpenVRRenderWindow* renWin =
1050 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
1051 vtkOpenVRRenderWindowInteractor* iren =
1052 static_cast<vtkOpenVRRenderWindowInteractor*>(this->Interactor);
1053
1054 if (!ren || !renWin || !iren)
1055 {
1056 return;
1057 }
1058
1059 vr::TrackedDeviceIndex_t idx = renWin->GetTrackedDeviceIndexForDevice(controller);
1060 if (idx == vr::k_unTrackedDeviceIndexInvalid)
1061 {
1062 return;
1063 }
1064 vtkOpenVRModel* mod = vtkOpenVRModel::SafeDownCast(renWin->GetTrackedDeviceModel(idx));
1065 if (!mod)
1066 {
1067 return;
1068 }
1069
1070 int idev = static_cast<int>(controller);
1071
1072 // Keep the same ray if a controller is interacting with a prop
1073 if (this->InteractionProps[idev] != nullptr)
1074 {
1075 return;
1076 }
1077
1078 // Check if interacting with a widget
1079 vtkPropCollection* props = ren->GetViewProps();
1080
1081 vtkIdType nbProps = props->GetNumberOfItems();
1082 for (vtkIdType i = 0; i < nbProps; i++)
1083 {
1084 vtkWidgetRepresentation* rep = vtkWidgetRepresentation::SafeDownCast(props->GetItemAsObject(i));
1085
1086 if (rep && rep->IsA("vtkQWidgetRepresentation") && rep->GetInteractionState() != 0)
1087 {
1088 mod->SetShowRay(true);
1089 mod->SetRayLength(ren->GetActiveCamera()->GetClippingRange()[1]);
1090 mod->SetRayColor(0.0, 0.0, 1.0);
1091 return;
1092 }
1093 }
1094
1095 if (this->GetGrabWithRay() || this->InteractionState[idev] == VTKIS_PICK)
1096 {
1097 mod->SetShowRay(true);
1098 }
1099 else
1100 {
1101 mod->SetShowRay(false);
1102 return;
1103 }
1104
1105 // Set length to its max if interactive picking is off
1106 if (!this->HoverPick)
1107 {
1108 mod->SetRayColor(1.0, 0.0, 0.0);
1109 mod->SetRayLength(ren->GetActiveCamera()->GetClippingRange()[1]);
1110 return;
1111 }
1112
1113 // Compute controller position and world orientation
1114 double p0[3]; // Ray start point
1115 double wxyz[4]; // Controller orientation
1116 double dummy_ppos[3];
1117 double wdir[3];
1118 vr::TrackedDevicePose_t* tdPose = renWin->GetTrackedDevicePose(mod->TrackedDevice);
1119 iren->ConvertPoseToWorldCoordinates(*tdPose, p0, wxyz, dummy_ppos, wdir);
1120
1121 // Compute ray length.
1122 this->InteractionPicker->Pick3DRay(p0, wxyz, ren);
1123
1124 // If something is picked, set the length accordingly
1125 vtkProp3D* prop = this->InteractionPicker->GetProp3D();
1126 if (prop)
1127 {
1128 double p1[3];
1129 this->InteractionPicker->GetPickPosition(p1);
1130 mod->SetRayLength(sqrt(vtkMath::Distance2BetweenPoints(p0, p1)));
1131 mod->SetRayColor(0.0, 1.0, 0.0);
1132 }
1133 // Otherwise set the length to its max
1134 else
1135 {
1136 mod->SetRayLength(ren->GetActiveCamera()->GetClippingRange()[1]);
1137 mod->SetRayColor(1.0, 0.0, 0.0);
1138 }
1139 }
1140 //------------------------------------------------------------------------------
1141
ShowBillboard(const std::string & text)1142 void vtkOpenVRInteractorStyle::ShowBillboard(const std::string& text)
1143 {
1144 vtkOpenVRRenderWindow* renWin =
1145 vtkOpenVRRenderWindow::SafeDownCast(this->Interactor->GetRenderWindow());
1146 vtkRenderer* ren = this->CurrentRenderer;
1147 if (!renWin || !ren)
1148 {
1149 return;
1150 }
1151
1152 renWin->UpdateHMDMatrixPose();
1153 double dop[3];
1154 ren->GetActiveCamera()->GetDirectionOfProjection(dop);
1155 double vr[3];
1156 double* vup = renWin->GetPhysicalViewUp();
1157 double dtmp[3];
1158 double vupdot = vtkMath::Dot(dop, vup);
1159 if (fabs(vupdot) < 0.999)
1160 {
1161 dtmp[0] = dop[0] - vup[0] * vupdot;
1162 dtmp[1] = dop[1] - vup[1] * vupdot;
1163 dtmp[2] = dop[2] - vup[2] * vupdot;
1164 vtkMath::Normalize(dtmp);
1165 }
1166 else
1167 {
1168 renWin->GetPhysicalViewDirection(dtmp);
1169 }
1170 vtkMath::Cross(dtmp, vup, vr);
1171 vtkNew<vtkMatrix4x4> rot;
1172 for (int i = 0; i < 3; ++i)
1173 {
1174 rot->SetElement(0, i, vr[i]);
1175 rot->SetElement(1, i, vup[i]);
1176 rot->SetElement(2, i, -dtmp[i]);
1177 }
1178 rot->Transpose();
1179 double orient[3];
1180 vtkTransform::GetOrientation(orient, rot);
1181 vtkTextProperty* prop = this->TextActor3D->GetTextProperty();
1182 this->TextActor3D->SetOrientation(orient);
1183 this->TextActor3D->RotateX(-30.0);
1184
1185 double tpos[3];
1186 double scale = renWin->GetPhysicalScale();
1187 ren->GetActiveCamera()->GetPosition(tpos);
1188 tpos[0] += (0.7 * scale * dop[0] - 0.1 * scale * vr[0] - 0.4 * scale * vup[0]);
1189 tpos[1] += (0.7 * scale * dop[1] - 0.1 * scale * vr[1] - 0.4 * scale * vup[1]);
1190 tpos[2] += (0.7 * scale * dop[2] - 0.1 * scale * vr[2] - 0.4 * scale * vup[2]);
1191 this->TextActor3D->SetPosition(tpos);
1192 // scale should cover 10% of FOV
1193 double fov = ren->GetActiveCamera()->GetViewAngle();
1194 double tsize = 0.1 * 2.0 * atan(fov * 0.5); // 10% of fov
1195 tsize /= 200.0; // about 200 pixel texture map
1196 scale *= tsize;
1197 this->TextActor3D->SetScale(scale, scale, scale);
1198 this->TextActor3D->SetInput(text.c_str());
1199 this->CurrentRenderer->AddActor(this->TextActor3D);
1200
1201 prop->SetFrame(1);
1202 prop->SetFrameColor(1.0, 1.0, 1.0);
1203 prop->SetBackgroundOpacity(1.0);
1204 prop->SetBackgroundColor(0.0, 0.0, 0.0);
1205 prop->SetFontSize(14);
1206 }
1207
HideBillboard()1208 void vtkOpenVRInteractorStyle::HideBillboard()
1209 {
1210 this->CurrentRenderer->RemoveActor(this->TextActor3D);
1211 }
1212
ShowPickSphere(double * pos,double radius,vtkProp3D * prop)1213 void vtkOpenVRInteractorStyle::ShowPickSphere(double* pos, double radius, vtkProp3D* prop)
1214 {
1215 this->PickActor->GetProperty()->SetColor(this->PickColor);
1216
1217 this->Sphere->SetCenter(pos);
1218 this->Sphere->SetRadius(radius);
1219 this->PickActor->GetMapper()->SetInputConnection(this->Sphere->GetOutputPort());
1220 if (prop)
1221 {
1222 this->PickActor->SetPosition(prop->GetPosition());
1223 this->PickActor->SetScale(prop->GetScale());
1224 }
1225 else
1226 {
1227 this->PickActor->SetPosition(0.0, 0.0, 0.0);
1228 this->PickActor->SetScale(1.0, 1.0, 1.0);
1229 }
1230 this->CurrentRenderer->AddActor(this->PickActor);
1231 }
1232
ShowPickCell(vtkCell * cell,vtkProp3D * prop)1233 void vtkOpenVRInteractorStyle::ShowPickCell(vtkCell* cell, vtkProp3D* prop)
1234 {
1235 vtkNew<vtkPolyData> pd;
1236 vtkNew<vtkPoints> pdpts;
1237 pdpts->SetDataTypeToDouble();
1238 vtkNew<vtkCellArray> lines;
1239
1240 this->PickActor->GetProperty()->SetColor(this->PickColor);
1241
1242 int nedges = cell->GetNumberOfEdges();
1243
1244 if (nedges)
1245 {
1246 for (int edgenum = 0; edgenum < nedges; ++edgenum)
1247 {
1248 vtkCell* edge = cell->GetEdge(edgenum);
1249 vtkPoints* pts = edge->GetPoints();
1250 int npts = edge->GetNumberOfPoints();
1251 lines->InsertNextCell(npts);
1252 for (int ep = 0; ep < npts; ++ep)
1253 {
1254 vtkIdType newpt = pdpts->InsertNextPoint(pts->GetPoint(ep));
1255 lines->InsertCellPoint(newpt);
1256 }
1257 }
1258 }
1259 else if (cell->GetCellType() == VTK_LINE || cell->GetCellType() == VTK_POLY_LINE)
1260 {
1261 vtkPoints* pts = cell->GetPoints();
1262 int npts = cell->GetNumberOfPoints();
1263 lines->InsertNextCell(npts);
1264 for (int ep = 0; ep < npts; ++ep)
1265 {
1266 vtkIdType newpt = pdpts->InsertNextPoint(pts->GetPoint(ep));
1267 lines->InsertCellPoint(newpt);
1268 }
1269 }
1270 else
1271 {
1272 return;
1273 }
1274
1275 pd->SetPoints(pdpts.Get());
1276 pd->SetLines(lines.Get());
1277
1278 if (prop)
1279 {
1280 this->PickActor->SetPosition(prop->GetPosition());
1281 this->PickActor->SetScale(prop->GetScale());
1282 this->PickActor->SetUserMatrix(prop->GetUserMatrix());
1283 }
1284 else
1285 {
1286 this->PickActor->SetPosition(0.0, 0.0, 0.0);
1287 this->PickActor->SetScale(1.0, 1.0, 1.0);
1288 }
1289 this->PickActor->SetOrientation(prop->GetOrientation());
1290 static_cast<vtkPolyDataMapper*>(this->PickActor->GetMapper())->SetInputData(pd);
1291 this->CurrentRenderer->AddActor(this->PickActor);
1292 }
1293
HidePickActor()1294 void vtkOpenVRInteractorStyle::HidePickActor()
1295 {
1296 if (this->CurrentRenderer)
1297 {
1298 this->CurrentRenderer->RemoveActor(this->PickActor);
1299 }
1300 }
1301
1302 //------------------------------------------------------------------------------
AddTooltipForInput(vtkEventDataDevice device,vtkEventDataDeviceInput input)1303 void vtkOpenVRInteractorStyle::AddTooltipForInput(
1304 vtkEventDataDevice device, vtkEventDataDeviceInput input)
1305 {
1306 this->AddTooltipForInput(device, input, "");
1307 }
1308
1309 //------------------------------------------------------------------------------
AddTooltipForInput(vtkEventDataDevice device,vtkEventDataDeviceInput input,const std::string & text)1310 void vtkOpenVRInteractorStyle::AddTooltipForInput(
1311 vtkEventDataDevice device, vtkEventDataDeviceInput input, const std::string& text)
1312 {
1313 int iInput = static_cast<int>(input);
1314 int iDevice = static_cast<int>(device);
1315
1316 vtkStdString controlName = vtkStdString();
1317 vtkStdString controlText = vtkStdString();
1318 int drawSide = -1;
1319 int buttonSide = -1;
1320
1321 // Setup default text and layout
1322 switch (input)
1323 {
1324 case vtkEventDataDeviceInput::Trigger:
1325 controlName = "trigger";
1326 drawSide = vtkOpenVRControlsHelper::Left;
1327 buttonSide = vtkOpenVRControlsHelper::Back;
1328 controlText = "Trigger :\n";
1329 break;
1330 case vtkEventDataDeviceInput::TrackPad:
1331 controlName = "trackpad";
1332 drawSide = vtkOpenVRControlsHelper::Right;
1333 buttonSide = vtkOpenVRControlsHelper::Front;
1334 controlText = "Trackpad :\n";
1335 break;
1336 case vtkEventDataDeviceInput::Grip:
1337 controlName = "lgrip";
1338 drawSide = vtkOpenVRControlsHelper::Right;
1339 buttonSide = vtkOpenVRControlsHelper::Back;
1340 controlText = "Grip :\n";
1341 break;
1342 case vtkEventDataDeviceInput::ApplicationMenu:
1343 controlName = "button";
1344 drawSide = vtkOpenVRControlsHelper::Left;
1345 buttonSide = vtkOpenVRControlsHelper::Front;
1346 controlText = "Application Menu :\n";
1347 break;
1348 }
1349
1350 controlText += text;
1351
1352 // Clean already existing helpers
1353 if (this->ControlsHelpers[iDevice][iInput] != nullptr)
1354 {
1355 if (this->CurrentRenderer)
1356 {
1357 this->CurrentRenderer->RemoveViewProp(this->ControlsHelpers[iDevice][iInput]);
1358 }
1359 this->ControlsHelpers[iDevice][iInput]->Delete();
1360 this->ControlsHelpers[iDevice][iInput] = nullptr;
1361 }
1362
1363 // Create an input helper and add it to the renderer
1364 vtkOpenVRControlsHelper* inputHelper = vtkOpenVRControlsHelper::New();
1365 inputHelper->SetTooltipInfo(controlName.c_str(), buttonSide, drawSide, controlText.c_str());
1366
1367 this->ControlsHelpers[iDevice][iInput] = inputHelper;
1368 this->ControlsHelpers[iDevice][iInput]->SetDevice(device);
1369
1370 if (this->CurrentRenderer)
1371 {
1372 this->ControlsHelpers[iDevice][iInput]->SetRenderer(this->CurrentRenderer);
1373 this->ControlsHelpers[iDevice][iInput]->BuildRepresentation();
1374 // this->ControlsHelpers[iDevice][iInput]->SetEnabled(false);
1375 this->CurrentRenderer->AddViewProp(this->ControlsHelpers[iDevice][iInput]);
1376 }
1377 }
1378