0032306: Draw Harness, ViewerTest - move window message processing to TKService
[occt.git] / src / AIS / AIS_ViewController.hxx
index e82027d..747e8bf 100644 (file)
@@ -16,6 +16,9 @@
 
 #include <Aspect_VKeySet.hxx>
 #include <Aspect_TouchMap.hxx>
+#include <Aspect_WindowInputListener.hxx>
+#include <Aspect_XRHapticActionData.hxx>
+#include <Aspect_XRTrackedDeviceRole.hxx>
 #include <AIS_DragAction.hxx>
 #include <AIS_MouseGesture.hxx>
 #include <AIS_NavigationMode.hxx>
 #include <NCollection_Array1.hxx>
 #include <OSD_Timer.hxx>
 #include <Precision.hxx>
+#include <Quantity_ColorRGBA.hxx>
 #include <Standard_Mutex.hxx>
 
+class AIS_AnimationCamera;
 class AIS_InteractiveObject;
 class AIS_InteractiveContext;
 class AIS_Point;
 class AIS_RubberBand;
+class AIS_XRTrackedDevice;
+class Graphic3d_Camera;
+class SelectMgr_EntityOwner;
 class V3d_View;
+class WNT_HIDSpaceMouse;
 
 //! Auxiliary structure for handling viewer events between GUI and Rendering threads.
 //!
@@ -43,19 +52,31 @@ class V3d_View;
 //! - Mapping mouse/multi-touch input to View camera manipulations (panning/rotating/zooming).
 //! - Input events are not applied immediately but queued for separate processing from two working threads
 //!   UI thread receiving user input and Rendering thread for OCCT 3D Viewer drawing.
-class AIS_ViewController
+class AIS_ViewController : public Aspect_WindowInputListener
 {
 public:
 
   //! Empty constructor.
   Standard_EXPORT AIS_ViewController();
 
+  //! Destructor.
+  Standard_EXPORT virtual ~AIS_ViewController();
+
   //! Return input buffer.
   const AIS_ViewInputBuffer& InputBuffer (AIS_ViewInputBufferType theType) const { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
 
   //! Return input buffer.
   AIS_ViewInputBuffer& ChangeInputBuffer (AIS_ViewInputBufferType theType)       { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
 
+  //! Return view animation; empty (but not NULL) animation by default.
+  const Handle(AIS_AnimationCamera)& ViewAnimation() const { return myViewAnimation; }
+
+  //! Set view animation to be handled within handleViewRedraw().
+  void SetViewAnimation (const Handle(AIS_AnimationCamera)& theAnimation) { myViewAnimation = theAnimation; }
+
+  //! Interrupt active view animation.
+  Standard_EXPORT void AbortViewAnimation();
+
 public: //! @name global parameters
 
   //! Return camera rotation mode, AIS_RotationMode_BndBoxActive by default.
@@ -142,6 +163,18 @@ public: //! @name global parameters
   //! Set if dynamic highlight on mouse move is allowed.
   void SetAllowDragging (bool theToEnable) { myToAllowDragging = theToEnable; }
 
+  //! Return TRUE if picked point should be projected to picking ray on zooming at point; TRUE by default.
+  bool ToStickToRayOnZoom() const { return myToStickToRayOnZoom; }
+
+  //! Set if picked point should be projected to picking ray on zooming at point.
+  void SetStickToRayOnZoom (bool theToEnable) { myToStickToRayOnZoom = theToEnable; }
+
+  //! Return TRUE if picked point should be projected to picking ray on rotating around point; TRUE by default.
+  bool ToStickToRayOnRotation() const { return myToStickToRayOnRotation; }
+
+  //! Set if picked point should be projected to picking ray on rotating around point.
+  void SetStickToRayOnRotation (bool theToEnable) { myToStickToRayOnRotation = theToEnable; }
+
   //! Return TRUE if pitch direction should be inverted while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown; FALSE by default.
   bool ToInvertPitch() const { return myToInvertPitch; }
 
@@ -175,32 +208,44 @@ public: //! @name global parameters
   //! Reset previous position of MoveTo.
   void ResetPreviousMoveTo() { myPrevMoveTo = Graphic3d_Vec2i (-1); }
 
-public: //! @name keyboard input
+  //! Return TRUE to display auxiliary tracked XR devices (like tracking stations).
+  bool ToDisplayXRAuxDevices() const { return myToDisplayXRAuxDevices; }
+
+  //! Set if auxiliary tracked XR devices should be displayed.
+  void SetDisplayXRAuxDevices (bool theToDisplay) { myToDisplayXRAuxDevices = theToDisplay; }
+
+  //! Return TRUE to display XR hand controllers.
+  bool ToDisplayXRHands() const { return myToDisplayXRHands; }
+
+  //! Set if tracked XR hand controllers should be displayed.
+  void SetDisplayXRHands (bool theToDisplay) { myToDisplayXRHands = theToDisplay; }
 
-  //! Return keyboard state.
-  const Aspect_VKeySet& Keys() const { return myKeys; }
+public: //! @name keyboard input
 
-  //! Return keyboard state.
-  Aspect_VKeySet& ChangeKeys() { return myKeys; }
+  using Aspect_WindowInputListener::Keys;
+  using Aspect_WindowInputListener::ChangeKeys;
 
   //! Press key.
+  //! Default implementation updates internal cache.
   //! @param theKey key pressed
   //! @param theTime event timestamp
   Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
                                         double theTime,
-                                        double thePressure = 1.0);
+                                        double thePressure = 1.0) Standard_OVERRIDE;
 
   //! Release key.
+  //! Default implementation updates internal cache.
   //! @param theKey key pressed
   //! @param theTime event timestamp
   Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
-                                      double theTime);
+                                      double theTime) Standard_OVERRIDE;
 
   //! Simulate key up/down events from axis value.
