00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __SGL_BOX_BOUND_HPP
00026 #define __SGL_BOX_BOUND_HPP
00027
00028 #include <sgl.h>
00029 #include <sglVector.hpp>
00030 #include <sglBound.hpp>
00031 #include <sglPlane.hpp>
00032 #include <sglPolytope.hpp>
00033 #include <sglSegment.hpp>
00034
00035 class SGL_DLL_API sglBoxBound : public sglBound
00036 {
00037 public:
00038 sglBoxBound();
00039 sglBoxBound(const sglBoxBound &);
00040 sglBoxBound &operator=(const sglBoxBound &);
00041
00042 ~sglBoxBound() {};
00043
00044 void makeEmpty();
00045 bool isEmpty() const { return (m_min[0]>m_max[0]); }
00046
00047
00048
00049 void setMin(float x, float y, float z) { m_min.set(x,y,z); }
00050 void setMin(const sglVec3f &min) { m_min = min; }
00051 const sglVec3f &getMin() const { return m_min; }
00052
00053 void setMax(float x, float y, float z) { m_max.set(x,y,z); }
00054 void setMax(const sglVec3f &max) { m_max = max; }
00055 const sglVec3f &getMax() const { return m_max; }
00056
00057
00058
00059 void expandToInclude(const sglVec3f & point);
00060 void expandToInclude(const sglBoxBound &box);
00061 static void expandToInclude2s(sglBoxBound *bbox, const void *ptr);
00062 static void expandToInclude2i(sglBoxBound *bbox, const void *ptr);
00063 static void expandToInclude2f(sglBoxBound *bbox, const void *ptr);
00064 static void expandToInclude2d(sglBoxBound *bbox, const void *ptr);
00065 static void expandToInclude3s(sglBoxBound *bbox, const void *ptr);
00066 static void expandToInclude3i(sglBoxBound *bbox, const void *ptr);
00067 static void expandToInclude3f(sglBoxBound *bbox, const void *ptr);
00068 static void expandToInclude3d(sglBoxBound *bbox, const void *ptr);
00069 static void expandToInclude4s(sglBoxBound *bbox, const void *ptr);
00070 static void expandToInclude4i(sglBoxBound *bbox, const void *ptr);
00071 static void expandToInclude4f(sglBoxBound *bbox, const void *ptr);
00072 static void expandToInclude4d(sglBoxBound *bbox, const void *ptr);
00073
00074 typedef void (*ExpandToIncludeFunc)(sglBoxBound *, const void *vtx);
00075
00076
00077 static ExpandToIncludeFunc getExpandToIncludeFunc(int vertex_type)
00078 { return s_expand_to_include_func_table[vertex_type]; }
00079
00080
00081
00082
00083
00084
00085 template <class S>
00086 IntersectResultEnum intersect(sglSegment<S> &ray) const
00087 {
00088
00089 if (isEmpty()) return eOUTSIDE;
00090
00091 enum LocationEnum {eRIGHT = 0, eLEFT = 1, eMIDDLE = 2};
00092 int quadrant[3];
00093 register unsigned int i;
00094 unsigned int whichPlane;
00095 sglVec3<S> maxT;
00096 sglVec3<S> candidatePlane;
00097 sglVec3<S> coord;
00098
00099
00100
00101 sglVec3<S> origin(ray.getPos());
00102 sglVec3<S> dir(ray.getDir());
00103
00104
00105
00106 bool inside = TRUE;
00107 for (i=0; i<3; i++)
00108 {
00109 if (origin[i] < m_min[i])
00110 {
00111 quadrant[i] = eLEFT;
00112 candidatePlane[i] = m_min[i];
00113 inside = FALSE;
00114 }
00115 else if (origin[i] > m_max[i])
00116 {
00117 quadrant[i] = eRIGHT;
00118 candidatePlane[i] = m_max[i];
00119 inside = FALSE;
00120 }
00121 else
00122 {
00123 quadrant[i] = eMIDDLE;
00124 }
00125 }
00126
00127
00128 if (inside)
00129 {
00130 return eINSIDE;
00131 }
00132
00133
00134
00135 for (i = 0; i < 3; i++)
00136 {
00137 if ((quadrant[i] != eMIDDLE) && (dir[i] != 0.))
00138 maxT[i] = (candidatePlane[i]-origin[i]) / dir[i];
00139 else
00140 maxT[i] = -1.;
00141 }
00142
00143
00144 whichPlane = 0;
00145 for (i = 1; i < 3; i++)
00146 {
00147 if (maxT[whichPlane] < maxT[i])
00148 {
00149 whichPlane = i;
00150 }
00151 }
00152
00153
00154 if (maxT[whichPlane] < 0. || maxT[whichPlane] > ray.getLen())
00155 {
00156 return eOUTSIDE;
00157 }
00158
00159 for (i = 0; i < 3; i++)
00160 {
00161 if (whichPlane != i)
00162 {
00163 coord[i] = origin[i] + maxT[whichPlane] *dir[i];
00164 if (coord[i] < m_min[i] || coord[i] > m_max[i])
00165 {
00166 return eOUTSIDE;
00167 }
00168 }
00169 else
00170 {
00171 coord[i] = candidatePlane[i];
00172 }
00173 }
00174
00175 ray.setLen(maxT[whichPlane]);
00176 return eINTERSECT;
00177 }
00178
00179
00180 template <class S>
00181 IntersectResultEnum intersect(const sglPlane<S> &plane) const
00182 {
00183
00184 if (m_max[0] < m_min[0])
00185 return eOUTSIDE;
00186
00187
00188 sglVec3f vmin, vmax;
00189 sglVec3f pnorm = plane.getNormal();
00190
00191 if (pnorm[0] > 0.f)
00192 {
00193 vmin[0] = m_min[0];
00194 vmax[0] = m_max[0];
00195 }
00196 else
00197 {
00198 vmin[0] = m_max[0];
00199 vmax[0] = m_min[0];
00200 }
00201
00202 if (pnorm[1] > 0.f)
00203 {
00204 vmin[1] = m_min[1];
00205 vmax[1] = m_max[1];
00206 }
00207 else
00208 {
00209 vmin[1] = m_max[1];
00210 vmax[1] = m_min[1];
00211 }
00212
00213 if (pnorm[2] > 0.f)
00214 {
00215 vmin[2] = m_min[2];
00216 vmax[2] = m_max[2];
00217 }
00218 else
00219 {
00220 vmin[2] = m_max[2];
00221 vmax[2] = m_min[2];
00222 }
00223
00224
00225 if (plane.signedDistance(vmax) < 0.f)
00226 return eOUTSIDE;
00227 else if (plane.signedDistance(vmin) >= 0.f)
00228 return eINSIDE;
00229 else
00230 return eINTERSECT;
00231 }
00232
00233 template <class S>
00234 IntersectResultEnum intersect(const sglPolytope<S> &ptope) const
00235 {
00236 bool intersect_flag = false;
00237
00238 for (unsigned int i=0; i<ptope.getNumPlanes(); i++)
00239 {
00240 IntersectResultEnum result = intersect(ptope.getPlane(i));
00241 if (result == eOUTSIDE)
00242 {
00243 return eOUTSIDE;
00244 }
00245 else if (result == eINTERSECT)
00246 {
00247 intersect_flag = true;
00248 }
00249 }
00250
00251 if (!intersect_flag)
00252 {
00253 return eINSIDE;
00254 }
00255
00256
00257
00258 return eINTERSECT;
00259 }
00260
00261 #if 1 //defined(WIN32)
00262 template <class S>
00263 IntersectResultEnum intersect(const sglPolytope<S> &ptope,
00264 unsigned int &plane_flags) const
00265 {
00266 unsigned int cull_flags = 0;
00267
00268 for (unsigned int i=0; i<ptope.getNumPlanes(); i++)
00269 {
00270
00271
00272 if (plane_flags & (1<<i))
00273 {
00274 IntersectResultEnum result = intersect(ptope.getPlane(i));
00275 if (result == eOUTSIDE)
00276 {
00277 plane_flags=0;
00278 return eOUTSIDE;
00279 }
00280 else if (result == eINTERSECT)
00281 {
00282 cull_flags |= (1<<i);
00283 }
00284 }
00285 }
00286
00287 if (cull_flags == 0)
00288 {
00289 plane_flags=0;
00290 return eINSIDE;
00291 }
00292
00293
00294
00295 plane_flags = cull_flags;
00296 return eINTERSECT;
00297 }
00298 #else
00299 IntersectResultEnum intersect(const sglPolytope<float> &ptope,
00300 unsigned int &plane_flags) const
00301 {
00302 unsigned int cull_flags = 0;
00303
00304 for (unsigned int i=0; i<ptope.getNumPlanes(); i++)
00305 {
00306
00307
00308 if (plane_flags & (1<<i))
00309 {
00310 IntersectResultEnum result = intersect(ptope.getPlane(i));
00311 if (result == eOUTSIDE)
00312 {
00313 plane_flags=0;
00314 return eOUTSIDE;
00315 }
00316 else if (result == eINTERSECT)
00317 {
00318 cull_flags |= (1<<i);
00319 }
00320 }
00321 }
00322
00323 if (cull_flags == 0)
00324 {
00325 plane_flags=0;
00326 return eINSIDE;
00327 }
00328
00329
00330
00331 plane_flags = cull_flags;
00332 return eINTERSECT;
00333 }
00334
00335 IntersectResultEnum intersect(const sglPolytope<double> &ptope,
00336 unsigned int &plane_flags) const
00337 {
00338 unsigned int cull_flags = 0;
00339
00340 for (unsigned int i=0; i<ptope.getNumPlanes(); i++)
00341 {
00342
00343
00344 if (plane_flags & (1<<i))
00345 {
00346 IntersectResultEnum result = intersect(ptope.getPlane(i));
00347 if (result == eOUTSIDE)
00348 {
00349 plane_flags=0;
00350 return eOUTSIDE;
00351 }
00352 else if (result == eINTERSECT)
00353 {
00354 cull_flags |= (1<<i);
00355 }
00356 }
00357 }
00358
00359 if (cull_flags == 0)
00360 {
00361 plane_flags=0;
00362 return eINSIDE;
00363 }
00364
00365
00366
00367 plane_flags = cull_flags;
00368 return eINTERSECT;
00369 }
00370 #endif
00371
00372
00373
00374 void drawImmediate() const;
00375 void drawOcclusionBox() const;
00376
00377 friend SGL_DLL_API ostream &operator<<(ostream &ostrm,
00378 const sglBoxBound &box);
00379
00380 private:
00381 static ExpandToIncludeFunc s_expand_to_include_func_table[24];
00382
00383 sglVec3f m_min;
00384 sglVec3f m_max;
00385 };
00386
00387 SGL_DLL_API ostream &operator<<(ostream &ostrm, const sglBoxBound &box);
00388
00389 #endif