Skip to content
/ VTK Public

Commit b7f02e6

Browse files
committed
update openvr to action based input model
OpenVR has updated its input model to be action based and now supports action binding and customization within the OpenVR user interface. As such, rework the device based event model to also support actions. Have event creators set the event type on event data instead of having subclasses for each event data event type. Fix world rotation code for multitouch. Update widget event code to be based off a trigger event as opposed to a specific hardware device such as right trigger. Update event dispatch code to better handle event id. Update widget event processing as needed to track move events based on the original device that initiated to action.
1 parent 465e640 commit b7f02e6

27 files changed

+1218
-562
lines changed

Common/Core/vtkCommand.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ bool vtkCommand::EventHasData(unsigned long event)
103103
{
104104
case vtkCommand::Button3DEvent:
105105
case vtkCommand::Move3DEvent:
106+
case vtkCommand::ViewerMovement3DEvent:
107+
case vtkCommand::Menu3DEvent:
108+
case vtkCommand::NextPose3DEvent:
109+
case vtkCommand::Clip3DEvent:
110+
case vtkCommand::PositionProp3DEvent:
111+
case vtkCommand::Pick3DEvent:
112+
case vtkCommand::Select3DEvent:
106113
return true;
107114
default:
108115
return false;

Common/Core/vtkCommand.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,14 @@
372372
_vtk_add_event(MiddleButtonDoubleClickEvent) \
373373
_vtk_add_event(RightButtonDoubleClickEvent) \
374374
_vtk_add_event(MouseWheelLeftEvent) \
375-
_vtk_add_event(MouseWheelRightEvent)
375+
_vtk_add_event(MouseWheelRightEvent) \
376+
_vtk_add_event(ViewerMovement3DEvent) \
377+
_vtk_add_event(Menu3DEvent) \
378+
_vtk_add_event(NextPose3DEvent) \
379+
_vtk_add_event(Clip3DEvent) \
380+
_vtk_add_event(PositionProp3DEvent) \
381+
_vtk_add_event(Pick3DEvent) \
382+
_vtk_add_event(Select3DEvent)
376383
// clang-format on
377384

378385
#define vtkEventDeclarationMacro(_enum_name) \

Common/Core/vtkEventData.h

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum class vtkEventDataDevice
2929
RightController,
3030
LeftController,
3131
GenericTracker,
32+
Any,
3233
NumberOfDevices
3334
};
3435

