1
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:e0cd26848372d4e5c891c569017e11f1"
|
||||
"GUID:e0cd26848372d4e5c891c569017e11f1",
|
||||
"GUID:2665a8d13d1b3f18800f46e256720795"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -6,6 +6,8 @@ using System.Collections.Generic;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BITKit;
|
||||
using Unity.Burst;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Net.BITKit.Quadtree
|
||||
@@ -22,23 +24,33 @@ namespace Net.BITKit.Quadtree
|
||||
return _positions;
|
||||
}
|
||||
}
|
||||
public IDictionary<int, float2> Sizes => _sizes;
|
||||
private readonly Dictionary<int, float2> _positions;
|
||||
private Memory<int> _memory;
|
||||
private readonly ConcurrentQueue<(int, float2)> _queue;
|
||||
private readonly Dictionary<int, float2> _sizes;
|
||||
public Quadtree(float2 center, float2 size)
|
||||
{
|
||||
_sizes = new Dictionary<int, float2>();
|
||||
_memory = new int[(int)math.max(size.x, size.y)];
|
||||
_positions = new Dictionary<int, float2>();
|
||||
_queue = new ConcurrentQueue<(int, float2)>();
|
||||
Root = new QuadtreeNode(this,center, size);
|
||||
}
|
||||
public void Insert(in int objectId,in float2 position)
|
||||
public void Insert(in int objectId,in float2 position,in float2 size = default)
|
||||
{
|
||||
_queue.Enqueue((objectId, position));
|
||||
|
||||
var root = Root;
|
||||
if (size.x is not 0)
|
||||
{
|
||||
_sizes.TryAdd(objectId, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var root = Root;
|
||||
|
||||
InsertRecursive(ref root,in objectId,in position);
|
||||
InsertRecursive(ref root,in objectId,in position);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertRecursive(ref QuadtreeNode node,in int objectId,in float2 position)
|
||||
@@ -69,27 +81,36 @@ namespace Net.BITKit.Quadtree
|
||||
|
||||
var root = Root;
|
||||
|
||||
|
||||
/*
|
||||
var array = MemoryPool<int>.Shared.Rent(_positions.Count);
|
||||
|
||||
try
|
||||
{
|
||||
QueryRecursive(in root, in position, in radius, array.Memory.Span, ref index);
|
||||
|
||||
return array.Memory;
|
||||
}
|
||||
finally
|
||||
{
|
||||
array.Dispose();
|
||||
}
|
||||
*/
|
||||
|
||||
QueryRecursive(in root,in position,in radius, _memory.Span, ref index);
|
||||
|
||||
foreach (var (key,size) in _sizes)
|
||||
{
|
||||
var pos = _positions[key];
|
||||
|
||||
if (IsCircleInRect(pos, radius, position, size))
|
||||
{
|
||||
_memory.Span[index] = key;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return _memory[..index];
|
||||
}
|
||||
[BurstCompile]
|
||||
private static bool IsCircleInRect(float2 point, float radius, float2 pos, float2 size)
|
||||
{
|
||||
var halfSize = size * 0.5f;
|
||||
var min = pos - halfSize; // 矩形左下角
|
||||
var max = pos + halfSize; // 矩形右上角
|
||||
|
||||
// 计算扩展后的包围盒
|
||||
var expandedMin = min - radius;
|
||||
var expandedMax = max + radius;
|
||||
|
||||
// 检查点是否在扩展的矩形内
|
||||
return point.x >= expandedMin.x && point.x <= expandedMax.x &&
|
||||
point.y >= expandedMin.y && point.y <= expandedMax.y;
|
||||
}
|
||||
private void Expansion()
|
||||
{
|
||||
while (_queue.TryDequeue(out var item))
|
||||
@@ -102,7 +123,7 @@ namespace Net.BITKit.Quadtree
|
||||
_memory = new int[_positions.Count*2];
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private void QueryRecursive(in QuadtreeNode node,in float2 position,in float radius,Span<int> result,ref int index)
|
||||
{
|
||||
if (!Intersects(node.Center, node.Size, position, radius))
|
||||
@@ -132,7 +153,7 @@ namespace Net.BITKit.Quadtree
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private static bool Intersects(in float2 center,in float2 size,in float2 position,in float radius)
|
||||
{
|
||||
// 计算 AABB 的最小/最大点
|
||||
@@ -158,10 +179,14 @@ namespace Net.BITKit.Quadtree
|
||||
|
||||
if (_positions.TryGetValue(objectId, out var position) is false) return false;
|
||||
|
||||
_sizes.TryRemove(objectId);
|
||||
|
||||
var root = Root;
|
||||
|
||||
if (RemoveRecursive(ref root, objectId, position) is false) return false;
|
||||
_positions.Remove(objectId);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user