96 lines
2.6 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|