[vtk-developers] Some Event handling ideas

Ken Martin ken.martin at kitware.com
Mon Jul 10 11:15:50 EDT 2017


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/dad3a98d/attachment.html>


More information about the vtk-developers mailing list