private void QueryContainsObjectsFromNode(QuadNode node, AABB2D bounds, List <IQuadObject> objectList) { if (!node.Bounds.Intersects(bounds)) { return; } List <IQuadObject> objectsInNode = node.InsideObjects; foreach (var obj in objectsInNode) { if (bounds.Contains(obj.Bounds)) { objectList.Add(obj); } } if (!node.IsLeaf) { QuadNode[] childNodes = node.ChildNodes; foreach (var childNode in childNodes) { if (childNode.Bounds.Intersects(bounds)) { QueryContainsObjectsFromNode(childNode, bounds, objectList); } } } }
/// <summary> /// 判断是否完全包含指定的AABB /// </summary> /// <param name="b"></param> /// <returns></returns> public bool Contains(AABB2D b) { return(Contains(b.Center + new Vector2(-b.Extents.x, -b.Extents.y)) && Contains(b.Center + new Vector2(-b.Extents.x, b.Extents.y)) && Contains(b.Center + new Vector2(b.Extents.x, -b.Extents.y)) && Contains(b.Center + new Vector2(b.Extents.x, b.Extents.y))); }
public QuadTree(int maxDepth, int splitThreshold, AABB2D bounds) { m_MaxDepth = maxDepth; m_NodeSplitThreshold = splitThreshold; Root = new QuadNode(); Root.SetData(0, QuadNodeDirection.None, bounds); }
public IQuadObject[] QueryContainsObjects(AABB2D bounds) { List <IQuadObject> objects = QuadPool.GetObjectList(); QueryContainsObjectsFromNode(Root, bounds, objects); IQuadObject[] result = objects.ToArray(); QuadPool.ReleaseObjectList(objects); return(result); }
public static void DrawGizmoAABBCross(AABB2D bounds, Color color) { Color oldColor = Gizmos.color; Gizmos.color = color; float minX = bounds.MinX; float maxX = bounds.MaxX; float minY = bounds.MinY; float maxY = bounds.MaxY; float extentX = bounds.Extents.x; float extentY = bounds.Extents.y; Gizmos.DrawLine(new Vector3(minX, 0, minY + extentY), new Vector3(maxX, 0, minY + extentY)); Gizmos.DrawLine(new Vector3(minX + extentX, 0, minY), new Vector3(minX + extentX, 0, maxY)); Gizmos.color = oldColor; }
public static void DrawGizmoAABBBorder(AABB2D bounds, Color color) { Color oldColor = Gizmos.color; Gizmos.color = color; float minX = bounds.MinX; float maxX = bounds.MaxX; float minY = bounds.MinY; float maxY = bounds.MaxY; Gizmos.DrawLine(new Vector3(minX, 0, minY), new Vector3(maxX, 0, minY)); Gizmos.DrawLine(new Vector3(minX, 0, maxY), new Vector3(maxX, 0, maxY)); Gizmos.DrawLine(new Vector3(minX, 0, minY), new Vector3(minX, 0, maxY)); Gizmos.DrawLine(new Vector3(maxX, 0, minY), new Vector3(maxX, 0, maxY)); Gizmos.color = oldColor; }
//结点达到分裂的限定,进行结点的分裂 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; }
/// <summary> /// 设置结点中的数据,为了节省内存已创建的结点将会使用缓存池循环使用 /// </summary> /// <param name="depth"></param> /// <param name="direction"></param> /// <param name="bounds"></param> internal void SetData(int depth, QuadNodeDirection direction, AABB2D bounds) { Depth = depth; Bounds = bounds; Direction = direction; }
public void QueryContainsObjects(AABB2D bounds, List <IQuadObject> objectList) { QueryContainsObjectsFromNode(Root, bounds, objectList); }
public void QueryIntersectsObjects(AABB2D bounds, ref List <IQuadObject> objectList) { QueryIntersectsObjectsFromNode(Root, bounds, objectList); }
private void OnHandleObjectBoundsChanged(IQuadObject quadObject, AABB2D oldBounds, AABB2D newBounds) { UpdateObject(quadObject); }
/// <summary> /// 判断是否与指定的AABB有交集 /// </summary> /// <param name="b"></param> /// <returns></returns> public bool Intersects(AABB2D b) { return((Mathf.Abs(Center.x - b.Center.x) < (Extents.x + b.Extents.x)) && (Mathf.Abs(Center.y - b.Center.y) < (Extents.y + b.Extents.y))); }