OSGCylinderVolume.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2003 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  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039
00040 //---------------------------------------------------------------------------
00041 //  Includes
00042 //---------------------------------------------------------------------------
00043
00044 #include "OSGConfig.h"
00045
00046 #include <cassert>
00047
00048 #include "OSGCylinderVolume.h"
00049 #include "OSGPlane.h"
00050 #include "OSGMatrix.h"
00051
00052 OSG_BEGIN_NAMESPACE
00053
00054
00055 void CylinderVolume::getCenter(Pnt3r &center) const
00056 {
00057     center = _axisPos + _axisDir * .5f;
00058 }
00059
00060
00061 Real CylinderVolume::getScalarVolume(void) const
00062 {
00063     return isEmpty() ? 0.0f : (_radius * _radius * Pi * _axisDir.length());
00064 }
00065
00068 void CylinderVolume::getBounds(Pnt3r &min, Pnt3r &max) const
00069 {
00070     for(UInt32 i = 0; i < 3; i++)
00071     {
00072         min[i] = _axisPos[i] - _radius;
00073         max[i] = _axisPos[i] + _radius;
00074
00075         ((_axisDir[i] < 0.f) ? min[i] : max[i]) += _axisDir[i];
00076     }
00077 }
00078
00079 /*-------------------------- extending ------------------------------------*/
00080
00081 #ifdef __sgi
00082 #pragma set woff 1209
00083 #endif
00084 
00087 void CylinderVolume::extendBy(const Pnt3r &OSG_CHECK_ARG(pt))
00088 {
00089     assert(false);
00090 }
00091
00092
00093 void CylinderVolume::extendBy(const Volume &volume)
00094 {
00095   OSG::extend(*this, volume);
00096 }
00097
00098 #ifdef __sgi
00099 #pragma reset woff 1209
00100 #endif
00101 
00102
00103 /*-------------------------- intersection ---------------------------------*/
00104
00109 bool CylinderVolume::intersect(const Pnt3r &point) const
00110 {
00111     Real dist = Line(_axisPos, _axisDir).distance(point);
00112
00113     if(dist > _radius)
00114         return false;
00115
00116     Plane bottom( _axisDir, _axisPos           );
00117     Plane top   (-_axisDir, _axisPos + _axisDir);
00118
00119     bool inspace = bottom.isInHalfSpace(point) && top.isInHalfSpace(point);
00120
00121     return inspace;
00122 }
00123
00124
00127 bool CylinderVolume::intersect(const Line &line) const
00128 {
00129     return line.intersect(*this);
00130 }
00131
00134 bool CylinderVolume::intersect(const Line        &line,
00135                                      Real &enter,
00136                                      Real &exit ) const
00137 {
00138     return line.intersect(*this, enter, exit);
00139 }
00140
00141 bool CylinderVolume::intersect(const Volume &volume) const
00142 {
00143     return OSG::intersect(*this,volume);
00144 }
00145
00146
00147 bool CylinderVolume::isOnSurface(const Pnt3r &point) const
00148 {
00149     Real dist = Line(_axisPos, _axisDir).distance(point);
00150
00151     if(dist > _radius)
00152         return false;
00153
00154     Plane bottom(-_axisDir, _axisPos           );
00155     Plane top   ( _axisDir, _axisPos + _axisDir);
00156
00157     bool onplane = bottom.isOnPlane(point) || top.isOnPlane(point);
00158
00159     return  ( onplane &&  dist <= _radius            ) ||
00160             (!onplane && osgAbs(dist - _radius) < Eps);
00161 }
00162
00163 /*-------------------------- transformation -------------------------------*/
00164
00166 void CylinderVolume::transform(const Matrixr &mtx)
00167 {
00168      // get pos & axis
00169     Pnt3r p;
00170     Vec3r v, v2, v3;
00171
00172     getAxis(p,v);
00173
00174      // find perpendicular vector (to detect radius transformation)
00175     v2 = v;
00176     v2.normalize();
00177     v3 = v2.x() > 0.9f ? Vec3r(0.f,1.f,0.f) : Vec3r(1.f,0.f,0.f);
00178     v3.crossThis(v2);
00179
00180     // transform
00181     mtx.mult(p,  p );
00182     mtx.mult(v,  v );
00183     mtx.mult(v3, v3);
00184
00185     // update
00186     setAxis(p,v);
00187     setRadius(getRadius() * v3.length());
00188 }
00189
00190 #ifdef __sgi
00191 #pragma reset woff 1209
00192 #endif
00193 
00195
00196 void CylinderVolume::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
00197                           const BitVector OSG_CHECK_ARG(bvFlags )) const
00198 {
00199     print(PLOG);
00200 }
00201
00202 void CylinderVolume::print(std::ostream &os) const
00203 {
00204     os << "Cylinder (" << _axisPos
00205        << "|"          << _axisDir
00206        << "|"          << _radius
00207        << ")";
00208     printState(os);
00209 }
00210
00211 /*---------------------------------------------------------------------------*/
00212 /* Operators                                                                 */
00213
00214 bool CylinderVolume::operator ==(const CylinderVolume &rhs) const
00215 {
00216     return (_axisPos == rhs._axisPos) &&
00217            (_axisDir == rhs._axisDir) &&
00218            (_radius  == rhs._radius );
00219 }
00220
00221 CylinderVolume &CylinderVolume::operator =(const CylinderVolume &source)
00222 {
00223     if(this == &source)
00224         return *this;
00225
00226     _axisPos = source._axisPos;
00227     _axisDir = source._axisDir;
00228     _radius  = source._radius;
00229
00230     return *this;
00231 }
00232
00233 OSG_END_NAMESPACE