0029837: Visualization, Graphic3d_Camera - Fit All operation works incorrectly on...
[occt.git] / src / Graphic3d / Graphic3d_Camera.hxx
1 // Created on: 2013-05-29
2 // Created by: Anton POLETAEV
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _Graphic3d_Camera_HeaderFile
17 #define _Graphic3d_Camera_HeaderFile
18
19 #include <Graphic3d_CameraTile.hxx>
20 #include <Graphic3d_Mat4d.hxx>
21 #include <Graphic3d_Mat4.hxx>
22 #include <Graphic3d_Vec3.hxx>
23 #include <Graphic3d_WorldViewProjState.hxx>
24 #include <NCollection_Lerp.hxx>
25 #include <NCollection_Array1.hxx>
26
27 #include <gp_Dir.hxx>
28 #include <gp_Pnt.hxx>
29
30 #include <Standard_Macro.hxx>
31 #include <Standard_TypeDef.hxx>
32
33 #include <Bnd_Box.hxx>
34
35 //! Forward declaration
36 class Graphic3d_WorldViewProjState;
37
38 //! Camera class provides object-oriented approach to setting up projection
39 //! and orientation properties of 3D view.
40 class Graphic3d_Camera : public Standard_Transient
41 {
42 private:
43
44   //! Template container for cached matrices or Real/ShortReal types.
45   template<typename Elem_t>
46   struct TransformMatrices
47   {
48
49     //! Default constructor.
50     TransformMatrices() : myIsOrientationValid (Standard_False), myIsProjectionValid (Standard_False) {}
51
52     //! Initialize orientation.
53     void InitOrientation()
54     {
55       myIsOrientationValid = Standard_True;
56       Orientation.InitIdentity();
57     }
58
59     //! Initialize projection.
60     void InitProjection()
61     {
62       myIsProjectionValid = Standard_True;
63       MProjection.InitIdentity();
64       LProjection.InitIdentity();
65       RProjection.InitIdentity();
66     }
67
68     //! Invalidate orientation.
69     void ResetOrientation() { myIsOrientationValid = Standard_False; }
70
71     //! Invalidate projection.
72     void ResetProjection()  { myIsProjectionValid  = Standard_False; }
73
74     //! Return true if Orientation was not invalidated.
75     Standard_Boolean IsOrientationValid() const { return myIsOrientationValid; }
76
77     //! Return true if Projection was not invalidated.
78     Standard_Boolean IsProjectionValid()  const { return myIsProjectionValid;  }
79
80   public:
81
82     NCollection_Mat4<Elem_t> Orientation;
83     NCollection_Mat4<Elem_t> MProjection;
84     NCollection_Mat4<Elem_t> LProjection;
85     NCollection_Mat4<Elem_t> RProjection;
86
87   private:
88
89     Standard_Boolean myIsOrientationValid;
90     Standard_Boolean myIsProjectionValid;
91
92   };
93
94 public:
95
96   //! Enumerates supported monographic projections.
97   //! - Projection_Orthographic : orthographic projection.
98   //! - Projection_Perspective  : perspective projection.
99   //! - Projection_Stereo       : stereographic projection.
100   //! - Projection_MonoLeftEye  : mono projection for stereo left eye.
101   //! - Projection_MonoRightEye : mono projection for stereo right eye.
102   enum Projection
103   {
104     Projection_Orthographic,
105     Projection_Perspective,
106     Projection_Stereo,
107     Projection_MonoLeftEye,
108     Projection_MonoRightEye
109   };
110
111   //! Enumerates approaches to define stereographic focus.
112   //! - FocusType_Absolute : focus is specified as absolute value.
113   //! - FocusType_Relative : focus is specified relative to
114   //! (as coefficient of) camera focal length.
115   enum FocusType
116   {
117     FocusType_Absolute,
118     FocusType_Relative
119   };
120
121   //! Enumerates approaches to define Intraocular distance.
122   //! - IODType_Absolute : Intraocular distance is defined as absolute value.
123   //! - IODType_Relative : Intraocular distance is defined relative to
124   //! (as coefficient of) camera focal length.
125   enum IODType
126   {
127     IODType_Absolute,
128     IODType_Relative
129   };
130
131 public:
132
133   //! Default constructor.
134   //! Initializes camera with the following properties:
135   //! Eye (0, 0, -2); Center (0, 0, 0); Up (0, 1, 0);
136   //! Type (Orthographic); FOVy (45); Scale (1000); IsStereo(false);
137   //! ZNear (0.001); ZFar (3000.0); Aspect(1);
138   //! ZFocus(1.0); ZFocusType(Relative); IOD(0.05); IODType(Relative)
139   Standard_EXPORT Graphic3d_Camera();
140
141   //! Copy constructor.
142   //! @param theOther [in] the camera to copy from.
143   Standard_EXPORT Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther);
144
145   //! Initialize mapping related parameters from other camera handle.
146   Standard_EXPORT void CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera);
147
148   //! Initialize orientation related parameters from other camera handle.
149   Standard_EXPORT void CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera);
150
151   //! Copy properties of another camera.
152   //! @param theOther [in] the camera to copy from.
153   Standard_EXPORT void Copy (const Handle(Graphic3d_Camera)& theOther);
154
155 //! @name Public camera properties
156 public:
157
158   //! Get camera look direction.
159   //! @return camera look direction.
160   const gp_Dir& Direction() const { return myDirection; }
161
162   //! Sets camera look direction preserving the current Eye() position.
163   //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction.
164   //! @param theDir [in] the direction.
165   Standard_EXPORT void SetDirectionFromEye (const gp_Dir& theDir);
166
167   //! Sets camera look direction and computes the new Eye position relative to current Center.
168   //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction.
169   //! @param theDir [in] the direction.
170   Standard_EXPORT void SetDirection (const gp_Dir& theDir);
171
172   //! Get camera Up direction vector.
173   //! @return Camera's Up direction vector.
174   const gp_Dir& Up() const { return myUp; }
175
176   //! Sets camera Up direction vector, orthogonal to camera direction.
177   //! WARNING! This method does NOT verify that the new Up vector is orthogonal to the current Direction().
178   //! @param theUp [in] the Up direction vector.
179   //! @sa OrthogonalizeUp().
180   Standard_EXPORT void SetUp (const gp_Dir& theUp);
181
182   //! Orthogonalize up direction vector.
183   Standard_EXPORT void OrthogonalizeUp();
184
185   //! Return a copy of orthogonalized up direction vector.
186   Standard_EXPORT gp_Dir OrthogonalizedUp() const;
187
188   //! Get camera Eye position.
189   //! @return camera eye location.
190   const gp_Pnt& Eye() const { return myEye; }
191
192   //! Sets camera Eye position.
193   //! Unlike SetEye(), this method only changes Eye point and preserves camera direction.
194   //! @param theEye [in] the location of camera's Eye.
195   //! @sa SetEye()
196   Standard_EXPORT void MoveEyeTo (const gp_Pnt& theEye);
197
198   //! Sets camera Eye and Center positions.
199   //! @param theEye    [in] the location of camera's Eye
200   //! @param theCenter [in] the location of camera's Center
201   Standard_EXPORT void SetEyeAndCenter (const gp_Pnt& theEye,
202                                         const gp_Pnt& theCenter);
203
204   //! Sets camera Eye position.
205   //! WARNING! For backward compatibility reasons, this method also changes view direction,
206   //! so that the new direction is computed from new Eye position to old Center position.
207   //! @param theEye [in] the location of camera's Eye.
208   //! @sa MoveEyeTo(), SetEyeAndCenter()
209   Standard_EXPORT void SetEye (const gp_Pnt& theEye);
210
211   //! Get Center of the camera, e.g. the point where camera looks at.
212   //! This point is computed as Eye() translated along Direction() at Distance().
213   //! @return the point where the camera looks at.
214   gp_Pnt Center() const
215   {
216     return myEye.XYZ() + myDirection.XYZ() * myDistance;
217   }
218
219   //! Sets Center of the camera, e.g. the point where camera looks at.
220   //! This methods changes camera direction, so that the new direction is computed
221   //! from current Eye position to specified Center position.
222   //! @param theCenter [in] the point where the camera looks at.
223   Standard_EXPORT void SetCenter (const gp_Pnt& theCenter);
224
225   //! Get distance of Eye from camera Center.
226   //! @return the distance.
227   Standard_Real Distance() const { return myDistance; }
228
229   //! Set distance of Eye from camera Center.
230   //! @param theDistance [in] the distance.
231   Standard_EXPORT void SetDistance (const Standard_Real theDistance);
232
233   //! Get camera scale.
234   //! @return camera scale factor.
235   Standard_EXPORT Standard_Real Scale() const;
236
237   //! Sets camera scale. For orthographic projection the scale factor
238   //! corresponds to parallel scale of view mapping  (i.e. size
239   //! of viewport). For perspective camera scale is converted to
240   //! distance. The scale specifies equal size of the view projection in
241   //! both dimensions assuming that the aspect is 1.0. The projection height
242   //! and width are specified with the scale and correspondingly multiplied
243   //! by the aspect.
244   //! @param theScale [in] the scale factor.
245   Standard_EXPORT void SetScale (const Standard_Real theScale);
246
247   //! Get camera axial scale.
248   //! @return Camera's axial scale.
249   const gp_XYZ& AxialScale() const { return myAxialScale; }
250
251   //! Set camera axial scale.
252   //! @param theAxialScale [in] the axial scale vector.
253   Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale);
254
255   //! Change camera projection type.
256   //! When switching to perspective projection from orthographic one,
257   //! the ZNear and ZFar are reset to default values (0.001, 3000.0)
258   //! if less than 0.0.
259   //! @param theProjectionType [in] the camera projection type.
260   Standard_EXPORT void SetProjectionType (const Projection theProjection);
261
262   //! @return camera projection type.
263   Projection ProjectionType() const
264   {
265     return myProjType;
266   }
267
268   //! Check that the camera projection is orthographic.
269   //! @return boolean flag that indicates whether the camera's projection is
270   //! orthographic or not.
271   Standard_Boolean IsOrthographic() const
272   {
273     return (myProjType == Projection_Orthographic);
274   }
275
276   //! Check whether the camera projection is stereo.
277   //! Please note that stereo rendering is now implemented with support of
278   //! Quad buffering.
279   //! @return boolean flag indicating whether the stereographic L/R projection
280   //! is chosen.
281   Standard_Boolean IsStereo() const
282   {
283     return (myProjType == Projection_Stereo);
284   }
285
286   //! Set Field Of View (FOV) in y axis for perspective projection.
287   //! @param theFOVy [in] the FOV in degrees.
288   Standard_EXPORT void SetFOVy (const Standard_Real theFOVy);
289
290   //! Get Field Of View (FOV) in y axis.
291   //! @return the FOV value in degrees.
292   Standard_Real FOVy() const
293   {
294     return myFOVy;
295   }
296
297   //! Estimate Z-min and Z-max planes of projection volume to match the
298   //! displayed objects. The methods ensures that view volume will
299   //! be close by depth range to the displayed objects. Fitting assumes that
300   //! for orthogonal projection the view volume contains the displayed objects
301   //! completely. For zoomed perspective view, the view volume is adjusted such
302   //! that it contains the objects or their parts, located in front of the camera.
303   //! @param theScaleFactor [in] the scale factor for Z-range.
304   //!   The range between Z-min, Z-max projection volume planes
305   //!   evaluated by z fitting method will be scaled using this coefficient.
306   //!   Program error exception is thrown if negative or zero value is passed.
307   //! @param theMinMax [in] applicative min max boundaries.
308   //! @param theScaleFactor [in] real graphical boundaries (not accounting infinite flag).
309   Standard_EXPORT bool ZFitAll (const Standard_Real theScaleFactor,
310                                 const Bnd_Box&      theMinMax,
311                                 const Bnd_Box&      theGraphicBB,
312                                 Standard_Real&      theZNear,
313                                 Standard_Real&      theZFar) const;
314
315   //! Change Z-min and Z-max planes of projection volume to match the displayed objects.
316   void ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB)
317   {
318     Standard_Real aZNear = 0.0, aZFar = 1.0;
319     ZFitAll (theScaleFactor, theMinMax, theGraphicBB, aZNear, aZFar);
320     SetZRange (aZNear, aZFar);
321   }
322
323   //! Change the Near and Far Z-clipping plane positions.
324   //! For orthographic projection, theZNear, theZFar can be negative or positive.
325   //! For perspective projection, only positive values are allowed.
326   //! Program error exception is raised if non-positive values are
327   //! specified for perspective projection or theZNear >= theZFar.
328   //! @param theZNear [in] the distance of the plane from the Eye.
329   //! @param theZFar [in] the distance of the plane from the Eye.
330   Standard_EXPORT void SetZRange (const Standard_Real theZNear, const Standard_Real theZFar);
331
332   //! Get the Near Z-clipping plane position.
333   //! @return the distance of the plane from the Eye.
334   Standard_Real ZNear() const
335   {
336     return myZNear;
337   }
338
339   //! Get the Far Z-clipping plane position.
340   //! @return the distance of the plane from the Eye.
341   Standard_Real ZFar() const
342   {
343     return myZFar;
344   }
345
346   //! Changes width / height display ratio.
347   //! @param theAspect [in] the display ratio.
348   Standard_EXPORT void SetAspect (const Standard_Real theAspect);
349
350   //! Get camera display ratio.
351   //! @return display ratio.
352   Standard_Real Aspect() const
353   {
354     return myAspect;
355   }
356
357   //! Sets stereographic focus distance.
358   //! @param theType [in] the focus definition type. Focus can be defined
359   //! as absolute value or relatively to (as coefficient of) coefficient of
360   //! camera focal length.
361   //! @param theZFocus [in] the focus absolute value or coefficient depending
362   //! on the passed definition type.
363   Standard_EXPORT void SetZFocus (const FocusType theType, const Standard_Real theZFocus);
364
365   //! Get stereographic focus value.
366   //! @return absolute or relative stereographic focus value
367   //! depending on its definition type.
368   Standard_Real ZFocus() const
369   {
370     return myZFocus;
371   }
372
373   //! Get stereographic focus definition type.
374   //! @return definition type used for stereographic focus.
375   FocusType ZFocusType() const
376   {
377     return myZFocusType;
378   }
379
380   //! Sets Intraocular distance.
381   //! @param theType [in] the IOD definition type. IOD can be defined as
382   //! absolute value or relatively to (as coefficient of) camera focal length.
383   //! @param theIOD [in] the Intraocular distance.
384   Standard_EXPORT void SetIOD (const IODType theType, const Standard_Real theIOD);
385
386   //! Get Intraocular distance value.
387   //! @return absolute or relative IOD value depending on its definition type.
388   Standard_Real IOD() const
389   {
390     return myIOD;
391   }
392
393   //! Get Intraocular distance definition type.
394   //! @return definition type used for Intraocular distance.
395   IODType GetIODType() const
396   {
397     return myIODType;
398   }
399
400   //! Get current tile.
401   const Graphic3d_CameraTile& Tile() const { return myTile; }
402
403   //! Sets the Tile defining the drawing sub-area within View.
404   //! Note that tile defining a region outside the view boundaries is also valid - use method Graphic3d_CameraTile::Cropped() to assign a cropped copy.
405   //! @param theTile tile definition
406   Standard_EXPORT void SetTile (const Graphic3d_CameraTile& theTile);
407
408 //! @name Basic camera operations
409 public:
410
411   //! Transform orientation components of the camera:
412   //! Eye, Up and Center points.
413   //! @param theTrsf [in] the transformation to apply.
414   Standard_EXPORT void Transform (const gp_Trsf& theTrsf);
415
416   //! Calculate view plane size at center (target) point
417   //! and distance between ZFar and ZNear planes.
418   //! @return values in form of gp_Pnt (Width, Height, Depth).
419   gp_XYZ ViewDimensions() const
420   {
421     return ViewDimensions (Distance());
422   }
423
424   //! Calculate view plane size at center point with specified Z offset
425   //! and distance between ZFar and ZNear planes.
426   //! @param theZValue [in] the distance from the eye in eye-to-center direction
427   //! @return values in form of gp_Pnt (Width, Height, Depth).
428   Standard_EXPORT gp_XYZ ViewDimensions (const Standard_Real theZValue) const;
429
430   //! Calculate WCS frustum planes for the camera projection volume.
431   //! Frustum is a convex volume determined by six planes directing
432   //! inwards.
433   //! The frustum planes are usually used as inputs for camera algorithms.
434   //! Thus, if any changes to projection matrix calculation are necessary,
435   //! the frustum planes calculation should be also touched.
436   //! @param theLeft [out] the frustum plane for left side of view.
437   //! @param theRight [out] the frustum plane for right side of view.
438   //! @param theBottom [out] the frustum plane for bottom side of view.
439   //! @param theTop [out] the frustum plane for top side of view.
440   //! @param theNear [out] the frustum plane for near side of view.
441   //! @param theFar [out] the frustum plane for far side of view.
442   Standard_EXPORT void Frustum (gp_Pln& theLeft,
443                                 gp_Pln& theRight,
444                                 gp_Pln& theBottom,
445                                 gp_Pln& theTop,
446                                 gp_Pln& theNear,
447                                 gp_Pln& theFar) const;
448
449 //! @name Projection methods
450 public:
451
452   //! Project point from world coordinate space to
453   //! normalized device coordinates (mapping).
454   //! @param thePnt [in] the 3D point in WCS.
455   //! @return mapped point in NDC.
456   Standard_EXPORT gp_Pnt Project (const gp_Pnt& thePnt) const;
457
458   //! Unproject point from normalized device coordinates
459   //! to world coordinate space.
460   //! @param thePnt [in] the NDC point.
461   //! @return 3D point in WCS.
462   Standard_EXPORT gp_Pnt UnProject (const gp_Pnt& thePnt) const;
463
464   //! Convert point from view coordinate space to
465   //! projection coordinate space.
466   //! @param thePnt [in] the point in VCS.
467   //! @return point in NDC.
468   Standard_EXPORT gp_Pnt ConvertView2Proj (const gp_Pnt& thePnt) const;
469
470   //! Convert point from projection coordinate space
471   //! to view coordinate space.
472   //! @param thePnt [in] the point in NDC.
473   //! @return point in VCS.
474   Standard_EXPORT gp_Pnt ConvertProj2View (const gp_Pnt& thePnt) const;
475
476   //! Convert point from world coordinate space to
477   //! view coordinate space.
478   //! @param thePnt [in] the 3D point in WCS.
479   //! @return point in VCS.
480   Standard_EXPORT gp_Pnt ConvertWorld2View (const gp_Pnt& thePnt) const;
481
482   //! Convert point from view coordinate space to
483   //! world coordinates.
484   //! @param thePnt [in] the 3D point in VCS.
485   //! @return point in WCS.
486   Standard_EXPORT gp_Pnt ConvertView2World (const gp_Pnt& thePnt) const;
487
488 //! @name Camera modification state
489 public:
490
491   //! @return projection modification state of the camera.
492   const Graphic3d_WorldViewProjState& WorldViewProjState() const
493   {
494     return myWorldViewProjState;
495   }
496
497
498   //! Returns modification state of camera projection matrix
499   Standard_Size ProjectionState() const
500   {
501     return myWorldViewProjState.ProjectionState();
502   }
503
504   //! Returns modification state of camera world view transformation matrix.
505   Standard_Size WorldViewState() const
506   {
507     return myWorldViewProjState.WorldViewState();
508   }
509
510 //! @name Lazily-computed orientation and projection matrices derived from camera parameters
511 public:
512
513   //! Get orientation matrix.
514   //! @return camera orientation matrix.
515   Standard_EXPORT const Graphic3d_Mat4d& OrientationMatrix() const;
516
517   //! Get orientation matrix of Standard_ShortReal precision.
518   //! @return camera orientation matrix.
519   Standard_EXPORT const Graphic3d_Mat4& OrientationMatrixF() const;
520
521   //! Get monographic or middle point projection matrix used for monographic
522   //! rendering and for point projection / unprojection.
523   //! @return monographic projection matrix.
524   Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
525
526   //! Get monographic or middle point projection matrix of Standard_ShortReal precision used for monographic
527   //! rendering and for point projection / unprojection.
528   //! @return monographic projection matrix.
529   Standard_EXPORT const Graphic3d_Mat4& ProjectionMatrixF() const;
530
531   //! @return stereographic matrix computed for left eye. Please note
532   //! that this method is used for rendering for <i>Projection_Stereo</i>.
533   Standard_EXPORT const Graphic3d_Mat4d& ProjectionStereoLeft() const;
534
535   //! @return stereographic matrix of Standard_ShortReal precision computed for left eye.
536   //! Please note that this method is used for rendering for <i>Projection_Stereo</i>.
537   Standard_EXPORT const Graphic3d_Mat4& ProjectionStereoLeftF() const;
538
539   //! @return stereographic matrix computed for right eye. Please note
540   //! that this method is used for rendering for <i>Projection_Stereo</i>.
541   Standard_EXPORT const Graphic3d_Mat4d& ProjectionStereoRight() const;
542
543   //! @return stereographic matrix of Standard_ShortReal precision computed for right eye.
544   //! Please note that this method is used for rendering for <i>Projection_Stereo</i>.
545   Standard_EXPORT const Graphic3d_Mat4& ProjectionStereoRightF() const;
546
547   //! Invalidate state of projection matrix.
548   //! The matrix will be updated on request.
549   Standard_EXPORT void InvalidateProjection();
550
551   //! Invalidate orientation matrix.
552   //! The matrix will be updated on request.
553   Standard_EXPORT void InvalidateOrientation();
554
555 //! @name Managing projection and orientation cache
556 private:
557
558   //! Compute projection matrices.
559   //! @param theMatrices [in] the matrices data container.
560   template <typename Elem_t>
561   Standard_EXPORT
562     TransformMatrices<Elem_t>& UpdateProjection (TransformMatrices<Elem_t>& theMatrices) const;
563
564   //! Compute orientation matrix.
565   //! @param theMatrices [in] the matrices data container.
566   template <typename Elem_t>
567   Standard_EXPORT
568     TransformMatrices<Elem_t>& UpdateOrientation (TransformMatrices<Elem_t>& theMatrices) const;
569
570 private:
571
572   //! Compose orthographic projection matrix for
573   //! the passed camera volume mapping.
574   //! @param theLeft [in] the left mapping (clipping) coordinate.
575   //! @param theRight [in] the right mapping (clipping) coordinate.
576   //! @param theBottom [in] the bottom mapping (clipping) coordinate.
577   //! @param theTop [in] the top mapping (clipping) coordinate.
578   //! @param theNear [in] the near mapping (clipping) coordinate.
579   //! @param theFar [in] the far mapping (clipping) coordinate.
580   //! @param theOutMx [out] the projection matrix.
581   template <typename Elem_t>
582   static void 
583     OrthoProj (const Elem_t              theLeft,
584                const Elem_t              theRight,
585                const Elem_t              theBottom,
586                const Elem_t              theTop,
587                const Elem_t              theNear,
588                const Elem_t              theFar,
589                NCollection_Mat4<Elem_t>& theOutMx);
590
591   //! Compose perspective projection matrix for
592   //! the passed camera volume mapping.
593   //! @param theLeft [in] the left mapping (clipping) coordinate.
594   //! @param theRight [in] the right mapping (clipping) coordinate.
595   //! @param theBottom [in] the bottom mapping (clipping) coordinate.
596   //! @param theTop [in] the top mapping (clipping) coordinate.
597   //! @param theNear [in] the near mapping (clipping) coordinate.
598   //! @param theFar [in] the far mapping (clipping) coordinate.
599   //! @param theOutMx [out] the projection matrix.
600   template <typename Elem_t>
601   static void
602     PerspectiveProj (const Elem_t              theLeft,
603                      const Elem_t              theRight,
604                      const Elem_t              theBottom,
605                      const Elem_t              theTop,
606                      const Elem_t              theNear,
607                      const Elem_t              theFar,
608                      NCollection_Mat4<Elem_t>& theOutMx);
609
610   //! Compose projection matrix for L/R stereo eyes.
611   //! @param theLeft [in] the left mapping (clipping) coordinate.
612   //! @param theRight [in] the right mapping (clipping) coordinate.
613   //! @param theBottom [in] the bottom mapping (clipping) coordinate.
614   //! @param theTop [in] the top mapping (clipping) coordinate.
615   //! @param theNear [in] the near mapping (clipping) coordinate.
616   //! @param theFar [in] the far mapping (clipping) coordinate.
617   //! @param theIOD [in] the Intraocular distance.
618   //! @param theZFocus [in] the z coordinate of off-axis
619   //! projection plane with zero parallax.
620   //! @param theIsLeft [in] boolean flag to choose between L/R eyes.
621   //! @param theOutMx [out] the projection matrix.
622   template <typename Elem_t>
623   static void
624     StereoEyeProj (const Elem_t              theLeft,
625                    const Elem_t              theRight,
626                    const Elem_t              theBottom,
627                    const Elem_t              theTop,
628                    const Elem_t              theNear,
629                    const Elem_t              theFar,
630                    const Elem_t              theIOD,
631                    const Elem_t              theZFocus,
632                    const Standard_Boolean    theIsLeft,
633                    NCollection_Mat4<Elem_t>& theOutMx);
634
635   //! Construct "look at" orientation transformation.
636   //! Reference point differs for perspective and ortho modes 
637   //! (made for compatibility, to be improved..).
638   //! @param theEye [in] the eye coordinates in 3D space.
639   //! @param theFwdDir [in] view direction
640   //! @param theUpDir [in] the up direction vector.
641   //! @param theAxialScale [in] the axial scale vector.
642   //! @param theOutMx [in/out] the orientation matrix.
643   template <typename Elem_t>
644   static void
645     LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
646                      const NCollection_Vec3<Elem_t>& theFwdDir,
647                      const NCollection_Vec3<Elem_t>& theUpDir,
648                      const NCollection_Vec3<Elem_t>& theAxialScale,
649                      NCollection_Mat4<Elem_t>&       theOutMx);
650
651 public:
652
653   //! Enumerates vertices of view volume.
654   enum
655   {
656     FrustumVert_LeftBottomNear,
657     FrustumVert_LeftBottomFar,
658     FrustumVert_LeftTopNear,
659     FrustumVert_LeftTopFar,
660     FrustumVert_RightBottomNear,
661     FrustumVert_RightBottomFar,
662     FrustumVert_RightTopNear,
663     FrustumVert_RightTopFar,
664     FrustumVerticesNB
665   };
666
667   //! Fill array of current view frustum corners.
668   //! The size of this array is equal to FrustumVerticesNB.
669   //! The order of vertices is as defined in FrustumVert_* enumeration.
670   Standard_EXPORT void FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePoints) const;
671
672 private:
673
674   gp_Dir        myUp;       //!< Camera up direction vector
675   gp_Dir        myDirection;//!< Camera view direction (from eye)
676   gp_Pnt        myEye;      //!< Camera eye position
677   Standard_Real myDistance; //!< distance from Eye to Center
678
679   gp_XYZ myAxialScale; //!< World axial scale.
680
681   Projection    myProjType; //!< Projection type used for rendering.
682   Standard_Real myFOVy;     //!< Field Of View in y axis.
683   Standard_Real myFOVyTan;  //!< Field Of View as Tan(DTR_HALF * myFOVy)
684   Standard_Real myZNear;    //!< Distance to near clipping plane.
685   Standard_Real myZFar;     //!< Distance to far clipping plane.
686   Standard_Real myAspect;   //!< Width to height display ratio.
687
688   Standard_Real myScale;      //!< Specifies parallel scale for orthographic projection.
689   Standard_Real myZFocus;     //!< Stereographic focus value.
690   FocusType     myZFocusType; //!< Stereographic focus definition type.
691
692   Standard_Real myIOD;     //!< Intraocular distance value.
693   IODType       myIODType; //!< Intraocular distance definition type.
694
695   Graphic3d_CameraTile myTile;//!< Tile defining sub-area for drawing
696
697   mutable TransformMatrices<Standard_Real>      myMatricesD;
698   mutable TransformMatrices<Standard_ShortReal> myMatricesF;
699
700   mutable Graphic3d_WorldViewProjState myWorldViewProjState;
701
702 public:
703
704   DEFINE_STANDARD_RTTIEXT(Graphic3d_Camera,Standard_Transient)
705 };
706
707 DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
708
709 //! Linear interpolation tool for camera orientation and position.
710 //! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently.
711 //!
712 //! Eye/Center interpolation is performed through defining an anchor point in-between Center and Eye.
713 //! The anchor position is defined as point near to the camera point which has smaller translation part.
714 //! The main idea is to keep the distance between Center and Eye
715 //! (which will change if Center and Eye translation will be interpolated independently).
716 //! E.g.:
717 //!  - When both Center and Eye are moved at the same vector -> both will be just translated by straight line
718 //!  - When Center is not moved -> camera Eye    will move around Center through arc
719 //!  - When Eye    is not moved -> camera Center will move around Eye    through arc
720 //!  - When both Center and Eye are move by different vectors -> transformation will be something in between,
721 //!    and will try interpolate linearly the distance between Center and Eye.
722 //!
723 //! This transformation might be not in line with user expectations.
724 //! In this case, application might define intermediate camera positions for interpolation
725 //! or implement own interpolation logic.
726 template<>
727 Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
728                                                                               Handle(Graphic3d_Camera)& theResult) const;
729 typedef NCollection_Lerp<Handle(Graphic3d_Camera)> Graphic3d_CameraLerp;
730
731 #endif