+  //! Default implementation updates internal cache.
   Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
                                             Aspect_VKey thePositive,
                                             double theTime,
-                                            double thePressure);
+                                            double thePressure) Standard_OVERRIDE;
 
   //! Fetch active navigation actions.
   Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
@@ -214,6 +259,12 @@ public: //! @name mouse input
   //! Return map defining mouse gestures.
   AIS_MouseGestureMap& ChangeMouseGestureMap() { return myMouseGestureMap; }
 
+  //! Return map defining mouse selection schemes.
+  const AIS_MouseSelectionSchemeMap& MouseSelectionSchemes() const { return myMouseSelectionSchemes; }
+
+  //! Return map defining mouse gestures.
+  AIS_MouseSelectionSchemeMap& ChangeMouseSelectionSchemes() { return myMouseSelectionSchemes; }
+
   //! Return double click interval in seconds; 0.4 by default.
   double MouseDoubleClickInterval() const { return myMouseDoubleClickInt; }
 
@@ -223,25 +274,23 @@ public: //! @name mouse input
   //! Perform selection in 3D viewer.
   //! This method is expected to be called from UI thread.
   //! @param thePnt picking point
-  //! @param theIsXOR XOR selection flag
+  //! @param theScheme selection scheme
   Standard_EXPORT virtual void SelectInViewer (const Graphic3d_Vec2i& thePnt,
-                                               const bool theIsXOR = false);
+                                               const AIS_SelectionScheme theScheme = AIS_SelectionScheme_Replace);
 
   //! Perform selection in 3D viewer.
   //! This method is expected to be called from UI thread.
   //! @param thePnts picking point
-  //! @param theIsXOR XOR selection flag
+  //! @param theScheme selection scheme
   Standard_EXPORT virtual void SelectInViewer (const NCollection_Sequence<Graphic3d_Vec2i>& thePnts,
-                                               const bool theIsXOR = false);
+                                               const AIS_SelectionScheme theScheme = AIS_SelectionScheme_Replace);
 
   //! Update rectangle selection tool.
   //! This method is expected to be called from UI thread.
   //! @param thePntFrom rectangle first   corner
   //! @param thePntTo   rectangle another corner
