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