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

  1.  
  2. #ifndef __BV_BOUNDS_H__
  3. #define __BV_BOUNDS_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.     Axis Aligned Bounding Box
  9.  
  10. ===============================================================================
  11. */
  12.  
  13. class idBounds {
  14. public:
  15.                     idBounds( void );
  16.                     explicit idBounds( const idVec3 &mins, const idVec3 &maxs );
  17.                     explicit idBounds( const idVec3 &point );
  18.  
  19.     const idVec3 &    operator[]( const int index ) const;
  20.     idVec3 &        operator[]( const int index );
  21.     idBounds        operator+( const idVec3 &t ) const;                // returns translated bounds
  22.     idBounds &        operator+=( const idVec3 &t );                    // translate the bounds
  23.     idBounds        operator*( const idMat3 &r ) const;                // returns rotated bounds
  24.     idBounds &        operator*=( const idMat3 &r );                    // rotate the bounds
  25.     idBounds        operator+( const idBounds &a ) const;
  26.     idBounds &        operator+=( const idBounds &a );
  27.     idBounds        operator-( const idBounds &a ) const;
  28.     idBounds &        operator-=( const idBounds &a );
  29.  
  30.     bool            Compare( const idBounds &a ) const;                            // exact compare, no epsilon
  31.     bool            Compare( const idBounds &a, const float epsilon ) const;    // compare with epsilon
  32.     bool            operator==(    const idBounds &a ) const;                        // exact compare, no epsilon
  33.     bool            operator!=(    const idBounds &a ) const;                        // exact compare, no epsilon
  34.  
  35.     void            Clear( void );                                    // inside out bounds
  36.     void            Zero( void );                                    // single point at origin
  37.  
  38.     idVec3            GetCenter( void ) const;                        // returns center of bounds
  39.     float            GetRadius( void ) const;                        // returns the radius relative to the bounds origin
  40.     float            GetRadius( const idVec3 ¢er ) const;        // returns the radius relative to the given center
  41.     float            GetVolume( void ) const;                        // returns the volume of the bounds
  42.     bool            IsCleared( void ) const;                        // returns true if bounds are inside out
  43.  
  44.     bool            AddPoint( const idVec3 &v );                    // add the point, returns true if the bounds expanded
  45.     bool            AddBounds( const idBounds &a );                    // add the bounds, returns true if the bounds expanded
  46.     idBounds        Intersect( const idBounds &a ) const;            // return intersection of this bounds with the given bounds
  47.     idBounds &        IntersectSelf( const idBounds &a );                // intersect this bounds with the given bounds
  48.     idBounds        Expand( const float d ) const;                    // return bounds expanded in all directions with the given value
  49.     idBounds &        ExpandSelf( const float d );                    // expand bounds in all directions with the given value
  50.  
  51. // RAVEN BEGIN
  52. // jscott: for BSE
  53.     idBounds &        ExpandSelf( const idVec3 &d );                    // expand bounds in all directions by the given vector
  54.     const idVec3    Size( void ) const;
  55.     float            ShortestDistance( const idVec3 &point ) const;
  56.     bool            Contains( const idBounds &a ) const;
  57. // jscott: for material types
  58.     int                GetLargestAxis( void ) const;
  59. // abahr: can be used to get width of bounds
  60.     idVec3            FindEdgePoint( const idVec3& dir ) const;
  61.     idVec3            FindEdgePoint( const idVec3& start, const idVec3& dir ) const;
  62.     idVec3            FindVectorToEdge( const idVec3& dir ) const;
  63.     idVec3            FindVectorToEdge( const idVec3& start, const idVec3& dir ) const;
  64. // RAVEN END
  65.  
  66.     idBounds        Translate( const idVec3 &translation ) const;    // return translated bounds
  67.     idBounds &        TranslateSelf( const idVec3 &translation );        // translate this bounds
  68.     idBounds        Rotate( const idMat3 &rotation ) const;            // return rotated bounds
  69.     idBounds &        RotateSelf( const idMat3 &rotation );            // rotate this bounds
  70.  
  71.     float            PlaneDistance( const idPlane &plane ) const;
  72.     int                PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
  73.  
  74.     bool            ContainsPoint( const idVec3 &p ) const;            // includes touching
  75.     bool            IntersectsBounds( const idBounds &a ) const;    // includes touching
  76.     bool            LineIntersection( const idVec3 &start, const idVec3 &end ) const;
  77.                     // intersection point is start + dir * scale
  78.     bool            RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const;
  79.  
  80.                     // most tight bounds for the given transformed bounds
  81.     void            FromTransformedBounds( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis );
  82.                     // most tight bounds for a point set
  83.     void            FromPoints( const idVec3 *points, const int numPoints );
  84.                     // most tight bounds for a translation
  85.     void            FromPointTranslation( const idVec3 &point, const idVec3 &translation );
  86.     void            FromBoundsTranslation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idVec3 &translation );
  87.                     // most tight bounds for a rotation
  88.     void            FromPointRotation( const idVec3 &point, const idRotation &rotation );
  89.     void            FromBoundsRotation( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis, const idRotation &rotation );
  90.  
  91.     void            ToPoints( idVec3 points[8] ) const;
  92.     idSphere        ToSphere( void ) const;
  93.  
  94.     void            AxisProjection( const idVec3 &dir, float &min, float &max ) const;
  95.     void            AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const;
  96.  
  97.     idVec3            b[2];
  98. };
  99.  
  100. extern idBounds    bounds_zero;
  101.  
  102. ID_INLINE idBounds::idBounds( void ) {
  103. }
  104.  
  105. ID_INLINE idBounds::idBounds( const idVec3 &mins, const idVec3 &maxs ) {
  106.     b[0] = mins;
  107.     b[1] = maxs;
  108. }
  109.  
  110. ID_INLINE idBounds::idBounds( const idVec3 &point ) {
  111.     b[0] = point;
  112.     b[1] = point;
  113. }
  114.  
  115. ID_INLINE const idVec3 &idBounds::operator[]( const int index ) const {
  116.     return b[index];
  117. }
  118.  
  119. ID_INLINE idVec3 &idBounds::operator[]( const int index ) {
  120.     return b[index];
  121. }
  122.  
  123. ID_INLINE idBounds idBounds::operator+( const idVec3 &t ) const {
  124.     return idBounds( b[0] + t, b[1] + t );
  125. }
  126.  
  127. ID_INLINE idBounds &idBounds::operator+=( const idVec3 &t ) {
  128.     b[0] += t;
  129.     b[1] += t;
  130.     return *this;
  131. }
  132.  
  133. ID_INLINE idBounds idBounds::operator*( const idMat3 &r ) const {
  134.     idBounds bounds;
  135.     bounds.FromTransformedBounds( *this, vec3_origin, r );
  136.     return bounds;
  137. }
  138.  
  139. ID_INLINE idBounds &idBounds::operator*=( const idMat3 &r ) {
  140.     this->FromTransformedBounds( *this, vec3_origin, r );
  141.     return *this;
  142. }
  143.  
  144. ID_INLINE idBounds idBounds::operator+( const idBounds &a ) const {
  145.     idBounds newBounds;
  146.     newBounds = *this;
  147.     newBounds.AddBounds( a );
  148.     return newBounds;
  149. }
  150.  
  151. ID_INLINE idBounds &idBounds::operator+=( const idBounds &a ) {
  152.     idBounds::AddBounds( a );
  153.     return *this;
  154. }
  155.  
  156. ID_INLINE idBounds idBounds::operator-( const idBounds &a ) const {
  157.     assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] &&
  158.                 b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] &&
  159.                     b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] );
  160.     return idBounds( idVec3( b[0][0] + a.b[1][0], b[0][1] + a.b[1][1], b[0][2] + a.b[1][2] ),
  161.                     idVec3( b[1][0] + a.b[0][0], b[1][1] + a.b[0][1], b[1][2] + a.b[0][2] ) );
  162. }
  163.  
  164. ID_INLINE idBounds &idBounds::operator-=( const idBounds &a ) {
  165.     assert( b[1][0] - b[0][0] > a.b[1][0] - a.b[0][0] &&
  166.                 b[1][1] - b[0][1] > a.b[1][1] - a.b[0][1] &&
  167.                     b[1][2] - b[0][2] > a.b[1][2] - a.b[0][2] );
  168.     b[0] += a.b[1];
  169.     b[1] += a.b[0];
  170.     return *this;
  171. }
  172.  
  173. ID_INLINE bool idBounds::Compare( const idBounds &a ) const {
  174.     return ( b[0].Compare( a.b[0] ) && b[1].Compare( a.b[1] ) );
  175. }
  176.  
  177. ID_INLINE bool idBounds::Compare( const idBounds &a, const float epsilon ) const {
  178.     return ( b[0].Compare( a.b[0], epsilon ) && b[1].Compare( a.b[1], epsilon ) );
  179. }
  180.  
  181. ID_INLINE bool idBounds::operator==( const idBounds &a ) const {
  182.     return Compare( a );
  183. }
  184.  
  185. ID_INLINE bool idBounds::operator!=( const idBounds &a ) const {
  186.     return !Compare( a );
  187. }
  188.  
  189. ID_INLINE void idBounds::Clear( void ) {
  190.     b[0][0] = b[0][1] = b[0][2] = idMath::INFINITY;
  191.     b[1][0] = b[1][1] = b[1][2] = -idMath::INFINITY;
  192. }
  193.  
  194. ID_INLINE void idBounds::Zero( void ) {
  195.     b[0][0] = b[0][1] = b[0][2] =
  196.     b[1][0] = b[1][1] = b[1][2] = 0;
  197. }
  198.  
  199. ID_INLINE idVec3 idBounds::GetCenter( void ) const {
  200.     return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f );
  201. }
  202.  
  203. ID_INLINE float idBounds::GetVolume( void ) const {
  204.     if ( b[0][0] >= b[1][0] || b[0][1] >= b[1][1] || b[0][2] >= b[1][2] ) {
  205.         return 0.0f;
  206.     }
  207.     return ( ( b[1][0] - b[0][0] ) * ( b[1][1] - b[0][1] ) * ( b[1][2] - b[0][2] ) );
  208. }
  209.  
  210. ID_INLINE bool idBounds::IsCleared( void ) const {
  211.     return b[0][0] > b[1][0];
  212. }
  213.  
  214. ID_INLINE bool idBounds::AddPoint( const idVec3 &v ) {
  215.     bool expanded = false;
  216.     if ( v[0] < b[0][0]) {
  217.         b[0][0] = v[0];
  218.         expanded = true;
  219.     }
  220.     if ( v[0] > b[1][0]) {
  221.         b[1][0] = v[0];
  222.         expanded = true;
  223.     }
  224.     if ( v[1] < b[0][1] ) {
  225.         b[0][1] = v[1];
  226.         expanded = true;
  227.     }
  228.     if ( v[1] > b[1][1]) {
  229.         b[1][1] = v[1];
  230.         expanded = true;
  231.     }
  232.     if ( v[2] < b[0][2] ) {
  233.         b[0][2] = v[2];
  234.         expanded = true;
  235.     }
  236.     if ( v[2] > b[1][2]) {
  237.         b[1][2] = v[2];
  238.         expanded = true;
  239.     }
  240.     return expanded;
  241. }
  242.  
  243. ID_INLINE bool idBounds::AddBounds( const idBounds &a ) {
  244.     bool expanded = false;
  245.     if ( a.b[0][0] < b[0][0] ) {
  246.         b[0][0] = a.b[0][0];
  247.         expanded = true;
  248.     }
  249.     if ( a.b[0][1] < b[0][1] ) {
  250.         b[0][1] = a.b[0][1];
  251.         expanded = true;
  252.     }
  253.     if ( a.b[0][2] < b[0][2] ) {
  254.         b[0][2] = a.b[0][2];
  255.         expanded = true;
  256.     }
  257.     if ( a.b[1][0] > b[1][0] ) {
  258.         b[1][0] = a.b[1][0];
  259.         expanded = true;
  260.     }
  261.     if ( a.b[1][1] > b[1][1] ) {
  262.         b[1][1] = a.b[1][1];
  263.         expanded = true;
  264.     }
  265.     if ( a.b[1][2] > b[1][2] ) {
  266.         b[1][2] = a.b[1][2];
  267.         expanded = true;
  268.     }
  269.     return expanded;
  270. }
  271.  
  272. ID_INLINE idBounds idBounds::Intersect( const idBounds &a ) const {
  273.     idBounds n;
  274.     n.b[0][0] = ( a.b[0][0] > b[0][0] ) ? a.b[0][0] : b[0][0];
  275.     n.b[0][1] = ( a.b[0][1] > b[0][1] ) ? a.b[0][1] : b[0][1];
  276.     n.b[0][2] = ( a.b[0][2] > b[0][2] ) ? a.b[0][2] : b[0][2];
  277.     n.b[1][0] = ( a.b[1][0] < b[1][0] ) ? a.b[1][0] : b[1][0];
  278.     n.b[1][1] = ( a.b[1][1] < b[1][1] ) ? a.b[1][1] : b[1][1];
  279.     n.b[1][2] = ( a.b[1][2] < b[1][2] ) ? a.b[1][2] : b[1][2];
  280.     return n;
  281. }
  282.  
  283. ID_INLINE idBounds &idBounds::IntersectSelf( const idBounds &a ) {
  284.     if ( a.b[0][0] > b[0][0] ) {
  285.         b[0][0] = a.b[0][0];
  286.     }
  287.     if ( a.b[0][1] > b[0][1] ) {
  288.         b[0][1] = a.b[0][1];
  289.     }
  290.     if ( a.b[0][2] > b[0][2] ) {
  291.         b[0][2] = a.b[0][2];
  292.     }
  293.     if ( a.b[1][0] < b[1][0] ) {
  294.         b[1][0] = a.b[1][0];
  295.     }
  296.     if ( a.b[1][1] < b[1][1] ) {
  297.         b[1][1] = a.b[1][1];
  298.     }
  299.     if ( a.b[1][2] < b[1][2] ) {
  300.         b[1][2] = a.b[1][2];
  301.     }
  302.     return *this;
  303. }
  304.  
  305. ID_INLINE idBounds idBounds::Expand( const float d ) const {
  306.     return idBounds( idVec3( b[0][0] - d, b[0][1] - d, b[0][2] - d ),
  307.                         idVec3( b[1][0] + d, b[1][1] + d, b[1][2] + d ) );
  308. }
  309.  
  310. ID_INLINE idBounds &idBounds::ExpandSelf( const float d ) {
  311.     b[0][0] -= d;
  312.     b[0][1] -= d;
  313.     b[0][2] -= d;
  314.     b[1][0] += d;
  315.     b[1][1] += d;
  316.     b[1][2] += d;
  317.     return *this;
  318. }
  319.  
  320. // RAVEN BEGIN
  321. // jscott: for BSE
  322. ID_INLINE idBounds &idBounds::ExpandSelf( const idVec3 &d ) 
  323. {
  324.     b[0][0] -= d[0];
  325.     b[0][1] -= d[1];
  326.     b[0][2] -= d[2];
  327.     b[1][0] += d[0];
  328.     b[1][1] += d[1];
  329.     b[1][2] += d[2];
  330.     return( *this );
  331. }
  332.  
  333. ID_INLINE const idVec3 idBounds::Size( void ) const 
  334. {
  335.     return( b[1] - b[0] );
  336. }
  337.  
  338. ID_INLINE bool idBounds::Contains( const idBounds &a ) const
  339. {
  340.     int        i;
  341.  
  342.     for( i = 0; i < 3; i++ ) {
  343.         if( a[1][i] > b[1][i] ) {
  344.             return( false );
  345.         }
  346.         if( a[0][i] < b[0][i] ) {
  347.             return( false );
  348.         }
  349.     }
  350.  
  351.     return( true );
  352. }
  353.  
  354. // jscott: for material types
  355. ID_INLINE int idBounds::GetLargestAxis( void ) const
  356. {
  357.     idVec3 work = b[1] - b[0];
  358.     int axis = 0;
  359.  
  360.     if( work[1] > work[0] )
  361.     {
  362.         axis = 1;
  363.     }
  364.     if( work[2] > work[axis] )
  365.     {
  366.         axis = 2;
  367.     }
  368.     return( axis );
  369. }
  370. // RAVEN END
  371.  
  372. ID_INLINE idBounds idBounds::Translate( const idVec3 &translation ) const {
  373.     return idBounds( b[0] + translation, b[1] + translation );
  374. }
  375.  
  376. ID_INLINE idBounds &idBounds::TranslateSelf( const idVec3 &translation ) {
  377.     b[0] += translation;
  378.     b[1] += translation;
  379.     return *this;
  380. }
  381.  
  382. ID_INLINE idBounds idBounds::Rotate( const idMat3 &rotation ) const {
  383.     idBounds bounds;
  384.     bounds.FromTransformedBounds( *this, vec3_origin, rotation );
  385.     return bounds;
  386. }
  387.  
  388. ID_INLINE idBounds &idBounds::RotateSelf( const idMat3 &rotation ) {
  389.     FromTransformedBounds( *this, vec3_origin, rotation );
  390.     return *this;
  391. }
  392.  
  393. ID_INLINE bool idBounds::ContainsPoint( const idVec3 &p ) const {
  394.     if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2]
  395.         || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {
  396.         return false;
  397.     }
  398.     return true;
  399. }
  400.  
  401. ID_INLINE bool idBounds::IntersectsBounds( const idBounds &a ) const {
  402.     if ( a.b[1][0] < b[0][0] || a.b[1][1] < b[0][1] || a.b[1][2] < b[0][2]
  403.         || a.b[0][0] > b[1][0] || a.b[0][1] > b[1][1] || a.b[0][2] > b[1][2] ) {
  404.         return false;
  405.     }
  406.     return true;
  407. }
  408.  
  409. ID_INLINE idSphere idBounds::ToSphere( void ) const {
  410.     idSphere sphere;
  411.     sphere.SetOrigin( ( b[0] + b[1] ) * 0.5f );
  412.     sphere.SetRadius( ( b[1] - sphere.GetOrigin() ).Length() );
  413.     return sphere;
  414. }
  415.  
  416. ID_INLINE void idBounds::AxisProjection( const idVec3 &dir, float &min, float &max ) const {
  417.     float d1, d2;
  418.     idVec3 center, extents;
  419.  
  420.     center = ( b[0] + b[1] ) * 0.5f;
  421.     extents = b[1] - center;
  422.  
  423.     d1 = dir * center;
  424.     d2 = idMath::Fabs( extents[0] * dir[0] ) +
  425.             idMath::Fabs( extents[1] * dir[1] ) +
  426.                 idMath::Fabs( extents[2] * dir[2] );
  427.  
  428.     min = d1 - d2;
  429.     max = d1 + d2;
  430. }
  431.  
  432. ID_INLINE void idBounds::AxisProjection( const idVec3 &origin, const idMat3 &axis, const idVec3 &dir, float &min, float &max ) const {
  433.     float d1, d2;
  434.     idVec3 center, extents;
  435.  
  436.     center = ( b[0] + b[1] ) * 0.5f;
  437.     extents = b[1] - center;
  438.     center = origin + center * axis;
  439.  
  440.     d1 = dir * center;
  441.     d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) +
  442.             idMath::Fabs( extents[1] * ( dir * axis[1] ) ) +
  443.                 idMath::Fabs( extents[2] * ( dir * axis[2] ) );
  444.  
  445.     min = d1 - d2;
  446.     max = d1 + d2;
  447. }
  448.  
  449. #endif /* !__BV_BOUNDS_H__ */
  450.