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