summaryrefslogtreecommitdiff
path: root/hammer/culltreenode.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/culltreenode.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'hammer/culltreenode.cpp')
-rw-r--r--hammer/culltreenode.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/hammer/culltreenode.cpp b/hammer/culltreenode.cpp
new file mode 100644
index 0000000..6b40db2
--- /dev/null
+++ b/hammer/culltreenode.cpp
@@ -0,0 +1,262 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "stdafx.h"
+#include "CullTreeNode.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+// dvs: decide how this code should be organized
+bool BoxesIntersect(Vector const &mins1, Vector const &maxs1, Vector const &mins2, Vector const &maxs2);
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCullTreeNode::CCullTreeNode(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCullTreeNode::~CCullTreeNode(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pChild -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::AddCullTreeChild(CCullTreeNode *pChild)
+{
+ if ( pChild == NULL )
+ Assert( pChild );
+ else
+ m_Children.AddToTail(pChild);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pObject -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::AddCullTreeObject(CMapClass *pObject)
+{
+ // First make sure the object isn't already in this node.
+
+ // If it's already here, bail out.
+ if ( m_Objects.Find( pObject ) != -1 )
+ return;
+
+ // Add the object.
+ m_Objects.AddToTail(pObject);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pObject -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::AddCullTreeObjectRecurse(CMapClass *pObject)
+{
+ //
+ // If the object intersects this node, add it to this node and recurse,
+ // testing each of our children in the same fashion.
+ //
+ Vector ObjMins;
+ Vector ObjMaxs;
+ pObject->GetCullBox(ObjMins, ObjMaxs);
+ if (BoxesIntersect(ObjMins, ObjMaxs, bmins, bmaxs))
+ {
+ int nChildCount = GetChildCount();
+ if (nChildCount != 0)
+ {
+ // dvs: we should split when appropriate!
+ // otherwise the tree becomes less optimal over time.
+ for (int nChild = 0; nChild < nChildCount; nChild++)
+ {
+ CCullTreeNode *pChild = GetCullTreeChild(nChild);
+ pChild->AddCullTreeObjectRecurse(pObject);
+ }
+ }
+ else
+ {
+ AddCullTreeObject(pObject);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes all objects from this node.
+//-----------------------------------------------------------------------------
+void CCullTreeNode::RemoveAllCullTreeObjects(void)
+{
+ m_Objects.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes all objects from this branch of the tree recursively.
+//-----------------------------------------------------------------------------
+void CCullTreeNode::RemoveAllCullTreeObjectsRecurse(void)
+{
+ RemoveAllCullTreeObjects();
+
+ int nChildCount = GetChildCount();
+ for (int nChild = 0; nChild < nChildCount; nChild++)
+ {
+ CCullTreeNode *pChild = GetCullTreeChild(nChild);
+ pChild->RemoveAllCullTreeObjectsRecurse();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes all instances of a given object from this node.
+// Input : pObject -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::RemoveCullTreeObject(CMapClass *pObject)
+{
+ // Remove occurrence of pObject from the array
+
+ m_Objects.FindAndRemove( pObject );
+
+ // make sure it's not in there twice
+ Assert( m_Objects.Find( pObject) == -1 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes all instances of a given object from this node.
+// Input : pObject -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::RemoveCullTreeObjectRecurse(CMapClass *pObject)
+{
+ RemoveCullTreeObject(pObject);
+
+ for (int nChild = 0; nChild < m_Children.Count(); nChild++)
+ {
+ CCullTreeNode *pChild = m_Children[nChild];
+ pChild->RemoveCullTreeObjectRecurse(pObject);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes all instances of a given object from this node.
+// Input : pObject -
+//-----------------------------------------------------------------------------
+CCullTreeNode *CCullTreeNode::FindCullTreeObjectRecurse(CMapClass *pObject)
+{
+ for (int i = 0; i < m_Objects.Count(); i++)
+ {
+ CMapClass *pCurrent = m_Objects[i];
+ if (pCurrent == pObject)
+ {
+ return(this);
+ }
+ }
+
+ int nChildCount = GetChildCount();
+ for (int nChild = 0; nChild < nChildCount; nChild++)
+ {
+ CCullTreeNode *pChild = GetCullTreeChild(nChild);
+ CCullTreeNode *pFound = pChild->FindCullTreeObjectRecurse(pObject);
+ if (pFound != NULL)
+ {
+ return(pFound);
+ }
+ }
+
+ return(NULL);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pObject -
+//-----------------------------------------------------------------------------
+void CCullTreeNode::UpdateCullTreeObject(CMapClass *pObject)
+{
+ Vector mins;
+ Vector maxs;
+ pObject->GetCullBox(mins, maxs);
+
+ if (!BoxesIntersect(mins, maxs, bmins, bmaxs))
+ {
+ RemoveCullTreeObject(pObject);
+ }
+ else
+ {
+ AddCullTreeObject(pObject);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates the culling tree due to a change in the bounding box of a
+// given object within the tree. The object is added to any leaf nodes
+// that it now intersects, and is removed from any leaf nodes that it
+// no longer intersects.
+// Input : pObject - The object whose bounding box has changed.
+//-----------------------------------------------------------------------------
+void CCullTreeNode::UpdateCullTreeObjectRecurse(CMapClass *pObject)
+{
+ int nChildCount = GetChildCount();
+ if (nChildCount != 0)
+ {
+ for (int nChild = 0; nChild < nChildCount; nChild++)
+ {
+ CCullTreeNode *pChild = GetCullTreeChild(nChild);
+ pChild->UpdateCullTreeObjectRecurse(pObject);
+ }
+ }
+ else
+ {
+ UpdateCullTreeObject(pObject);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pObject - The object whose bounding box has changed.
+//-----------------------------------------------------------------------------
+void CCullTreeNode::UpdateAllCullTreeObjectsRecurse(void)
+{
+ int nChildCount = GetChildCount();
+ if (nChildCount != 0)
+ {
+ for (int nChild = 0; nChild < nChildCount; nChild++)
+ {
+ CCullTreeNode *pChild = GetCullTreeChild(nChild);
+ pChild->UpdateAllCullTreeObjectsRecurse();
+ }
+ }
+ else
+ {
+ int nObjectCount = GetObjectCount();
+ for (int nObject = 0; nObject < nObjectCount; nObject++)
+ {
+ CMapClass *pObject = GetCullTreeObject(nObject);
+
+ Vector mins;
+ Vector maxs;
+ pObject->GetCullBox(mins, maxs);
+ if (!BoxesIntersect(mins, maxs, bmins, bmaxs))
+ {
+ RemoveCullTreeObject(pObject);
+ }
+ }
+ }
+}