-  //! @param theIsXOR XOR selection flag
   Standard_EXPORT virtual void UpdateRubberBand (const Graphic3d_Vec2i& thePntFrom,
-                                                 const Graphic3d_Vec2i& thePntTo,
-                                                 const bool theIsXOR = false);
+                                                 const Graphic3d_Vec2i& thePntTo);
 
   //! Update polygonal selection tool.
   //! This method is expected to be called from UI thread.
@@ -265,7 +314,7 @@ public: //! @name mouse input
   //! This method is expected to be called from UI thread.
   //! @param theDelta mouse cursor position and delta
   //! @return TRUE if new event has been created or FALSE if existing one has been updated
-  Standard_EXPORT virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta);
+  Standard_EXPORT virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta) Standard_OVERRIDE;
 
   //! Handle mouse button press/release event.
   //! This method is expected to be called from UI thread.
@@ -278,7 +327,7 @@ public: //! @name mouse input
   Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
                                                    Aspect_VKeyMouse theButtons,
                                                    Aspect_VKeyFlags theModifiers,
-                                                   bool theIsEmulated);
+                                                   bool theIsEmulated) Standard_OVERRIDE;
 
   //! Handle mouse cursor movement event.
   //! This method is expected to be called from UI thread.
@@ -291,40 +340,7 @@ public: //! @name mouse input
   Standard_EXPORT virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
                                                     Aspect_VKeyMouse theButtons,
                                                     Aspect_VKeyFlags theModifiers,
-                                                    bool theIsEmulated);
-
-  //! Handle mouse button press event.
-  //! This method is expected to be called from UI thread.
-  //! @param thePoint      mouse cursor position
-  //! @param theButton     pressed button
-  //! @param theModifiers  key modifiers
-  //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
-  //!                      but emulated from non-precise input like touch on screen
-  //! @return TRUE if View should be redrawn
-  bool PressMouseButton (const Graphic3d_Vec2i& thePoint,
-                         Aspect_VKeyMouse theButton,
-                         Aspect_VKeyFlags theModifiers,
-                         bool theIsEmulated)
-  {
-    return UpdateMouseButtons (thePoint, myMousePressed | theButton, theModifiers, theIsEmulated);
-  }
-
-  //! Handle mouse button release event.
-  //! This method is expected to be called from UI thread.
-  //! @param thePoint      mouse cursor position
-  //! @param theButton     released button
-  //! @param theModifiers  key modifiers
-  //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
-  //!                      but emulated from non-precise input like touch on screen
-  //! @return TRUE if View should be redrawn
-  bool ReleaseMouseButton (const Graphic3d_Vec2i& thePoint,
-                           Aspect_VKeyMouse theButton,
-                           Aspect_VKeyFlags theModifiers,
-                           bool theIsEmulated)
-  {
-    Aspect_VKeyMouse aButtons = myMousePressed & (~theButton);
-    return UpdateMouseButtons (thePoint, aButtons, theModifiers, theIsEmulated);
-  }
+                                                    bool theIsEmulated) Standard_OVERRIDE;
 
   //! Handle mouse button click event (emulated by UpdateMouseButtons() while releasing single button).
   //! Note that as this method is called by UpdateMouseButtons(), it should be executed from UI thread.
@@ -340,14 +356,12 @@ public: //! @name mouse input
                                                  Aspect_VKeyFlags theModifiers,
                                                  bool theIsDoubleClick);
 
-  //! Return currently pressed mouse buttons.
-  Aspect_VKeyMouse PressedMouseButtons() const { return myMousePressed; }
+  using Aspect_WindowInputListener::PressMouseButton;
+  using Aspect_WindowInputListener::ReleaseMouseButton;
 
