mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Harder DynamicTree against NaN.
B2DynamicTree<T> has asserts, DynamicTree<T> handles them gracefully. NaNs in DynamicTree were causing the internal state to corrupt resulting in the sprite flickering issues. Fixes https://github.com/space-wizards/space-station-14/issues/2896
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
// #define DEBUG_DYNAMIC_TREE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -268,6 +270,9 @@ namespace Robust.Shared.Physics
|
||||
/// </summary>
|
||||
public Proxy CreateProxy(in Box2 aabb, T userData)
|
||||
{
|
||||
// Also catches NaN fuckery.
|
||||
Assert(aabb.Right >= aabb.Left && aabb.Top >= aabb.Bottom);
|
||||
|
||||
ref var proxy = ref AllocateNode(out var proxyId);
|
||||
|
||||
// Fatten the aabb.
|
||||
@@ -292,6 +297,8 @@ namespace Robust.Shared.Physics
|
||||
public bool MoveProxy(Proxy proxy, in Box2 aabb, Vector2 displacement)
|
||||
{
|
||||
Assert(0 <= proxy && proxy < Capacity);
|
||||
// Also catches NaN fuckery.
|
||||
Assert(aabb.Right >= aabb.Left && aabb.Top >= aabb.Bottom);
|
||||
|
||||
ref var leafNode = ref _nodes[proxy];
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Robust.Shared.Physics
|
||||
private readonly ExtractAabbDelegate _extractAabb;
|
||||
|
||||
// avoids "Collection was modified; enumeration operation may not execute."
|
||||
private IDictionary<T, Proxy> _nodeLookup;
|
||||
private Dictionary<T, Proxy> _nodeLookup;
|
||||
private readonly B2DynamicTree<T> _b2Tree;
|
||||
|
||||
public DynamicTree(ExtractAabbDelegate extractAabbFunc, IEqualityComparer<T>? comparer = null, float aabbExtendSize = 1f / 32, int capacity = 256, Func<int, int>? growthFunc = null)
|
||||
@@ -134,6 +134,12 @@ namespace Robust.Shared.Physics
|
||||
|
||||
var box = _extractAabb(item);
|
||||
|
||||
if (CheckNaNs(box))
|
||||
{
|
||||
_nodeLookup[item] = Proxy.Free;
|
||||
return true;
|
||||
}
|
||||
|
||||
proxy = _b2Tree.CreateProxy(box, item);
|
||||
_nodeLookup[item] = proxy;
|
||||
|
||||
@@ -162,7 +168,11 @@ namespace Robust.Shared.Physics
|
||||
return false;
|
||||
}
|
||||
|
||||
_b2Tree.DestroyProxy(proxy);
|
||||
if (proxy != Proxy.Free)
|
||||
{
|
||||
_b2Tree.DestroyProxy(proxy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -178,6 +188,25 @@ namespace Robust.Shared.Physics
|
||||
}
|
||||
|
||||
var newBox = _extractAabb(item);
|
||||
|
||||
if (CheckNaNs(newBox))
|
||||
{
|
||||
if (proxy == Proxy.Free)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_b2Tree.DestroyProxy(proxy);
|
||||
_nodeLookup[item] = Proxy.Free;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (proxy == Proxy.Free)
|
||||
{
|
||||
_nodeLookup[item] = _b2Tree.CreateProxy(newBox, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
return _b2Tree.MoveProxy(proxy, newBox, Vector2.Zero);
|
||||
}
|
||||
|
||||
@@ -304,6 +333,14 @@ namespace Robust.Shared.Physics
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool AddOrUpdate(T item) => Update(item) || Add(item);
|
||||
|
||||
private static bool CheckNaNs(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]
|
||||
|
||||
Reference in New Issue
Block a user