//----------------------------------------------------------------------------- // 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); } } } }
void CMapWorld::CullTree_SplitNode(CCullTreeNode *pNode) { Vector Mins; Vector Maxs; Vector Size; pNode->GetBounds(Mins, Maxs); VectorSubtract(Maxs, Mins, Size); if ((Size[0] > MIN_NODE_DIM) && (Size[1] > MIN_NODE_DIM) && (Size[2] > MIN_NODE_DIM)) { Vector Mids; int nChild; Mids[0] = (Mins[0] + Maxs[0]) / 2.0; Mids[1] = (Mins[1] + Maxs[1]) / 2.0; Mids[2] = (Mins[2] + Maxs[2]) / 2.0; for (nChild = 0; nChild < 8; nChild++) { Vector ChildMins; Vector ChildMaxs; // // Create a child and set its bounding box. // CCullTreeNode *pChild = new CCullTreeNode; if (nChild & 1) { ChildMins[0] = Mins[0]; ChildMaxs[0] = Mids[0]; } else { ChildMins[0] = Mids[0]; ChildMaxs[0] = Maxs[0]; } if (nChild & 2) { ChildMins[1] = Mins[1]; ChildMaxs[1] = Mids[1]; } else { ChildMins[1] = Mids[1]; ChildMaxs[1] = Maxs[1]; } if (nChild & 4) { ChildMins[2] = Mins[2]; ChildMaxs[2] = Mids[2]; } else { ChildMins[2] = Mids[2]; ChildMaxs[2] = Maxs[2]; } pChild->UpdateBounds(ChildMins, ChildMaxs); pNode->AddCullTreeChild(pChild); Vector mins1; Vector maxs1; pChild->GetBounds(mins1, maxs1); // // Check all objects in this node against the child's bounding box, adding the // objects that intersect to the child's object list. // int nObjectCount = pNode->GetObjectCount(); for (int nObject = 0; nObject < nObjectCount; nObject++) { CMapClass *pObject = pNode->GetCullTreeObject(nObject); Assert(pObject != NULL); Vector mins2; Vector maxs2; pObject->GetCullBox(mins2, maxs2); if (BoxesIntersect(mins1, maxs1, mins2, maxs2)) { pChild->AddCullTreeObject(pObject); } } } // // Remove all objects from this node's object list (since we are not a leaf). // pNode->RemoveAllCullTreeObjects(); // // Recurse into all children with at least two objects, splitting them. // int nChildCount = pNode->GetChildCount(); for (nChild = 0; nChild < nChildCount; nChild++) { CCullTreeNode *pChild = pNode->GetCullTreeChild(nChild); if (pChild->GetObjectCount() >= MIN_NODE_OBJECT_SPLIT) { CullTree_SplitNode(pChild); } } } }