-  //! Return active key modifiers passed with last mouse event.
-  Aspect_VKeyFlags LastMouseFlags() const { return myMouseModifiers; }
-
-  //! Return last mouse position.
-  const Graphic3d_Vec2i& LastMousePosition() const { return myMousePositionLast; }
+  using Aspect_WindowInputListener::PressedMouseButtons;
+  using Aspect_WindowInputListener::LastMouseFlags;
+  using Aspect_WindowInputListener::LastMousePosition;
 
 public: //! @name multi-touch input
 
@@ -386,10 +400,42 @@ public: //! @name multi-touch input
   Standard_EXPORT virtual void UpdateTouchPoint (Standard_Size theId,
                                                  const Graphic3d_Vec2d& thePnt);
 
+public: //! @name 3d mouse input
+
+  //! Process 3d mouse input event (redirects to translation, rotation and keys).
+  Standard_EXPORT virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent) Standard_OVERRIDE;
+
+public: //! @name resize events
+
+  //! Handle expose event (window content has been invalidation and should be redrawn).
+  //! Default implementation does nothing.
+  virtual void ProcessExpose() Standard_OVERRIDE {}
+
+  //! Handle window resize event.
+  //! Default implementation does nothing.
+  virtual void ProcessConfigure (bool theIsResized) Standard_OVERRIDE
+  {
+    (void )theIsResized;
+  }
+
+  //! Handle window input event immediately.
+  //! Default implementation does nothing - input events are accumulated in internal buffer until explicit FlushViewEvents() call.
+  virtual void ProcessInput() Standard_OVERRIDE {}
+
+  //! Handle focus event.
+  //! Default implementation does nothing.
+  virtual void ProcessFocus (bool theIsActivated)
+  {
+    (void )theIsActivated;
+  }
+
+  //! Handle window close event.
+  //! Default implementation does nothing.
+  virtual void ProcessClose() {}
+
 public:
 
-  //! Return event time (e.g. current time).
-  double EventTime() const { return myEventTimer.ElapsedTime(); }
+  using Aspect_WindowInputListener::EventTime;
 
   //! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
   //! This method is expected to be called from UI thread.
@@ -446,9 +492,25 @@ public:
   Standard_EXPORT virtual gp_Pnt GravityPoint (const Handle(AIS_InteractiveContext)& theCtx,
                                                const Handle(V3d_View)& theView);
 
+  //! Modify view camera to fit all objects.
+  //! Default implementation fits either all visible and all selected objects (swapped on each call).
+  Standard_EXPORT virtual void FitAllAuto (const Handle(AIS_InteractiveContext)& theCtx,
+                                           const Handle(V3d_View)& theView);
+
 public:
 
-  //! Perform camera actions.
+  //! Handle hot-keys defining new camera orientation (Aspect_VKey_ViewTop and similar keys).
+  //! Default implementation starts an animated transaction from the current to the target camera orientation, when specific action key was pressed.
+  //! This method is expected to be called from rendering thread.
+  Standard_EXPORT virtual void handleViewOrientationKeys (const Handle(AIS_InteractiveContext)& theCtx,
+                                                          const Handle(V3d_View)& theView);
+
+  //! Perform navigation (Aspect_VKey_NavForward and similar keys).
+  //! This method is expected to be called from rendering thread.
+  Standard_EXPORT virtual AIS_WalkDelta handleNavigationKeys (const Handle(AIS_InteractiveContext)& theCtx,
+                                                              const Handle(V3d_View)& theView);
+
+  //! Perform immediate camera actions (rotate/zoom/pan) on gesture progress.
   //! This method is expected to be called from rendering thread.
   Standard_EXPORT virtual void handleCameraActions (const Handle(AIS_InteractiveContext)& theCtx,
                                                     const Handle(V3d_View)& theView,
@@ -523,6 +585,40 @@ public:
   Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
                                                  const Handle(V3d_View)& theView);
 
