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.

205 lines
5.3 KiB

  1. //===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
  2. //--------------------------------------------------------------------------------------------------
  3. // Dynamic tree
  4. //--------------------------------------------------------------------------------------------------
  5. FORCEINLINE void* CDynamicTree::GetUserData( int32 nProxyId ) const
  6. {
  7. AssertDbg( m_NodePool[ nProxyId ].IsLeaf() );
  8. return m_NodePool[ nProxyId ].m_pUserData;
  9. }
  10. //--------------------------------------------------------------------------------------------------
  11. FORCEINLINE AABB_t CDynamicTree::GetBounds( int32 nProxyId ) const
  12. {
  13. AssertDbg( m_NodePool[ nProxyId ].IsLeaf() );
  14. return m_NodePool[ nProxyId ].m_Bounds;
  15. }
  16. //-------------------------------------------------------------------------------------------------
  17. FORCEINLINE AABB_t CDynamicTree::Inflate( const AABB_t& aabb, float flExtent ) const
  18. {
  19. AABB_t out;
  20. Vector vExtent( flExtent, flExtent, flExtent );
  21. out.m_vMinBounds = aabb.m_vMinBounds - vExtent;
  22. out.m_vMaxBounds = aabb.m_vMaxBounds + vExtent;
  23. return out;
  24. }
  25. //-------------------------------------------------------------------------------------------------
  26. FORCEINLINE AABB_t CDynamicTree::Inflate( const AABB_t& aabb, const Vector& vExtent ) const
  27. {
  28. AABB_t out;
  29. out.m_vMinBounds = aabb.m_vMinBounds - vExtent;
  30. out.m_vMaxBounds = aabb.m_vMaxBounds + vExtent;
  31. return out;
  32. }
  33. //--------------------------------------------------------------------------------------------------
  34. FORCEINLINE void CDynamicTree::ClipRay( const Ray_t& ray, const AABB_t& aabb, float& flMinT, float& flMaxT ) const
  35. {
  36. for ( int nAxis = 0; nAxis < 3; ++nAxis )
  37. {
  38. float t1 = ( aabb.m_vMinBounds[ nAxis ] - ray.vOrigin[ nAxis ] ) * ray.vDeltaInv[ nAxis ];
  39. float t2 = ( aabb.m_vMaxBounds[ nAxis ] - ray.vOrigin[ nAxis ] ) * ray.vDeltaInv[ nAxis ];
  40. flMinT = fpmax( flMinT, fpmin( t1, t2 ) );
  41. flMaxT = fpmin( flMaxT, fpmax( t1, t2 ) );
  42. }
  43. }
  44. //--------------------------------------------------------------------------------------------------
  45. template < typename Functor > void CDynamicTree::CastRay( const Vector& vRayStart, const Vector& vRayDelta, Functor& callback ) const
  46. {
  47. if ( m_nRoot < 0 )
  48. {
  49. AssertDbg( m_nRoot == NULL_NODE );
  50. return;
  51. }
  52. // Setup the ray
  53. Ray_t ray = Ray_t( vRayStart, vRayStart + vRayDelta );
  54. float flBestT = 1.0f;
  55. int nCount = 0;
  56. int32 stack[ STACK_DEPTH ];
  57. stack[ nCount++ ] = m_nRoot;
  58. while ( nCount > 0 )
  59. {
  60. int32 nNode = stack[ --nCount ];
  61. const Node_t& node = m_NodePool[ nNode ];
  62. float flMinT = 0.0f, flMaxT = 1.0f;
  63. ClipRay( ray, node.m_Bounds, flMinT, flMaxT );
  64. if ( flMinT > flMaxT || flMinT > flBestT )
  65. {
  66. continue;
  67. }
  68. if ( !node.IsLeaf() )
  69. {
  70. AssertDbg( nCount + 2 <= STACK_DEPTH );
  71. stack[ nCount++ ] = node.m_nChild2;
  72. stack[ nCount++ ] = node.m_nChild1;
  73. }
  74. else
  75. {
  76. float T = callback( GetUserData( nNode ), vRayStart, vRayDelta, flBestT );
  77. flBestT = fpmin( T, flBestT );
  78. if ( T == 0.0f )
  79. {
  80. // The user terminated the query.
  81. return;
  82. }
  83. }
  84. }
  85. }
  86. //--------------------------------------------------------------------------------------------------
  87. template< typename Functor > void CDynamicTree::CastSphere( const Vector& vRayStart, const Vector& vRayDelta, float flRadius, Functor& callback ) const
  88. {
  89. if ( m_nRoot < 0 )
  90. {
  91. AssertDbg( m_nRoot == NULL_NODE );
  92. return;
  93. }
  94. // Setup the ray
  95. Ray_t ray = Ray_t( vRayStart, vRayStart + vRayDelta );
  96. float flBestT = 1.0f;
  97. int nCount = 0;
  98. int32 stack[ STACK_DEPTH ];
  99. stack[ nCount++ ] = m_nRoot;
  100. while ( nCount > 0 )
  101. {
  102. int32 nNode = stack[ --nCount ];
  103. const Node_t& node = m_NodePool[ nNode ];
  104. float flMinT = 0.0f, flMaxT = 1.0f;
  105. ClipRay( ray, Inflate( node.m_Bounds, flRadius ), flMinT, flMaxT );
  106. if ( flMinT > flMaxT || flMinT > flBestT )
  107. {
  108. continue;
  109. }
  110. if ( !node.IsLeaf() )
  111. {
  112. AssertDbg( nCount + 2 <= STACK_DEPTH );
  113. stack[ nCount++ ] = node.m_nChild2;
  114. stack[ nCount++ ] = node.m_nChild1;
  115. }
  116. else
  117. {
  118. float T = callback( GetUserData( nNode ), vRayStart, vRayDelta, flRadius, flBestT );
  119. flBestT = fpmin( T, flBestT );
  120. if ( T == 0.0f )
  121. {
  122. // The user terminated the query
  123. return;
  124. }
  125. }
  126. }
  127. }
  128. //--------------------------------------------------------------------------------------------------
  129. template< typename Functor > void CDynamicTree::CastBox( const Vector& vRayStart, const Vector& vRayDelta, const Vector& vExtent, Functor& callback ) const
  130. {
  131. if ( m_nRoot < 0 )
  132. {
  133. AssertDbg( m_nRoot == NULL_NODE );
  134. return;
  135. }
  136. // Setup the ray
  137. Ray_t ray = Ray_t( vRayStart, vRayStart + vRayDelta );
  138. float flBestT = 1.0f;
  139. int nCount = 0;
  140. int32 stack[ STACK_DEPTH ];
  141. stack[ nCount++ ] = m_nRoot;
  142. while ( nCount > 0 )
  143. {
  144. int32 nNode = stack[ --nCount ];
  145. const Node_t& node = m_NodePool[ nNode ];
  146. float flMinT = 0.0f, flMaxT = 1.0f;
  147. ClipRay( ray, Inflate( node.m_Bounds, vExtent ), flMinT, flMaxT );
  148. if ( flMinT > flMaxT || flMinT > flBestT )
  149. {
  150. continue;
  151. }
  152. if ( !node.IsLeaf() )
  153. {
  154. AssertDbg( nCount + 2 <= STACK_DEPTH );
  155. stack[ nCount++ ] = node.m_nChild2;
  156. stack[ nCount++ ] = node.m_nChild1;
  157. }
  158. else
  159. {
  160. float T = callback( GetUserData( nNode ), vRayStart, vRayDelta, vExtent, flBestT );
  161. flBestT = fpmin( T, flBestT );
  162. if ( T == 0.0f )
  163. {
  164. // The user terminated the query
  165. return;
  166. }
  167. }
  168. }
  169. }