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.

258 lines
7.1 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "stdafx.h"
  8. #include "CullTreeNode.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include <tier0/memdbgon.h>
  11. // dvs: decide how this code should be organized
  12. bool BoxesIntersect(Vector const &mins1, Vector const &maxs1, Vector const &mins2, Vector const &maxs2);
  13. //-----------------------------------------------------------------------------
  14. // Purpose:
  15. //-----------------------------------------------------------------------------
  16. CCullTreeNode::CCullTreeNode(void)
  17. {
  18. }
  19. //-----------------------------------------------------------------------------
  20. // Purpose:
  21. //-----------------------------------------------------------------------------
  22. CCullTreeNode::~CCullTreeNode(void)
  23. {
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Purpose:
  27. // Input : pChild -
  28. //-----------------------------------------------------------------------------
  29. void CCullTreeNode::AddCullTreeChild(CCullTreeNode *pChild)
  30. {
  31. m_Children.AddToTail(pChild);
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Purpose:
  35. // Input : pObject -
  36. //-----------------------------------------------------------------------------
  37. void CCullTreeNode::AddCullTreeObject(CMapClass *pObject)
  38. {
  39. // First make sure the object isn't already in this node.
  40. // If it's already here, bail out.
  41. if ( m_Objects.Find( pObject ) != -1 )
  42. return;
  43. // Add the object.
  44. m_Objects.AddToTail(pObject);
  45. }
  46. //-----------------------------------------------------------------------------
  47. // Purpose:
  48. // Input : pObject -
  49. //-----------------------------------------------------------------------------
  50. void CCullTreeNode::AddCullTreeObjectRecurse(CMapClass *pObject)
  51. {
  52. //
  53. // If the object intersects this node, add it to this node and recurse,
  54. // testing each of our children in the same fashion.
  55. //
  56. Vector ObjMins;
  57. Vector ObjMaxs;
  58. pObject->GetCullBox(ObjMins, ObjMaxs);
  59. if (BoxesIntersect(ObjMins, ObjMaxs, bmins, bmaxs))
  60. {
  61. int nChildCount = GetChildCount();
  62. if (nChildCount != 0)
  63. {
  64. // dvs: we should split when appropriate!
  65. // otherwise the tree becomes less optimal over time.
  66. for (int nChild = 0; nChild < nChildCount; nChild++)
  67. {
  68. CCullTreeNode *pChild = GetCullTreeChild(nChild);
  69. pChild->AddCullTreeObjectRecurse(pObject);
  70. }
  71. }
  72. else
  73. {
  74. AddCullTreeObject(pObject);
  75. }
  76. }
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Purpose: Removes all objects from this node.
  80. //-----------------------------------------------------------------------------
  81. void CCullTreeNode::RemoveAllCullTreeObjects(void)
  82. {
  83. m_Objects.RemoveAll();
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose: Removes all objects from this branch of the tree recursively.
  87. //-----------------------------------------------------------------------------
  88. void CCullTreeNode::RemoveAllCullTreeObjectsRecurse(void)
  89. {
  90. RemoveAllCullTreeObjects();
  91. int nChildCount = GetChildCount();
  92. for (int nChild = 0; nChild < nChildCount; nChild++)
  93. {
  94. CCullTreeNode *pChild = GetCullTreeChild(nChild);
  95. pChild->RemoveAllCullTreeObjectsRecurse();
  96. }
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Removes all instances of a given object from this node.
  100. // Input : pObject -
  101. //-----------------------------------------------------------------------------
  102. void CCullTreeNode::RemoveCullTreeObject(CMapClass *pObject)
  103. {
  104. // Remove occurrence of pObject from the array
  105. m_Objects.FindAndFastRemove( pObject );
  106. // make sure it's not in there twice
  107. Assert( m_Objects.Find( pObject) == -1 );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose: Removes all instances of a given object from this node.
  111. // Input : pObject -
  112. //-----------------------------------------------------------------------------
  113. void CCullTreeNode::RemoveCullTreeObjectRecurse(CMapClass *pObject)
  114. {
  115. RemoveCullTreeObject(pObject);
  116. for (int nChild = 0; nChild < m_Children.Count(); nChild++)
  117. {
  118. CCullTreeNode *pChild = m_Children[nChild];
  119. pChild->RemoveCullTreeObjectRecurse(pObject);
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose: Removes all instances of a given object from this node.
  124. // Input : pObject -
  125. //-----------------------------------------------------------------------------
  126. CCullTreeNode *CCullTreeNode::FindCullTreeObjectRecurse(CMapClass *pObject)
  127. {
  128. for (int i = 0; i < m_Objects.Count(); i++)
  129. {
  130. CMapClass *pCurrent = m_Objects[i];
  131. if (pCurrent == pObject)
  132. {
  133. return(this);
  134. }
  135. }
  136. int nChildCount = GetChildCount();
  137. for (int nChild = 0; nChild < nChildCount; nChild++)
  138. {
  139. CCullTreeNode *pChild = GetCullTreeChild(nChild);
  140. CCullTreeNode *pFound = pChild->FindCullTreeObjectRecurse(pObject);
  141. if (pFound != NULL)
  142. {
  143. return(pFound);
  144. }
  145. }
  146. return(NULL);
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Purpose:
  150. // Input : pObject -
  151. //-----------------------------------------------------------------------------
  152. void CCullTreeNode::UpdateCullTreeObject(CMapClass *pObject)
  153. {
  154. Vector mins;
  155. Vector maxs;
  156. pObject->GetCullBox(mins, maxs);
  157. if (!BoxesIntersect(mins, maxs, bmins, bmaxs))
  158. {
  159. RemoveCullTreeObject(pObject);
  160. }
  161. else
  162. {
  163. AddCullTreeObject(pObject);
  164. }
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Purpose: Updates the culling tree due to a change in the bounding box of a
  168. // given object within the tree. The object is added to any leaf nodes
  169. // that it now intersects, and is removed from any leaf nodes that it
  170. // no longer intersects.
  171. // Input : pObject - The object whose bounding box has changed.
  172. //-----------------------------------------------------------------------------
  173. void CCullTreeNode::UpdateCullTreeObjectRecurse(CMapClass *pObject)
  174. {
  175. int nChildCount = GetChildCount();
  176. if (nChildCount != 0)
  177. {
  178. for (int nChild = 0; nChild < nChildCount; nChild++)
  179. {
  180. CCullTreeNode *pChild = GetCullTreeChild(nChild);
  181. pChild->UpdateCullTreeObjectRecurse(pObject);
  182. }
  183. }
  184. else
  185. {
  186. UpdateCullTreeObject(pObject);
  187. }
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose:
  191. // Input : pObject - The object whose bounding box has changed.
  192. //-----------------------------------------------------------------------------
  193. void CCullTreeNode::UpdateAllCullTreeObjectsRecurse(void)
  194. {
  195. int nChildCount = GetChildCount();
  196. if (nChildCount != 0)
  197. {
  198. for (int nChild = 0; nChild < nChildCount; nChild++)
  199. {
  200. CCullTreeNode *pChild = GetCullTreeChild(nChild);
  201. pChild->UpdateAllCullTreeObjectsRecurse();
  202. }
  203. }
  204. else
  205. {
  206. int nObjectCount = GetObjectCount();
  207. for (int nObject = 0; nObject < nObjectCount; nObject++)
  208. {
  209. CMapClass *pObject = GetCullTreeObject(nObject);
  210. Vector mins;
  211. Vector maxs;
  212. pObject->GetCullBox(mins, maxs);
  213. if (!BoxesIntersect(mins, maxs, bmins, bmaxs))
  214. {
  215. RemoveCullTreeObject(pObject);
  216. }
  217. }
  218. }
  219. }