#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_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.
//!
//! - 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; }
//! 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; }
//! 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; }
- //! Return keyboard state.
- const Aspect_VKeySet& Keys() const { return myKeys; }
+ //! Set if tracked XR hand controllers should be displayed.
+ void SetDisplayXRHands (bool theToDisplay) { myToDisplayXRHands = theToDisplay; }
- //! Return keyboard state.
- Aspect_VKeySet& ChangeKeys() { return myKeys; }
+public: //! @name keyboard input
+
+ 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,
//! 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; }
//! 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.
//! 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.
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.
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.
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
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.
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,
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.
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
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
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
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
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