private void SearchObjects(QuadNode node, List <IQuadObject> objectList, bool isIncludeChildNode) { objectList.AddRange(node.InsideObjects); if (node.IsLeaf || !isIncludeChildNode) { return; } else { foreach (var childNode in node.ChildNodes) { SearchObjects(childNode, objectList, isIncludeChildNode); } } }
private int GetNodeObjectCount(QuadNode node, bool isIncludeChildNode) { if (node.IsLeaf || !isIncludeChildNode) { return(node.InsideObjects.Count); } int count = node.InsideObjects.Count; foreach (var childNode in node.ChildNodes) { count += GetNodeObjectCount(childNode, true); } return(count); }
//对象删除或更新后,需要对旧的结点进行合并操作 private void MergeNode(QuadNode mergedNode) { if (mergedNode == null || mergedNode.ObjectCount >= m_NodeSplitThreshold) { return; } QuadNode targetNode = mergedNode; while (targetNode != null) { if (targetNode.ParentNode != null && targetNode.ParentNode.GetTotalObjectCount() >= m_NodeSplitThreshold) { break; } targetNode = targetNode.ParentNode; } if (targetNode != null && !targetNode.IsLeaf) { List <QuadNode> nodeList = QuadPool.GetNodeList(); targetNode.GetTotalChildNodes(ref nodeList); List <IQuadObject> objectList = QuadPool.GetObjectList(); targetNode.GetTotalObjects(ref objectList); targetNode[QuadNodeDirection.LB] = null; targetNode[QuadNodeDirection.RB] = null; targetNode[QuadNodeDirection.LT] = null; targetNode[QuadNodeDirection.RT] = null; foreach (var childNode in nodeList) { m_NodePool.Release(childNode); } targetNode.ClearObjects(); foreach (var obj in objectList) { m_ObjectToNodeDic.Remove(obj); InsertObjectToNode(targetNode, obj); } QuadPool.ReleaseNodeList(nodeList); QuadPool.ReleaseObjectList(objectList); } }
private void SearchNodes(QuadNode node, List <QuadNode> nodeList, bool isIncludeSelf, bool isIncludeChildNode) { if (isIncludeSelf) { nodeList.Add(node); } if (node.IsLeaf) { return; } nodeList.AddRange(node.ChildNodes); if (isIncludeChildNode) { foreach (var childNode in node.ChildNodes) { SearchNodes(childNode, nodeList, false, isIncludeChildNode); } } }
//结点分裂后重新整理原来的对象 private void ResetNodeObjects(QuadNode node) { List <IQuadObject> nodeObjects = QuadPool.GetObjectList(); node.GetObjects(ref nodeObjects); node.ClearObjects(); List <IQuadObject> uninsertToChildObjects = QuadPool.GetObjectList(); foreach (var obj in nodeObjects) { bool isInsertToChildNode = false; QuadNode[] childNodes = node.ChildNodes; foreach (var childNode in childNodes) { if (childNode.TryInsertObject(obj)) { m_ObjectToNodeDic[obj] = childNode; isInsertToChildNode = true; break; } } if (!isInsertToChildNode) { uninsertToChildObjects.Add(obj); } } if (uninsertToChildObjects.Count > 0) { foreach (var obj in uninsertToChildObjects) { node.InsertObject(obj); } } QuadPool.ReleaseObjectList(nodeObjects); QuadPool.ReleaseObjectList(uninsertToChildObjects); }
//结点达到分裂的限定,进行结点的分裂 private void SplitNode(QuadNode node) { AABB2D bounds = node.Bounds; Vector2 childNodeExtents = bounds.HalfExtents; QuadNode childNode = m_NodePool.Get(); childNode.SetData(node.Depth + 1, QuadNodeDirection.LB, new AABB2D(bounds.Center - childNodeExtents, childNodeExtents)); node[QuadNodeDirection.LB] = childNode; childNode = m_NodePool.Get(); childNode.SetData(node.Depth + 1, QuadNodeDirection.RB, new AABB2D(bounds.Center + new Vector2(childNodeExtents.x, -childNodeExtents.y), childNodeExtents)); node[QuadNodeDirection.RB] = childNode; childNode = m_NodePool.Get(); childNode.SetData(node.Depth + 1, QuadNodeDirection.LT, new AABB2D(bounds.Center + new Vector2(-childNodeExtents.x, childNodeExtents.y), childNodeExtents)); node[QuadNodeDirection.LT] = childNode; childNode = m_NodePool.Get(); childNode.SetData(node.Depth + 1, QuadNodeDirection.RT, new AABB2D(bounds.Center + childNodeExtents, childNodeExtents)); node[QuadNodeDirection.RT] = childNode; }
private void RemoveObjectFromNode(QuadNode node, IQuadObject quadObject) { m_ObjectToNodeDic.Remove(quadObject); node.RemoveObject(quadObject); }