00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __UT_BoundingBox_h__
00016 #define __UT_BoundingBox_h__
00017
00018 #include "UT_API.h"
00019 #include "UT_Assert.h"
00020 #include "UT_Vector3.h"
00021 #include "UT_VectorTypes.h"
00022 #include <iostream.h>
00023
00024
00025 template <typename T>
00026 class UT_API UT_BoundingBoxT
00027 {
00028 public:
00029 UT_BoundingBoxT() {}
00030
00031
00032 UT_BoundingBoxT(T axmin, T aymin, T azmin,
00033 T axmax, T aymax, T azmax)
00034 {
00035 setBounds(axmin, aymin, azmin, axmax, aymax, azmax);
00036 }
00037
00038 UT_BoundingBoxT(const UT_Vector3T<T> &lowerbound,
00039 const UT_Vector3T<T> &upperbound)
00040 {
00041 vals[0][0] = lowerbound.vec[0];
00042 vals[0][1] = upperbound.vec[0];
00043 vals[1][0] = lowerbound.vec[1];
00044 vals[1][1] = upperbound.vec[1];
00045 vals[2][0] = lowerbound.vec[2];
00046 vals[2][1] = upperbound.vec[2];
00047 }
00048
00049 template <typename S>
00050 UT_BoundingBoxT(const UT_BoundingBoxT<S> &bbox)
00051 {
00052 vals[0][0] = bbox.vals[0][0];
00053 vals[0][1] = bbox.vals[0][1];
00054 vals[1][0] = bbox.vals[1][0];
00055 vals[1][1] = bbox.vals[1][1];
00056 vals[2][0] = bbox.vals[2][0];
00057 vals[2][1] = bbox.vals[2][1];
00058 }
00059
00060 template <typename S>
00061 UT_BoundingBoxT &operator=(const UT_BoundingBoxT<S> &bbox)
00062 {
00063 vals[0][0] = bbox.vals[0][0];
00064 vals[0][1] = bbox.vals[0][1];
00065 vals[1][0] = bbox.vals[1][0];
00066 vals[1][1] = bbox.vals[1][1];
00067 vals[2][0] = bbox.vals[2][0];
00068 vals[2][1] = bbox.vals[2][1];
00069 return *this;
00070 }
00071
00072 T operator()(unsigned m, unsigned n) const
00073 {
00074 UT_ASSERT_P( m < 3 && n < 2 );
00075 return vals[m][n];
00076 }
00077 T &operator()(unsigned m, unsigned n)
00078 {
00079 UT_ASSERT_P( m < 3 && n < 2 );
00080 return vals[m][n];
00081 }
00082 bool operator==(const UT_BoundingBoxT<T> &bbox) const
00083 {
00084 return vals[0][0] == bbox.vals[0][0] &&
00085 vals[0][1] == bbox.vals[0][1] &&
00086 vals[1][0] == bbox.vals[1][0] &&
00087 vals[1][1] == bbox.vals[1][1] &&
00088 vals[2][0] == bbox.vals[2][0] &&
00089 vals[2][1] == bbox.vals[2][1];
00090 }
00091 bool operator!=(const UT_BoundingBoxT<T> &bbox) const
00092 {
00093 return !(*this == bbox);
00094 }
00095 bool isEqual(const UT_BoundingBoxT<T> &bbox,
00096 T tol = SYS_FTOLERANCE_R) const
00097 {
00098 return SYSisEqual(vals[0][0], bbox.vals[0][0], tol) &&
00099 SYSisEqual(vals[0][1], bbox.vals[0][1], tol) &&
00100 SYSisEqual(vals[1][0], bbox.vals[1][0], tol) &&
00101 SYSisEqual(vals[1][1], bbox.vals[1][1], tol) &&
00102 SYSisEqual(vals[2][0], bbox.vals[2][0], tol) &&
00103 SYSisEqual(vals[2][1], bbox.vals[2][1], tol);
00104 }
00105
00106 T xmin() const { return vals[0][0]; }
00107 T xmax() const { return vals[0][1]; }
00108 T ymin() const { return vals[1][0]; }
00109 T ymax() const { return vals[1][1]; }
00110 T zmin() const { return vals[2][0]; }
00111 T zmax() const { return vals[2][1]; }
00112
00113 UT_Vector3T<T> minvec() const
00114 { return UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][0]); }
00115 UT_Vector3T<T> maxvec() const
00116 { return UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][1]); }
00117
00118 int isInside(const UT_Vector3T<T> &pt) const;
00119 int isInside(const UT_Vector4T<T> &pt) const;
00120 int isInside(T x, T y, T z) const;
00121
00122
00123
00124 int isInside(const UT_BoundingBoxT<T> &bbox) const;
00125
00126
00127
00128 int isLineInside(const UT_Vector3T<T> &v0,
00129 const UT_Vector3T<T> &idir) const;
00130
00131
00132
00133
00134
00135
00136 T approxLineDist2(const UT_Vector3T<T> &v0,
00137 const UT_Vector3T<T> &dir) const;
00138
00139
00140 bool isValid() const;
00141 void makeInvalid() { initBounds(); }
00142
00143 void setBounds(T x_min, T y_min, T z_min,
00144 T x_max, T y_max, T z_max)
00145 {
00146 vals[0][0] = x_min;
00147 vals[1][0] = y_min;
00148 vals[2][0] = z_min;
00149 vals[0][1] = x_max;
00150 vals[1][1] = y_max;
00151 vals[2][1] = z_max;
00152 }
00153
00154
00155
00156
00157 void setSerialized(const fpreal32 floats[6])
00158 {
00159 for (int i = 0; i < 6; ++i)
00160 myFloats[i] = floats[i];
00161 }
00162 void setSerialized(const fpreal64 floats[6])
00163 {
00164 for (int i = 0; i < 6; ++i)
00165 myFloats[i] = floats[i];
00166 }
00167 const T *getSerialized() const { return myFloats; }
00168
00169
00170
00171 void initMaxBounds();
00172
00173
00174
00175
00176 void initBounds();
00177 void initBounds(const UT_Vector3T<T> &min,
00178 const UT_Vector3T<T> &max);
00179 void initBounds(const UT_Vector3T<T> &pt);
00180 void initBounds(const UT_Vector4T<T> &pt);
00181 void initBounds(T x, T y, T z);
00182 void initBounds(const fpreal32 *v)
00183 { initBounds(v[0], v[1], v[2]); }
00184 void initBounds(const fpreal64 *v)
00185 { initBounds(v[0], v[1], v[2]); }
00186 void initBounds(const UT_BoundingBoxT<T> &box);
00187
00188 void enlargeBounds(const UT_Vector3T<T> &min,
00189 const UT_Vector3T<T> &max);
00190 void enlargeBounds(const UT_Vector3T<T> &pt);
00191 void enlargeBounds(const UT_Vector4T<T> &pt);
00192 void enlargeBounds(T x, T y, T z);
00193 void enlargeBounds(const fpreal32 *v)
00194 { enlargeBounds(v[0], v[1], v[2]); }
00195 void enlargeBounds(const fpreal64 *v)
00196 { enlargeBounds(v[0], v[1], v[2]); }
00197 void enlargeBounds(const UT_BoundingBoxT<T> &box);
00198 void enlargeBounds(T percent = 0.001, T min = 0.001);
00199 void expandBounds(T dltx, T dlty, T dlyz);
00200
00201
00202
00203
00204
00205
00206 void enlargeFloats(int bits = 1, T min = 1e-5);
00207
00208
00209 void clipBounds(const UT_BoundingBoxT<T> &box);
00210
00211
00212
00213
00214 void splitLeft(UT_BoundingBoxT<T> &box, int axis, T split)
00215 {
00216 box = *this;
00217 box.vals[axis][0] = split;
00218 vals[axis][1] = split;
00219 }
00220 void splitRight(UT_BoundingBoxT<T> &box, int axis, T split)
00221 {
00222 box = *this;
00223 box.vals[axis][1] = split;
00224 vals[axis][0] = split;
00225 }
00226
00227 template <typename S>
00228 void transform(const UT_Matrix4T<S> &mat);
00229 template <typename S>
00230 void transform(const UT_Matrix4T<S> &mat,
00231 UT_BoundingBoxT<T> &newbbox) const;
00232
00233
00234 void translate(const UT_Vector3T<T> &delta);
00235
00236 T xsize() const { return sizeX(); }
00237 T ysize() const { return sizeY(); }
00238 T zsize() const { return sizeZ(); }
00239 T sizeX() const { return vals[0][1] - vals[0][0]; }
00240 T sizeY() const { return vals[1][1] - vals[1][0]; }
00241 T sizeZ() const { return vals[2][1] - vals[2][0]; }
00242
00243 UT_Vector3T<T> size() const
00244 { return UT_Vector3T<T>(vals[0][1] - vals[0][0],
00245 vals[1][1] - vals[1][0],
00246 vals[2][1] - vals[2][0]); }
00247 T sizeAxis(int axis) const
00248 {
00249 UT_ASSERT(axis >= 0 && axis < 3);
00250 return vals[axis][1] - vals[axis][0];
00251 }
00252
00253
00254 T sizeMax() const;
00255
00256
00257 T sizeMax(int &axis) const;
00258
00259
00260 UT_Vector3T<T> minDistDelta(const UT_Vector3T<T> &p) const;
00261 UT_Vector3T<T> minDistDelta(const UT_BoundingBoxT<T> &box) const;
00262
00263
00264 T minDist2(const UT_Vector3T<T> &p) const
00265 { return minDistDelta(p).length2(); }
00266
00267 T minDist2(const UT_BoundingBoxT<T> &box) const
00268 { return minDistDelta(box).length2(); }
00269
00270
00271 T getRadius() const { return 0.5*size().length(); }
00272
00273
00274 int getOutCode(const UT_Vector3T<T> &pt) const;
00275
00276 T xcenter() const { return centerX(); }
00277 T ycenter() const { return centerY(); }
00278 T zcenter() const { return centerZ(); }
00279 T centerX() const { return (vals[0][0] + vals[0][1])*0.5; }
00280 T centerY() const { return (vals[1][0] + vals[1][1])*0.5; }
00281 T centerZ() const { return (vals[2][0] + vals[2][1])*0.5; }
00282 T centerAxis(int axis) const
00283 { return (vals[axis][0] + vals[axis][1])*0.5; }
00284 UT_Vector3T<T> center() const
00285 { return UT_Vector3T<T>((vals[0][0] + vals[0][1])*0.5,
00286 (vals[1][0] + vals[1][1])*0.5,
00287 (vals[2][0] + vals[2][1])*0.5); }
00288
00289 T area() const;
00290 T volume() const { return xsize()*ysize()*zsize(); }
00291 void addToMin(const UT_Vector3T<T> &vec);
00292 void addToMax(const UT_Vector3T<T> &vec);
00293
00294
00295 void scaleOffset(const UT_Vector3T<T> &scale,
00296 const UT_Vector3T<T> &offset);
00297 int maxAxis() const;
00298 int minAxis() const;
00299
00300
00301
00302
00303
00304
00305 int intersectRay(const UT_Vector3T<T> &org,
00306 const UT_Vector3T<T> &dir,
00307 T tmax=1E17F,
00308 T *distance=0, UT_Vector3T<T> *nml=0) const;
00309 int intersectRange(const UT_Vector3T<T> &org,
00310 const UT_Vector3T<T> &dir,
00311 T &min, T &max) const;
00312
00313
00314
00315 int intersectTube(const UT_Vector3T<T> &org,
00316 const UT_Vector3T<T> &dir,
00317 T radius,
00318 T tmin=-1E17f, T tmax=1E17f) const;
00319
00320 int intersects(const UT_BoundingBoxT<T> &box) const;
00321
00322
00323
00324 int computeIntersection(const UT_BoundingBoxT<T> &box);
00325
00326
00327 union {
00328 T vals[3][2];
00329 T myFloats[6];
00330 };
00331
00332 void getBBoxPoints(UT_Vector3T<T> (&ptarray)[8]) const;
00333 template <typename S>
00334 int getBBoxPoints(UT_Vector3T<T> (&ptarray)[8],
00335 const UT_Matrix4T<S> &transform_matrix) const;
00336
00337
00338 void dump(const char *msg=0) const;
00339
00340 void dumpGeo(FILE *fp) const;
00341
00342
00343
00344
00345 bool save(UT_JSONWriter &w) const;
00346 bool save(UT_JSONValue &v) const;
00347 bool load(UT_JSONParser &p);
00348
00349
00350
00351 protected:
00352 friend
00353 ostream &operator<<(ostream &os, const UT_BoundingBoxT<T> &box)
00354 {
00355 box.outTo(os);
00356 return os;
00357 }
00358
00359 void outTo(ostream &os) const;
00360 void enlargeBoundsByPtArray(UT_Vector3T<T> (&ptarray)[8],
00361 bool init = false);
00362 };
00363
00364 typedef UT_BoundingBoxT<fpreal> UT_BoundingBoxR;
00365 typedef UT_BoundingBoxT<fpreal32> UT_BoundingBoxF;
00366 typedef UT_BoundingBoxT<fpreal64> UT_BoundingBoxD;
00367 typedef UT_BoundingBoxT<float> UT_BoundingBox;
00368
00369 #endif