[vtk-developers] Some Event handling ideas
David Gobbi
david.gobbi at gmail.com
Mon Jul 10 14:59:07 EDT 2017
Hi Ken,
Why not use polymorphism here? I use an event hierarchy like so:
Event <- InputEvent <- PointEvent, KeyEvent
I've never used a union; the code that generates the event knows what type
of event object to instantiate, and the observer methods just get a pointer
to the event object. Qt does things similarly.
- David
On Mon, Jul 10, 2017 at 9:15 AM, Ken Martin <ken.martin at kitware.com> wrote:
>
> Lucas and I have been working on VTK's VR support and one issue we bumped
> into was event handing. VTK's event handling tends to be data light where
> most events follow this approach
>
> 1) event happens
>
> 2) we set properties on the interactor such as alt/shift/control key
> state, mouse position, etc
>
> 3) fire the event (with little or no calldata)
>
> 4) event handlers query needed properties from the interactor
>
> The challenge here is that as more event types are supported, the
> interactor's state and structure is required to grow to match them. For
> example with multitouch events, the interactor now has to support multiple
> mouse positions and pointer indexes. Now add in multi controller VR and we
> have to also store arrays of world coordinate positions and orientations
> and what controller the current event corresponds to.
>
> Many systems use a different approach where they define an event data
> structure or class that get passed with the event (or associated with the
> event). Then whatever is handling the event receives that data structure
> which contains most of the key properties of the event. Such an event
> structure can also be used for filtering. For example currently in VTK you
> can map keyboard events on a widget using the vtkWidgetCallbackMapper method
>
> void SetCallbackMethod(unsigned long VTKEvent, int modifiers, char keyCode,
> int repeatCount, const char* keySym,
> unsigned long widgetEvent,
> vtkAbstractWidget *w, CallbackType f);
>
> Note that this signature is designed for keyboard events as it contains
> keyboard event specific parameters. To add a mapping for multitouch, or VR
> controller events would require more event specific signatures. In contrast
> if we had a formal vtkEventData structure then the method could use a
> vtkEventData as a filter and handle many different event types as long as
> the EventData has an equality operator on it (or maybe a filtering specific
> equality).
>
> Lucas and I have tried this out for VR and it has made event handling
> reasonable and fairly clean and I would like to get some feedback on the
> idea/approach/etc. Right now our vtkEventData is included below. It uses
> the approach of a union of event type structs and what has been fleshed out
> is targeted at VR but it should be easy to see how keyboard or mouse
> devices/events could get added as well.
>
> Thanks!
> Ken
>
>
>
> enum class vtkEventDataDevice {
> Unknown = -1,
> HeadMountedDisplay,
> RightController,
> LeftController,
> NumberOfDevices
> };
>
> const int vtkEventDataNumberOfDevices =
> static_cast<int>(vtkEventDataDevice::NumberOfDevices);
>
> enum class vtkEventDataDeviceInput {
> Unknown = -1,
> Trigger,
> TrackPad,
> Grip,
> ApplicationMenu,
> NumberOfInputs
> };
>
> const int vtkEventDataNumberOfInputs =
> static_cast<int>(vtkEventDataDeviceInput::NumberOfInputs);
>
> enum class vtkEventDataAction {
> Unknown = -1,
> Press,
> Release,
> NumberOfActions
> };
>
> struct vtkEventDataButton3D
> {
> vtkEventDataDevice Device;
> vtkEventDataDeviceInput Input;
> vtkEventDataAction Action;
> double WorldPosition[3];
> double WorldOrientation[4];
>
> bool operator==(const vtkEventDataButton3D& rh)
> {
> return (Device == rh.Device && Input == rh.Input && Action ==
> rh.Action);
> }
> void SetWorldPosition(const double p[3])
> {
> WorldPosition[0] = p[0];
> WorldPosition[1] = p[1];
> WorldPosition[2] = p[2];
> }
> void SetWorldOrientation(const double p[4])
> {
> WorldOrientation[0] = p[0];
> WorldOrientation[1] = p[1];
> WorldOrientation[2] = p[2];
> WorldOrientation[3] = p[3];
> }
> };
>
> struct vtkEventDataMove3D
> {
> vtkEventDataDevice Device;
> double WorldPosition[3];
> double WorldOrientation[4];
>
> bool operator==(const vtkEventDataMove3D& rh)
> {
> return (Device == rh.Device);
> }
> void SetWorldPosition(const double p[3])
> {
> WorldPosition[0] = p[0];
> WorldPosition[1] = p[1];
> WorldPosition[2] = p[2];
> }
> void SetWorldOrientation(const double p[4])
> {
> WorldOrientation[0] = p[0];
> WorldOrientation[1] = p[1];
> WorldOrientation[2] = p[2];
> WorldOrientation[3] = p[3];
> }
> };
>
> typedef union
> {
> vtkEventDataButton3D Button;
> vtkEventDataMove3D Move;
> } vtkEventDataUnion;
>
> struct vtkEventData
> {
> int Type; // see vtkCommand.h
> vtkEventDataUnion Data;
>
> bool operator==(const vtkEventData& rh)
> {
> if (Type != rh.Type)
> {
> return false;
> }
> switch (Type)
> {
> case vtkCommand::ButtonEvent3D:
> return Data.Button == rh.Data.Button;
> case vtkCommand::MoveEvent3D:
> return Data.Move == rh.Data.Move;
> }
> return false;
> }
>
> bool GetDevice(vtkEventDataDevice &val)
> {
> switch (Type)
> {
> case vtkCommand::ButtonEvent3D:
> val = Data.Button.Device;
> return true;
> case vtkCommand::MoveEvent3D:
> val = Data.Move.Device;
> return true;
> }
> return false;
> }
>
> bool GetWorldPosition(double *&pos)
> {
> switch (Type)
> {
> case vtkCommand::ButtonEvent3D:
> pos = Data.Button.WorldPosition;
> return true;
> case vtkCommand::MoveEvent3D:
> pos = Data.Move.WorldPosition;
> return true;
> }
> return false;
> }
>
> bool GetWorldOrientation(double *&val)
> {
> switch (Type)
> {
> case vtkCommand::ButtonEvent3D:
> val = Data.Button.WorldOrientation;
> return true;
> case vtkCommand::MoveEvent3D:
> val = Data.Move.WorldOrientation;
> return true;
> }
> return false;
> }
> };
>
>
>
> --
> Ken Martin PhD
> Distinguished Engineer
> Kitware Inc.
> 28 Corporate Drive
> Clifton Park NY 12065
>
> This communication, including all attachments, contains confidential and
> legally privileged information, and it is intended only for the use of the
> addressee. Access to this email by anyone else is unauthorized. If you are
> not the intended recipient, any disclosure, copying, distribution or any
> action taken in reliance on it is prohibited and may be unlawful. If you
> received this communication in error please notify us immediately and
> destroy the original message. Thank you.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20170710/034a5919/attachment.html>
More information about the vtk-developers
mailing list