eaa12fb1374c30b367ac22623060bab14252af0d
[occt.git] / src / AIS / AIS_ViewController.hxx
1 // Copyright (c) 2016-2019 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _AIS_ViewController_HeaderFile
15 #define _AIS_ViewController_HeaderFile
16
17 #include <Aspect_VKeySet.hxx>
18 #include <Aspect_TouchMap.hxx>
19 #include <Aspect_XRHapticActionData.hxx>
20 #include <Aspect_XRTrackedDeviceRole.hxx>
21 #include <AIS_DragAction.hxx>
22 #include <AIS_MouseGesture.hxx>
23 #include <AIS_NavigationMode.hxx>
24 #include <AIS_ViewInputBuffer.hxx>
25 #include <AIS_RotationMode.hxx>
26 #include <AIS_WalkDelta.hxx>
27
28 #include <gp_Pnt.hxx>
29 #include <Graphic3d_Vec3.hxx>
30 #include <NCollection_Array1.hxx>
31 #include <OSD_Timer.hxx>
32 #include <Precision.hxx>
33 #include <Quantity_ColorRGBA.hxx>
34 #include <Standard_Mutex.hxx>
35
36 class AIS_AnimationCamera;
37 class AIS_InteractiveObject;
38 class AIS_InteractiveContext;
39 class AIS_Point;
40 class AIS_RubberBand;
41 class AIS_XRTrackedDevice;
42 class Graphic3d_Camera;
43 class V3d_View;
44
45 //! Auxiliary structure for handling viewer events between GUI and Rendering threads.
46 //!
47 //! Class implements the following features:
48 //! - Buffers storing the state of user input (mouse, touches and keyboard).
49 //! - Mapping mouse/multi-touch input to View camera manipulations (panning/rotating/zooming).
50 //! - Input events are not applied immediately but queued for separate processing from two working threads
51 //!   UI thread receiving user input and Rendering thread for OCCT 3D Viewer drawing.
52 class AIS_ViewController
53 {
54 public:
55
56   //! Empty constructor.
57   Standard_EXPORT AIS_ViewController();
58
59   //! Destructor.
60   Standard_EXPORT virtual ~AIS_ViewController();
61
62   //! Return input buffer.
63   const AIS_ViewInputBuffer& InputBuffer (AIS_ViewInputBufferType theType) const { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
64
65   //! Return input buffer.
66   AIS_ViewInputBuffer& ChangeInputBuffer (AIS_ViewInputBufferType theType)       { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
67
68   //! Return view animation; empty (but not NULL) animation by default.
69   const Handle(AIS_AnimationCamera)& ViewAnimation() const { return myViewAnimation; }
70
71   //! Set view animation to be handled within handleViewRedraw().
72   void SetViewAnimation (const Handle(AIS_AnimationCamera)& theAnimation) { myViewAnimation = theAnimation; }
73
74   //! Interrupt active view animation.
75   Standard_EXPORT void AbortViewAnimation();
76
77 public: //! @name global parameters
78
79   //! Return camera rotation mode, AIS_RotationMode_BndBoxActive by default.
80   AIS_RotationMode RotationMode() const { return myRotationMode; }
81
82   //! Set camera rotation mode.
83   void SetRotationMode (AIS_RotationMode theMode) { myRotationMode = theMode; }
84
85   //! Return camera navigation mode; AIS_NavigationMode_Orbit by default.
86   AIS_NavigationMode NavigationMode() const { return myNavigationMode; }
87
88   //! Set camera navigation mode.
89   Standard_EXPORT void SetNavigationMode (AIS_NavigationMode theMode);
90
91   //! Return mouse input acceleration ratio in First Person mode; 1.0 by default.
92   float MouseAcceleration() const { return myMouseAccel; }
93
94   //! Set mouse input acceleration ratio.
95   void SetMouseAcceleration (float theRatio) { myMouseAccel = theRatio; }
96
97   //! Return orbit rotation acceleration ratio; 1.0 by default.
98   float OrbitAcceleration() const { return myOrbitAccel; }
99
100   //! Set orbit rotation acceleration ratio.
101   void SetOrbitAcceleration (float theRatio) { myOrbitAccel = theRatio; }
102
103   //! Return TRUE if panning anchor point within perspective projection should be displayed in 3D Viewer; TRUE by default.
104   bool ToShowPanAnchorPoint() const { return myToShowPanAnchorPoint; }
105
106   //! Set if panning anchor point within perspective projection should be displayed in 3D Viewer.
107   void SetShowPanAnchorPoint (bool theToShow) { myToShowPanAnchorPoint = theToShow; }
108
109   //! Return TRUE if rotation point should be displayed in 3D Viewer; TRUE by default.
110   bool ToShowRotateCenter() const { return myToShowRotateCenter; }
111
112   //! Set if rotation point should be displayed in 3D Viewer.
113   void SetShowRotateCenter (bool theToShow) { myToShowRotateCenter = theToShow; }
114
115   //! Return TRUE if camera up orientation within AIS_NavigationMode_Orbit rotation mode should be forced Z up; FALSE by default.
116   bool ToLockOrbitZUp() const { return myToLockOrbitZUp; }
117
118   //! Set if camera up orientation within AIS_NavigationMode_Orbit rotation mode should be forced Z up.
119   void SetLockOrbitZUp (bool theToForceUp) { myToLockOrbitZUp = theToForceUp; }
120
121   //! Return TRUE if z-rotation via two-touches gesture is enabled; FALSE by default.
122   bool ToAllowTouchZRotation() const { return myToAllowTouchZRotation; }
123
124   //! Set if z-rotation via two-touches gesture is enabled.
125   void SetAllowTouchZRotation (bool theToEnable) { myToAllowTouchZRotation = theToEnable; }
126
127   //! Return TRUE if camera rotation is allowed; TRUE by default.
128   bool ToAllowRotation() const { return myToAllowRotation; }
129
130   //! Set if camera rotation is allowed.
131   void SetAllowRotation (bool theToEnable) { myToAllowRotation = theToEnable; }
132
133   //! Return TRUE if panning is allowed; TRUE by default.
134   bool ToAllowPanning() const { return myToAllowPanning; }
135
136   //! Set if panning is allowed.
137   void SetAllowPanning (bool theToEnable) { myToAllowPanning = theToEnable; }
138
139   //! Return TRUE if zooming is allowed; TRUE by default.
140   bool ToAllowZooming() const { return myToAllowZooming; }
141
142   //! Set if zooming is allowed.
143   void SetAllowZooming (bool theToEnable) { myToAllowZooming = theToEnable; }
144
145   //! Return TRUE if ZFocus change is allowed; TRUE by default.
146   bool ToAllowZFocus() const { return myToAllowZFocus; }
147
148   //! Set if ZFocus change is allowed.
149   void SetAllowZFocus (bool theToEnable) { myToAllowZFocus = theToEnable; }
150
151   //! Return TRUE if dynamic highlight on mouse move is allowed; TRUE by default.
152   bool ToAllowHighlight() const { return myToAllowHighlight; }
153
154   //! Set if dragging object is allowed.
155   void SetAllowHighlight (bool theToEnable) { myToAllowHighlight = theToEnable; }
156
157   //! Return TRUE if dragging object is allowed; TRUE by default.
158   bool ToAllowDragging() const { return myToAllowDragging; }
159
160   //! Set if dynamic highlight on mouse move is allowed.
161   void SetAllowDragging (bool theToEnable) { myToAllowDragging = theToEnable; }
162
163   //! Return TRUE if picked point should be projected to picking ray on zooming at point; TRUE by default.
164   bool ToStickToRayOnZoom() const { return myToStickToRayOnZoom; }
165
166   //! Set if picked point should be projected to picking ray on zooming at point.
167   void SetStickToRayOnZoom (bool theToEnable) { myToStickToRayOnZoom = theToEnable; }
168
169   //! Return TRUE if picked point should be projected to picking ray on rotating around point; TRUE by default.
170   bool ToStickToRayOnRotation() const { return myToStickToRayOnRotation; }
171
172   //! Set if picked point should be projected to picking ray on rotating around point.
173   void SetStickToRayOnRotation (bool theToEnable) { myToStickToRayOnRotation = theToEnable; }
174
175   //! Return TRUE if pitch direction should be inverted while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown; FALSE by default.
176   bool ToInvertPitch() const { return myToInvertPitch; }
177
178   //! Set flag inverting pitch direction.
179   void SetInvertPitch (bool theToInvert) { myToInvertPitch = theToInvert; }
180
181   //! Return normal walking speed, in m/s; 1.5 by default.
182   float WalkSpeedAbsolute() const { return myWalkSpeedAbsolute; }
183
184   //! Set normal walking speed, in m/s; 1.5 by default.
185   void SetWalkSpeedAbsolute (float theSpeed) { myWalkSpeedAbsolute = theSpeed; }
186
187   //! Return walking speed relative to scene bounding box; 0.1 by default.
188   float WalkSpeedRelative() const { return myWalkSpeedRelative; }
189
190   //! Set walking speed relative to scene bounding box.
191   void SetWalkSpeedRelative (float theFactor) { myWalkSpeedRelative = theFactor; }
192
193   //! Return active thrust value; 0.0f by default.
194   float ThrustSpeed() const { return myThrustSpeed; }
195
196   //! Set active thrust value.
197   void SetThrustSpeed (float theSpeed) { myThrustSpeed = theSpeed; }
198
199   //! Return TRUE if previous position of MoveTo has been defined.
200   bool HasPreviousMoveTo() const { return myPrevMoveTo != Graphic3d_Vec2i (-1); }
201
202   //! Return previous position of MoveTo event in 3D viewer.
203   const Graphic3d_Vec2i& PreviousMoveTo() const { return myPrevMoveTo; }
204
205   //! Reset previous position of MoveTo.
206   void ResetPreviousMoveTo() { myPrevMoveTo = Graphic3d_Vec2i (-1); }
207
208   //! Return TRUE to display auxiliary tracked XR devices (like tracking stations).
209   bool ToDisplayXRAuxDevices() const { return myToDisplayXRAuxDevices; }
210
211   //! Set if auxiliary tracked XR devices should be displayed.
212   void SetDisplayXRAuxDevices (bool theToDisplay) { myToDisplayXRAuxDevices = theToDisplay; }
213
214   //! Return TRUE to display XR hand controllers.
215   bool ToDisplayXRHands() const { return myToDisplayXRHands; }
216
217   //! Set if tracked XR hand controllers should be displayed.
218   void SetDisplayXRHands (bool theToDisplay) { myToDisplayXRHands = theToDisplay; }
219
220 public: //! @name keyboard input
221
222   //! Return keyboard state.
223   const Aspect_VKeySet& Keys() const { return myKeys; }
224
225   //! Return keyboard state.
226   Aspect_VKeySet& ChangeKeys() { return myKeys; }
227
228   //! Press key.
229   //! @param theKey key pressed
230   //! @param theTime event timestamp
231   Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
232                                         double theTime,
233                                         double thePressure = 1.0);
234
235   //! Release key.
236   //! @param theKey key pressed
237   //! @param theTime event timestamp
238   Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
239                                       double theTime);
240
241   //! Simulate key up/down events from axis value.
242   Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
243                                             Aspect_VKey thePositive,
244                                             double theTime,
245                                             double thePressure);
246
247   //! Fetch active navigation actions.
248   Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
249                                                      Standard_Real theRunRatio);
250
251 public: //! @name mouse input
252
253   //! Return map defining mouse gestures.
254   const AIS_MouseGestureMap& MouseGestureMap() const { return myMouseGestureMap; }
255
256   //! Return map defining mouse gestures.
257   AIS_MouseGestureMap& ChangeMouseGestureMap() { return myMouseGestureMap; }
258
259   //! Return double click interval in seconds; 0.4 by default.
260   double MouseDoubleClickInterval() const { return myMouseDoubleClickInt; }
261
262   //! Set double click interval in seconds.
263   void SetMouseDoubleClickInterval (double theSeconds) { myMouseDoubleClickInt = theSeconds; }
264
265   //! Perform selection in 3D viewer.
266   //! This method is expected to be called from UI thread.
267   //! @param thePnt picking point
268   //! @param theIsXOR XOR selection flag
269   Standard_EXPORT virtual void SelectInViewer (const Graphic3d_Vec2i& thePnt,
270                                                const bool theIsXOR = false);
271
272   //! Perform selection in 3D viewer.
273   //! This method is expected to be called from UI thread.
274   //! @param thePnts picking point
275   //! @param theIsXOR XOR selection flag
276   Standard_EXPORT virtual void SelectInViewer (const NCollection_Sequence<Graphic3d_Vec2i>& thePnts,
277                                                const bool theIsXOR = false);
278
279   //! Update rectangle selection tool.
280   //! This method is expected to be called from UI thread.
281   //! @param thePntFrom rectangle first   corner
282   //! @param thePntTo   rectangle another corner
283   //! @param theIsXOR XOR selection flag
284   Standard_EXPORT virtual void UpdateRubberBand (const Graphic3d_Vec2i& thePntFrom,
285                                                  const Graphic3d_Vec2i& thePntTo,
286                                                  const bool theIsXOR = false);
287
288   //! Update polygonal selection tool.
289   //! This method is expected to be called from UI thread.
290   //! @param thePnt new point to add to polygon
291   //! @param theToAppend append new point or update the last point
292   Standard_EXPORT virtual void UpdatePolySelection (const Graphic3d_Vec2i& thePnt,
293                                                     bool theToAppend);
294
295   //! Update zoom event (e.g. from mouse scroll).
296   //! This method is expected to be called from UI thread.
297   //! @param theDelta mouse cursor position to zoom at and zoom delta
298   //! @return TRUE if new zoom event has been created or FALSE if existing one has been updated
299   Standard_EXPORT virtual bool UpdateZoom (const Aspect_ScrollDelta& theDelta);
300
301   //! Update Z rotation event.
302   //! @param theAngle rotation angle, in radians.
303   //! @return TRUE if new zoom event has been created or FALSE if existing one has been updated
304   Standard_EXPORT virtual bool UpdateZRotation (double theAngle);
305
306   //! Update mouse scroll event; redirects to UpdateZoom by default.
307   //! This method is expected to be called from UI thread.
308   //! @param theDelta mouse cursor position and delta
309   //! @return TRUE if new event has been created or FALSE if existing one has been updated
310   Standard_EXPORT virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta);
311
312   //! Handle mouse button press/release event.
313   //! This method is expected to be called from UI thread.
314   //! @param thePoint      mouse cursor position
315   //! @param theButtons    pressed buttons
316   //! @param theModifiers  key modifiers
317   //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
318   //!                      but emulated from non-precise input like touch on screen
319   //! @return TRUE if View should be redrawn
320   Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
321                                                    Aspect_VKeyMouse theButtons,
322                                                    Aspect_VKeyFlags theModifiers,
323                                                    bool theIsEmulated);
324
325   //! Handle mouse cursor movement event.
326   //! This method is expected to be called from UI thread.
327   //! @param thePoint      mouse cursor position
328   //! @param theButtons    pressed buttons
329   //! @param theModifiers  key modifiers
330   //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
331   //!                      but emulated from non-precise input like touch on screen
332   //! @return TRUE if View should be redrawn
333   Standard_EXPORT virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
334                                                     Aspect_VKeyMouse theButtons,
335                                                     Aspect_VKeyFlags theModifiers,
336                                                     bool theIsEmulated);
337
338   //! Handle mouse button press event.
339   //! This method is expected to be called from UI thread.
340   //! @param thePoint      mouse cursor position
341   //! @param theButton     pressed button
342   //! @param theModifiers  key modifiers
343   //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
344   //!                      but emulated from non-precise input like touch on screen
345   //! @return TRUE if View should be redrawn
346   bool PressMouseButton (const Graphic3d_Vec2i& thePoint,
347                          Aspect_VKeyMouse theButton,
348                          Aspect_VKeyFlags theModifiers,
349                          bool theIsEmulated)
350   {
351     return UpdateMouseButtons (thePoint, myMousePressed | theButton, theModifiers, theIsEmulated);
352   }
353
354   //! Handle mouse button release event.
355   //! This method is expected to be called from UI thread.
356   //! @param thePoint      mouse cursor position
357   //! @param theButton     released button
358   //! @param theModifiers  key modifiers
359   //! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
360   //!                      but emulated from non-precise input like touch on screen
361   //! @return TRUE if View should be redrawn
362   bool ReleaseMouseButton (const Graphic3d_Vec2i& thePoint,
363                            Aspect_VKeyMouse theButton,
364                            Aspect_VKeyFlags theModifiers,
365                            bool theIsEmulated)
366   {
367     Aspect_VKeyMouse aButtons = myMousePressed & (~theButton);
368     return UpdateMouseButtons (thePoint, aButtons, theModifiers, theIsEmulated);
369   }
370
371   //! Handle mouse button click event (emulated by UpdateMouseButtons() while releasing single button).
372   //! Note that as this method is called by UpdateMouseButtons(), it should be executed from UI thread.
373   //! Default implementation redirects to SelectInViewer().
374   //! This method is expected to be called from UI thread.
375   //! @param thePoint      mouse cursor position
376   //! @param theButton     clicked button
377   //! @param theModifiers  key modifiers
378   //! @param theIsDoubleClick flag indicating double mouse click
379   //! @return TRUE if View should be redrawn
380   Standard_EXPORT virtual bool UpdateMouseClick (const Graphic3d_Vec2i& thePoint,
381                                                  Aspect_VKeyMouse theButton,
382                                                  Aspect_VKeyFlags theModifiers,
383                                                  bool theIsDoubleClick);
384
385   //! Return currently pressed mouse buttons.
386   Aspect_VKeyMouse PressedMouseButtons() const { return myMousePressed; }
387
388   //! Return active key modifiers passed with last mouse event.
389   Aspect_VKeyFlags LastMouseFlags() const { return myMouseModifiers; }
390
391   //! Return last mouse position.
392   const Graphic3d_Vec2i& LastMousePosition() const { return myMousePositionLast; }
393
394 public: //! @name multi-touch input
395
396   //! Return scale factor for adjusting tolerances for starting multi-touch gestures; 1.0 by default
397   //! This scale factor is expected to be computed from touch screen resolution.
398   float TouchToleranceScale() const { return myTouchToleranceScale; }
399
400   //! Set scale factor for adjusting tolerances for starting multi-touch gestures.
401   void SetTouchToleranceScale (float theTolerance) { myTouchToleranceScale = theTolerance; }
402
403   //! Return TRUE if touches map is not empty.
404   bool HasTouchPoints() const { return !myTouchPoints.IsEmpty(); }
405
406   //! Add touch point with the given ID.
407   //! This method is expected to be called from UI thread.
408   //! @param theId touch unique identifier
409   //! @param thePnt touch coordinates
410   //! @param theClearBefore if TRUE previously registered touches will be removed
411   Standard_EXPORT virtual void AddTouchPoint (Standard_Size theId,
412                                               const Graphic3d_Vec2d& thePnt,
413                                               Standard_Boolean theClearBefore = false);
414
415   //! Remove touch point with the given ID.
416   //! This method is expected to be called from UI thread.
417   //! @param theId touch unique identifier
418   //! @param theClearSelectPnts if TRUE will initiate clearing of selection points
419   //! @return TRUE if point has been removed
420   Standard_EXPORT virtual bool RemoveTouchPoint (Standard_Size theId,
421                                                  Standard_Boolean theClearSelectPnts = false);
422
423   //! Update touch point with the given ID.
424   //! If point with specified ID was not registered before, it will be added.
425   //! This method is expected to be called from UI thread.
426   //! @param theId touch unique identifier
427   //! @param thePnt touch coordinates
428   Standard_EXPORT virtual void UpdateTouchPoint (Standard_Size theId,
429                                                  const Graphic3d_Vec2d& thePnt);
430
431 public:
432
433   //! Return event time (e.g. current time).
434   double EventTime() const { return myEventTimer.ElapsedTime(); }
435
436   //! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
437   //! This method is expected to be called from UI thread.
438   Standard_EXPORT virtual void ResetViewInput();
439
440   //! Reset view orientation.
441   //! This method is expected to be called from UI thread.
442   Standard_EXPORT virtual void UpdateViewOrientation (V3d_TypeOfOrientation theOrientation,
443                                                       bool theToFitAll);
444
445   //! Update buffer for rendering thread.
446   //! This method is expected to be called within synchronization barrier between GUI
447   //! and Rendering threads (e.g. GUI thread should be locked beforehand to avoid data races).
448   //! @param theCtx interactive context
449   //! @param theView active view
450   //! @param theToHandle if TRUE, the HandleViewEvents() will be called
451   Standard_EXPORT virtual void FlushViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
452                                                 const Handle(V3d_View)& theView,
453                                                 Standard_Boolean theToHandle = Standard_False);
454
455   //! Process events within rendering thread.
456   Standard_EXPORT virtual void HandleViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
457                                                  const Handle(V3d_View)& theView);
458
459 public:
460
461   //! Callback called by handleMoveTo() on Selection in 3D Viewer.
462   //! This method is expected to be called from rendering thread.
463   Standard_EXPORT virtual void OnSelectionChanged (const Handle(AIS_InteractiveContext)& theCtx,
464                                                    const Handle(V3d_View)& theView);
465
466   //! Callback called by handleMoveTo() on dragging object in 3D Viewer.
467   //! This method is expected to be called from rendering thread.
468   Standard_EXPORT virtual void OnObjectDragged (const Handle(AIS_InteractiveContext)& theCtx,
469                                                 const Handle(V3d_View)& theView,
470                                                 AIS_DragAction theAction);
471
472   //! Pick closest point under mouse cursor.
473   //! This method is expected to be called from rendering thread.
474   //! @param thePnt   [out] result point
475   //! @param theCtx    [in] interactive context
476   //! @param theView   [in] active view
477   //! @param theCursor [in] mouse cursor
478   //! @param theToStickToPickRay [in] when TRUE, the result point will lie on picking ray
479   //! @return TRUE if result has been found
480   Standard_EXPORT virtual bool PickPoint (gp_Pnt& thePnt,
481                                           const Handle(AIS_InteractiveContext)& theCtx,
482                                           const Handle(V3d_View)& theView,
483                                           const Graphic3d_Vec2i& theCursor,
484                                           bool theToStickToPickRay);
485
486   //! Compute rotation gravity center point depending on rotation mode.
487   //! This method is expected to be called from rendering thread.
488   Standard_EXPORT virtual gp_Pnt GravityPoint (const Handle(AIS_InteractiveContext)& theCtx,
489                                                const Handle(V3d_View)& theView);
490
491 public:
492
493   //! Perform navigation.
494   //! This method is expected to be called from rendering thread.
495   Standard_EXPORT virtual AIS_WalkDelta handleNavigationKeys (const Handle(AIS_InteractiveContext)& theCtx,
496                                                               const Handle(V3d_View)& theView);
497
498   //! Perform camera actions.
499   //! This method is expected to be called from rendering thread.
500   Standard_EXPORT virtual void handleCameraActions (const Handle(AIS_InteractiveContext)& theCtx,
501                                                     const Handle(V3d_View)& theView,
502                                                     const AIS_WalkDelta& theWalk);
503
504   //! Perform moveto/selection/dragging.
505   //! This method is expected to be called from rendering thread.
506   Standard_EXPORT virtual void handleMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
507                                              const Handle(V3d_View)& theView);
508
509   //! Return TRUE if another frame should be drawn right after this one.
510   bool toAskNextFrame() const { return myToAskNextFrame; }
511
512   //! Set if another frame should be drawn right after this one.
513   void setAskNextFrame (bool theToDraw = true) { myToAskNextFrame = theToDraw; }
514
515   //! Return if panning anchor point has been defined.
516   bool hasPanningAnchorPoint() const { return !Precision::IsInfinite (myPanPnt3d.X()); }
517
518   //! Return active panning anchor point.
519   const gp_Pnt& panningAnchorPoint() const { return myPanPnt3d; }
520
521   //! Set active panning anchor point.
522   void setPanningAnchorPoint (const gp_Pnt& thePnt) { myPanPnt3d = thePnt; }
523
524   //! Handle panning event myGL.Panning.
525   Standard_EXPORT virtual void handlePanning (const Handle(V3d_View)& theView);
526
527   //! Handle Z rotation event myGL.ZRotate.
528   Standard_EXPORT virtual void handleZRotate (const Handle(V3d_View)& theView);
529
530   //! Return minimal camera distance for zoom operation.
531   double MinZoomDistance() const { return myMinCamDistance; }
532
533   //! Set minimal camera distance for zoom operation.
534   void SetMinZoomDistance (double theDist) { myMinCamDistance = theDist; }
535
536   //! Handle zoom event myGL.ZoomActions.
537   //! This method is expected to be called from rendering thread.
538   Standard_EXPORT virtual void handleZoom (const Handle(V3d_View)& theView,
539                                            const Aspect_ScrollDelta& theParams,
540                                            const gp_Pnt* thePnt);
541
542   //! Handle ZScroll event myGL.ZoomActions.
543   //! This method is expected to be called from rendering thread.
544   Standard_EXPORT virtual void handleZFocusScroll (const Handle(V3d_View)& theView,
545                                                    const Aspect_ScrollDelta& theParams);
546
547   //! Handle orbital rotation events myGL.OrbitRotation.
548   //! @param theView view to modify
549   //! @param thePnt 3D point to rotate around
550   //! @param theToLockZUp amend camera to exclude roll angle (put camera Up vector to plane containing global Z and view direction)
551   Standard_EXPORT virtual void handleOrbitRotation (const Handle(V3d_View)& theView,
552                                                     const gp_Pnt& thePnt,
553                                                     bool theToLockZUp);
554
555   //! Handle view direction rotation events myGL.ViewRotation.
556   //! This method is expected to be called from rendering thread.
557   //! @param theView       camera to modify
558   //! @param theYawExtra   extra yaw increment
559   //! @param thePitchExtra extra pitch increment
560   //! @param theRoll       roll value
561   //! @param theToRestartOnIncrement flag indicating flight mode
562   Standard_EXPORT virtual void handleViewRotation (const Handle(V3d_View)& theView,
563                                                    double theYawExtra,
564                                                    double thePitchExtra,
565                                                    double theRoll,
566                                                    bool theToRestartOnIncrement);
567
568   //! Handle view redraw.
569   //! This method is expected to be called from rendering thread.
570   Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
571                                                  const Handle(V3d_View)& theView);
572
573 public:
574
575   //! Perform XR input.
576   //! This method is expected to be called from rendering thread.
577   Standard_EXPORT virtual void handleXRInput (const Handle(AIS_InteractiveContext)& theCtx,
578                                               const Handle(V3d_View)& theView,
579                                               const AIS_WalkDelta& theWalk);
580
581   //! Handle trackpad view turn action.
582   Standard_EXPORT virtual void handleXRTurnPad (const Handle(AIS_InteractiveContext)& theCtx,
583                                                 const Handle(V3d_View)& theView);
584
585   //! Handle trackpad teleportation action.
586   Standard_EXPORT virtual void handleXRTeleport (const Handle(AIS_InteractiveContext)& theCtx,
587                                                  const Handle(V3d_View)& theView);
588
589   //! Handle picking on trigger click.
590   Standard_EXPORT virtual void handleXRPicking (const Handle(AIS_InteractiveContext)& theCtx,
591                                                 const Handle(V3d_View)& theView);
592
593   //! Perform dynamic highlighting for active hand.
594   Standard_EXPORT virtual void handleXRHighlight (const Handle(AIS_InteractiveContext)& theCtx,
595                                                   const Handle(V3d_View)& theView);
596
597   //! Display auxiliary XR presentations.
598   Standard_EXPORT virtual void handleXRPresentations (const Handle(AIS_InteractiveContext)& theCtx,
599                                                       const Handle(V3d_View)& theView);
600
601   //! Perform picking with/without dynamic highlighting for XR pose.
602   Standard_EXPORT virtual Standard_Integer handleXRMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
603                                                            const Handle(V3d_View)& theView,
604                                                            const gp_Trsf& thePose,
605                                                            const Standard_Boolean theToHighlight);
606
607 protected:
608
609   //! Flush buffers.
610   Standard_EXPORT virtual void flushBuffers (const Handle(AIS_InteractiveContext)& theCtx,
611                                              const Handle(V3d_View)& theView);
612
613   //! Flush touch gestures.
614   Standard_EXPORT virtual void flushGestures (const Handle(AIS_InteractiveContext)& theCtx,
615                                               const Handle(V3d_View)& theView);
616
617   //! Return current and previously fetched event times.
618   //! This callback is intended to compute delta between sequentially processed events.
619   //! @param thePrevTime [out] events time fetched previous time by this method
620   //! @param theCurrTime [out] actual events time
621   void updateEventsTime (double& thePrevTime,
622                          double& theCurrTime)
623   {
624     thePrevTime = myLastEventsTime;
625     myLastEventsTime = EventTime();
626     theCurrTime = myLastEventsTime;
627   }
628
629   //! Perform selection via mouse click.
630   //! This method is expected to be called from rendering thread.
631   Standard_EXPORT virtual void handleSelectionPick (const Handle(AIS_InteractiveContext)& theCtx,
632                                                     const Handle(V3d_View)& theView);
633
634   //! Perform dynamic highlight on mouse move.
635   //! This method is expected to be called from rendering thread.
636   Standard_EXPORT virtual void handleDynamicHighlight (const Handle(AIS_InteractiveContext)& theCtx,
637                                                        const Handle(V3d_View)& theView);
638
639   //! Perform rubber-band selection.
640   //! This method is expected to be called from rendering thread.
641   Standard_EXPORT virtual void handleSelectionPoly (const Handle(AIS_InteractiveContext)& theCtx,
642                                                     const Handle(V3d_View)& theView);
643
644   //! Lazy AIS_InteractiveContext::MoveTo() with myPrevMoveTo check.
645   Standard_EXPORT virtual void contextLazyMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
646                                                   const Handle(V3d_View)& theView,
647                                                   const Graphic3d_Vec2i& thePnt);
648
649 protected:
650
651   AIS_ViewInputBuffer myUI;                       //!< buffer for UI thread
652   AIS_ViewInputBuffer myGL;                       //!< buffer for rendering thread
653
654   OSD_Timer           myEventTimer;               //!< timer for timestamping events
655   Standard_Real       myLastEventsTime;           //!< last fetched events timer value for computing delta/progress
656   Standard_Boolean    myToAskNextFrame;           //!< flag indicating that another frame should be drawn right after this one
657
658   Standard_Real       myMinCamDistance;           //!< minimal camera distance for zoom operation
659   AIS_RotationMode    myRotationMode;             //!< rotation mode
660   AIS_NavigationMode  myNavigationMode;           //!< navigation mode (orbit rotation / first person)
661   Standard_ShortReal  myMouseAccel;               //!< mouse input acceleration ratio in First Person mode
662   Standard_ShortReal  myOrbitAccel;               //!< Orbit rotation acceleration ratio
663   Standard_Boolean    myToShowPanAnchorPoint;     //!< option displaying panning  anchor point
664   Standard_Boolean    myToShowRotateCenter;       //!< option displaying rotation center point
665   Standard_Boolean    myToLockOrbitZUp;           //!< force camera up orientation within AIS_NavigationMode_Orbit rotation mode
666   Standard_Boolean    myToInvertPitch;            //!< flag inverting pitch direction while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown
667   Standard_Boolean    myToAllowTouchZRotation;    //!< enable z-rotation two-touches gesture; FALSE by default
668   Standard_Boolean    myToAllowRotation;          //!< enable rotation; TRUE by default
669   Standard_Boolean    myToAllowPanning;           //!< enable panning; TRUE by default
670   Standard_Boolean    myToAllowZooming;           //!< enable zooming; TRUE by default
671   Standard_Boolean    myToAllowZFocus;            //!< enable ZFocus change; TRUE by default
672   Standard_Boolean    myToAllowHighlight;         //!< enable dynamic highlight on mouse move; TRUE by default
673   Standard_Boolean    myToAllowDragging;          //!< enable dragging object; TRUE by default
674   Standard_Boolean    myToStickToRayOnZoom;       //!< project picked point to ray while zooming at point, TRUE by default
675   Standard_Boolean    myToStickToRayOnRotation;   //!< project picked point to ray while rotating around point; TRUE by default
676
677   Standard_ShortReal  myWalkSpeedAbsolute;        //!< normal walking speed, in m/s; 1.5 by default
678   Standard_ShortReal  myWalkSpeedRelative;        //!< walking speed relative to scene bounding box; 0.1 by default
679   Standard_ShortReal  myThrustSpeed;              //!< active thrust value
680   Standard_Boolean    myHasThrust;                //!< flag indicating active thrust
681
682   Handle(AIS_AnimationCamera) myViewAnimation;    //!< view animation
683   Handle(AIS_RubberBand) myRubberBand;            //!< Rubber-band presentation
684   Handle(AIS_InteractiveObject) myDragObject;     //!< currently dragged object
685   Graphic3d_Vec2i     myPrevMoveTo;               //!< previous position of MoveTo event in 3D viewer
686   Standard_Boolean    myHasHlrOnBeforeRotation;   //!< flag for restoring Computed mode after rotation
687
688 protected: //! @name XR input variables
689
690   NCollection_Array1<Handle(AIS_XRTrackedDevice)> myXRPrsDevices; //!< array of XR tracked devices presentations
691   Handle(Graphic3d_Camera)   myXRCameraTmp;       //!< temporary camera
692   Quantity_Color             myXRLaserTeleColor;  //!< color of teleport laser
693   Quantity_Color             myXRLaserPickColor;  //!< color of picking  laser
694   Aspect_XRTrackedDeviceRole myXRLastTeleportHand;//!< active hand for teleport
695   Aspect_XRTrackedDeviceRole myXRLastPickingHand; //!< active hand for picking objects
696   Aspect_XRHapticActionData  myXRTeleportHaptic;  //!< vibration on picking teleport destination
697   Aspect_XRHapticActionData  myXRPickingHaptic;   //!< vibration on dynamic highlighting
698   Aspect_XRHapticActionData  myXRSelectHaptic;    //!< vibration on selection
699   Standard_Real       myXRLastPickDepthLeft;      //!< last picking depth for left  hand
700   Standard_Real       myXRLastPickDepthRight;     //!< last picking depth for right hand
701   Standard_Real       myXRTurnAngle;              //!< discrete turn angle for XR trackpad
702   Standard_Boolean    myToDisplayXRAuxDevices;    //!< flag to display auxiliary tracked XR devices
703   Standard_Boolean    myToDisplayXRHands;         //!< flag to display XR hands
704
705 protected: //! @name keyboard input variables
706
707   Aspect_VKeySet      myKeys;                     //!< keyboard state
708
709 protected: //! @name mouse input variables
710
711   Standard_Real       myMouseClickThreshold;      //!< mouse click threshold in pixels; 3 by default
712   Standard_Real       myMouseDoubleClickInt;      //!< double click interval in seconds; 0.4 by default
713   Standard_ShortReal  myScrollZoomRatio;          //!< distance ratio for mapping mouse scroll event to zoom; 15.0 by default
714
715   AIS_MouseGestureMap myMouseGestureMap;          //!< map defining mouse gestures
716   AIS_MouseGesture    myMouseActiveGesture;       //!< initiated mouse gesture (by pressing mouse button)
717   Standard_Boolean    myMouseActiveIdleRotation;  //!< flag indicating view idle rotation state
718   Graphic3d_Vec2i     myMousePositionLast;        //!< last mouse position
719   Graphic3d_Vec2i     myMousePressPoint;          //!< mouse position where active gesture was been initiated
720   Graphic3d_Vec2i     myMouseProgressPoint;       //!< gesture progress
721   OSD_Timer           myMouseClickTimer;          //!< timer for handling double-click event
722   Standard_Integer    myMouseClickCounter;        //!< counter for handling double-click event
723   Aspect_VKeyMouse    myMousePressed;             //!< active mouse buttons
724   Aspect_VKeyFlags    myMouseModifiers;           //!< active key modifiers passed with last mouse event
725   Standard_Integer    myMouseSingleButton;        //!< index of mouse button pressed alone (>0)
726   Standard_Boolean    myMouseStopDragOnUnclick;   //!< queue stop dragging even with at next mouse unclick
727
728 protected: //! @name multi-touch input variables
729
730   Standard_ShortReal  myTouchToleranceScale;      //!< tolerance scale factor; 1.0 by default
731   Standard_ShortReal  myTouchRotationThresholdPx; //!< threshold for starting one-touch rotation     gesture in pixels;  6 by default
732   Standard_ShortReal  myTouchZRotationThreshold;  //!< threshold for starting two-touch Z-rotation   gesture in radians; 2 degrees by default
733   Standard_ShortReal  myTouchPanThresholdPx;      //!< threshold for starting two-touch panning      gesture in pixels;  4 by default
734   Standard_ShortReal  myTouchZoomThresholdPx;     //!< threshold for starting two-touch zoom (pitch) gesture in pixels;  6 by default
735   Standard_ShortReal  myTouchZoomRatio;           //!< distance ratio for mapping two-touch zoom (pitch) gesture from pixels to zoom; 0.13 by default
736
737   Aspect_TouchMap     myTouchPoints;              //!< map of active touches
738   Graphic3d_Vec2d     myStartPanCoord;            //!< touch coordinates at the moment of starting panning  gesture
739   Graphic3d_Vec2d     myStartRotCoord;            //!< touch coordinates at the moment of starting rotating gesture
740   Standard_Integer    myNbTouchesLast;            //!< number of touches within previous gesture flush to track gesture changes
741   Standard_Boolean    myUpdateStartPointPan;      //!< flag indicating that new anchor  point should be picked for starting panning    gesture
742   Standard_Boolean    myUpdateStartPointRot;      //!< flag indicating that new gravity point should be picked for starting rotation   gesture
743   Standard_Boolean    myUpdateStartPointZRot;     //!< flag indicating that new gravity point should be picked for starting Z-rotation gesture
744
745 protected: //! @name rotation/panning transient state variables
746
747   Handle(AIS_Point)   myAnchorPointPrs1;          //!< anchor point presentation (Graphic3d_ZLayerId_Top)
748   Handle(AIS_Point)   myAnchorPointPrs2;          //!< anchor point presentation (Graphic3d_ZLayerId_Topmost)
749   gp_Pnt              myPanPnt3d;                 //!< active panning anchor point
750   gp_Pnt              myRotatePnt3d;              //!< active rotation center of gravity
751   gp_Dir              myCamStartOpUp;             //!< camera Up    direction at the beginning of rotation
752   gp_Dir              myCamStartOpDir;            //!< camera View  direction at the beginning of rotation
753   gp_Pnt              myCamStartOpEye;            //!< camera Eye    position at the beginning of rotation
754   gp_Pnt              myCamStartOpCenter;         //!< camera Center position at the beginning of rotation
755   gp_Vec              myCamStartOpToCenter;       //!< vector from rotation gravity point to camera Center at the beginning of rotation
756   gp_Vec              myCamStartOpToEye;          //!< vector from rotation gravity point to camera Eye    at the beginning of rotation
757   Graphic3d_Vec3d     myRotateStartYawPitchRoll;  //!< camera yaw pitch roll at the beginning of rotation
758
759 };
760
761 #endif // _AIS_ViewController_HeaderFile