OSGBoxVolume.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028  *                                                                           *
00029 \*---------------------------------------------------------------------------*/
00030 /*---------------------------------------------------------------------------*\
00031  *                                Changes                                    *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037  *                                                                           *
00038 \*---------------------------------------------------------------------------*/
00039
00040 //---------------------------------------------------------------------------
00041 //  Includes
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 &center) 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 &center,
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 /*-------------------------- extending ------------------------------------*/
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 /*-------------------------- intersection ---------------------------------*/
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     // calculate xmin and xmax of new tranformed BBox
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     // calculate ymin and ymax of new tranformed BBox
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     // calculate zmin and zmax of new tranformed BBox
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