0031511: Point Cloud Rendering, Volume Rendering - reuse Graphic3d_CullingTool
[occt.git] / src / Graphic3d / Graphic3d_Camera.hxx
index 0450205..f4b5246 100644 (file)
 #ifndef _Graphic3d_Camera_HeaderFile
 #define _Graphic3d_Camera_HeaderFile
 
+#include <Graphic3d_CameraTile.hxx>
 #include <Graphic3d_Mat4d.hxx>
 #include <Graphic3d_Mat4.hxx>
 #include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_WorldViewProjState.hxx>
-
-#include <NCollection_Handle.hxx>
+#include <NCollection_Lerp.hxx>
+#include <NCollection_Array1.hxx>
 
 #include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
@@ -44,46 +45,50 @@ private:
   template<typename Elem_t>
   struct TransformMatrices
   {
+
+    //! Default constructor.
+    TransformMatrices() : myIsOrientationValid (Standard_False), myIsProjectionValid (Standard_False) {}
+
+    //! Initialize orientation.
     void InitOrientation()
     {
-      Orientation = new NCollection_Mat4<Elem_t>();
+      myIsOrientationValid = Standard_True;
+      Orientation.InitIdentity();
     }
 
+    //! Initialize projection.
     void InitProjection()
     {
-      MProjection = new NCollection_Mat4<Elem_t>();
-      LProjection = new NCollection_Mat4<Elem_t>();
-      RProjection = new NCollection_Mat4<Elem_t>();
+      myIsProjectionValid = Standard_True;
+      MProjection.InitIdentity();
+      LProjection.InitIdentity();
+      RProjection.InitIdentity();
     }
 
-    void ResetOrientation()
-    {
-      Orientation.Nullify();
-    }
+    //! Invalidate orientation.
+    void ResetOrientation() { myIsOrientationValid = Standard_False; }
 
-    void ResetProjection()
-    {
-      MProjection.Nullify();
-      LProjection.Nullify();
-      RProjection.Nullify();
-    }
+    //! Invalidate projection.
+    void ResetProjection()  { myIsProjectionValid  = Standard_False; }
 
-    Standard_Boolean IsOrientationValid()
-    {
-      return !Orientation.IsNull();
-    }
+    //! Return true if Orientation was not invalidated.
+    Standard_Boolean IsOrientationValid() const { return myIsOrientationValid; }
 
-    Standard_Boolean IsProjectionValid()
-    {
-      return !MProjection.IsNull() &&
-             !LProjection.IsNull() &&
-             !RProjection.IsNull();
-    }
+    //! Return true if Projection was not invalidated.
+    Standard_Boolean IsProjectionValid()  const { return myIsProjectionValid;  }
+
+  public:
+
+    NCollection_Mat4<Elem_t> Orientation;
+    NCollection_Mat4<Elem_t> MProjection;
+    NCollection_Mat4<Elem_t> LProjection;
+    NCollection_Mat4<Elem_t> RProjection;
+
+  private:
+
+    Standard_Boolean myIsOrientationValid;
+    Standard_Boolean myIsProjectionValid;
 
-    NCollection_Handle< NCollection_Mat4<Elem_t> > Orientation;
-    NCollection_Handle< NCollection_Mat4<Elem_t> > MProjection;
-    NCollection_Handle< NCollection_Mat4<Elem_t> > LProjection;
-    NCollection_Handle< NCollection_Mat4<Elem_t> > RProjection;
   };
 
 public:
@@ -150,30 +155,28 @@ public:
 //! @name Public camera properties
 public:
 
-  //! Sets camera Eye position.
-  //! @param theEye [in] the location of camera's Eye.
-  Standard_EXPORT void SetEye (const gp_Pnt& theEye);
+  //! Get camera look direction.
+  //! @return camera look direction.
+  const gp_Dir& Direction() const { return myDirection; }
 
-  //! Get camera Eye position.
-  //! @return camera eye location.
-  const gp_Pnt& Eye() const
-  {
-    return myEye;
-  }
+  //! Sets camera look direction preserving the current Eye() position.
+  //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction.
+  //! @param theDir [in] the direction.
+  Standard_EXPORT void SetDirectionFromEye (const gp_Dir& theDir);
 
