Net.Like.Xue.Tokyo/Assets/BITKit/Core/Quadtree/QuadtreeNode.cs

96 lines
2.6 KiB
C#

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<int> 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<int>();
//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();
}
}
}