Team Fortress 2 Source Code as on 22/4/2020
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.

262 lines
7.2 KiB

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