Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
6.0 KiB

  1. //========= Copyright � Valve Corporation, All rights reserved. ============//
  2. #ifndef MATHLIB_AABB_HDR
  3. #define MATHLIB_AABB_HDR
  4. #include "mathlib/vector4d.h"
  5. #include "mathlib/vector.h"
  6. #include "mathlib/mathlib.h"
  7. /// Axis-aligned 3d bounding box.
  8. schema struct AABB_t
  9. {
  10. public:
  11. Vector m_vMinBounds;
  12. Vector m_vMaxBounds;
  13. FORCEINLINE AABB_t() {}
  14. FORCEINLINE AABB_t( const Vector &vMins, const Vector &vMaxs )
  15. {
  16. m_vMinBounds = vMins;
  17. m_vMaxBounds = vMaxs;
  18. }
  19. FORCEINLINE Vector GetCenter() const { return ( m_vMaxBounds + m_vMinBounds ) / 2.0f; }
  20. /// radius of bounding sphere centered at GetCenter()
  21. FORCEINLINE float GetBoundingRadius( void ) const
  22. {
  23. return ( m_vMinBounds - GetCenter() ).Length();
  24. }
  25. FORCEINLINE float GetSurfaceArea( void ) const { return BoxSurfaceArea( m_vMinBounds, m_vMaxBounds ); }
  26. /// Calculate the volume. Does not contain special handling for inside-out volumes - if an odd
  27. /// number of axes are inside-out, this will return a negative volume, but if an even number,
  28. /// it will return a positive one.
  29. FORCEINLINE float GetVolume( void ) const { return ComputeVolume( m_vMinBounds, m_vMaxBounds ); }
  30. FORCEINLINE float GetMinDistToPoint( const Vector &vPoint ) const
  31. {
  32. return CalcDistanceToAABB( m_vMinBounds, m_vMaxBounds, vPoint );
  33. }
  34. FORCEINLINE float GetMinAxialDistanceToPoint( const Vector &vPoint ) const
  35. {
  36. float flXInterval = MAX( 0, MAX( vPoint.x - m_vMaxBounds.x, m_vMinBounds.x - vPoint.x ) );
  37. float flYInterval = MAX( 0, MAX( vPoint.y - m_vMaxBounds.y, m_vMinBounds.y - vPoint.y ) );
  38. float flZInterval = MAX( 0, MAX( vPoint.z - m_vMaxBounds.z, m_vMinBounds.z - vPoint.z ) );
  39. return MAX( flXInterval, MAX( flYInterval, flZInterval ) );
  40. }
  41. /// expand the aabt_t to contain a point
  42. FORCEINLINE void operator |=( const Vector &vPoint )
  43. {
  44. AddPointToBounds( vPoint, m_vMinBounds, m_vMaxBounds );
  45. }
  46. /// expand the bounds to enclose another aabb_t
  47. FORCEINLINE void operator |=( const AABB_t &other )
  48. {
  49. VectorMin( other.m_vMinBounds, m_vMinBounds, m_vMinBounds );
  50. VectorMax( other.m_vMaxBounds, m_vMaxBounds, m_vMaxBounds );
  51. }
  52. /// set the bounds to the bounds of the union of this and another aabb_t
  53. FORCEINLINE void operator &=( const AABB_t &other )
  54. {
  55. VectorMax( other.m_vMinBounds, m_vMinBounds, m_vMinBounds );
  56. VectorMin( other.m_vMaxBounds, m_vMaxBounds, m_vMaxBounds );
  57. }
  58. void CreatePlanesFrom( Vector4D *pPlanes ) const
  59. {
  60. // X
  61. pPlanes[0] = Vector4D( 1, 0, 0, -m_vMaxBounds.x );
  62. pPlanes[1] = Vector4D( -1, 0, 0, m_vMinBounds.x );
  63. // Y
  64. pPlanes[2] = Vector4D( 0, 1, 0, -m_vMaxBounds.y );
  65. pPlanes[3] = Vector4D( 0, -1, 0, m_vMinBounds.y );
  66. // Z
  67. pPlanes[4] = Vector4D( 0, 0, 1, -m_vMaxBounds.z );
  68. pPlanes[5] = Vector4D( 0, 0, -1, m_vMinBounds.z );
  69. }
  70. /// Set the aabb to be invalid (max < min )
  71. void MakeInvalid( void )
  72. {
  73. m_vMinBounds.Init( FLT_MAX, FLT_MAX, FLT_MAX );
  74. m_vMaxBounds.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX );
  75. }
  76. // Returns if the bounds are invalid (negative volume), this is different
  77. // than empty, the bounds are still considered valid if min == max.
  78. FORCEINLINE bool IsInvalid() const
  79. {
  80. return ( ( m_vMinBounds.x > m_vMaxBounds.x ) ||
  81. ( m_vMinBounds.y > m_vMaxBounds.y ) ||
  82. ( m_vMinBounds.z > m_vMaxBounds.z ) );
  83. }
  84. /// Return if the bounding box has either 0 or negative volume (i.e. if min >= max for any
  85. /// coord ). Note that this treats bounds set to a single point as empty.
  86. FORCEINLINE bool IsEmpty( void ) const
  87. {
  88. return (
  89. ( m_vMinBounds.x >= m_vMaxBounds.x ) ||
  90. ( m_vMinBounds.y >= m_vMaxBounds.y ) ||
  91. ( m_vMinBounds.z >= m_vMaxBounds.z )
  92. );
  93. }
  94. FORCEINLINE bool Overlaps( AABB_t bBox ) const
  95. {
  96. bBox &= *this;
  97. return (! bBox.IsEmpty() );
  98. }
  99. FORCEINLINE bool ContainsPoint( Vector const &vPnt ) const
  100. {
  101. return (
  102. ( vPnt.x >= m_vMinBounds.x ) &&
  103. ( vPnt.y >= m_vMinBounds.y ) &&
  104. ( vPnt.z >= m_vMinBounds.z ) &&
  105. ( vPnt.x <= m_vMaxBounds.x ) &&
  106. ( vPnt.y <= m_vMaxBounds.y ) &&
  107. ( vPnt.z <= m_vMaxBounds.z )
  108. );
  109. }
  110. FORCEINLINE bool Contains( const AABB_t &box ) const
  111. {
  112. return (
  113. ( box.m_vMinBounds.x >= m_vMinBounds.x ) &&
  114. ( box.m_vMinBounds.y >= m_vMinBounds.y ) &&
  115. ( box.m_vMinBounds.z >= m_vMinBounds.z ) &&
  116. ( box.m_vMaxBounds.x <= m_vMaxBounds.x ) &&
  117. ( box.m_vMaxBounds.y <= m_vMaxBounds.y ) &&
  118. ( box.m_vMaxBounds.z <= m_vMaxBounds.z )
  119. );
  120. }
  121. /// set the aabb_t to a zero volume point in space.
  122. FORCEINLINE void SetToPoint( Vector const &vPnt )
  123. {
  124. m_vMinBounds = vPnt;
  125. m_vMaxBounds = vPnt;
  126. }
  127. FORCEINLINE float LengthOfSmallestDimension() const
  128. {
  129. Vector vDelta = m_vMaxBounds - m_vMinBounds;
  130. return vDelta.SmallestComponentValue();
  131. }
  132. FORCEINLINE const Vector GetSize() const
  133. {
  134. return m_vMaxBounds - m_vMinBounds;
  135. }
  136. FORCEINLINE void EnsureMinSize( const Vector &vMinSize )
  137. {
  138. Vector vHalfExpand = VectorMax( Vector( 0,0,0 ), vMinSize - GetSize() ) * 0.5f;
  139. m_vMaxBounds += vHalfExpand;
  140. m_vMinBounds -= vHalfExpand;
  141. }
  142. FORCEINLINE void Move( const Vector &vDelta )
  143. {
  144. m_vMinBounds += vDelta;
  145. m_vMaxBounds += vDelta;
  146. }
  147. FORCEINLINE void Expand( float flRadius )
  148. {
  149. m_vMinBounds -= Vector( flRadius, flRadius, flRadius );
  150. m_vMaxBounds += Vector( flRadius, flRadius, flRadius );
  151. }
  152. };
  153. inline const AABB_t Snap( const AABB_t& aabb, float flSnap )
  154. {
  155. return AABB_t( Snap( aabb.m_vMinBounds, flSnap ), Snap( aabb.m_vMaxBounds, flSnap ) );
  156. }
  157. inline AABB_t operator+( const AABB_t& aabb1, const AABB_t& aabb2 )
  158. {
  159. Vector vMin = VectorMin( aabb1.m_vMinBounds, aabb2.m_vMinBounds );
  160. Vector vMax = VectorMax( aabb1.m_vMaxBounds, aabb2.m_vMaxBounds );
  161. return AABB_t( vMin, vMax );
  162. }
  163. FORCEINLINE void TransformAABB( const matrix3x4_t &matTransform, AABB_t const &boundsIn, AABB_t *pBoundsOut )
  164. {
  165. TransformAABB( matTransform, boundsIn.m_vMinBounds, boundsIn.m_vMaxBounds, pBoundsOut->m_vMinBounds, pBoundsOut->m_vMaxBounds );
  166. }
  167. inline AABB_t GetAabb( const VectorAligned *pPos, int nCount )
  168. {
  169. AABB_t aabb;
  170. aabb.MakeInvalid();
  171. for ( int i = 0; i < nCount; ++i )
  172. {
  173. aabb |= pPos[ i ];
  174. }
  175. return aabb;
  176. };
  177. #endif