+public:
+
+  //! Perform XR input.
+  //! This method is expected to be called from rendering thread.
+  Standard_EXPORT virtual void handleXRInput (const Handle(AIS_InteractiveContext)& theCtx,
+                                              const Handle(V3d_View)& theView,
+                                              const AIS_WalkDelta& theWalk);
+
+  //! Handle trackpad view turn action.
+  Standard_EXPORT virtual void handleXRTurnPad (const Handle(AIS_InteractiveContext)& theCtx,
+                                                const Handle(V3d_View)& theView);
+
+  //! Handle trackpad teleportation action.
+  Standard_EXPORT virtual void handleXRTeleport (const Handle(AIS_InteractiveContext)& theCtx,
+                                                 const Handle(V3d_View)& theView);
+
+  //! Handle picking on trigger click.
+  Standard_EXPORT virtual void handleXRPicking (const Handle(AIS_InteractiveContext)& theCtx,
+                                                const Handle(V3d_View)& theView);
+
+  //! Perform dynamic highlighting for active hand.
+  Standard_EXPORT virtual void handleXRHighlight (const Handle(AIS_InteractiveContext)& theCtx,
+                                                  const Handle(V3d_View)& theView);
+
+  //! Display auxiliary XR presentations.
+  Standard_EXPORT virtual void handleXRPresentations (const Handle(AIS_InteractiveContext)& theCtx,
+                                                      const Handle(V3d_View)& theView);
+
+  //! Perform picking with/without dynamic highlighting for XR pose.
+  Standard_EXPORT virtual Standard_Integer handleXRMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
+                                                           const Handle(V3d_View)& theView,
+                                                           const gp_Trsf& thePose,
+                                                           const Standard_Boolean theToHighlight);
+
 protected:
 
   //! Flush buffers.
@@ -570,7 +666,6 @@ protected:
   AIS_ViewInputBuffer myUI;                       //!< buffer for UI thread
   AIS_ViewInputBuffer myGL;                       //!< buffer for rendering thread
 
-  OSD_Timer           myEventTimer;               //!< timer for timestamping events
   Standard_Real       myLastEventsTime;           //!< last fetched events timer value for computing delta/progress
   Standard_Boolean    myToAskNextFrame;           //!< flag indicating that another frame should be drawn right after this one
 
@@ -590,20 +685,37 @@ protected:
   Standard_Boolean    myToAllowZFocus;            //!< enable ZFocus change; TRUE by default
   Standard_Boolean    myToAllowHighlight;         //!< enable dynamic highlight on mouse move; TRUE by default
   Standard_Boolean    myToAllowDragging;          //!< enable dragging object; TRUE by default
+  Standard_Boolean    myToStickToRayOnZoom;       //!< project picked point to ray while zooming at point, TRUE by default
+  Standard_Boolean    myToStickToRayOnRotation;   //!< project picked point to ray while rotating around point; TRUE by default
 
   Standard_ShortReal  myWalkSpeedAbsolute;        //!< normal walking speed, in m/s; 1.5 by default
   Standard_ShortReal  myWalkSpeedRelative;        //!< walking speed relative to scene bounding box; 0.1 by default
   Standard_ShortReal  myThrustSpeed;              //!< active thrust value
   Standard_Boolean    myHasThrust;                //!< flag indicating active thrust
 
+  Handle(AIS_AnimationCamera) myViewAnimation;    //!< view animation
   Handle(AIS_RubberBand) myRubberBand;            //!< Rubber-band presentation
+  Handle(SelectMgr_EntityOwner) myDragOwner;      //!< detected owner of currently dragged object
   Handle(AIS_InteractiveObject) myDragObject;     //!< currently dragged object
   Graphic3d_Vec2i     myPrevMoveTo;               //!< previous position of MoveTo event in 3D viewer
   Standard_Boolean    myHasHlrOnBeforeRotation;   //!< flag for restoring Computed mode after rotation
 
