home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / bv / Sphere.h < prev   
C/C++ Source or Header  |  2005-11-14  |  8KB  |  249 lines

  1.  
  2. #ifndef __BV_SPHERE_H__
  3. #define __BV_SPHERE_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.     Sphere
  9.  
  10. ===============================================================================
  11. */
  12.  
  13. class idSphere {
  14. public:
  15.                     idSphere( void );
  16.                     explicit idSphere( const idVec3 &point );
  17.                     explicit idSphere( const idVec3 &point, const float r );
  18.  
  19.     float            operator[]( const int index ) const;
  20.     float &            operator[]( const int index );
  21.     idSphere        operator+( const idVec3 &t ) const;                // returns tranlated sphere
  22.     idSphere &        operator+=( const idVec3 &t );                    // translate the sphere
  23.     idSphere        operator+( const idSphere &s ) const;
  24.     idSphere &        operator+=( const idSphere &s );
  25.  
  26.     bool            Compare( const idSphere &a ) const;                            // exact compare, no epsilon
  27.     bool            Compare( const idSphere &a, const float epsilon ) const;    // compare with epsilon
  28.     bool            operator==(    const idSphere &a ) const;                        // exact compare, no epsilon
  29.     bool            operator!=(    const idSphere &a ) const;                        // exact compare, no epsilon
  30.  
  31.     void            Clear( void );                                    // inside out sphere
  32.     void            Zero( void );                                    // single point at origin
  33.     void            SetOrigin( const idVec3 &o );                    // set origin of sphere
  34.     void            SetRadius( const float r );                        // set square radius
  35.  
  36.     const idVec3 &    GetOrigin( void ) const;                        // returns origin of sphere
  37.     float            GetRadius( void ) const;                        // returns sphere radius
  38.     bool            IsCleared( void ) const;                        // returns true if sphere is inside out
  39.  
  40.     bool            AddPoint( const idVec3 &p );                    // add the point, returns true if the sphere expanded
  41.     bool            AddSphere( const idSphere &s );                    // add the sphere, returns true if the sphere expanded
  42.     idSphere        Expand( const float d ) const;                    // return bounds expanded in all directions with the given value
  43.     idSphere &        ExpandSelf( const float d );                    // expand bounds in all directions with the given value
  44.     idSphere        Translate( const idVec3 &translation ) const;
  45.     idSphere &        TranslateSelf( const idVec3 &translation );
  46.  
  47.     float            PlaneDistance( const idPlane &plane ) const;
  48.     int                PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
  49.  
  50.     bool            ContainsPoint( const idVec3 &p ) const;            // includes touching
  51.     bool            IntersectsSphere( const idSphere &s ) const;    // includes touching
  52.     bool            LineIntersection( const idVec3 &start, const idVec3 &end ) const;
  53.                     // intersection points are (start + dir * scale1) and (start + dir * scale2)
  54.     bool            RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const;
  55.  
  56.                     // Tight sphere for a point set.
  57.     void            FromPoints( const idVec3 *points, const int numPoints );
  58.                     // Most tight sphere for a translation.
  59.     void            FromPointTranslation( const idVec3 &point, const idVec3 &translation );
  60.     void            FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation );
  61.                     // Most tight sphere for a rotation.
  62.     void            FromPointRotation( const idVec3 &point, const idRotation &rotation );
  63.     void            FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation );
  64.  
  65.     void            AxisProjection( const idVec3 &dir, float &min, float &max ) const;
  66.  
  67. private:
  68.     idVec3            origin;
  69.     float            radius;
  70. };
  71.  
  72. extern idSphere    sphere_zero;
  73.  
  74. ID_INLINE idSphere::idSphere( void ) {
  75. }
  76.  
  77. ID_INLINE idSphere::idSphere( const idVec3 &point ) {
  78.     origin = point;
  79.     radius = 0.0f;
  80. }
  81.  
  82. ID_INLINE idSphere::idSphere( const idVec3 &point, const float r ) {
  83.     origin = point;
  84.     radius = r;
  85. }
  86.  
  87. ID_INLINE float idSphere::operator[]( const int index ) const {
  88.     return ((float *) &origin)[index];
  89. }
  90.  
  91. ID_INLINE float &idSphere::operator[]( const int index ) {
  92.     return ((float *) &origin)[index];
  93. }
  94.  
  95. ID_INLINE idSphere idSphere::operator+( const idVec3 &t ) const {
  96.     return idSphere( origin + t, radius );
  97. }
  98.  
  99. ID_INLINE idSphere &idSphere::operator+=( const idVec3 &t ) {
  100.     origin += t;
  101.     return *this;
  102. }
  103.  
  104. ID_INLINE bool idSphere::Compare( const idSphere &a ) const {
  105.     return ( origin.Compare( a.origin ) && radius == a.radius );
  106. }
  107.  
  108. ID_INLINE bool idSphere::Compare( const idSphere &a, const float epsilon ) const {
  109.     return ( origin.Compare( a.origin, epsilon ) && idMath::Fabs( radius - a.radius ) <= epsilon );
  110. }
  111.  
  112. ID_INLINE bool idSphere::operator==( const idSphere &a ) const {
  113.     return Compare( a );
  114. }
  115.  
  116. ID_INLINE bool idSphere::operator!=( const idSphere &a ) const {
  117.     return !Compare( a );
  118. }
  119.  
  120. ID_INLINE void idSphere::Clear( void ) {
  121.     origin.Zero();
  122.     radius = -1.0f;
  123. }
  124.  
  125. ID_INLINE void idSphere::Zero( void ) {
  126.     origin.Zero();
  127.     radius = 0.0f;
  128. }
  129.  
  130. ID_INLINE void idSphere::SetOrigin( const idVec3 &o ) {
  131.     origin = o;
  132. }
  133.  
  134. ID_INLINE void idSphere::SetRadius( const float r ) {
  135.     radius = r;
  136. }
  137.  
  138. ID_INLINE const idVec3 &idSphere::GetOrigin( void ) const {
  139.     return origin;
  140. }
  141.  
  142. ID_INLINE float idSphere::GetRadius( void ) const {
  143.     return radius;
  144. }
  145.  
  146. ID_INLINE bool idSphere::IsCleared( void ) const {
  147.     return ( radius < 0.0f );
  148. }
  149.  
  150. ID_INLINE bool idSphere::AddPoint( const idVec3 &p ) {
  151.     if ( radius < 0.0f ) {
  152.         origin = p;
  153.         radius = 0.0f;
  154.         return true;
  155.     }
  156.     else {
  157.         float r = ( p - origin ).LengthSqr();
  158.         if ( r > radius * radius ) {
  159.             r = idMath::Sqrt( r );
  160.             origin += ( p - origin ) * 0.5f * (1.0f - radius / r );
  161.             radius += 0.5f * ( r - radius );
  162.             return true;
  163.         }
  164.         return false;
  165.     }
  166. }
  167.  
  168. ID_INLINE bool idSphere::AddSphere( const idSphere &s ) {
  169.     if ( radius < 0.0f ) {
  170.         origin = s.origin;
  171.         radius = s.radius;
  172.         return true;
  173.     }
  174.     else {
  175.         float r = ( s.origin - origin ).LengthSqr();
  176.         if ( r > ( radius + s.radius ) * ( radius + s.radius ) ) {
  177.             r = idMath::Sqrt( r );
  178.             origin += ( s.origin - origin ) * 0.5f * (1.0f - radius / ( r + s.radius ) );
  179.             radius += 0.5f * ( ( r + s.radius ) - radius );
  180.             return true;
  181.         }
  182.         return false;
  183.     }
  184. }
  185.  
  186. ID_INLINE idSphere idSphere::Expand( const float d ) const {
  187.     return idSphere( origin, radius + d );
  188. }
  189.  
  190. ID_INLINE idSphere &idSphere::ExpandSelf( const float d ) {
  191.     radius += d;
  192.     return *this;
  193. }
  194.  
  195. ID_INLINE idSphere idSphere::Translate( const idVec3 &translation ) const {
  196.     return idSphere( origin + translation, radius );
  197. }
  198.  
  199. ID_INLINE idSphere &idSphere::TranslateSelf( const idVec3 &translation ) {
  200.     origin += translation;
  201.     return *this;
  202. }
  203.  
  204. ID_INLINE bool idSphere::ContainsPoint( const idVec3 &p ) const {
  205.     if ( ( p - origin ).LengthSqr() > radius * radius ) {
  206.         return false;
  207.     }
  208.     return true;
  209. }
  210.  
  211. ID_INLINE bool idSphere::IntersectsSphere( const idSphere &s ) const {
  212.     float r = s.radius + radius;
  213.     if ( ( s.origin - origin ).LengthSqr() > r * r ) {
  214.         return false;
  215.     }
  216.     return true;
  217. }
  218.  
  219. ID_INLINE void idSphere::FromPointTranslation( const idVec3 &point, const idVec3 &translation ) {
  220.     origin = point + 0.5f * translation;
  221.     radius = idMath::Sqrt( 0.5f * translation.LengthSqr() );
  222. }
  223.  
  224. ID_INLINE void idSphere::FromSphereTranslation( const idSphere &sphere, const idVec3 &start, const idVec3 &translation ) {
  225.     origin = start + sphere.origin + 0.5f * translation;
  226.     radius = idMath::Sqrt( 0.5f * translation.LengthSqr() ) + sphere.radius;
  227. }
  228.  
  229. ID_INLINE void idSphere::FromPointRotation( const idVec3 &point, const idRotation &rotation ) {
  230.     idVec3 end = rotation * point;
  231.     origin = ( point + end ) * 0.5f;
  232.     radius = idMath::Sqrt( 0.5f * ( end - point ).LengthSqr() );
  233. }
  234.  
  235. ID_INLINE void idSphere::FromSphereRotation( const idSphere &sphere, const idVec3 &start, const idRotation &rotation ) {
  236.     idVec3 end = rotation * sphere.origin;
  237.     origin = start + ( sphere.origin + end ) * 0.5f;
  238.     radius = idMath::Sqrt( 0.5f * ( end - sphere.origin ).LengthSqr() ) + sphere.radius;
  239. }
  240.  
  241. ID_INLINE void idSphere::AxisProjection( const idVec3 &dir, float &min, float &max ) const {
  242.     float d;
  243.     d = dir * origin;
  244.     min = d - radius;
  245.     max = d + radius;
  246. }
  247.  
  248. #endif /* !__BV_SPHERE_H__ */
  249.