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 <assert.h>
00047
00048 #include <OSGPlane.h>
00049 #include <OSGVolume.h>
00050
00051 #include "OSGCylinderVolume.h"
00052
00053 OSG_USING_NAMESPACE
00054
00055
00056 void CylinderVolume::getCenter(Pnt3f ¢er) const
00057 {
00058 center = _axisPos + _axisDir * .5;
00059 }
00060
00061
00062 Real32 CylinderVolume::getScalarVolume(void) const
00063 {
00064 return isEmpty() ? 0.0f : (_radius * _radius * Pi * _axisDir.length());
00065 }
00066
00069 void CylinderVolume::getBounds(Pnt3f &min, Pnt3f &max) const
00070 {
00071 for(UInt32 i = 0; i < 3; i++)
00072 {
00073 min[i] = _axisPos[i] - _radius;
00074 max[i] = _axisPos[i] + _radius;
00075 ((_axisDir[i] < 0) ? min[i] : max[i]) += _axisDir[i];
00076 }
00077 }
00078
00079
00080
00081 #ifdef __sgi
00082 #pragma set woff 1209
00083 #endif
00084
00087 void CylinderVolume::extendBy(const Pnt3f &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
00104
00109 bool CylinderVolume::intersect(const Pnt3f &point) const
00110 {
00111 Real32 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 Real32 &enter,
00136 Real32 &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 Pnt3f &point) const
00148 {
00149 Real32 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
00164
00166 void CylinderVolume::transform(const Matrix& mtx)
00167 {
00168
00169 Pnt3f p;
00170 Vec3f v, v2, v3;
00171 getAxis(p,v);
00172
00173
00174 v2 = v;
00175 v2.normalize();
00176 v3 = v2.x() > 0.9 ? Vec3f(0,1,0) : Vec3f(1,0,0);
00177 v3.crossThis(v2);
00178
00179
00180 mtx.mult(p);
00181 mtx.mult(v);
00182 mtx.mult(v3);
00183
00184
00185 setAxis(p,v);
00186 setRadius(getRadius() * v3.length());
00187 }
00188
00189 #ifdef __sgi
00190 #pragma reset woff 1209
00191 #endif
00192
00194
00195 void CylinderVolume::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00196 const BitVector OSG_CHECK_ARG(bvFlags )) const
00197 {
00198 PLOG << "Cylinder("
00199 << _axisPos
00200 << "|"
00201 << _axisDir
00202 << "|"
00203 << _radius
00204 << ")";
00205 }
00206