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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "OSGConfig.h"
00045
00046 #include <cassert>
00047
00048 #include "OSGBoxVolume.h"
00049 #include "OSGLine.h"
00050 #include "OSGMatrix.h"
00051
00052
00061 OSG_BEGIN_NAMESPACE
00062
00064
00065 void BoxVolume::getCenter(Pnt3r ¢er) const
00066 {
00067 if(isEmpty() == true)
00068 {
00069 center.setValues(0.0f, 0.0f, 0.0f);
00070 }
00071 else
00072 {
00073 center = _min + (_max - _min) * .5f;
00074 }
00075 }
00076
00078
00079 Real BoxVolume::getScalarVolume() const
00080 {
00081 return (isEmpty() == true) ? 0.0f : (_max[0] - _min[0]) *
00082 (_max[1] - _min[1]) *
00083 (_max[2] - _min[2]);
00084 }
00085
00086
00087 void BoxVolume::getBounds(Pnt3r &min, Pnt3r &max) const
00088 {
00089 min = _min;
00090 max = _max;
00091 }
00092
00093 void BoxVolume::getCorners(Pnt3r &nlt, Pnt3r &nlb,
00094 Pnt3r &nrt, Pnt3r &nrb,
00095 Pnt3r &flt, Pnt3r &flb,
00096 Pnt3r &frt, Pnt3r &frb ) const
00097 {
00098 nlt.setValues(_min[0], _max[1], _min[2]);
00099 nlb.setValues(_min[0], _min[1], _min[2]);
00100 nrt.setValues(_max[0], _max[1], _min[2]);
00101 nrb.setValues(_max[0], _min[1], _min[2]);
00102
00103 flt.setValues(_min[0], _max[1], _max[2]);
00104 flb.setValues(_min[0], _min[1], _max[2]);
00105 frt.setValues(_max[0], _max[1], _max[2]);
00106 frb.setValues(_max[0], _min[1], _max[2]);
00107 }
00108
00109
00111 void BoxVolume::setBoundsByCenterAndSize(const Pnt3r ¢er,
00112 const Vec3r &size)
00113 {
00114 _min.setValues(center.x() - size.x() / 2.0f,
00115 center.y() - size.y() / 2.0f,
00116 center.z() - size.z() / 2.0f);
00117 _max.setValues(center.x() + size.x() / 2.0f,
00118 center.y() + size.y() / 2.0f,
00119 center.z() + size.z() / 2.0f);
00120
00121 Volume::setValid (true);
00122 Volume::setEmpty (size.isZero());
00123 Volume::setInfinite(false);
00124 }
00125
00126
00127
00128
00130
00131 void BoxVolume::extendBy(const Pnt3r &pt)
00132 {
00133 if(isUntouchable() == true)
00134 return;
00135
00136 if(isEmpty() == true)
00137 {
00138 _min[0] = _max[0] = pt[0];
00139 _min[1] = _max[1] = pt[1];
00140 _min[2] = _max[2] = pt[2];
00141
00142 setEmpty(false);
00143
00144 return;
00145 }
00146
00147 if(pt[0] < _min[0])
00148 {
00149 _min[0] = pt[0];
00150 }
00151 else
00152 {
00153 if(pt[0] > _max[0])
00154 _max[0] = pt[0];
00155 }
00156
00157 if(pt[1] < _min[1])
00158 {
00159 _min[1] = pt[1];
00160 }
00161 else
00162 {
00163 if(pt[1] > _max[1])
00164 _max[1] = pt[1];
00165 }
00166
00167 if(pt[2] < _min[2])
00168 {
00169 _min[2] = pt[2];
00170 }
00171 else
00172 {
00173 if(pt[2] > _max[2])
00174 _max[2] = pt[2];
00175 }
00176 }
00177
00178
00179 void BoxVolume::extendBy(const Volume &volume)
00180 {
00181 OSG::extend(*this,volume);
00182 }
00183
00184
00185
00187
00188 bool BoxVolume::intersect(const Pnt3r &pt) const
00189 {
00190 return
00191 (!isEmpty() &&
00192 (_min[0] < pt[0] && _max[0] > pt[0]) &&
00193 (_min[1] < pt[1] && _max[1] > pt[1]) &&
00194 (_min[2] < pt[2] && _max[2] > pt[2]));
00195 }
00196
00199 bool BoxVolume::intersect(const Line &line) const
00200 {
00201 Real enter;
00202 Real exit;
00203
00204 return line.intersect(*this, enter, exit);
00205 }
00206
00207
00208
00211 bool BoxVolume::intersect(const Line &line,
00212 Real &min,
00213 Real &max) const
00214 {
00215 return line.intersect(*this, min, max);
00216 }
00217
00218
00219 bool BoxVolume::intersect(const Volume &volume) const
00220 {
00221 return OSG::intersect(*this, volume);
00222 }
00223
00224
00225 bool BoxVolume::intersect(const BoxVolume &volume) const
00226 {
00227 return OSG::intersect(*this, volume);
00228 }
00229
00230
00231 bool BoxVolume::isOnSurface (const Pnt3r &point) const
00232 {
00233 if(((osgAbs(point[0] - _min[0]) < Eps ||
00234 osgAbs(point[0] - _max[0]) < Eps ) &&
00235 (point[1] >= _min[1] && point[1] <= _max[1] &&
00236 point[2] >= _min[2] && point[2] <= _max[2] ) ) ||
00237
00238 ((osgAbs(point[1] - _min[1]) < Eps ||
00239 osgAbs(point[1] - _max[1]) < Eps ) &&
00240 (point[0] >= _min[0] && point[0] <= _max[1] &&
00241 point[2] >= _min[2] && point[2] <= _max[2] ) ) ||
00242
00243 ((osgAbs(point[2] - _min[2]) < Eps ||
00244 osgAbs(point[2] - _max[2]) < Eps ) &&
00245 (point[1] >= _min[1] && point[1] <= _max[1] &&
00246 point[0] >= _min[0] && point[0] <= _max[0] ) ) )
00247 {
00248 return true;
00249 }
00250 else
00251 {
00252 return false;
00253 }
00254 }
00255
00256
00258
00259 void BoxVolume::transform(const Matrixr &m)
00260 {
00261 Real xmin;
00262 Real ymin;
00263 Real zmin;
00264 Real xmax;
00265 Real ymax;
00266 Real zmax;
00267 Real a;
00268 Real b;
00269
00270 if(isEmpty() == true)
00271 return;
00272
00273 xmin = xmax = m[3][0];
00274 ymin = ymax = m[3][1];
00275 zmin = zmax = m[3][2];
00276
00277
00278
00279
00280
00281 a = _max[0] * m[0][0];
00282 b = _min[0] * m[0][0];
00283
00284 if(a >= b)
00285 {
00286 xmax += a;
00287 xmin += b;
00288 }
00289 else
00290 {
00291 xmax += b;
00292 xmin += a;
00293 }
00294
00295 a = _max[1] * m[1][0];
00296 b = _min[1] * m[1][0];
00297
00298 if(a >= b)
00299 {
00300 xmax += a;
00301 xmin += b;
00302 }
00303 else
00304 {
00305 xmax += b;
00306 xmin += a;
00307 }
00308
00309 a = _max[2] * m[2][0];
00310 b = _min[2] * m[2][0];
00311
00312 if(a >= b)
00313 {
00314 xmax += a;
00315 xmin += b;
00316 }
00317 else
00318 {
00319 xmax += b;
00320 xmin += a;
00321 }
00322
00323
00324
00325
00326
00327 a = _max[0] * m[0][1];
00328 b = _min[0] * m[0][1];
00329
00330 if(a >= b)
00331 {
00332 ymax += a;
00333 ymin += b;
00334 }
00335 else
00336 {
00337 ymax += b;
00338 ymin += a;
00339 }
00340
00341 a = _max[1] * m[1][1];
00342 b = _min[1] * m[1][1];
00343
00344 if(a >= b)
00345 {
00346 ymax += a;
00347 ymin += b;
00348 }
00349 else
00350 {
00351 ymax += b;
00352 ymin += a;
00353 }
00354
00355 a = _max[2] * m[2][1];
00356 b = _min[2] * m[2][1];
00357
00358 if(a >= b)
00359 {
00360 ymax += a;
00361 ymin += b;
00362 }
00363 else
00364 {
00365 ymax += b;
00366 ymin += a;
00367 }
00368
00369
00370
00371
00372
00373 a = _max[0] * m[0][2];
00374 b = _min[0] * m[0][2];
00375
00376 if(a >= b)
00377 {
00378 zmax += a;
00379 zmin += b;
00380 }
00381 else
00382 {
00383 zmax += b;
00384 zmin += a;
00385 }
00386
00387 a = _max[1] * m[1][2];
00388 b = _min[1] * m[1][2];
00389
00390 if(a >= b)
00391 {
00392 zmax += a;
00393 zmin += b;
00394 }
00395 else
00396 {
00397 zmax += b;
00398 zmin += a;
00399 }
00400
00401 a = _max[2] * m[2][2];
00402 b = _min[2] * m[2][2];
00403
00404 if(a >= b)
00405 {
00406 zmax += a;
00407 zmin += b;
00408 }
00409 else
00410 {
00411 zmax += b;
00412 zmin += a;
00413 }
00414
00415 _min.setValues(xmin, ymin, zmin);
00416 _max.setValues(xmax, ymax, zmax);
00417 }
00418
00420
00421 BoxVolume &BoxVolume::operator =(const BoxVolume &b1)
00422 {
00423 if(&b1 == this)
00424 return *this;
00425
00426 _min = b1._min;
00427 _max = b1._max;
00428 _state = b1._state;
00429
00430 return *this;
00431 }
00432
00434
00435 void BoxVolume::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00436 const BitVector OSG_CHECK_ARG(bvFlags )) const
00437 {
00438 print(PLOG);
00439 }
00440
00441 void BoxVolume::print(std::ostream &os) const
00442 {
00443 os << "Box(" << _min << "|" << _max << ")";
00444 printState(os);
00445 }
00446
00448
00449 bool BoxVolume::operator ==(const BoxVolume &rhs) const
00450 {
00451 return ((_min[0] == rhs._min[0]) &&
00452 (_min[1] == rhs._min[1]) &&
00453 (_min[2] == rhs._min[2]) &&
00454 (_max[0] == rhs._max[0]) &&
00455 (_max[1] == rhs._max[1]) &&
00456 (_max[2] == rhs._max[2]) );
00457 }
00458
00459
00460 OSG_END_NAMESPACE