-  //! Sets Center of the camera.
-  //! @param theCenter [in] the point where the camera looks at.
-  Standard_EXPORT void SetCenter (const gp_Pnt& theCenter);
+  //! Sets camera look direction and computes the new Eye position relative to current Center.
+  //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction.
+  //! @param theDir [in] the direction.
+  Standard_EXPORT void SetDirection (const gp_Dir& theDir);
 
-  //! Get Center of the camera.
-  //! @return the point where the camera looks at.
-  const gp_Pnt& Center() const
-  {
-    return myCenter;
-  }
+  //! Get camera Up direction vector.
+  //! @return Camera's Up direction vector.
+  const gp_Dir& Up() const { return myUp; }
 
   //! Sets camera Up direction vector, orthogonal to camera direction.
+  //! WARNING! This method does NOT verify that the new Up vector is orthogonal to the current Direction().
   //! @param theUp [in] the Up direction vector.
+  //! @sa OrthogonalizeUp().
   Standard_EXPORT void SetUp (const gp_Dir& theUp);
 
   //! Orthogonalize up direction vector.
@@ -182,39 +185,54 @@ public:
   //! Return a copy of orthogonalized up direction vector.
   Standard_EXPORT gp_Dir OrthogonalizedUp() const;
 
-  //! Get camera Up direction vector.
-  //! @return Camera's Up direction vector.
-  const gp_Dir& Up() const
-  {
-    return myUp;
-  }
+  //! Get camera Eye position.
+  //! @return camera eye location.
+  const gp_Pnt& Eye() const { return myEye; }
 
-  //! Set camera axial scale.
-  //! @param theAxialScale [in] the axial scale vector.
-  Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale);
+  //! Sets camera Eye position.
+  //! Unlike SetEye(), this method only changes Eye point and preserves camera direction.
+  //! @param theEye [in] the location of camera's Eye.
+  //! @sa SetEye()
+  Standard_EXPORT void MoveEyeTo (const gp_Pnt& theEye);
 
-  //! Get camera axial scale.
-  //! @return Camera's axial scale.
-  const gp_XYZ& AxialScale() const
+  //! Sets camera Eye and Center positions.
+  //! @param theEye    [in] the location of camera's Eye
+  //! @param theCenter [in] the location of camera's Center
+  Standard_EXPORT void SetEyeAndCenter (const gp_Pnt& theEye,
+                                        const gp_Pnt& theCenter);
+
+  //! Sets camera Eye position.
+  //! WARNING! For backward compatibility reasons, this method also changes view direction,
+  //! so that the new direction is computed from new Eye position to old Center position.
+  //! @param theEye [in] the location of camera's Eye.
+  //! @sa MoveEyeTo(), SetEyeAndCenter()
+  Standard_EXPORT void SetEye (const gp_Pnt& theEye);
+
+  //! Get Center of the camera, e.g. the point where camera looks at.
+  //! This point is computed as Eye() translated along Direction() at Distance().
+  //! @return the point where the camera looks at.
+  gp_Pnt Center() const
   {
-    return myAxialScale;
+    return myEye.XYZ() + myDirection.XYZ() * myDistance;
   }
 
-  //! Set distance of Eye from camera Center.
-  //! @param theDistance [in] the distance.
-  Standard_EXPORT void SetDistance (const Standard_Real theDistance);
+  //! Sets Center of the camera, e.g. the point where camera looks at.
+  //! This methods changes camera direction, so that the new direction is computed
+  //! from current Eye position to specified Center position.
+  //! @param theCenter [in] the point where the camera looks at.
+  Standard_EXPORT void SetCenter (const gp_Pnt& theCenter);
 
   //! Get distance of Eye from camera Center.
   //! @return the distance.
-  Standard_EXPORT Standard_Real Distance() const;
+  Standard_Real Distance() const { return myDistance; }
 
-  //! Sets camera look direction.
-  //! @param theDir [in] the direction.
-  Standard_EXPORT void SetDirection (const gp_Dir& theDir);
+  //! Set distance of Eye from camera Center.
+  //! @param theDistance [in] the distance.
+  Standard_EXPORT void SetDistance (const Standard_Real theDistance);
 
