0029516: Visualization - eliminate redundant property Graphic3d_MaterialAspect::Refle...
[occt.git] / src / Graphic3d / Graphic3d_CullingTool.hxx
1 // Created on: 2013-12-25
2 // Created by: Varvara POSKONINA
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_CullingTool_HeaderFile
17 #define _Graphic3d_CullingTool_HeaderFile
18
19 #include <Graphic3d_Camera.hxx>
20 #include <Graphic3d_Vec4.hxx>
21 #include <Graphic3d_WorldViewProjState.hxx>
22
23 //! Graphic3d_CullingTool class provides a possibility to store parameters of view volume,
24 //! such as its vertices and equations, and contains methods detecting if given AABB overlaps view volume.
25 class Graphic3d_CullingTool
26 {
27 public:
28   //! Auxiliary structure holding non-persistent culling options.
29   struct CullingContext
30   {
31     Standard_Real DistCull;  //!< culling distance
32     Standard_Real SizeCull2; //!< squared culling size
33
34     //! Empty constructor.
35     CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {}
36   };
37
38   //! Auxiliary structure representing 3D plane.
39   struct Plane
40   {
41     //! Creates default plane.
42     Plane()
43     : Origin (0.0, 0.0, 0.0),
44       Normal (0.0, 0.0, 1.0) {}
45
46     //! Creates plane with specific parameters.
47     Plane (const Graphic3d_Vec3d& theOrigin,
48            const Graphic3d_Vec3d& theNormal)
49     : Origin (theOrigin),
50       Normal (theNormal) {}
51
52     Graphic3d_Vec3d Origin;
53     Graphic3d_Vec3d Normal;
54   };
55
56 public:
57
58   //! Creates an empty selector object with parallel projection type by default.
59   Standard_EXPORT Graphic3d_CullingTool();
60
61   //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices.
62   Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
63
64   Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth,
65                                         Standard_Integer theViewportHeight,
66                                         Standard_Real theResolutionRatio);
67
68   //! Setup distance culling.
69   Standard_EXPORT void SetCullingDistance (CullingContext& theCtx,
70                                            Standard_Real theDistance) const;
71
72   //! Setup size culling.
73   Standard_EXPORT void SetCullingSize (CullingContext& theCtx,
74                                        Standard_Real theSize) const;
75
76   //! Caches view volume's vertices projections along its normals and AABBs dimensions.
77   //! Must be called at the beginning of each BVH tree traverse loop.
78   Standard_EXPORT void CacheClipPtsProjections();
79
80   //! Checks whether given AABB should be entirely culled or not.
81   //! @param theCtx   [in] culling properties
82   //! @param theMinPt [in] maximum point of AABB
83   //! @param theMaxPt [in] minimum point of AABB
84   //! @return Standard_True, if AABB is in viewing area, Standard_False otherwise
85   bool IsCulled (const CullingContext& theCtx,
86                  const Graphic3d_Vec3d& theMinPt,
87                  const Graphic3d_Vec3d& theMaxPt) const
88   {
89     return isFullOut   (theMinPt, theMaxPt)
90         || isTooDistant(theCtx, theMinPt, theMaxPt)
91         || isTooSmall  (theCtx, theMinPt, theMaxPt);
92   }
93
94   //! Return the camera definition.
95   const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
96
97   //! Returns current projection matrix.
98   const Graphic3d_Mat4d& ProjectionMatrix() const
99   {
100     return myProjectionMat;
101   }
102
103   //! Returns current world view transformation matrix.
104   const Graphic3d_Mat4d& WorldViewMatrix() const
105   {
106     return myWorldViewMat;
107   }
108
109   Standard_Integer ViewportWidth() const
110   {
111     return myViewportWidth;
112   }
113
114   Standard_Integer ViewportHeight() const
115   {
116     return myViewportHeight;
117   }
118
119   //! Returns state of current world view projection transformation matrices.
120   const Graphic3d_WorldViewProjState& WorldViewProjState() const
121   {
122     return myWorldViewProjState;
123   }
124
125 protected:
126
127   //! Calculates signed distance from plane to point.
128   //! @param theNormal [in] the plane's normal.
129   //! @param thePnt    [in]
130   Standard_EXPORT Standard_Real SignedPlanePointDistance (const Graphic3d_Vec4d& theNormal,
131                                                           const Graphic3d_Vec4d& thePnt);
132
133   //! Detects if AABB overlaps view volume using separating axis theorem (SAT).
134   //! @param theMinPt [in] maximum point of AABB.
135   //! @param theMaxPt [in] minimum point of AABB.
136   //! @return FALSE, if AABB is in viewing area, TRUE otherwise.
137   bool isFullOut (const Graphic3d_Vec3d& theMinPt,
138                   const Graphic3d_Vec3d& theMaxPt) const
139   {
140     //     E1
141     //    |_ E0
142     //   /
143     //    E2
144
145     // E0 test (x axis)
146     if (theMinPt.x() > myMaxOrthoProjectionPts[0]
147      || theMaxPt.x() < myMinOrthoProjectionPts[0])
148     {
149       return true;
150     }
151
152     // E1 test (y axis)
153     if (theMinPt.y() > myMaxOrthoProjectionPts[1]
154      || theMaxPt.y() < myMinOrthoProjectionPts[1])
155     {
156       return true;
157     }
158
159     // E2 test (z axis)
160     if (theMinPt.z() > myMaxOrthoProjectionPts[2]
161      || theMaxPt.z() < myMinOrthoProjectionPts[2])
162     {
163       return true;
164     }
165
166     const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
167     for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor)
168     {
169       // frustum normals
170       const Graphic3d_Vec3d anAxis = myClipPlanes[aPlaneIter].Normal;
171
172       const Graphic3d_Vec3d aPVertex (anAxis.x() > 0.0 ? theMaxPt.x() : theMinPt.x(),
173                                       anAxis.y() > 0.0 ? theMaxPt.y() : theMinPt.y(),
174                                       anAxis.z() > 0.0 ? theMaxPt.z() : theMinPt.z());
175       Standard_Real aPnt0 = aPVertex.Dot (anAxis);
176
177       if (aPnt0 >= myMinClipProjectionPts[aPlaneIter]
178        && aPnt0 <= myMaxClipProjectionPts[aPlaneIter])
179       {
180         continue;
181       }
182       
183       const Graphic3d_Vec3d aNVertex (anAxis.x() > 0.0 ? theMinPt.x() : theMaxPt.x(),
184                                       anAxis.y() > 0.0 ? theMinPt.y() : theMaxPt.y(),
185                                       anAxis.z() > 0.0 ? theMinPt.z() : theMaxPt.z());
186       Standard_Real aPnt1 = aNVertex.Dot (anAxis);
187
188       const Standard_Real aMin = aPnt0 < aPnt1 ? aPnt0 : aPnt1;
189       const Standard_Real aMax = aPnt0 > aPnt1 ? aPnt0 : aPnt1;
190       
191       if (aMin > myMaxClipProjectionPts[aPlaneIter]
192        || aMax < myMinClipProjectionPts[aPlaneIter])
193       {
194         return true;
195       }
196     }
197     return false;
198   }
199
200   //! Returns TRUE if given AABB should be discarded by distance culling criterion.
201   bool isTooDistant (const CullingContext& theCtx,
202                      const Graphic3d_Vec3d& theMinPt,
203                      const Graphic3d_Vec3d& theMaxPt) const
204   {
205     if (theCtx.DistCull <= 0.0)
206     {
207       return false;
208     }
209
210     // check distance to the bounding sphere as fast approximation
211     const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5;
212     const Standard_Real   aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5;
213     return (aSphereCenter - myCamEye).Modulus() - aSphereRadius > theCtx.DistCull;
214   }
215
216   //! Returns TRUE if given AABB should be discarded by size culling criterion.
217   bool isTooSmall (const CullingContext& theCtx,
218                    const Graphic3d_Vec3d& theMinPt,
219                    const Graphic3d_Vec3d& theMaxPt) const
220   {
221     if (theCtx.SizeCull2 <= 0.0)
222     {
223       return false;
224     }
225
226     const Standard_Real aBoxDiag2 = (theMaxPt - theMinPt).SquareModulus();
227     if (myIsProjectionParallel)
228     {
229       return aBoxDiag2 < theCtx.SizeCull2;
230     }
231
232     // note that distances behind the Eye (aBndDist < 0) are not scaled correctly here,
233     // but majority of such objects should be culled by frustum
234     const Graphic3d_Vec3d aBndCenter = (theMinPt + theMaxPt) * 0.5;
235     const Standard_Real   aBndDist   = (aBndCenter - myCamEye).Dot (myCamDir);
236     return aBoxDiag2 < theCtx.SizeCull2 * aBndDist * aBndDist;
237   }
238
239 protected:
240
241   //! Enumerates planes of view volume.
242   enum
243   {
244     Plane_Left,
245     Plane_Right,
246     Plane_Bottom,
247     Plane_Top,
248     Plane_Near,
249     Plane_Far,
250     PlanesNB
251   };
252
253 protected:
254
255   Plane                               myClipPlanes[PlanesNB]; //!< Planes
256   NCollection_Array1<Graphic3d_Vec3d> myClipVerts;            //!< Vertices
257
258   Handle(Graphic3d_Camera) myCamera; //!< camera definition
259
260   // for caching clip points projections onto viewing area normals once per traverse
261   // ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
262   Standard_Real myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
263   Standard_Real myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
264
265   // for caching clip points projections onto AABB normals once per traverse
266   // ORDER: E0, E1, E2
267   Standard_Real myMaxOrthoProjectionPts[3]; //!< Max view volume's vertices projections onto normalized dimensions of AABB
268   Standard_Real myMinOrthoProjectionPts[3]; //!< Min view volume's vertices projections onto normalized dimensions of AABB
269
270   Standard_Boolean myIsProjectionParallel;
271
272   Graphic3d_Mat4d myProjectionMat;
273   Graphic3d_Mat4d myWorldViewMat;
274
275   Standard_Integer myViewportWidth;
276   Standard_Integer myViewportHeight;
277
278   Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices.
279
280   Graphic3d_Vec3d myCamEye;      //!< camera eye position for distance culling
281   Graphic3d_Vec3d myCamDir;      //!< camera direction for size culling
282   Standard_Real   myCamScale;    //!< camera scale for size culling
283   Standard_Real   myPixelSize;   //!< pixel size for size culling
284
285 };
286
287 #endif // _Graphic3d_CullingTool_HeaderFile