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.

177 lines
4.9 KiB

  1. //========= Copyright � Valve Corporation, All rights reserved. ============//
  2. #ifndef DYNAMIC_TREE_HDR
  3. #define DYNAMIC_TREE_HDR
  4. #include "vector.h"
  5. #include "aabb.h"
  6. #include "utlvector.h"
  7. // This class implements a dynamic AABB tree and allows node insertion, removal and updates.
  8. // The user needs to provide an AABB on construction and will receive a unique identifier
  9. // to update and remove the node later. On construction you can also associate some arbitrary
  10. // user data. The tree is build using the SAH and uses AVL rotations for balancing. Nodes are
  11. // managed in a free list and no pointers are returned. This allows for fast allocations and
  12. // we can still grow the tree. Note that no memory is released destruction.
  13. // If you have a large number of proxies and all are moving each frame it is recommend to
  14. // insert and inflated AABB and only trigger and update if the original AABB moved out of the
  15. // fat AABB in the tree. This approach is very successfully used in the Rubikon broadphase.
  16. // Casting:
  17. // Ray, sphere and box casting uses a simple callback mechanism.
  18. // The callback signature is: float f( pUserData, vRayStart, vRayDelta, flBestT );
  19. // The callback mechanism allows us to implement any-, closest-, and
  20. // all hit(s) queries in one function. We expect from the client to
  21. // return the following for this to work:
  22. // Any: t = 0 (if hit something)
  23. // Closest: 0 < t < 1
  24. // All: t = 1 (always)
  25. // Queries:
  26. // * The dynamic tree supports sphere and box queries to find all proxies intersected by
  27. // the specified volume.
  28. // * The dynamic tree supports 'closest proxy' queries
  29. //--------------------------------------------------------------------------------------------------
  30. // Proxy vector
  31. //--------------------------------------------------------------------------------------------------
  32. typedef CUtlVectorFixedGrowable< int32, 512 > CProxyVector;
  33. //--------------------------------------------------------------------------------------------------
  34. // Dynamic tree
  35. //--------------------------------------------------------------------------------------------------
  36. class CDynamicTree
  37. {
  38. public:
  39. // Construction
  40. CDynamicTree();
  41. // Proxy interface
  42. int ProxyCount() const;
  43. int32 CreateProxy( const AABB_t& bounds, void* pUserData = NULL );
  44. void* DestroyProxy( int32 nProxyId );
  45. void MoveProxy( int32 nProxyId, const AABB_t& bounds );
  46. void* GetUserData( int32 nProxyId ) const;
  47. AABB_t GetBounds( int32 nProxyId ) const;
  48. // Casting
  49. template < typename Functor >
  50. void CastRay( const Vector& vRayStart, const Vector &vRayDelta, Functor& callback ) const;
  51. template< typename Functor >
  52. void CastSphere( const Vector& vRayStart, const Vector& vRayDelta, float flRadius, Functor& callback ) const;
  53. template< typename Functor >
  54. void CastBox( const Vector& vRayStart, const Vector& vRayDelta, const Vector& vExtent, Functor& callback ) const;
  55. // Queries
  56. void Query( CProxyVector& proxies, const AABB_t& aabb ) const;
  57. void Query( CProxyVector& proxies, const Vector& vCenter, float flRadius ) const;
  58. // Returns the distance to the closest proxy; FLT_MAX if no proxies were
  59. // found (i.e. your tree is empty)
  60. float ClosestProxies( CProxyVector& proxies, const Vector &vQuery ) const;
  61. private:
  62. // Implementation
  63. enum
  64. {
  65. NULL_NODE = -1,
  66. STACK_DEPTH = 64
  67. };
  68. void InsertLeaf( int32 nLeaf );
  69. void RemoveLeaf( int32 nLeaf );
  70. void AdjustAncestors( int32 nNode );
  71. int32 Balance( int32 nNode );
  72. struct Ray_t
  73. {
  74. Ray_t() {}
  75. Ray_t( const Vector& vStart, const Vector& vEnd )
  76. {
  77. vOrigin = vStart;
  78. vDelta = vEnd - vStart;
  79. // Pre-compute inverse
  80. vDeltaInv.x = vDelta.x != 0.0f ? 1.0f / vDelta.x : FLT_MAX;
  81. vDeltaInv.y = vDelta.y != 0.0f ? 1.0f / vDelta.y : FLT_MAX;
  82. vDeltaInv.z = vDelta.z != 0.0f ? 1.0f / vDelta.z : FLT_MAX;
  83. }
  84. Vector vOrigin;
  85. Vector vDelta;
  86. Vector vDeltaInv;
  87. };
  88. AABB_t Inflate( const AABB_t& aabb, float flExtent ) const;
  89. AABB_t Inflate( const AABB_t& aabb, const Vector& vExtent ) const;
  90. void ClipRay( const Ray_t& ray, const AABB_t& aabb, float& flMinT, float& flMaxT ) const;
  91. struct Node_t
  92. {
  93. AABB_t m_Bounds;
  94. int32 m_nHeight;
  95. int32 m_nParent;
  96. int32 m_nChild1;
  97. int32 m_nChild2;
  98. void* m_pUserData;
  99. FORCEINLINE bool IsLeaf() const
  100. {
  101. return m_nChild1 == NULL_NODE;
  102. }
  103. };
  104. class CNodePool
  105. {
  106. public:
  107. // Construction / Destruction
  108. CNodePool();
  109. ~CNodePool();
  110. // Memory management
  111. void Clear();
  112. void Reserve( int nCapacity );
  113. int32 Alloc();
  114. void Free( int32 id );
  115. // Accessors
  116. FORCEINLINE Node_t& operator[]( int32 id )
  117. {
  118. AssertDbg( 0 <= id && id < m_nCapacity );
  119. return m_pObjects[ id ];
  120. }
  121. FORCEINLINE const Node_t& operator[]( int32 id ) const
  122. {
  123. AssertDbg( 0 <= id && id < m_nCapacity );
  124. return m_pObjects[ id ];
  125. }
  126. private:
  127. int m_nCapacity;
  128. Node_t* m_pObjects;
  129. int32 m_nNext;
  130. };
  131. // Data members
  132. int32 m_nRoot;
  133. int m_nProxyCount;
  134. CNodePool m_NodePool;
  135. };
  136. #include "dynamictree.inl"
  137. #endif