26 typedef float DVALUE_t; //!< Dimension value type.
27 cVector3f m_vCenter; //!< Sphere center
28 DVALUE_t m_fRadius; //!< Sphere radius
32 cSpheref(DVALUE_t fObjectRadius = 0) noexcept
33 : m_fRadius(fObjectRadius)
37 cSpheref(const cVector3f& vObjectCenter, DVALUE_t fObjectRadius) noexcept
38 : m_vCenter(vObjectCenter)
39 , m_fRadius(fObjectRadius)
41 cSpheref(DVALUE_t x, DVALUE_t y, DVALUE_t z, DVALUE_t r = 0) noexcept
47 DVALUE_t get_Radius() const
51 DVALUE_t get_RadiusSq() const
53 return Calc::Sqr(m_fRadius);
55 const cVector3f& get_Center() const
62 return(m_fRadius <= 0);
64 bool operator == (const cSpheref& sphere) const
66 return(sphere.m_vCenter == m_vCenter && sphere.m_fRadius == m_fRadius);
69 bool IsInSphere(const cVector3f& v) const
73 DVALUE_t fDistSq = m_vCenter.GetDistSq(v);
74 return(fDistSq <= get_RadiusSq());
76 bool IsInSphere(DVALUE_t _x, DVALUE_t _y, DVALUE_t _z) const
78 return IsInSphere(cVector3f(_x, _y, _z));
81 bool IsInSphere(const cSpheref& s) const
85 DVALUE_t fDistSq = m_vCenter.GetDistSq(s.m_vCenter);
86 return (fDistSq <= Calc::Sqr(m_fRadius - s.m_fRadius));
89 bool IsOverlapSphere(const cVector3f& vObjectCenter, DVALUE_t fObjectRadius) const
92 DVALUE_t fDistSq = m_vCenter.GetDistSq(vObjectCenter);
93 return (fDistSq <= Calc::Sqr(m_fRadius + fObjectRadius));
95 bool IsOverlapSphere(const cSpheref& s) const
97 return IsOverlapSphere(s.m_vCenter, s.m_fRadius);
100 GINTERSECT_TYPE GetIntersectSphere(const cSpheref& s) const
106 DVALUE_t fDistSq = m_vCenter.GetDistSq(s.m_vCenter);
107 if (fDistSq >= Calc::Sqr(m_fRadius + s.m_fRadius))
108 return GINTERSECT_None;
109 DVALUE_t fRadiusDiff = m_fRadius - s.m_fRadius;
110 if (fDistSq <= Calc::Sqr(fRadiusDiff))
112 // one is inside the other.
113 if (fRadiusDiff < 0) // s is larger.
114 return GINTERSECT_In2; // *this is inside s
115 return GINTERSECT_In1; // s is inside *this.
117 return GINTERSECT_Partial; // partial overlap.
120 GINTERSECT_TYPE GetIntersectBounds(const cBounds3f& bbox) const;
121 bool IsIntersectSegment(const cSegment3f& segment) const;
122 bool TestRay(const cVector3f& vPickRayOrig, const cVector3f& vPickRayDir) const;
125 void SetSphere(const cVector3f &vObjectCenter, DVALUE_t fObjectRadius)
127 m_vCenter = vObjectCenter;
128 m_fRadius = fObjectRadius;
138 m_fRadius = k_FLT_MAX2;
140 void SetFromBoxO(const cBounds3f& box)
144 m_vCenter = box.get_Center();
145 m_fRadius = box.get_Radius();
147 void SetFromBoxI(const cBounds3f& box)
151 m_vCenter = box.get_Center();
152 m_fRadius = box.get_MaxDelta() / 2;
157 void put_Radius(DVALUE_t fObjectRadius)
159 m_fRadius = fObjectRadius;
161 void ScaleCoords(DVALUE_t fScale)
167 void Encapsulate(const cVector3f& v);
168 void UnionSphere(const cSpheref& sphere);
172 void OrthoTransform(const cMatrix4x4f& xform)
175 cVector3f vAx(xform.m[0][0], xform.m[1][0], xform.m[2][0]); // transposed ??
176 DVALUE_t fScale = vAx.get_Magnitude();
178 m_vCenter = m_vCenter.GetProj(xform);
181 void BoundsAffineTransform(const cMatrix4x4f& xform)
184 cVector3f vAx(xform.m[0][0], xform.m[1][0], xform.m[2][0]); // transposed ??
185 cVector3f vAy(xform.m[0][1], xform.m[1][1], xform.m[2][1]);
186 cVector3f vAz(xform.m[0][2], xform.m[1][2], xform.m[2][2]);
188 DVALUE_t fLenX = vAx.get_MagnitudeSq();
189 DVALUE_t fLenY = vAy.get_MagnitudeSq();
190 DVALUE_t fLenZ = vAz.get_MagnitudeSq();
191 DVALUE_t fScale = Calc::Sqrt(Calc::Max3(fLenX, fLenY, fLenZ));
194 m_vCenter = m_vCenter.GetProj(xform);
197 void ComputeBoundingSphere(const cVector3f* pVerts, UINT dwNumVertices, size_t dwStride);
200 ITERATE_t v_SetSphere(const cVariant& vArgs, ITERATE_t i = 0);
201 void v_GetSphere(cVariant& vArgs) const;
203 ITERATE_t v_SetSphereRev(const cVariant& vArgs, ITERATE_t i = 0);
204 void v_GetSphereRev(cVariant& vArgs) const;
206 UNITTEST_FRIEND(cSphere);
209 class GRAYLIB_LINK cSphere2 : public cSpheref
215 typedef cSpheref SUPER_t;
218 DVALUE_t m_fRadiusSq; //!< keep radius squared. for faster access.
221 : cSpheref(cVector3f(0.0f, 0.0f, 0.0f), 0.0f)
225 cSphere2(const cVector3f& vCenter, DVALUE_t fObjectRadius)
226 : cSpheref(vCenter, fObjectRadius)
227 , m_fRadiusSq(Calc::Sqr(fObjectRadius))
230 void put_Radius(DVALUE_t fRadius)
232 SUPER_t::put_Radius(fRadius);
233 m_fRadiusSq = Calc::Sqr(fRadius);
235 DVALUE_t get_RadiusSq() const
239 void SetSphere(const cVector3f &vCenter, DVALUE_t fRadius)
241 SUPER_t::SetSphere(vCenter, fRadius);
242 m_fRadiusSq = Calc::Sqr(fRadius);
245 GINTERSECT_TYPE GetRayIntersectionFrustum(const cVector3f &vRayOrigin,
246 const cVector3f &vRayDir,
247 cVector3f* pvIntersect, DVALUE_t fDistMaxSq) const;
249 bool IsRayIntersectionInFront(const cVector3f& vRayOrigin,
250 const cVector3f &vRayDir,
251 cVector3f* pvIntersect) const;
253 bool IsRayIntersectionDistSq(const cVector3f& vRayOrigin,
254 const cVector3f &vRayDir,
256 OUT cVector3f* pvIntersect) const;
259 class GRAYLIB_LINK cSphereWork
265 int m_iPass; //!< pass 1 or 2 on the data set.
268 cVector3f m_xmin, m_xmax, m_ymin, m_ymax, m_zmin, m_zmax; //!< used to compute box. after pass 1
269 cSphere2 m_sphere; //!< valid after pass 2
276 void AddVertex(const cVector3f& vTmp);
277 void InitPass2(); // we are about to make pass2 on the data set
279 void AddVertices1(const cVector3f* pVerts, UINT dwNumVertices, size_t dwStride);
280 void AddVertices2(const cVector3f* pVerts, UINT dwNumVertices, size_t dwStride);
283 cBounds3f get_Box() const
287 bbox.m_vMin.x = m_xmin.x;
288 bbox.m_vMin.y = m_ymin.y;
289 bbox.m_vMin.z = m_zmin.z;
290 bbox.m_vMax.x = m_xmax.x;
291 bbox.m_vMax.y = m_ymax.y;
292 bbox.m_vMax.z = m_zmax.z;
295 cSphere2 get_Sphere() const // get a box from my first pass data.
302 #endif // _INC_cSphere_H
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
#define DECLSPEC_UUID(x)
Definition: IUnknown.h:19
Definition: cVariant.h:26
UNITTEST2_PREDEF(cQuadtree)