0030439: Visualization - extend fonts search within Font_FontMgr::FindFont() on Linux
[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{
2b8832bb 28public:
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 };
30a1b24e 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
b7cd4ba7 57public:
58
59 //! Creates an empty selector object with parallel projection type by default.
60 Standard_EXPORT OpenGl_BVHTreeSelector();
61
825aa485 62 //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices.
b7cd4ba7 63 Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
64
4ecf34cc 65 Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth,
66 Standard_Integer theViewportHeight,
67 Standard_Real theResolutionRatio);
68
69 //! Setup distance culling.
2b8832bb 70 Standard_EXPORT void SetCullingDistance (CullingContext& theCtx,
71 Standard_Real theDistance) const;
4ecf34cc 72
73 //! Setup size culling.
2b8832bb 74 Standard_EXPORT void SetCullingSize (CullingContext& theCtx,
75 Standard_Real theSize) const;
4ecf34cc 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();
91d96372 80
2b8832bb 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 }
b7cd4ba7 94
3fe9ce0e 95 //! Return the camera definition.
96 const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
97
825aa485 98 //! Returns current projection matrix.
7c3ef2f7 99 const OpenGl_Mat4d& ProjectionMatrix() const
825aa485 100 {
101 return myProjectionMat;
102 }
b7cd4ba7 103
825aa485 104 //! Returns current world view transformation matrix.
7c3ef2f7 105 const OpenGl_Mat4d& WorldViewMatrix() const
825aa485 106 {
107 return myWorldViewMat;
108 }
b7cd4ba7 109
91d96372 110 Standard_Integer ViewportWidth() const
111 {
112 return myViewportWidth;
113 }
114
115 Standard_Integer ViewportHeight() const
116 {
117 return myViewportHeight;
118 }
119
825aa485 120 //! Returns state of current world view projection transformation matrices.
121 const Graphic3d_WorldViewProjState& WorldViewProjState() const
122 {
123 return myWorldViewProjState;
124 }
b7cd4ba7 125
126protected:
127
128 //! Calculates signed distance from plane to point.
129 //! @param theNormal [in] the plane's normal.
130 //! @param thePnt [in]
7c3ef2f7 131 Standard_EXPORT Standard_Real SignedPlanePointDistance (const OpenGl_Vec4d& theNormal,
132 const OpenGl_Vec4d& thePnt);
b7cd4ba7 133
2b8832bb 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
30a1b24e 146 // E0 test (x axis)
2b8832bb 147 if (theMinPt.x() > myMaxOrthoProjectionPts[0]
148 || theMaxPt.x() < myMinOrthoProjectionPts[0])
149 {
150 return true;
151 }
152
30a1b24e 153 // E1 test (y axis)
2b8832bb 154 if (theMinPt.y() > myMaxOrthoProjectionPts[1]
155 || theMaxPt.y() < myMinOrthoProjectionPts[1])
156 {
157 return true;
158 }
159
30a1b24e 160 // E2 test (z axis)
2b8832bb 161 if (theMinPt.z() > myMaxOrthoProjectionPts[2]
162 || theMaxPt.z() < myMinOrthoProjectionPts[2])
163 {
164 return true;
165 }
166
2b8832bb 167 const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
30a1b24e 168 for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor)
2b8832bb 169 {
30a1b24e 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])
2b8832bb 180 {
181 continue;
182 }
30a1b24e 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])
2b8832bb 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 }
f29de682 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;
2b8832bb 238 }
239
b7cd4ba7 240protected:
241
242 //! Enumerates planes of view volume.
243 enum
244 {
b7cd4ba7 245 Plane_Left,
246 Plane_Right,
30a1b24e 247 Plane_Bottom,
248 Plane_Top,
b7cd4ba7 249 Plane_Near,
250 Plane_Far,
251 PlanesNB
252 };
253
b7cd4ba7 254protected:
255
30a1b24e 256 Plane myClipPlanes[PlanesNB]; //!< Planes
257 NCollection_Array1<OpenGl_Vec3d> myClipVerts; //!< Vertices
b7cd4ba7 258
3fe9ce0e 259 Handle(Graphic3d_Camera) myCamera; //!< camera definition
260
b7cd4ba7 261 // for caching clip points projections onto viewing area normals once per traverse
30a1b24e 262 // ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
7c3ef2f7 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
b7cd4ba7 265
266 // for caching clip points projections onto AABB normals once per traverse
267 // ORDER: E0, E1, E2
7c3ef2f7 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
b7cd4ba7 270
825aa485 271 Standard_Boolean myIsProjectionParallel;
b7cd4ba7 272
7c3ef2f7 273 OpenGl_Mat4d myProjectionMat;
274 OpenGl_Mat4d myWorldViewMat;
b7cd4ba7 275
91d96372 276 Standard_Integer myViewportWidth;
277 Standard_Integer myViewportHeight;
278
825aa485 279 Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices.
4ecf34cc 280
281 Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling
f29de682 282 Graphic3d_Vec3d myCamDir; //!< camera direction for size culling
283 Standard_Real myCamScale; //!< camera scale for size culling
4ecf34cc 284 Standard_Real myPixelSize; //!< pixel size for size culling
4ecf34cc 285
b7cd4ba7 286};
287
288#endif // _OpenGl_BVHTreeSelector_HeaderFile