Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cBounds3.h
Go to the documentation of this file.
1 
5 #ifndef _INC_cBounds3_H
6 #define _INC_cBounds3_H
7 #ifndef NO_PRAGMA_ONCE
8 #pragma once
9 #endif
10 
11 #include "cSegment3.h"
12 #include "../Math/cMatrix.h"
13 #include "GrayCore/include/cValT.h"
15 
16 namespace GrayLib
17 {
18  class cSpheref;
19 
20  class GRAYLIB_LINK DECLSPEC_UUID("{17fbdf25-4963-4556-b3a3-7c9dfc8f4430}") cBounds3f
21  : public cSegment3f
22  {
29 
30  public:
31  static const WORD k_Indexes[4 * 2 * 3]; //!< indexes for creation/render of cube/bbox mesh. (24)
32 
33  public:
34  cBounds3f() noexcept
35  {}
36 
37  cBounds3f(const cVector3f& v1, const cVector3f& v2) noexcept
38  : cSegment3f(v1, v2)
39  {}
40 
42  bool IsEmptyX() const noexcept
43  {
44  return(m_vMin.x >= m_vMax.x);
45  }
46  bool IsEmptyY() const noexcept
47  {
48  return(m_vMin.y >= m_vMax.y);
49  }
50  bool IsEmptyZ() const noexcept
51  {
52  return(m_vMin.z >= m_vMax.z);
53  }
54 
55  bool IsEmptyBox() const noexcept
56  {
58  for (int i = 0; i < 3; i++)
59  {
60  if (m_vMin.m_a[i] >= m_vMax.m_a[i]) // One dimension is empty = empty box.
61  return true;
62  }
63  return false; // Not empty.
64  }
65  bool IsInsideBox(DVALUE_t x, DVALUE_t y, DVALUE_t z) const noexcept
66  {
68  if (x < m_vMin.x || x > m_vMax.x)
69  return false;
70  if (y < m_vMin.y || y > m_vMax.y)
71  return false;
72  if (z < m_vMin.z || z > m_vMax.z)
73  return false;
74  return true;
75  }
76  bool IsInsideBox(const cVector3f& v) const noexcept
77  {
79  for (int i = 0; i < 3; i++)
80  {
81  if (v.m_a[i] < m_vMin.m_a[i] || v.m_a[i] > m_vMax.m_a[i])
82  return false;
83  }
84  return true;
85  }
86  bool IsInsideBox(const cSegment3f& bbox) const noexcept
87  {
89  return IsInsideBox(bbox.m_vMax) && IsInsideBox(bbox.m_vMin) ;
90  }
91  bool IsInsideBox(const cVector3f& vPt, DVALUE_t fRadius) const noexcept;
92  bool IsInsideBox(const cSpheref& s) const;
93 
94  int CountInside2(DVALUE_t dminz, DVALUE_t dmaxz) const noexcept
95  {
96  // NOTE: I don't get this . What is this doing ?
97  int nInside = 0;
98  DVALUE_t fVal = m_vMin.x + m_vMin.y;
99  if (fVal > dminz)
100  nInside++;
101  if (fVal < dmaxz)
102  nInside++;
103 
104  fVal = m_vMax.x + m_vMin.y;
105  if (fVal > dminz)
106  nInside++;
107  if (fVal < dmaxz)
108  nInside++;
109 
110  fVal = m_vMin.x + m_vMax.y;
111  if (fVal > dminz)
112  nInside++;
113  if (fVal < dmaxz)
114  nInside++;
115 
116  fVal = m_vMax.x + m_vMax.y;
117  if (fVal > dminz)
118  nInside++;
119  if (fVal < dmaxz)
120  nInside++;
121 
122  return nInside;
123  }
124 
125  DVALUE_t get_Volume() const noexcept
126  {
127  if (IsEmptyBox())
128  return 0;
129  return get_Width() * get_Height() * get_Depth() ;
130  }
131 
132  DVALUE_t GetDistanceBound(const cVector3f &p) const noexcept
133  {
135  DVALUE_t dnx = (p.x < m_vMin.x) ? Calc::Abs(p.x - m_vMin.x) : 0;
136  DVALUE_t dny = (p.y < m_vMin.y) ? Calc::Abs(p.y - m_vMin.y) : 0;
137  DVALUE_t dnz = (p.z < m_vMin.z) ? Calc::Abs(p.z - m_vMin.z) : 0;
138 
139  DVALUE_t dpx = (p.x > m_vMax.x) ? Calc::Abs(p.x - m_vMax.x) : 0;
140  DVALUE_t dpy = (p.y > m_vMax.y) ? Calc::Abs(p.y - m_vMax.y) : 0;
141  DVALUE_t dpz = (p.z > m_vMax.z) ? Calc::Abs(p.z - m_vMax.x) : 0;
142 
143  DVALUE_t max_x = (dnx > dpx) ? dnx : dpx;
144  DVALUE_t max_y = (dny > dpy) ? dny : dpy;
145  DVALUE_t max_z = (dnz > dpz) ? dnz : dpz;
146  DVALUE_t max_max = (max_x > max_y) ? max_x : max_y;
147 
148  return (max_max > max_z) ? max_max : max_z;
149  }
150  DVALUE_t GetShortestDistanceToSq(const cVector3f& point) const
151  {
153  DVALUE_t d = 0;
154  for (int i = 0; i < 3; ++i)
155  {
156  DVALUE_t ci;
157  if ((ci = m_vMin[i] - point[i]) > 0)
158  d += Calc::Sqr(ci);
159  else if ((ci = point[i] - m_vMax[i]) > 0)
160  d += Calc::Sqr(ci);
161  }
162  return d;
163  }
164 
165  void GetVertices(cVector3f* pVerts) const;
166 
167  GINTERSECT_TYPE GetIntersectBounds(const cBounds3f& bbox) const;
168  bool IsIntersectSegment(const cSegment3f& segment) const;
169  bool TestRay(const cVector3f& vPickRayOrig, const cVector3f& vPickRayDir, DVALUE_t& fDistMax) const;
170 
172  void SetNormalized(const cVector3f& v1, const cVector3f& v2)
173  {
175  for (int i = 0; i < 3; i++)
176  {
177  if (v1[i] < v2[i])
178  {
179  m_vMin.m_a[i] = v1[i];
180  m_vMax.m_a[i] = v2[i];
181  }
182  else
183  {
184  m_vMin.m_a[i] = v2[i];
185  m_vMax.m_a[i] = v1[i];
186  }
187  }
188  }
189  void SetFromSphereO(const cVector3f& vPt, DVALUE_t fRadius)
190  {
193  ASSERT(fRadius >= 0);
194  for (int i = 0; i < 3; i++)
195  {
196  m_vMin.m_a[i] = vPt.m_a[i] - fRadius;
197  m_vMax.m_a[i] = vPt.m_a[i] + fRadius;
198  }
199  // 31.946184 + 1 = 32.946182 sometimes?
200  ASSERT(IsInsideBox(vPt, fRadius));
201  }
202 
203 #if 0
204  void SetFromSphereI(const cVector3f& vPt, DVALUE_t fRadius)
205  {
207  UNREFERENCED_PARAMETER(vPt);
208  UNREFERENCED_PARAMETER(fRadius);
209  ASSERT(fRadius >= 0);
210  ASSERT(0);
211  }
212 #endif
213 
214  void ComputeBoundingBox(const cVector3f* pVerts, UINT dwNumVertices, size_t nVertStride);
215 
217  void UnionAxis(AXIS_TYPE eAxis, DVALUE_t fVal)
218  {
220  if (fVal < m_vMin.m_a[eAxis])
221  m_vMin.m_a[eAxis] = fVal;
222  if (fVal > m_vMax.m_a[eAxis])
223  m_vMax.m_a[eAxis] = fVal;
224  }
225  void UnionVect(const cVector3f& v)
226  {
228  for (int i = 0; i < 3; i++)
229  {
230  UnionAxis((AXIS_TYPE)i, v.m_a[i]);
231  }
232  }
233  void UnionTriangle(const cVector3f& v1, const cVector3f& v2, const cVector3f& v3)
234  {
235  UnionVect(v1);
236  UnionVect(v2);
237  UnionVect(v3);
238  }
239  void SetNormalized()
240  {
242  for (int i = 0; i < 3; i++)
243  {
244  if (m_vMin.m_a[i] > m_vMax.m_a[i])
245  {
246  cMemT::Swap(m_vMin.m_a[i], m_vMax.m_a[i]);
247  }
248  }
249  }
250  void UnionBox(const cBounds3f& box)
251  {
253  for (int i = 0; i < 3; i++)
254  {
255  if (m_vMin.m_a[i] > box.m_vMin.m_a[i])
256  m_vMin.m_a[i] = box.m_vMin.m_a[i];
257  if (m_vMax.m_a[i] < box.m_vMax.m_a[i])
258  m_vMax.m_a[i] = box.m_vMax.m_a[i];
259  }
260  }
261 
262  void UnionSphere(const cVector3f& vPt, DVALUE_t fRadius)
263  {
265  ASSERT(fRadius >= 0);
266  for (int i = 0; i < 3; i++)
267  {
268  UnionAxis((AXIS_TYPE)i, vPt.m_a[i] + fRadius);
269  UnionAxis((AXIS_TYPE)i, vPt.m_a[i] - fRadius);
270  }
271  }
272 
273  void TransformBBox(const cMatrix4x4f& M);
274 
275  UNITTEST_FRIEND(cBounds3);
276  };
277 };
278 #endif // _INC_cBounds3_H
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
#define DECLSPEC_UUID(x)
Definition: IUnknown.h:19
Definition: cSphere.h:20
Definition: cMesh.h:22