@@ -38,6 +39,7 @@ const int vtkEventDataNumberOfDevices = (static_cast<int>(vtkEventDataDevice::Nu
3839
enum class vtkEventDataDeviceInput
3940
{
4041
Unknown = -1,
42+
Any,
4143
Trigger,
4244
TrackPad,
4345
Joystick,
@@ -52,6 +54,7 @@ const int vtkEventDataNumberOfInputs = (static_cast<int>(vtkEventDataDeviceInput
5254
enum class vtkEventDataAction
5355
{
5456
Unknown = -1,
57+
Any,
5558
Press,
5659
Release,
5760
Touch,
@@ -68,6 +71,7 @@ class vtkEventData : public vtkObjectBase
6871
vtkBaseTypeMacro(vtkEventData, vtkObjectBase);
6972

7073
int GetType() const { return this->Type; }
74+
void SetType(int val) { this->Type = val; }
7175

7276
// are two events equivalent
7377
bool operator==(const vtkEventData& a) const
@@ -114,6 +118,12 @@ class vtkEventDataForDevice : public vtkEventData
114118
void SetInput(vtkEventDataDeviceInput v) { this->Input = v; }
115119
void SetAction(vtkEventDataAction v) { this->Action = v; }
116120

121+
bool DeviceMatches(vtkEventDataDevice val)
122+
{
123+
return val == this->Device || val == vtkEventDataDevice::Any ||
124+
this->Device == vtkEventDataDevice::Any;
125+
}
126+
117127
vtkEventDataForDevice* GetAsEventDataForDevice() override { return this; }
118128

119129
protected:
@@ -124,7 +134,12 @@ class vtkEventDataForDevice : public vtkEventData
124134
bool Equivalent(const vtkEventData* e) const override
125135
{
126136
const vtkEventDataForDevice* edd = static_cast<const vtkEventDataForDevice*>(e);
127-
return this->Device == edd->Device && this->Input == edd->Input && this->Action == edd->Action;
137+
return (this->Device == vtkEventDataDevice::Any || edd->Device == vtkEventDataDevice::Any ||
138+
this->Device == edd->Device) &&
139+
(this->Input == vtkEventDataDeviceInput::Any || edd->Input == vtkEventDataDeviceInput::Any ||
140+
this->Input == edd->Input) &&
141+
(this->Action == vtkEventDataAction::Any || edd->Action == vtkEventDataAction::Any ||
142+
this->Action == edd->Action);
128143
}
129144

130145
vtkEventDataForDevice()
@@ -146,6 +161,12 @@ class vtkEventDataDevice3D : public vtkEventDataForDevice
146161
{
147162
public:
148163
vtkTypeMacro(vtkEventDataDevice3D, vtkEventDataForDevice);
164+
static vtkEventDataDevice3D* New()
165+
{
166+
vtkEventDataDevice3D* ret = new vtkEventDataDevice3D;
167+
ret->InitializeObjectBase();
168+
return ret;
169+
}
149170

150171
vtkEventDataDevice3D* GetAsEventDataDevice3D() override { return this; }
151172

@@ -224,48 +245,6 @@ class vtkEventDataDevice3D : public vtkEventDataForDevice
224245
void operator=(const vtkEventDataDevice3D&) = delete;
225246
};
226247

227-
// subclass for button event 3d
228-
class vtkEventDataButton3D : public vtkEventDataDevice3D
229-
{
230-
public:
231-
vtkTypeMacro(vtkEventDataButton3D, vtkEventDataDevice3D);
232-
static vtkEventDataButton3D* New()
233-
{
234-
vtkEventDataButton3D* ret = new vtkEventDataButton3D;
235-
ret->InitializeObjectBase();
236-
return ret;
237-
}
238-
239-
protected:
240-
vtkEventDataButton3D() { this->Type = vtkCommand::Button3DEvent; }
241-
~vtkEventDataButton3D() override = default;
242-
243-
private:
244-
vtkEventDataButton3D(const vtkEventDataButton3D& c) = delete;
245-
void operator=(const vtkEventDataButton3D&) = delete;
246-
};
247-
248-
// subclass for move event 3d
249-
class vtkEventDataMove3D : public vtkEventDataDevice3D
250-
{
251-
public:
252-
vtkTypeMacro(vtkEventDataMove3D, vtkEventDataDevice3D);
253-
static vtkEventDataMove3D* New()
254-
{
255-
vtkEventDataMove3D* ret = new vtkEventDataMove3D;
256-
ret->InitializeObjectBase();
257-
return ret;
258-
}
259-
260-
protected:
261-
vtkEventDataMove3D() { this->Type = vtkCommand::Move3DEvent; }
262-
~vtkEventDataMove3D() override = default;
263-
264-
private:
265-
vtkEventDataMove3D(const vtkEventDataMove3D& c) = delete;
266-
void operator=(const vtkEventDataMove3D&) = delete;
267-
};
268-
269248
#endif
270249

271250
// VTK-HeaderTest-Exclude: vtkEventData.h
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Update the OpenVR input model to support actions
2+
3+
OpenVR has updated its input model to be action based and now supports
4+
action binding and customization within the OpenVR user interface. This
5+
includes controller labeling and user configuration. As such, we reworked
6+
the device based event model to also support actions.
7+
8+
Part of this change involved updates to vtkEventData.h to add the notion of
9+
"Any" as a device or input so that event handlers could look for a select
10+
event from any input or any device for example. This also resulted in a
11+
number of new event ids such as menu3d, clip3d, etc and the old event data
12+
model used a new subclass for each id. We changed this to instead use a
13+
method to set the event id type.
14+
15+
Once these changes were done we updated widget event code to be based off a
16+
select3d event as opposed to a specific hardware device such as right
17+
trigger. We updated event dispatch code to better handle event id. And
18+
update widget event processing as needed to track move events based on the
19+
original device that initiated to action.
20+
21+
If you have your own custom 3D event handling code or widgets, then you can
22+
look at the changes made in this MR
23+
https://gitlab.kitware.com/vtk/vtk/-/merge_requests/7557#e8d22b8c27ce72ddec1110556087c6bd8d15fbec
24+
to see how to update your code. The distance widget is a good example to
25+
work from.

GUISupport/Qt/vtkQWidgetWidget.cxx

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,33 @@ vtkQWidgetWidget::vtkQWidgetWidget()
4444
this->WidgetState = vtkQWidgetWidget::Start;
4545

4646
{
47-
vtkNew<vtkEventDataButton3D> ed;
48-
ed->SetDevice(vtkEventDataDevice::RightController);
49-
ed->SetInput(vtkEventDataDeviceInput::Trigger);
47+
vtkNew<vtkEventDataDevice3D> ed;
48+
ed->SetDevice(vtkEventDataDevice::Any);
49+
ed->SetInput(vtkEventDataDeviceInput::Any);
5050
ed->SetAction(vtkEventDataAction::Press);
51-
this->CallbackMapper->SetCallbackMethod(vtkCommand::Button3DEvent, ed, vtkWidgetEvent::Select3D,
51+
this->CallbackMapper->SetCallbackMethod(vtkCommand::Select3DEvent, ed, vtkWidgetEvent::Select3D,
5252
this, vtkQWidgetWidget::SelectAction3D);
5353
}
5454

5555
{
56-
vtkNew<vtkEventDataButton3D> ed;
57-
ed->SetDevice(vtkEventDataDevice::RightController);
58-
ed->SetInput(vtkEventDataDeviceInput::Trigger);
56+
vtkNew<vtkEventDataDevice3D> ed;
57+
ed->SetDevice(vtkEventDataDevice::Any);
58+
ed->SetInput(vtkEventDataDeviceInput::Any);
5959
ed->SetAction(vtkEventDataAction::Release);
60-
this->CallbackMapper->SetCallbackMethod(vtkCommand::Button3DEvent, ed,
60+
this->CallbackMapper->SetCallbackMethod(vtkCommand::Select3DEvent, ed,
6161
vtkWidgetEvent::EndSelect3D, this, vtkQWidgetWidget::EndSelectAction3D);
6262
}
6363

6464
{
65-
vtkNew<vtkEventDataMove3D> ed;
66-
ed->SetDevice(vtkEventDataDevice::RightController);
65+
vtkNew<vtkEventDataDevice3D> ed;
66+
ed->SetDevice(vtkEventDataDevice::Any);
67+
ed->SetInput(vtkEventDataDeviceInput::Any);
6768
this->CallbackMapper->SetCallbackMethod(
6869
vtkCommand::Move3DEvent, ed, vtkWidgetEvent::Move3D, this, vtkQWidgetWidget::MoveAction3D);
6970
}
71+
72+
// start off responding to all move events
73+
this->LastDevice = static_cast<int>(vtkEventDataDevice::Any);
7074
}
7175

7276
//------------------------------------------------------------------------------
@@ -118,6 +122,15 @@ void vtkQWidgetWidget::SelectAction3D(vtkAbstractWidget* w)
118122
return;
119123
}
120124

125+
vtkEventData* edata = static_cast<vtkEventData*>(self->CallData);
126+
vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
127+
if (!edd)
128+
{
129+
return;
130+
}
131+
132+
self->LastDevice = static_cast<int>(edd->GetDevice());
133+
121134
QPointF mousePos(widgetCoords[0], widgetCoords[1]);
122135
Qt::MouseButton button = Qt::LeftButton;
123136
QPoint ptGlobal = mousePos.toPoint();
@@ -153,6 +166,19 @@ void vtkQWidgetWidget::MoveAction3D(vtkAbstractWidget* w)
153166
{
154167
vtkQWidgetWidget* self = reinterpret_cast<vtkQWidgetWidget*>(w);
155168

169+
vtkEventData* edata = static_cast<vtkEventData*>(self->CallData);
170+
vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
171+
if (!edd)
172+
{
173+
return;
174+
}
175+
176+
if (self->LastDevice != static_cast<int>(edd->GetDevice()) &&
177+
self->LastDevice != static_cast<int>(vtkEventDataDevice::Any))
178+
{
179+
return;
180+
}
181+
156182
int interactionState = self->WidgetRep->ComputeComplexInteractionState(
157183
self->Interactor, self, vtkWidgetEvent::Select3D, self->CallData);
158184

@@ -207,6 +233,9 @@ void vtkQWidgetWidget::EndSelectAction3D(vtkAbstractWidget* w)
207233
return;
208234
}
209235

236+
// reset back to responding to all move events
237+
self->LastDevice = static_cast<int>(vtkEventDataDevice::Any);
238+
210239
self->WidgetRep->ComputeComplexInteractionState(
211240
self->Interactor, self, vtkWidgetEvent::Select3D, self->CallData);
212241

Interaction/Widgets/vtkAbstractWidget.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ class VTKINTERACTIONWIDGETS_EXPORT vtkAbstractWidget : public vtkInteractorObser
191191
// On by default.
192192
vtkTypeBool ProcessEvents;
193193

194+
// Used by subclasses to ensure different events comes from the same
195+
// hardware device. Such as starting a move with the right controller
196+
// should then only respond to move events from the right controller.
197+
int LastDevice;
198+
194199
private:
195200
vtkAbstractWidget(const vtkAbstractWidget&) = delete;
196201
void operator=(const vtkAbstractWidget&) = delete;

Interaction/Widgets/vtkBoxWidget2.cxx

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,27 @@ vtkBoxWidget2::vtkBoxWidget2()
6767
vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this, vtkBoxWidget2::MoveAction);
6868

6969
{
70-
vtkNew<vtkEventDataButton3D> ed;
71-
ed->SetDevice(vtkEventDataDevice::RightController);
72-
ed->SetInput(vtkEventDataDeviceInput::Trigger);
70+
vtkNew<vtkEventDataDevice3D> ed;
71+
ed->SetDevice(vtkEventDataDevice::Any);
72+
ed->SetInput(vtkEventDataDeviceInput::Any);
7373
ed->SetAction(vtkEventDataAction::Press);
74-
this->CallbackMapper->SetCallbackMethod(vtkCommand::Button3DEvent, ed.Get(),
74+
this->CallbackMapper->SetCallbackMethod(vtkCommand::Select3DEvent, ed.Get(),
7575
vtkWidgetEvent::Select3D, this, vtkBoxWidget2::SelectAction3D);
7676
}
7777

7878
{
79-
vtkNew<vtkEventDataButton3D> ed;
80-
ed->SetDevice(vtkEventDataDevice::RightController);
81-
ed->SetInput(vtkEventDataDeviceInput::Trigger);
79+
vtkNew<vtkEventDataDevice3D> ed;
80+
ed->SetDevice(vtkEventDataDevice::Any);
81+
ed->SetInput(vtkEventDataDeviceInput::Any);
8282
ed->SetAction(vtkEventDataAction::Release);
83-
this->CallbackMapper->SetCallbackMethod(vtkCommand::Button3DEvent, ed.Get(),
83+
this->CallbackMapper->SetCallbackMethod(vtkCommand::Select3DEvent, ed.Get(),
8484
vtkWidgetEvent::EndSelect3D, this, vtkBoxWidget2::EndSelectAction3D);
8585
}
8686

8787
{
88-
vtkNew<vtkEventDataMove3D> ed;
89-
ed->SetDevice(vtkEventDataDevice::RightController);
88+
vtkNew<vtkEventDataDevice3D> ed;
89+
ed->SetDevice(vtkEventDataDevice::Any);
90+
ed->SetInput(vtkEventDataDeviceInput::Any);
9091
this->CallbackMapper->SetCallbackMethod(
9192
vtkCommand::Move3DEvent, ed.Get(), vtkWidgetEvent::Move3D, this, vtkBoxWidget2::MoveAction3D);
9293
}
@@ -250,6 +251,15 @@ void vtkBoxWidget2::SelectAction3D(vtkAbstractWidget* w)
250251
return;
251252
}
252253

254+
// watch for motion events from this device
255+
vtkEventData* edata = static_cast<vtkEventData*>(self->CallData);
256+
vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
257+
if (!edd)
258+
{
259+
return;
260+
}
261+
self->LastDevice = static_cast<int>(edd->GetDevice());
262+
253263
// We are definitely selected
254264
if (!self->Parent)
255265
{
@@ -397,6 +407,19 @@ void vtkBoxWidget2::MoveAction3D(vtkAbstractWidget* w)
397407
return;
398408
}
399409

410+
// watch for motion events from this device
411+
vtkEventData* edata = static_cast<vtkEventData*>(self->CallData);
412+
vtkEventDataDevice3D* edd = edata->GetAsEventDataDevice3D();
413+
if (!edd)
414+
{
415+
return;
416+
}
417+
418+
if (!edd->DeviceMatches(static_cast<vtkEventDataDevice>(self->LastDevice)))
419+
{
420+
return;
421+
}
422+
400423
// Okay, adjust the representation
401424
self->WidgetRep->ComplexInteraction(
402425
self->Interactor, self, vtkWidgetEvent::Move3D, self->CallData);

0 commit comments

Comments
 (0)