using System; using System.Buffers; using System.Collections.Concurrent; using Unity.Mathematics; using System.Collections.Generic; #if UNITY_5_3_OR_NEWER using Unity.Burst; #endif namespace Net.BITKit.Quadtree { public struct QuadtreeNode { private readonly Quadtree _root; public int Depth; public float2 Center; // 节点中心 public float2 Size; // 节点大小 public readonly QuadtreeNode[] Children; // 子节点 public readonly HashSet Objects; // 存储的对象ID public bool IsLeaf; public QuadtreeNode(Quadtree root,float2 center, float2 size) { _root = root; Center = center; Size = size; Children = new QuadtreeNode[4]; Objects = new HashSet(); //Objects = root.HashSetPool.Take(); //Objects.Clear(); IsLeaf = true; Depth = 0; } #if UNITY_5_3_OR_NEWER [BurstCompile] #endif public readonly bool Contains(float2 point) { var min = Center - Size * 0.5f; var max = Center + Size * 0.5f; return math.all(point >= min & point <= max); } public void Split() { if (IsLeaf is false) { throw new InvalidOperationException("Node has already been split."); } var childSize = Size / 2; var offset = childSize / 2; Children[0] = new QuadtreeNode(_root, Center + new float2(-offset.x, offset.y), childSize) { Depth = Depth + 1, }; Children[1] = new QuadtreeNode(_root, Center + new float2(offset.x, offset.y), childSize) { Depth = Depth + 1, }; Children[2] = new QuadtreeNode(_root, Center + new float2(-offset.x, -offset.y), childSize) { Depth = Depth + 1, }; Children[3] = new QuadtreeNode(_root, Center + new float2(offset.x, -offset.y), childSize) { Depth = Depth + 1, }; IsLeaf = false; foreach (var id in Objects) { var pos = _root.Positions[id]; for (var i = 0; i < Children.Length; i++) { ref var node =ref Children[i]; if (!node.Contains(pos)) continue; node.Objects.Add(id); break; } } Objects.Clear(); } } }