0031512: Foundation Classes - drop unused class NCollection_Comparator
[occt.git] / src / Graphic3d / Graphic3d_CullingTool.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
d325cb7f 16#ifndef _Graphic3d_CullingTool_HeaderFile
17#define _Graphic3d_CullingTool_HeaderFile
b7cd4ba7 18
19#include <Graphic3d_Camera.hxx>
d325cb7f 20#include <Graphic3d_Vec4.hxx>
825aa485 21#include <Graphic3d_WorldViewProjState.hxx>
b7cd4ba7 22
d325cb7f 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.
25class Graphic3d_CullingTool
b7cd4ba7 26{
27public:
2b8832bb 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 };
30a1b24e 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.
d325cb7f 47 Plane (const Graphic3d_Vec3d& theOrigin,
48 const Graphic3d_Vec3d& theNormal)
30a1b24e 49 : Origin (theOrigin),
50 Normal (theNormal) {}
51
d325cb7f 52 Graphic3d_Vec3d Origin;
53 Graphic3d_Vec3d Normal;
30a1b24e 54 };
55
2b8832bb 56public:
b7cd4ba7 57
58 //! Creates an empty selector object with parallel projection type by default.
d325cb7f 59 Standard_EXPORT Graphic3d_CullingTool();
b7cd4ba7 60
825aa485 61 //! Retrieves view volume's planes equations and its vertices from projection and world-view matrices.
b7cd4ba7 62 Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
63
4ecf34cc 64 Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth,
65 Standard_Integer theViewportHeight,
66 Standard_Real theResolutionRatio);
67
68 //! Setup distance culling.
2b8832bb 69 Standard_EXPORT void SetCullingDistance (CullingContext& theCtx,
70 Standard_Real theDistance) const;
4ecf34cc 71
72 //! Setup size culling.
2b8832bb 73 Standard_EXPORT void SetCullingSize (CullingContext& theCtx,
74 Standard_Real theSize) const;
4ecf34cc 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();
91d96372 79
2b8832bb 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,
d325cb7f 86 const Graphic3d_Vec3d& theMinPt,
87 const Graphic3d_Vec3d& theMaxPt) const
2b8832bb 88 {
89 return isFullOut (theMinPt, theMaxPt)
90 || isTooDistant(theCtx, theMinPt, theMaxPt)
91 || isTooSmall (theCtx, theMinPt, theMaxPt);
92 }
b7cd4ba7 93
3fe9ce0e 94 //! Return the camera definition.
95 const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
96
825aa485 97 //! Returns current projection matrix.
d325cb7f 98 const Graphic3d_Mat4d& ProjectionMatrix() const
825aa485 99 {
100 return myProjectionMat;
101 }
b7cd4ba7 102
825aa485 103 //! Returns current world view transformation matrix.
d325cb7f 104 const Graphic3d_Mat4d& WorldViewMatrix() const
825aa485 105 {
106 return myWorldViewMat;
107 }
b7cd4ba7 108
91d96372 109 Standard_Integer ViewportWidth() const
110 {
111 return myViewportWidth;
112 }
113
114 Standard_Integer ViewportHeight() const
115 {
116 return myViewportHeight;
117 }
118
825aa485 119 //! Returns state of current world view projection transformation matrices.
120 const Graphic3d_WorldViewProjState& WorldViewProjState() const
121 {
122 return myWorldViewProjState;
123 }
b7cd4ba7 124
125protected:
126
127 //! Calculates signed distance from plane to point.
128 //! @param theNormal [in] the plane's normal.
129 //! @param thePnt [in]
d325cb7f 130 Standard_EXPORT Standard_Real SignedPlanePointDistance (const Graphic3d_Vec4d& theNormal,
131 const Graphic3d_Vec4d& thePnt);
b7cd4ba7 132
2b8832bb 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.
d325cb7f 137 bool isFullOut (const Graphic3d_Vec3d& theMinPt,
138 const Graphic3d_Vec3d& theMaxPt) const
2b8832bb 139 {
140 // E1
141 // |_ E0
142 // /
143 // E2
144
30a1b24e 145 // E0 test (x axis)
2b8832bb 146 if (theMinPt.x() > myMaxOrthoProjectionPts[0]
147 || theMaxPt.x() < myMinOrthoProjectionPts[0])
148 {
149 return true;
150 }
151
30a1b24e 152 // E1 test (y axis)
2b8832bb 153 if (theMinPt.y() > myMaxOrthoProjectionPts[1]
154 || theMaxPt.y() < myMinOrthoProjectionPts[1])
155 {
156 return true;
157 }
158
30a1b24e 159 // E2 test (z axis)
2b8832bb 160 if (theMinPt.z() > myMaxOrthoProjectionPts[2]
161 || theMaxPt.z() < myMinOrthoProjectionPts[2])
162 {
163 return true;
164 }
165
2b8832bb 166 const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
30a1b24e 167 for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor)
2b8832bb 168 {
30a1b24e 169 // frustum normals
d325cb7f 170 const Graphic3d_Vec3d anAxis = myClipPlanes[aPlaneIter].Normal;
30a1b24e 171
d325cb7f 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());
30a1b24e 175 Standard_Real aPnt0 = aPVertex.Dot (anAxis);
176
177 if (aPnt0 >= myMinClipProjectionPts[aPlaneIter]
178 && aPnt0 <= myMaxClipProjectionPts[aPlaneIter])
2b8832bb 179 {
180 continue;
181 }
30a1b24e 182
d325cb7f 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());
30a1b24e 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])
2b8832bb 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,
d325cb7f 202 const Graphic3d_Vec3d& theMinPt,
203 const Graphic3d_Vec3d& theMaxPt) const
2b8832bb 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,
d325cb7f 218 const Graphic3d_Vec3d& theMinPt,
219 const Graphic3d_Vec3d& theMaxPt) const
2b8832bb 220 {
221 if (theCtx.SizeCull2 <= 0.0)
222 {
223 return false;
224 }
f29de682 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
d325cb7f 234 const Graphic3d_Vec3d aBndCenter = (theMinPt + theMaxPt) * 0.5;
235 const Standard_Real aBndDist = (aBndCenter - myCamEye).Dot (myCamDir);
f29de682 236 return aBoxDiag2 < theCtx.SizeCull2 * aBndDist * aBndDist;
2b8832bb 237 }
238
b7cd4ba7 239protected:
240
241 //! Enumerates planes of view volume.
242 enum
243 {
b7cd4ba7 244 Plane_Left,
245 Plane_Right,
30a1b24e 246 Plane_Bottom,
247 Plane_Top,
b7cd4ba7 248 Plane_Near,
249 Plane_Far,
250 PlanesNB
251 };
252
b7cd4ba7 253protected:
254
d325cb7f 255 Plane myClipPlanes[PlanesNB]; //!< Planes
256 NCollection_Array1<Graphic3d_Vec3d> myClipVerts; //!< Vertices
b7cd4ba7 257
3fe9ce0e 258 Handle(Graphic3d_Camera) myCamera; //!< camera definition
259
b7cd4ba7 260 // for caching clip points projections onto viewing area normals once per traverse
30a1b24e 261 // ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
7c3ef2f7 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
b7cd4ba7 264
265 // for caching clip points projections onto AABB normals once per traverse
266 // ORDER: E0, E1, E2
7c3ef2f7 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
b7cd4ba7 269
825aa485 270 Standard_Boolean myIsProjectionParallel;
b7cd4ba7 271
d325cb7f 272 Graphic3d_Mat4d myProjectionMat;
273 Graphic3d_Mat4d myWorldViewMat;
b7cd4ba7 274
91d96372 275 Standard_Integer myViewportWidth;
276 Standard_Integer myViewportHeight;
277
825aa485 278 Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices.
4ecf34cc 279
280 Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling
f29de682 281 Graphic3d_Vec3d myCamDir; //!< camera direction for size culling
282 Standard_Real myCamScale; //!< camera scale for size culling
4ecf34cc 283 Standard_Real myPixelSize; //!< pixel size for size culling
4ecf34cc 284
b7cd4ba7 285};
286
d325cb7f 287#endif // _Graphic3d_CullingTool_HeaderFile