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