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

  1.  
  2. #ifndef __BV_BOX_H__
  3. #define __BV_BOX_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.     Oriented Bounding Box
  9.  
  10. ===============================================================================
  11. */
  12.  
  13. class idBox {
  14. public:
  15.                     idBox( void );
  16.                     explicit idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis );
  17.                     explicit idBox( const idVec3 &point );
  18.                     explicit idBox( const idBounds &bounds );
  19.                     explicit idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis );
  20.  
  21.     idBox            operator+( const idVec3 &t ) const;                // returns translated box
  22.     idBox &            operator+=( const idVec3 &t );                    // translate the box
  23.     idBox            operator*( const idMat3 &r ) const;                // returns rotated box
  24.     idBox &            operator*=( const idMat3 &r );                    // rotate the box
  25.     idBox            operator+( const idBox &a ) const;
  26.     idBox &            operator+=( const idBox &a );
  27.     idBox            operator-( const idBox &a ) const;
  28.     idBox &            operator-=( const idBox &a );
  29.  
  30.     bool            Compare( const idBox &a ) const;                        // exact compare, no epsilon
  31.     bool            Compare( const idBox &a, const float epsilon ) const;    // compare with epsilon
  32.     bool            operator==(    const idBox &a ) const;                        // exact compare, no epsilon
  33.     bool            operator!=(    const idBox &a ) const;                        // exact compare, no epsilon
  34.  
  35.     void            Clear( void );                                    // inside out box
  36.     void            Zero( void );                                    // single point at origin
  37.  
  38.     const idVec3 &    GetCenter( void ) const;                        // returns center of the box
  39.     const idVec3 &    GetExtents( void ) const;                        // returns extents of the box
  40.     const idMat3 &    GetAxis( void ) const;                            // returns the axis of the box
  41.     float            GetVolume( void ) const;                        // returns the volume of the box
  42.     bool            IsCleared( void ) const;                        // returns true if box are inside out
  43.  
  44.     bool            AddPoint( const idVec3 &v );                    // add the point, returns true if the box expanded
  45.     bool            AddBox( const idBox &a );                        // add the box, returns true if the box expanded
  46.     idBox            Expand( const float d ) const;                    // return box expanded in all directions with the given value
  47.     idBox &            ExpandSelf( const float d );                    // expand box in all directions with the given value
  48.     idBox            Translate( const idVec3 &translation ) const;    // return translated box
  49.     idBox &            TranslateSelf( const idVec3 &translation );        // translate this box
  50.     idBox            Rotate( const idMat3 &rotation ) const;            // return rotated box
  51.     idBox &            RotateSelf( const idMat3 &rotation );            // rotate this box
  52.  
  53.     float            PlaneDistance( const idPlane &plane ) const;
  54.     int                PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
  55.  
  56.     bool            ContainsPoint( const idVec3 &p ) const;            // includes touching
  57.     bool            IntersectsBox( const idBox &a ) const;            // includes touching
  58.     bool            LineIntersection( const idVec3 &start, const idVec3 &end ) const;
  59.                     // intersection points are (start + dir * scale1) and (start + dir * scale2)
  60.     bool            RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const;
  61.  
  62.                     // tight box for a collection of points
  63.     void            FromPoints( const idVec3 *points, const int numPoints );
  64.                     // most tight box for a translation
  65.     void            FromPointTranslation( const idVec3 &point, const idVec3 &translation );
  66.     void            FromBoxTranslation( const idBox &box, const idVec3 &translation );
  67.                     // most tight box for a rotation
  68.     void            FromPointRotation( const idVec3 &point, const idRotation &rotation );
  69.     void            FromBoxRotation( const idBox &box, const idRotation &rotation );
  70.  
  71.     void            ToPoints( idVec3 points[8] ) const;
  72.     idSphere        ToSphere( void ) const;
  73.  
  74.                     // calculates the projection of this box onto the given axis
  75.     void            AxisProjection( const idVec3 &dir, float &min, float &max ) const;
  76.     void            AxisProjection( const idMat3 &ax, idBounds &bounds ) const;
  77.  
  78.                     // calculates the silhouette of the box
  79.     int                GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const;
  80.     int                GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const;
  81.  
  82. private:
  83.     idVec3            center;
  84.     idVec3            extents;
  85.     idMat3            axis;
  86. };
  87.  
  88. extern idBox    box_zero;
  89.  
  90. ID_INLINE idBox::idBox( void ) {
  91. }
  92.  
  93. ID_INLINE idBox::idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ) {
  94.     this->center = center;
  95.     this->extents = extents;
  96.     this->axis = axis;
  97. }
  98.  
  99. ID_INLINE idBox::idBox( const idVec3 &point ) {
  100.     this->center = point;
  101.     this->extents.Zero();
  102.     this->axis.Identity();
  103. }
  104.  
  105. ID_INLINE idBox::idBox( const idBounds &bounds ) {
  106.     this->center = ( bounds[0] + bounds[1] ) * 0.5f;
  107.     this->extents = bounds[1] - this->center;
  108.     this->axis.Identity();
  109. }
  110.  
  111. ID_INLINE idBox::idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) {
  112.     this->center = ( bounds[0] + bounds[1] ) * 0.5f;
  113.     this->extents = bounds[1] - this->center;
  114.     this->center = origin + this->center * axis;
  115.     this->axis = axis;
  116. }
  117.  
  118. ID_INLINE idBox idBox::operator+( const idVec3 &t ) const {
  119.     return idBox( center + t, extents, axis );
  120. }
  121.  
  122. ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) {
  123.     center += t;
  124.     return *this;
  125. }
  126.  
  127. ID_INLINE idBox idBox::operator*( const idMat3 &r ) const {
  128.     return idBox( center * r, extents, axis * r );
  129. }
  130.  
  131. ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) {
  132.     center *= r;
  133.     axis *= r;
  134.     return *this;
  135. }
  136.  
  137. ID_INLINE idBox idBox::operator+( const idBox &a ) const {
  138.     idBox newBox;
  139.     newBox = *this;
  140.     newBox.AddBox( a );
  141.     return newBox;
  142. }
  143.  
  144. ID_INLINE idBox &idBox::operator+=( const idBox &a ) {
  145.     idBox::AddBox( a );
  146.     return *this;
  147. }
  148.  
  149. ID_INLINE idBox idBox::operator-( const idBox &a ) const {
  150.     return idBox( center, extents - a.extents, axis );
  151. }
  152.  
  153. ID_INLINE idBox &idBox::operator-=( const idBox &a ) {
  154.     extents -= a.extents;
  155.     return *this;
  156. }
  157.  
  158. ID_INLINE bool idBox::Compare( const idBox &a ) const {
  159.     return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) );
  160. }
  161.  
  162. ID_INLINE bool idBox::Compare( const idBox &a, const float epsilon ) const {
  163.     return ( center.Compare( a.center, epsilon ) && extents.Compare( a.extents, epsilon ) && axis.Compare( a.axis, epsilon ) );
  164. }
  165.  
  166. ID_INLINE bool idBox::operator==( const idBox &a ) const {
  167.     return Compare( a );
  168. }
  169.  
  170. ID_INLINE bool idBox::operator!=( const idBox &a ) const {
  171.     return !Compare( a );
  172. }
  173.  
  174. ID_INLINE void idBox::Clear( void ) {
  175.     center.Zero();
  176.     extents[0] = extents[1] = extents[2] = -idMath::INFINITY;
  177.     axis.Identity();
  178. }
  179.  
  180. ID_INLINE void idBox::Zero( void ) {
  181.     center.Zero();
  182.     extents.Zero();
  183.     axis.Identity();
  184. }
  185.  
  186. ID_INLINE const idVec3 &idBox::GetCenter( void ) const {
  187.     return center;
  188. }
  189.  
  190. ID_INLINE const idVec3 &idBox::GetExtents( void ) const {
  191.     return extents;
  192. }
  193.  
  194. ID_INLINE const idMat3 &idBox::GetAxis( void ) const {
  195.     return axis;
  196. }
  197.  
  198. ID_INLINE float idBox::GetVolume( void ) const {
  199.     return ( extents * 2.0f ).LengthSqr();
  200. }
  201.  
  202. ID_INLINE bool idBox::IsCleared( void ) const {
  203.     return extents[0] < 0.0f;
  204. }
  205.  
  206. ID_INLINE idBox idBox::Expand( const float d ) const {
  207.     return idBox( center, extents + idVec3( d, d, d ), axis );
  208. }
  209.  
  210. ID_INLINE idBox &idBox::ExpandSelf( const float d ) {
  211.     extents[0] += d;
  212.     extents[1] += d;
  213.     extents[2] += d;
  214.     return *this;
  215. }
  216.  
  217. ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const {
  218.     return idBox( center + translation, extents, axis );
  219. }
  220.  
  221. ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) {
  222.     center += translation;
  223.     return *this;
  224. }
  225.  
  226. ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const {
  227.     return idBox( center * rotation, extents, axis * rotation );
  228. }
  229.  
  230. ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) {
  231.     center *= rotation;
  232.     axis *= rotation;
  233.     return *this;
  234. }
  235.  
  236. ID_INLINE bool idBox::ContainsPoint( const idVec3 &p ) const {
  237.     idVec3 lp = p - center;
  238.     if ( idMath::Fabs( lp * axis[0] ) > extents[0] ||
  239.             idMath::Fabs( lp * axis[1] ) > extents[1] ||
  240.                 idMath::Fabs( lp * axis[2] ) > extents[2] ) {
  241.         return false;
  242.     }
  243.     return true;
  244. }
  245.  
  246. ID_INLINE idSphere idBox::ToSphere( void ) const {
  247.     return idSphere( center, extents.Length() );
  248. }
  249.  
  250. ID_INLINE void idBox::AxisProjection( const idVec3 &dir, float &min, float &max ) const {
  251.     float d1 = dir * center;
  252.     float d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) +
  253.                 idMath::Fabs( extents[1] * ( dir * axis[1] ) ) +
  254.                 idMath::Fabs( extents[2] * ( dir * axis[2] ) );
  255.     min = d1 - d2;
  256.     max = d1 + d2;
  257. }
  258.  
  259. ID_INLINE void idBox::AxisProjection( const idMat3 &ax, idBounds &bounds ) const {
  260.     for ( int i = 0; i < 3; i++ ) {
  261.         float d1 = ax[i] * center;
  262.         float d2 = idMath::Fabs( extents[0] * ( ax[i] * axis[0] ) ) +
  263.                     idMath::Fabs( extents[1] * ( ax[i] * axis[1] ) ) +
  264.                     idMath::Fabs( extents[2] * ( ax[i] * axis[2] ) );
  265.         bounds[0][i] = d1 - d2;
  266.         bounds[1][i] = d1 + d2;
  267.     }
  268. }
  269.  
  270. #endif /* !__BV_BOX_H__ */
  271.