Use CollectionsMarshal in DynamicTree (#4433)

This commit is contained in:
Leon Friedrich
2023-09-19 17:58:02 +12:00
committed by GitHub
parent 005673a957
commit 2417dbb0e0
2 changed files with 27 additions and 22 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using JetBrains.Annotations;
using Robust.Shared.Utility;
@@ -35,9 +36,15 @@ namespace Robust.Shared.Maths
/// </summary>
[FieldOffset(sizeof(float) * 3)] public float Top;
[NonSerialized]
[FieldOffset(sizeof(float) * 0)] public Vector2 BottomLeft;
[NonSerialized]
[FieldOffset(sizeof(float) * 2)] public Vector2 TopRight;
[NonSerialized]
[FieldOffset(sizeof(float) * 0)] public System.Numerics.Vector4 AsVector4;
public readonly Vector2 BottomRight
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -141,6 +148,11 @@ namespace Robust.Shared.Maths
return new Box2(min, max);
}
public readonly bool HasNan()
{
return Vector128.EqualsAny(AsVector4.AsVector128(), Vector128.Create(float.NaN));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Pure]
public readonly bool Intersects(in Box2 other)

View File

@@ -24,6 +24,8 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using JetBrains.Annotations;
using Robust.Shared.Maths;
@@ -131,7 +133,7 @@ namespace Robust.Shared.Physics
aabb ??= _extractAabb(item);
if (HasNaNs(aabb.Value))
if (aabb.Value.HasNan())
{
_nodeLookup[item] = DynamicTree.Proxy.Free;
return true;
@@ -179,28 +181,25 @@ namespace Robust.Shared.Physics
[MethodImpl(MethodImplOptions.NoInlining)]
public bool Update(in T item, Box2? newBox = null)
{
if (!TryGetProxy(item, out var proxy))
{
ref var proxy = ref CollectionsMarshal.GetValueRefOrNullRef(_nodeLookup, item);
if (Unsafe.IsNullRef(ref proxy))
return false;
}
newBox ??= _extractAabb(item);
if (HasNaNs(newBox.Value))
if (newBox.Value.HasNan())
{
if (proxy == DynamicTree.Proxy.Free)
{
return false;
}
_b2Tree.DestroyProxy(proxy);
_nodeLookup[item] = DynamicTree.Proxy.Free;
proxy = DynamicTree.Proxy.Free;
return true;
}
if (proxy == DynamicTree.Proxy.Free)
{
_nodeLookup[item] = _b2Tree.CreateProxy(newBox.Value, item);
proxy = _b2Tree.CreateProxy(newBox.Value, item);
return true;
}
@@ -331,36 +330,30 @@ namespace Robust.Shared.Physics
public void AddOrUpdate(T item, Box2? aabb = null)
{
aabb ??= _extractAabb(item);
if (!_nodeLookup.TryGetValue(item, out var proxy))
ref var proxy = ref CollectionsMarshal.GetValueRefOrAddDefault(_nodeLookup, item, out var exists);
if (!exists)
{
_nodeLookup[item] = HasNaNs(aabb.Value) ? DynamicTree.Proxy.Free : _b2Tree.CreateProxy(aabb.Value, item);
proxy = aabb.Value.HasNan() ? DynamicTree.Proxy.Free : _b2Tree.CreateProxy(aabb.Value, item);
return;
}
if (HasNaNs(aabb.Value))
if (aabb.Value.HasNan())
{
if (proxy == DynamicTree.Proxy.Free)
return;
_b2Tree.DestroyProxy(proxy);
_nodeLookup[item] = DynamicTree.Proxy.Free;
proxy = DynamicTree.Proxy.Free;
return;
}
if (proxy == DynamicTree.Proxy.Free)
_nodeLookup[item] = _b2Tree.CreateProxy(aabb.Value, item);
proxy = _b2Tree.CreateProxy(aabb.Value, item);
else
_b2Tree.MoveProxy(proxy, aabb.Value, Vector2.Zero);
}
private static bool HasNaNs(in Box2 box)
{
return float.IsNaN(box.Left)
|| float.IsNaN(box.Top)
|| float.IsNaN(box.Bottom)
|| float.IsNaN(box.Right);
}
[Conditional("DEBUG_DYNAMIC_TREE")]
[Conditional("DEBUG_DYNAMIC_TREE_ASSERTS")]
[DebuggerNonUserCode]