CFx SDK Documentation 2026 SP0
Loading...
Searching...
No Matches
SiVolume.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
3// All rights reserved.
4//
5// This software and its documentation and related materials are owned by
6// the Alliance. The software may only be incorporated into application
7// programs owned by members of the Alliance, subject to a signed
8// Membership Agreement and Supplemental Software License Agreement with the
9// Alliance. The structure and organization of this software are the valuable
10// trade secrets of the Alliance and its suppliers. The software is also
11// protected by copyright law and international treaty provisions. Application
12// programs incorporating this software must include the following statement
13// with their copyright notices:
14//
15// This application incorporates Open Design Alliance software pursuant to a license
16// agreement with Open Design Alliance.
17// Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
18// All rights reserved.
19//
20// By use of this software, its documentation or related materials, you
21// acknowledge and accept the above terms.
23
24#ifndef _SpVolume_h_Included_
25#define _SpVolume_h_Included_
26
27#include "TD_PackPush.h"
28
29#include "Si/SiSpatialIndex.h"
30#include "Ge/GePlane.h"
31
32namespace OdSi
33{
34
40class Volume : public OdSiShape
41{
42 protected:
43 // Subset of OdGePlane functionality. Optimized allocation, transforms and accessibility.
45 {
46 OdGePoint3d m_origin;
47 OdGeVector3d m_normal;
48 double m_dist;
49 public:
50 PlaneImpl() : m_dist(0.0) { }
51 PlaneImpl(const PlaneImpl &pl2) : m_origin(pl2.m_origin), m_normal(pl2.m_normal), m_dist(pl2.m_dist) { }
53 {
54 m_origin = pl2.m_origin; m_normal = pl2.m_normal; m_dist = pl2.m_dist;
55 return *this;
56 }
57
58 void set(const OdGePoint3d &origin, const OdGeVector3d &normal)
59 {
60 m_origin = origin;
61 m_normal = normal;
62 m_dist = -m_normal.dotProduct(m_origin.asVector());
63 }
64 void transformBy(const OdGeMatrix3d &xfm)
65 {
66 m_origin.transformBy(xfm);
67 m_normal.transformBy(xfm);
68 m_normal.normalize();
69 m_dist = -m_normal.dotProduct(m_origin.asVector());
70 }
71 void getCoefficients(double& a, double& b, double& c, double& d) const
72 {
73 a = m_normal.x; b = m_normal.y; c = m_normal.z; d = m_dist;
74 }
75 };
77 //OdGePlane m_plane[6];
79 bool m_planeValid[6] = {};
80 public:
81 Volume() : m_nPlanes(0) {}
83 {
84 for (OdUInt32 npl = 0; npl < m_nPlanes; npl++)
85 {
86 if (source.m_planeValid[npl])
87 m_plane[npl] = source.m_plane[npl];
88 m_planeValid[npl] = source.m_planeValid[npl];
89 }
90 }
91 Volume( const OdGePoint3d& origin, const OdGeVector3d& zAxis, const OdGeVector3d& yAxis, const OdGeVector3d& xAxis,
92 double xFov, double yFov, bool xFovAsAspect = false, bool yFovAsAspect = false,
93 bool bNearPlane = false, double fNearPlane = 0.01,
94 bool bFarPlane = false, double fFarPlane = 1.0 );
95
96 // Si interface
97 virtual bool contains( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol ) const;
98
99 virtual bool intersects( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol ) const;
100
101 virtual OdSiShape* clone() const
102 {
103 return new Volume(*this);
104 }
105
106 virtual void transform(const OdGeMatrix3d& mtx)
107 {
108 for (OdUInt32 npl = 0; npl < m_nPlanes; npl++)
109 {
110 if (m_planeValid[npl])
111 m_plane[npl].transformBy(mtx);
112 }
113 }
114
115 // misc
116 static double fovToPlane(double fov, double len)
117 {
118 return 2.0 * (len * tan(fov * 0.5));
119 }
120 static double fovFromPlane(double plane, double len)
121 {
122 return atan(plane / len * .5) * 2.0;
123 }
124
137 static Volume buildPyramidInEyeCS( const OdGeExtents2d& baseProjecton, double viewDistance, bool bNearPnane = true, double dNearPlane = 0., bool bFarPlane = false, double dFarPlane = 0. )
138 {
139 double fW = fabs( baseProjecton.maxPoint().x - baseProjecton.minPoint().x );
140 double fH = fabs( baseProjecton.maxPoint().y - baseProjecton.minPoint().y );
141 OdGePoint3d target( 0., 0., 0. );
142 double fLen = viewDistance;
143 OdGePoint3d newtrg( baseProjecton.center().x, baseProjecton.center().y, 0. );
144
148
149 OdGePoint3d position = target - eyeVector * fLen;
150 eyeVector = ( newtrg - position );
151 fLen = eyeVector.length();
152 eyeVector.normalize();
153
154 double angleR = -OdGeVector3d::kZAxis.angleTo( eyeVector, upVector );
155 double angleU = -OdGeVector3d::kZAxis.angleTo( eyeVector, rightVector );
156 OdGeVector3d newUpVector = upVector;
157 newUpVector.rotateBy( angleU, rightVector );
158 OdGeVector3d newRVector = rightVector;
159 newRVector.rotateBy( angleR, upVector );
160 //Actually this pyramid is bigger than we need since fW and fH are sizes of base projection on view target plane. So, real base should be "unprojection" of baseProjecton.
161 //However, currently it is enought.
162 //Also, clipping looks incorrect now: pyramid near/far clip planes are parallel to the base, but view clipping planes are perpendicular to the eye vector.
163 //Probably, we should use "furthest" clip point projection for correct pyramid clipping.
164 OdSi::Volume volume( position, eyeVector, newUpVector,
165 newRVector,
166 fW / fH, OdSi::Volume::fovFromPlane( fW, fLen ),
167 true, false,
168 bNearPnane, dNearPlane, bFarPlane, dFarPlane );
169 return volume;
170 }
171 protected:
172 static bool planeFromTri(const OdGePoint3d &A, const OdGePoint3d &B, const OdGePoint3d &C, /*OdGePlane*/ PlaneImpl &pl)
173 {
174 OdGeVector3d u = B - A;
175 OdGeVector3d v = C - A;
176 if (!u.isZeroLength(1e-100) && !v.isZeroLength(1e-100))
177 {
178 u.normalize(1e-100);
179 v.normalize(1e-100);
180 }
181 else
182 {
183 return false;
184 }
185 pl.set(A, u.crossProduct(v).normal());
186 return true;
187 }
188 static bool aabbInsidePlane(const OdGePoint3d &min, const OdGePoint3d &max, const /*OdGePlane*/ PlaneImpl &plane, const OdGeTol &tol)
189 {
190 double pt[3];
191 double pl[4];
192 plane.getCoefficients(pl[0], pl[1], pl[2], pl[3]);
193 pt[0] = (pl[0] > 0.0) ? max.x : min.x;
194 pt[1] = (pl[1] > 0.0) ? max.y : min.y;
195 pt[2] = (pl[2] > 0.0) ? max.z : min.z;
196 return pl[0] * pt[0] + pl[1] * pt[1] + pl[2] * pt[2] + pl[3] >= /*0.0*/ -tol.equalVector();
197 }
198};
199
200inline
201Volume::Volume( const OdGePoint3d& origin, const OdGeVector3d& zAxis, const OdGeVector3d& yAxis, const OdGeVector3d& xAxis,
202 double xFov, double yFov, bool xFovAsAspect, bool yFovAsAspect,
203 bool bNearPlane, double fNearPlane,
204 bool bFarPlane, double fFarPlane )
205{
206 // Aspect is width/height, so x is y*aspect, y is x/aspect
207 ODA_ASSERT(!(xFovAsAspect && yFovAsAspect));
208 double nearPlane_ = odmax(fNearPlane, 1.0); // near plane is required for plane calculation
209 double planeWidth = 1., planeHeight = 1.;
210 if (!xFovAsAspect)
211 planeWidth = fovToPlane(xFov, nearPlane_);
212 if (!yFovAsAspect)
213 planeHeight = fovToPlane(yFov, nearPlane_);
214 if (xFovAsAspect)
215 planeWidth = xFov * planeHeight;
216 if (yFovAsAspect)
217 planeHeight = planeWidth / yFov;
218 OdGeVector3d basisX(xAxis.normal()), basisY(yAxis.normal()), basisZ(zAxis.normal());
219 //basisX = basisZ.crossProduct(basisY).normal(); // from input, for support isotropy
220 OdGeVector3d deltaX = basisX * (planeWidth * 0.5);
221 OdGeVector3d deltaY = basisY * (planeHeight * 0.5);
222 OdGePoint3d nearPlane = origin + basisZ * nearPlane_;
223 OdGePoint3d planeQuad[4] =
224 {
225 nearPlane - deltaX - deltaY,
226 nearPlane + deltaX - deltaY,
227 nearPlane + deltaX + deltaY,
228 nearPlane - deltaX + deltaY
229 };
230 m_planeValid[0] = planeFromTri(planeQuad[0], origin, planeQuad[1], m_plane[0]);
231 m_planeValid[1] = planeFromTri(planeQuad[1], origin, planeQuad[2], m_plane[1]);
232 m_planeValid[2] = planeFromTri(planeQuad[2], origin, planeQuad[3], m_plane[2]);
233 m_planeValid[3] = planeFromTri(planeQuad[3], origin, planeQuad[0], m_plane[3]);
234 if (bNearPlane || bFarPlane)
235 {
236 m_planeValid[4] = bNearPlane;
237 if (bNearPlane)
238 m_plane[4].set(origin + basisZ * fNearPlane, basisZ);
239 if (bFarPlane)
240 {
241 m_planeValid[5] = true;
242 m_plane[5].set(origin + basisZ * fFarPlane, -basisZ);
243 m_nPlanes = 6;
244 }
245 else
246 m_nPlanes = 5;
247 }
248 else
249 m_nPlanes = 4;
250}
251
252inline
253bool Volume::contains( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
254{
255 ODA_ASSERT( planar == false );
256 OdUInt32 i;
257 for (i = 0; i < m_nPlanes; i++)
258 {
259 if (!m_planeValid[i])
260 continue;
261 if (!aabbInsidePlane(extents.minPoint(), extents.maxPoint(), m_plane[i], tol))
262 return false; // entirely outside
263 }
264 for (i = 0; i < m_nPlanes; i++)
265 {
266 if (!m_planeValid[i])
267 continue;
268 if (!aabbInsidePlane(extents.maxPoint(), extents.minPoint(), m_plane[i], tol))
269 return false; // intersects
270 }
271 return true; // entirely inside
272}
273
274inline
275bool Volume::intersects( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
276{
277 ODA_ASSERT( planar == false );
278 for (OdUInt32 i = 0; i < m_nPlanes; i++)
279 {
280 if (!m_planeValid[i])
281 continue;
282 if (!aabbInsidePlane(extents.minPoint(), extents.maxPoint(), m_plane[i], tol))
283 return false;
284 }
285 return true;
286}
287
288} // OdSi
289
290#include "TD_PackPop.h"
291
292#endif // _SpVolume_h_Included_
#define ODA_ASSERT(exp)
Definition DebugStuff.h:57
tol
ODRX_CONSTEXPR const T & odmax(const T &a, const T &b)
Definition OdPlatform.h:38
unsigned int OdUInt32
OdGePoint2d center() const
const OdGePoint2d & maxPoint() const
Definition GeExtents2d.h:88
const OdGePoint2d & minPoint() const
Definition GeExtents2d.h:79
const OdGePoint3d & maxPoint() const
const OdGePoint3d & minPoint() const
static GE_STATIC_EXPORT const OdGeVector3d kZAxis
Definition GeVector3d.h:103
bool isZeroLength(const OdGeTol &tol=OdGeContext::gTol) const
double length() const
OdGeVector3d normal(const OdGeTol &tol=OdGeContext::gTol) const
OdGeVector3d & rotateBy(double angle, const OdGeVector3d &axis)
double dotProduct(const OdGeVector3d &vect) const
Definition GeVector3d.h:586
OdGeVector3d crossProduct(const OdGeVector3d &vect) const
Definition GeVector3d.h:595
static GE_STATIC_EXPORT const OdGeVector3d kYAxis
Definition GeVector3d.h:102
OdGeVector3d & normalize(const OdGeTol &tol=OdGeContext::gTol)
static GE_STATIC_EXPORT const OdGeVector3d kXAxis
Definition GeVector3d.h:101
void set(const OdGePoint3d &origin, const OdGeVector3d &normal)
Definition SiVolume.h:58
PlaneImpl & operator=(const PlaneImpl &pl2)
Definition SiVolume.h:52
void transformBy(const OdGeMatrix3d &xfm)
Definition SiVolume.h:64
void getCoefficients(double &a, double &b, double &c, double &d) const
Definition SiVolume.h:71
PlaneImpl(const PlaneImpl &pl2)
Definition SiVolume.h:51
bool m_planeValid[6]
Definition SiVolume.h:79
virtual bool contains(const OdGeExtents3d &extents, bool planar=false, const OdGeTol &tol=OdGeContext::gTol) const
Definition SiVolume.h:253
static double fovToPlane(double fov, double len)
Definition SiVolume.h:116
OdUInt32 m_nPlanes
Definition SiVolume.h:76
virtual OdSiShape * clone() const
Definition SiVolume.h:101
static double fovFromPlane(double plane, double len)
Definition SiVolume.h:120
Volume(const Volume &source)
Definition SiVolume.h:82
virtual bool intersects(const OdGeExtents3d &extents, bool planar=false, const OdGeTol &tol=OdGeContext::gTol) const
Definition SiVolume.h:275
static Volume buildPyramidInEyeCS(const OdGeExtents2d &baseProjecton, double viewDistance, bool bNearPnane=true, double dNearPlane=0., bool bFarPlane=false, double dFarPlane=0.)
Definition SiVolume.h:137
virtual void transform(const OdGeMatrix3d &mtx)
Definition SiVolume.h:106
PlaneImpl m_plane[6]
Definition SiVolume.h:78
static bool aabbInsidePlane(const OdGePoint3d &min, const OdGePoint3d &max, const PlaneImpl &plane, const OdGeTol &tol)
Definition SiVolume.h:188
static bool planeFromTri(const OdGePoint3d &A, const OdGePoint3d &B, const OdGePoint3d &C, PlaneImpl &pl)
Definition SiVolume.h:172
const GLfloat * v
Definition gles2_ext.h:315
GLsizei GLsizei GLchar * source
Definition gles2_ext.h:282
static GE_STATIC_EXPORT OdGeTol gTol
Definition GeGbl.h:67