-protected: //! @name keyboard input variables
-
-  Aspect_VKeySet      myKeys;                     //!< keyboard state
+protected: //! @name XR input variables
+
+  NCollection_Array1<Handle(AIS_XRTrackedDevice)> myXRPrsDevices; //!< array of XR tracked devices presentations
+  Handle(Graphic3d_Camera)   myXRCameraTmp;       //!< temporary camera
+  Quantity_Color             myXRLaserTeleColor;  //!< color of teleport laser
+  Quantity_Color             myXRLaserPickColor;  //!< color of picking  laser
+  Aspect_XRTrackedDeviceRole myXRLastTeleportHand;//!< active hand for teleport
+  Aspect_XRTrackedDeviceRole myXRLastPickingHand; //!< active hand for picking objects
+  Aspect_XRHapticActionData  myXRTeleportHaptic;  //!< vibration on picking teleport destination
+  Aspect_XRHapticActionData  myXRPickingHaptic;   //!< vibration on dynamic highlighting
+  Aspect_XRHapticActionData  myXRSelectHaptic;    //!< vibration on selection
+  Standard_Real       myXRLastPickDepthLeft;      //!< last picking depth for left  hand
+  Standard_Real       myXRLastPickDepthRight;     //!< last picking depth for right hand
+  Standard_Real       myXRTurnAngle;              //!< discrete turn angle for XR trackpad
+  Standard_Boolean    myToDisplayXRAuxDevices;    //!< flag to display auxiliary tracked XR devices
+  Standard_Boolean    myToDisplayXRHands;         //!< flag to display XR hands
 
 protected: //! @name mouse input variables
 
@@ -613,15 +725,15 @@ protected: //! @name mouse input variables
 
   AIS_MouseGestureMap myMouseGestureMap;          //!< map defining mouse gestures
   AIS_MouseGesture    myMouseActiveGesture;       //!< initiated mouse gesture (by pressing mouse button)
+  AIS_MouseSelectionSchemeMap
+                      myMouseSelectionSchemes;    //!< map defining selection schemes bound to mouse + modifiers
   Standard_Boolean    myMouseActiveIdleRotation;  //!< flag indicating view idle rotation state
-  Graphic3d_Vec2i     myMousePositionLast;        //!< last mouse position
   Graphic3d_Vec2i     myMousePressPoint;          //!< mouse position where active gesture was been initiated
   Graphic3d_Vec2i     myMouseProgressPoint;       //!< gesture progress
   OSD_Timer           myMouseClickTimer;          //!< timer for handling double-click event
   Standard_Integer    myMouseClickCounter;        //!< counter for handling double-click event
-  Aspect_VKeyMouse    myMousePressed;             //!< active mouse buttons
-  Aspect_VKeyFlags    myMouseModifiers;           //!< active key modifiers passed with last mouse event
   Standard_Integer    myMouseSingleButton;        //!< index of mouse button pressed alone (>0)
+  Standard_Boolean    myMouseStopDragOnUnclick;   //!< queue stop dragging even with at next mouse unclick
 
 protected: //! @name multi-touch input variables
 
@@ -647,6 +759,7 @@ protected: //! @name rotation/panning transient state variables
   gp_Pnt              myPanPnt3d;                 //!< active panning anchor point
   gp_Pnt              myRotatePnt3d;              //!< active rotation center of gravity
   gp_Dir              myCamStartOpUp;             //!< camera Up    direction at the beginning of rotation
+  gp_Dir              myCamStartOpDir;            //!< camera View  direction at the beginning of rotation
   gp_Pnt              myCamStartOpEye;            //!< camera Eye    position at the beginning of rotation
   gp_Pnt              myCamStartOpCenter;         //!< camera Center position at the beginning of rotation
   gp_Vec              myCamStartOpToCenter;       //!< vector from rotation gravity point to camera Center at the beginning of rotation