-  //! Get camera look direction.
-  //! @return camera look direction.
-  Standard_EXPORT gp_Dir Direction() const;
+  //! Get camera scale.
+  //! @return camera scale factor.
+  Standard_EXPORT Standard_Real Scale() const;
 
   //! Sets camera scale. For orthographic projection the scale factor
   //! corresponds to parallel scale of view mapping  (i.e. size
@@ -226,9 +244,13 @@ public:
   //! @param theScale [in] the scale factor.
   Standard_EXPORT void SetScale (const Standard_Real theScale);
 
-  //! Get camera scale.
-  //! @return camera scale factor.
-  Standard_EXPORT Standard_Real Scale() const;
+  //! Get camera axial scale.
+  //! @return Camera's axial scale.
+  const gp_XYZ& AxialScale() const { return myAxialScale; }
+
+  //! Set camera axial scale.
+  //! @param theAxialScale [in] the axial scale vector.
+  Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale);
 
   //! Change camera projection type.
   //! When switching to perspective projection from orthographic one,
@@ -272,7 +294,7 @@ public:
     return myFOVy;
   }
 
-  //! Change Z-min and Z-max planes of projection volume to match the
+  //! Estimate Z-min and Z-max planes of projection volume to match the
   //! displayed objects. The methods ensures that view volume will
   //! be close by depth range to the displayed objects. Fitting assumes that
   //! for orthogonal projection the view volume contains the displayed objects
@@ -284,8 +306,19 @@ public:
   //!   Program error exception is thrown if negative or zero value is passed.
   //! @param theMinMax [in] applicative min max boundaries.
   //! @param theScaleFactor [in] real graphical boundaries (not accounting infinite flag).
-
-  Standard_EXPORT void ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB);
+  Standard_EXPORT bool ZFitAll (const Standard_Real theScaleFactor,
+                                const Bnd_Box&      theMinMax,
+                                const Bnd_Box&      theGraphicBB,
+                                Standard_Real&      theZNear,
+                                Standard_Real&      theZFar) const;
+
+  //! Change Z-min and Z-max planes of projection volume to match the displayed objects.
+  void ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB)
+  {
+    Standard_Real aZNear = 0.0, aZFar = 1.0;
+    ZFitAll (theScaleFactor, theMinMax, theGraphicBB, aZNear, aZFar);
+    SetZRange (aZNear, aZFar);
+  }
 
   //! Change the Near and Far Z-clipping plane positions.
   //! For orthographic projection, theZNear, theZFar can be negative or positive.
@@ -364,6 +397,14 @@ public:
     return myIODType;
   }
 
+  //! Get current tile.
+  const Graphic3d_CameraTile& Tile() const { return myTile; }
+
+  //! Sets the Tile defining the drawing sub-area within View.
+  //! Note that tile defining a region outside the view boundaries is also valid - use method Graphic3d_CameraTile::Cropped() to assign a cropped copy.
+  //! @param theTile tile definition
+  Standard_EXPORT void SetTile (const Graphic3d_CameraTile& theTile);
+
 //! @name Basic camera operations
 public:
 
@@ -375,7 +416,16 @@ public:
   //! Calculate view plane size at center (target) point
   //! and distance between ZFar and ZNear planes.
   //! @return values in form of gp_Pnt (Width, Height, Depth).
-  Standard_EXPORT gp_XYZ ViewDimensions() const;
+  gp_XYZ ViewDimensions() const
+  {
+    return ViewDimensions (Distance());
+  }
+
+  //! Calculate view plane size at center point with specified Z offset
+  //! and distance between ZFar and ZNear planes.
+  //! @param theZValue [in] the distance from the eye in eye-to-center direction
+  //! @return values in form of gp_Pnt (Width, Height, Depth).
+  Standard_EXPORT gp_XYZ ViewDimensions (const Standard_Real theZValue) const;
 
   //! Calculate WCS frustum planes for the camera projection volume.
   //! Frustum is a convex volume determined by six planes directing
@@ -502,6 +552,9 @@ public:
   //! The matrix will be updated on request.
   Standard_EXPORT void InvalidateOrientation();
 
+  //! Dumps the content of me into the stream
+  Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
+
 //! @name Managing projection and orientation cache
 private:
 
@@ -586,28 +639,52 @@ private:
   //! Reference point differs for perspective and ortho modes 
   //! (made for compatibility, to be improved..).
   //! @param theEye [in] the eye coordinates in 3D space.
