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 <stdio.h>
00020 #include <iostream.h>
00021 #include "UT_Assert.h"
00022 #include "UT_Vector3.h"
00023
00024 class UT_Vector4;
00025 class UT_Matrix4;
00026
00027
00028 class UT_API UT_BoundingBox {
00029 public:
00030 UT_BoundingBox() {}
00031
00032
00033 UT_BoundingBox(fpreal axmin, fpreal aymin, fpreal azmin,
00034 fpreal axmax, fpreal aymax, fpreal azmax)
00035 {
00036 setBounds(axmin, aymin, azmin, axmax, aymax, azmax);
00037 }
00038
00039 UT_BoundingBox(const UT_Vector3 &lowerbound,
00040 const UT_Vector3 &upperbound)
00041 {
00042 vals[0][0] = lowerbound.vec[0];
00043 vals[0][1] = upperbound.vec[0];
00044 vals[1][0] = lowerbound.vec[1];
00045 vals[1][1] = upperbound.vec[1];
00046 vals[2][0] = lowerbound.vec[2];
00047 vals[2][1] = upperbound.vec[2];
00048 }
00049
00050
00051
00052
00053 float operator()(unsigned m, unsigned n) const
00054 {
00055 UT_ASSERT_P( m < 3 && n < 2 );
00056 return vals[m][n];
00057 }
00058 float &operator()(unsigned m, unsigned n)
00059 {
00060 UT_ASSERT_P( m < 3 && n < 2 );
00061 return vals[m][n];
00062 }
00063 bool operator==(const UT_BoundingBox &bbox) const
00064 {
00065 return vals[0][0] == bbox.vals[0][0] &&
00066 vals[0][1] == bbox.vals[0][1] &&
00067 vals[1][0] == bbox.vals[1][0] &&
00068 vals[1][1] == bbox.vals[1][1] &&
00069 vals[2][0] == bbox.vals[2][0] &&
00070 vals[2][1] == bbox.vals[2][1];
00071 }
00072 bool operator!=(const UT_BoundingBox &bbox) const
00073 {
00074 return !(*this == bbox);
00075 }
00076 bool isEqual(const UT_BoundingBox &bbox,
00077 fpreal tol = UT_FTOLERANCE) const
00078 {
00079 return SYSisEqual(vals[0][0], bbox.vals[0][0], tol) &&
00080 SYSisEqual(vals[0][1], bbox.vals[0][1], tol) &&
00081 SYSisEqual(vals[1][0], bbox.vals[1][0], tol) &&
00082 SYSisEqual(vals[1][1], bbox.vals[1][1], tol) &&
00083 SYSisEqual(vals[2][0], bbox.vals[2][0], tol) &&
00084 SYSisEqual(vals[2][1], bbox.vals[2][1], tol);
00085 }
00086
00087 fpreal xmin() const { return vals[0][0]; }
00088 fpreal xmax() const { return vals[0][1]; }
00089 fpreal ymin() const { return vals[1][0]; }
00090 fpreal ymax() const { return vals[1][1]; }
00091 fpreal zmin() const { return vals[2][0]; }
00092 fpreal zmax() const { return vals[2][1]; }
00093
00094 UT_Vector3 minvec() const
00095 { return UT_Vector3(vals[0][0], vals[1][0], vals[2][0]); }
00096 UT_Vector3 maxvec() const
00097 { return UT_Vector3(vals[0][1], vals[1][1], vals[2][1]); }
00098
00099 int isInside(const UT_Vector3 &pt) const;
00100 int isInside(const UT_Vector4 &pt) const;
00101 int isInside(fpreal x, fpreal y, fpreal z) const;
00102
00103
00104
00105 int isInside(const UT_BoundingBox &bbox) const;
00106
00107 int isLineInside(const UT_Vector3 &v0,
00108 const UT_Vector3 &v1) const;
00109
00110
00111 bool isValid() const;
00112 void makeInvalid() { initBounds(); }
00113
00114 void setBounds(fpreal x_min, fpreal y_min, fpreal z_min,
00115 fpreal x_max, fpreal y_max, fpreal z_max)
00116 {
00117 vals[0][0] = x_min;
00118 vals[1][0] = y_min;
00119 vals[2][0] = z_min;
00120 vals[0][1] = x_max;
00121 vals[1][1] = y_max;
00122 vals[2][1] = z_max;
00123 }
00124
00125
00126 void initMaxBounds();
00127
00128
00129
00130
00131 void initBounds();
00132 void initBounds(const UT_Vector3 &min, const UT_Vector3 &max);
00133 void initBounds(const UT_Vector3 &pt);
00134 void initBounds(const UT_Vector4 &pt);
00135 void initBounds(fpreal x, fpreal y, fpreal z);
00136 void initBounds(const UT_BoundingBox &box);
00137
00138 void enlargeBounds(const UT_Vector3 &min, const UT_Vector3 &max);
00139 void enlargeBounds(const UT_Vector3 &pt);
00140 void enlargeBounds(const UT_Vector4 &pt);
00141 void enlargeBounds(fpreal x, fpreal y, fpreal z);
00142 void enlargeBounds(const UT_BoundingBox &box);
00143 void enlargeBounds(fpreal percent = 0.001F, fpreal min = 0.001F);
00144 void expandBounds(fpreal dltx, fpreal dlty, fpreal dlyz);
00145
00146
00147
00148
00149
00150
00151 void enlargeFloats(int bits = 1, fpreal min = 1e-5F);
00152
00153
00154 void clipBounds(const UT_BoundingBox &box);
00155
00156
00157
00158
00159 void splitLeft(UT_BoundingBox &box, int axis, fpreal split)
00160 {
00161 box = *this;
00162 box.vals[axis][0] = split;
00163 vals[axis][1] = split;
00164 }
00165 void splitRight(UT_BoundingBox &box, int axis, fpreal split)
00166 {
00167 box = *this;
00168 box.vals[axis][1] = split;
00169 vals[axis][0] = split;
00170 }
00171
00172 void transform(const UT_Matrix4 &mat);
00173 void transform(const UT_Matrix4 &mat,
00174 UT_BoundingBox &newbbox) const;
00175
00176
00177 void translate(const UT_Vector3 &delta);
00178
00179 fpreal xsize() const { return sizeX(); }
00180 fpreal ysize() const { return sizeY(); }
00181 fpreal zsize() const { return sizeZ(); }
00182 fpreal sizeX() const { return vals[0][1] - vals[0][0]; }
00183 fpreal sizeY() const { return vals[1][1] - vals[1][0]; }
00184 fpreal sizeZ() const { return vals[2][1] - vals[2][0]; }
00185
00186 UT_Vector3 size() const
00187 { return UT_Vector3(vals[0][1] - vals[0][0],
00188 vals[1][1] - vals[1][0],
00189 vals[2][1] - vals[2][0]); }
00190 fpreal sizeAxis(int axis) const
00191 {
00192 UT_ASSERT(axis >= 0 && axis < 3);
00193 return vals[axis][1] - vals[axis][0];
00194 }
00195
00196
00197 fpreal sizeMax() const;
00198
00199
00200 fpreal sizeMax(int &axis) const;
00201
00202
00203 UT_Vector3 minDistDelta(const UT_Vector3 &p) const;
00204 UT_Vector3 minDistDelta(const UT_BoundingBox &box) const;
00205
00206
00207 fpreal minDist2(const UT_Vector3 &p) const
00208 { return minDistDelta(p).length2(); }
00209
00210 fpreal minDist2(const UT_BoundingBox &box) const
00211 { return minDistDelta(box).length2(); }
00212
00213
00214 int getOutCode(const UT_Vector3 &pt) const;
00215
00216 fpreal xcenter() const { return centerX(); }
00217 fpreal ycenter() const { return centerY(); }
00218 fpreal zcenter() const { return centerZ(); }
00219 fpreal centerX() const { return (vals[0][0] + vals[0][1])*0.5F; }
00220 fpreal centerY() const { return (vals[1][0] + vals[1][1])*0.5F; }
00221 fpreal centerZ() const { return (vals[2][0] + vals[2][1])*0.5F; }
00222 fpreal centerAxis(int axis) const
00223 { return (vals[axis][0] + vals[axis][1])*0.5F; }
00224 UT_Vector3 center() const
00225 { return UT_Vector3((vals[0][0] + vals[0][1])*0.5F,
00226 (vals[1][0] + vals[1][1])*0.5F,
00227 (vals[2][0] + vals[2][1])*0.5F); }
00228
00229 fpreal area() const;
00230 fpreal volume() const { return xsize()*ysize()*zsize(); }
00231 void addToMin(const UT_Vector3 &vec);
00232 void addToMax(const UT_Vector3 &vec);
00233
00234
00235 void scaleOffset(const UT_Vector3 &scale,
00236 const UT_Vector3 &offset);
00237 int maxAxis() const;
00238 int minAxis() const;
00239
00240
00241
00242
00243
00244
00245 int intersectRay(const UT_Vector3 &org,
00246 const UT_Vector3 &dir,
00247 fpreal tmax=1E17F,
00248 float *distance=0, UT_Vector3 *nml=0) const;
00249 int intersectRange(const UT_Vector3 &org,
00250 const UT_Vector3 &dir,
00251 float &min, float &max) const;
00252
00253
00254
00255 int intersectTube(const UT_Vector3 &org,
00256 const UT_Vector3 &dir,
00257 fpreal radius,
00258 fpreal tmin=-1E17f, fpreal tmax=1E17f) const;
00259
00260 int intersects(const UT_BoundingBox &box) const;
00261
00262
00263
00264 int computeIntersection(const UT_BoundingBox &box);
00265
00266
00267 float vals[3][2];
00268
00269 void getBBoxPoints(UT_Vector3 (&ptarray)[8]) const;
00270 int getBBoxPoints(UT_Vector3 (&ptarray)[8],
00271 const UT_Matrix4 &transform_matrix) const;
00272
00273
00274 void dump(const char *msg=0) const;
00275
00276 void dumpGeo(FILE *fp) const;
00277
00278 protected:
00279 friend
00280 ostream &operator<<(ostream &os, const UT_BoundingBox &box)
00281 {
00282 box.outTo(os);
00283 return os;
00284 }
00285
00286 void outTo(ostream &os) const;
00287 void enlargeBoundsByPtArray(UT_Vector3 (&ptarray)[8],
00288 bool init = false);
00289 };
00290
00291 #endif