-  //! @param theLookAt [in] the point the camera looks at.
+  //! @param theFwdDir [in] view direction
   //! @param theUpDir [in] the up direction vector.
   //! @param theAxialScale [in] the axial scale vector.
   //! @param theOutMx [in/out] the orientation matrix.
   template <typename Elem_t>
   static void
     LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
-                     const NCollection_Vec3<Elem_t>& theLookAt,
+                     const NCollection_Vec3<Elem_t>& theFwdDir,
                      const NCollection_Vec3<Elem_t>& theUpDir,
                      const NCollection_Vec3<Elem_t>& theAxialScale,
                      NCollection_Mat4<Elem_t>&       theOutMx);
 
+public:
+
+  //! Enumerates vertices of view volume.
+  enum
+  {
+    FrustumVert_LeftBottomNear,
+    FrustumVert_LeftBottomFar,
+    FrustumVert_LeftTopNear,
+    FrustumVert_LeftTopFar,
+    FrustumVert_RightBottomNear,
+    FrustumVert_RightBottomFar,
+    FrustumVert_RightTopNear,
+    FrustumVert_RightTopFar,
+    FrustumVerticesNB
+  };
+
+  //! Fill array of current view frustum corners.
+  //! The size of this array is equal to FrustumVerticesNB.
+  //! The order of vertices is as defined in FrustumVert_* enumeration.
+  Standard_EXPORT void FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePoints,
+                                      const Graphic3d_Mat4d& theModelWorld = Graphic3d_Mat4d()) const;
+
 private:
 
-  gp_Dir myUp;     //!< Camera up direction vector.
-  gp_Pnt myEye;    //!< Camera eye position.
-  gp_Pnt myCenter; //!< Camera center.
+  gp_Dir        myUp;       //!< Camera up direction vector
+  gp_Dir        myDirection;//!< Camera view direction (from eye)
+  gp_Pnt        myEye;      //!< Camera eye position
+  Standard_Real myDistance; //!< distance from Eye to Center
 
   gp_XYZ myAxialScale; //!< World axial scale.
 
   Projection    myProjType; //!< Projection type used for rendering.
   Standard_Real myFOVy;     //!< Field Of View in y axis.
+  Standard_Real myFOVyTan;  //!< Field Of View as Tan(DTR_HALF * myFOVy)
   Standard_Real myZNear;    //!< Distance to near clipping plane.
   Standard_Real myZFar;     //!< Distance to far clipping plane.
   Standard_Real myAspect;   //!< Width to height display ratio.
@@ -619,6 +696,8 @@ private:
   Standard_Real myIOD;     //!< Intraocular distance value.
   IODType       myIODType; //!< Intraocular distance definition type.
 
+  Graphic3d_CameraTile myTile;//!< Tile defining sub-area for drawing
+
   mutable TransformMatrices<Standard_Real>      myMatricesD;
   mutable TransformMatrices<Standard_ShortReal> myMatricesF;
 
@@ -626,9 +705,31 @@ private:
 
 public:
 
-  DEFINE_STANDARD_RTTI(Graphic3d_Camera, Standard_Transient);
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_Camera,Standard_Transient)
 };
 
 DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
 
+//! Linear interpolation tool for camera orientation and position.
+//! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently.
+//!
+//! Eye/Center interpolation is performed through defining an anchor point in-between Center and Eye.
+//! The anchor position is defined as point near to the camera point which has smaller translation part.
+//! The main idea is to keep the distance between Center and Eye
+//! (which will change if Center and Eye translation will be interpolated independently).
+//! E.g.:
+//!  - When both Center and Eye are moved at the same vector -> both will be just translated by straight line
+//!  - When Center is not moved -> camera Eye    will move around Center through arc
+//!  - When Eye    is not moved -> camera Center will move around Eye    through arc
+//!  - When both Center and Eye are move by different vectors -> transformation will be something in between,
+//!    and will try interpolate linearly the distance between Center and Eye.
+//!
+//! This transformation might be not in line with user expectations.
+//! In this case, application might define intermediate camera positions for interpolation
+//! or implement own interpolation logic.
+template<>
+Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
+                                                                              Handle(Graphic3d_Camera)& theResult) const;
+typedef NCollection_Lerp<Handle(Graphic3d_Camera)> Graphic3d_CameraLerp;
+
 #endif