Purge IPhysicsManager (#3652)

This commit is contained in:
metalgearsloth
2023-01-04 19:18:53 +11:00
committed by GitHub
parent a015e8722e
commit ec5f07b372
9 changed files with 42 additions and 136 deletions

View File

@@ -51,7 +51,7 @@ END TEMPLATE-->
### Internal
*None yet*
* IPhysManager has been removed for a slight physics contacts optimisation.
## 0.78.0.0

View File

@@ -89,7 +89,7 @@ namespace Robust.Client
deps.Register<IMidiManager, MidiManager>();
deps.Register<IAuthManager, AuthManager>();
deps.Register<ProfViewManager>();
deps.Register<IPhysicsManager, PhysicsManager>();
switch (mode)
{
case GameController.DisplayMode.Headless:

View File

@@ -74,11 +74,11 @@ namespace Robust.Client.Debugging
* Used for debugging shapes, controllers, joints, contacts
*/
[Dependency] private readonly IPhysicsManager _physicsManager = default!;
private const int MaxContactPoints = 2048;
internal int PointCount;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
internal ContactPoint[] Points = new ContactPoint[MaxContactPoints];
public PhysicsDebugFlags Flags
@@ -119,7 +119,8 @@ namespace Robust.Client.Debugging
if (manifold.PointCount == 0)
return;
Fixture fixtureA = contact.FixtureA!;
var fixtureA = contact.FixtureA!;
var fixtureB = contact.FixtureB!;
var state1 = new PointState[2];
var state2 = new PointState[2];
@@ -127,7 +128,9 @@ namespace Robust.Client.Debugging
CollisionManager.GetPointStates(ref state1, ref state2, oldManifold, manifold);
Span<Vector2> points = stackalloc Vector2[2];
contact.GetWorldManifold(_physicsManager, out var normal, points);
var transformA = _physics.GetPhysicsTransform(fixtureA.Body.Owner);
var transformB = _physics.GetPhysicsTransform(fixtureB.Body.Owner);
contact.GetWorldManifold(transformA, transformB, out var normal, points);
ContactPoint cp = Points[PointCount];
for (var i = 0; i < manifold.PointCount && PointCount < MaxContactPoints; ++i)

View File

@@ -79,7 +79,6 @@ namespace Robust.Server
deps.Register<IScriptHost, ScriptHost>();
deps.Register<IMetricsManager, MetricsManager>();
deps.Register<IAuthManager, AuthManager>();
deps.Register<IPhysicsManager, PhysicsManager>();
deps.Register<IBqlQueryManager, BqlQueryManager>();
deps.Register<HubManager, HubManager>();
deps.Register<IRobustSerializer, ServerRobustSerializer>();

View File

@@ -131,16 +131,12 @@ namespace Robust.Shared.Physics.Dynamics.Contacts
/// <summary>
/// Gets the world manifold.
/// </summary>
public void GetWorldManifold(IPhysicsManager physicsManager, out Vector2 normal, Span<Vector2> points)
public void GetWorldManifold(Transform transformA, Transform transformB, out Vector2 normal, Span<Vector2> points)
{
PhysicsComponent bodyA = FixtureA?.Body!;
PhysicsComponent bodyB = FixtureB?.Body!;
IPhysShape shapeA = FixtureA?.Shape!;
IPhysShape shapeB = FixtureB?.Shape!;
var bodyATransform = physicsManager.EnsureTransform(bodyA);
var bodyBTransform = physicsManager.EnsureTransform(bodyB);
var shapeA = FixtureA?.Shape!;
var shapeB = FixtureB?.Shape!;
SharedPhysicsSystem.InitializeManifold(ref Manifold, bodyATransform, bodyBTransform, shapeA.Radius, shapeB.Radius, out normal, points);
SharedPhysicsSystem.InitializeManifold(ref Manifold, transformA, transformB, shapeA.Radius, shapeB.Radius, out normal, points);
}
/// <summary>
@@ -149,11 +145,8 @@ namespace Robust.Shared.Physics.Dynamics.Contacts
/// </summary>
/// <param name="wake">Whether we should wake the bodies due to touching changing.</param>
/// <returns>What current status of the contact is (e.g. start touching, end touching, etc.)</returns>
internal ContactStatus Update(IPhysicsManager physicsManager, out bool wake)
internal ContactStatus Update(Transform bodyATransform, Transform bodyBTransform, out bool wake)
{
PhysicsComponent bodyA = FixtureA!.Body;
PhysicsComponent bodyB = FixtureB!.Body;
var oldManifold = Manifold;
// Re-enable this contact.
@@ -163,16 +156,13 @@ namespace Robust.Shared.Physics.Dynamics.Contacts
var wasTouching = IsTouching;
wake = false;
var sensor = !(FixtureA.Hard && FixtureB.Hard);
var bodyATransform = physicsManager.GetTransform(bodyA);
var bodyBTransform = physicsManager.GetTransform(bodyB);
var sensor = !(FixtureA!.Hard && FixtureB!.Hard);
// Is this contact a sensor?
if (sensor)
{
var shapeA = FixtureA.Shape;
var shapeB = FixtureB.Shape;
var shapeA = FixtureA!.Shape;
var shapeB = FixtureB!.Shape;
touching = _manifoldManager.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, bodyATransform, bodyBTransform);
// Sensors don't generate manifolds.

View File

@@ -1,88 +0,0 @@
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Physics.Components;
namespace Robust.Shared.Physics
{
public interface IPhysicsManager
{
/// <summary>
/// Clear all of the cached transforms.
/// </summary>
void ClearTransforms();
public Transform EnsureTransform(PhysicsComponent body);
public Transform EnsureTransform(EntityUid uid);
public void SetTransform(EntityUid uid, Transform transform);
public Transform UpdateTransform(EntityUid uid);
/// <summary>
/// Get a cached transform for physics use.
/// </summary>
public Transform GetTransform(PhysicsComponent body);
}
public sealed class PhysicsManager : IPhysicsManager
{
[Dependency] private readonly IEntityManager _entManager = default!;
private Dictionary<EntityUid, Transform> _transforms = new(64);
private Transform GetPhysicsTransform(EntityUid uid)
{
var xformComp = _entManager.GetComponent<TransformComponent>(uid);
var (worldPos, worldRot) = xformComp.GetWorldPositionRotation();
return new(worldPos, (float) worldRot.Theta);
}
/// <inheritdoc />
public void ClearTransforms()
{
_transforms.Clear();
}
public Transform EnsureTransform(PhysicsComponent body)
{
return EnsureTransform((body).Owner);
}
public Transform EnsureTransform(EntityUid uid)
{
if (!_transforms.TryGetValue(uid, out var transform))
{
transform = GetPhysicsTransform(uid);
_transforms[uid] = transform;
}
return transform;
}
public void SetTransform(EntityUid uid, Transform transform)
{
_transforms[uid] = transform;
}
public Transform UpdateTransform(EntityUid uid)
{
var xform = GetPhysicsTransform(uid);
_transforms[uid] = xform;
return xform;
}
/// <inheritdoc />
public Transform GetTransform(PhysicsComponent body)
{
return _transforms[body.Owner];
}
public Transform GetTransform(EntityUid uid)
{
return _transforms[uid];
}
}
}

View File

@@ -30,9 +30,11 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;
using Microsoft.Extensions.ObjectPool;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Physics.Collision;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
@@ -420,22 +422,10 @@ public abstract partial class SharedPhysicsSystem
}
var status = ArrayPool<ContactStatus>.Shared.Rent(index);
// To avoid race conditions with the dictionary we'll cache all of the transforms up front.
// Caching should provide better perf than multi-threading the GetTransform() as we can also re-use
// these in PhysicsIsland as well.
for (var i = 0; i < index; i++)
{
var contact = contacts[i];
var bodyA = contact.FixtureA!.Body;
var bodyB = contact.FixtureB!.Body;
_physicsManager.EnsureTransform(bodyA.Owner);
_physicsManager.EnsureTransform(bodyB.Owner);
}
var worldPoints = ArrayPool<Vector2>.Shared.Rent(index);
// Update contacts all at once.
BuildManifolds(contacts, index, status);
BuildManifolds(contacts, index, status, worldPoints);
// Single-threaded so content doesn't need to worry about race conditions.
for (var i = 0; i < index; i++)
@@ -452,7 +442,7 @@ public abstract partial class SharedPhysicsSystem
var fixtureB = contact.FixtureB!;
var bodyA = fixtureA.Body;
var bodyB = fixtureB.Body;
var worldPoint = Physics.Transform.Mul(_physicsManager.EnsureTransform(bodyA), contact.Manifold.LocalPoint);
var worldPoint = worldPoints[i];
var ev1 = new StartCollideEvent(fixtureA, fixtureB, worldPoint);
var ev2 = new StartCollideEvent(fixtureB, fixtureA, worldPoint);
@@ -491,9 +481,10 @@ public abstract partial class SharedPhysicsSystem
ArrayPool<Contact>.Shared.Return(contacts);
ArrayPool<ContactStatus>.Shared.Return(status);
ArrayPool<Vector2>.Shared.Return(worldPoints);
}
private void BuildManifolds(Contact[] contacts, int count, ContactStatus[] status)
private void BuildManifolds(Contact[] contacts, int count, ContactStatus[] status, Vector2[] worldPoints)
{
var wake = ArrayPool<bool>.Shared.Rent(count);
@@ -505,13 +496,13 @@ public abstract partial class SharedPhysicsSystem
{
var start = i * ContactsPerThread;
var end = Math.Min(start + ContactsPerThread, count);
UpdateContacts(contacts, start, end, status, wake);
UpdateContacts(contacts, start, end, status, wake, worldPoints);
});
}
else
{
UpdateContacts(contacts, 0, count, status, wake);
UpdateContacts(contacts, 0, count, status, wake, worldPoints);
}
// Can't do this during UpdateContacts due to IoC threading issues.
@@ -531,11 +522,25 @@ public abstract partial class SharedPhysicsSystem
ArrayPool<bool>.Shared.Return(wake);
}
private void UpdateContacts(Contact[] contacts, int start, int end, ContactStatus[] status, bool[] wake)
private void UpdateContacts(Contact[] contacts, int start, int end, ContactStatus[] status, bool[] wake, Vector2[] worldPoints)
{
var xformQuery = GetEntityQuery<TransformComponent>();
for (var i = start; i < end; i++)
{
status[i] = contacts[i].Update(_physicsManager, out wake[i]);
var contact = contacts[i];
var uidA = contact.FixtureA!.Body.Owner;
var uidB = contact.FixtureB!.Body.Owner;
var bodyATransform = GetPhysicsTransform(uidA, xformQuery.GetComponent(uidA), xformQuery);
var bodyBTransform = GetPhysicsTransform(uidB, xformQuery.GetComponent(uidB), xformQuery);
var contactStatus = contact.Update(bodyATransform, bodyBTransform, out wake[i]);
status[i] = contactStatus;
if (contactStatus == ContactStatus.StartTouching)
{
worldPoints[i] = Physics.Transform.Mul(bodyATransform, contacts[i].Manifold.LocalPoint);
}
}
}

View File

@@ -47,7 +47,6 @@ namespace Robust.Shared.Physics.Systems
[Dependency] private readonly IManifoldManager _manifoldManager = default!;
[Dependency] protected readonly IMapManager MapManager = default!;
[Dependency] private readonly IParallelManager _parallel = default!;
[Dependency] private readonly IPhysicsManager _physicsManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IDependencyCollection _deps = default!;
[Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
@@ -328,7 +327,6 @@ namespace Robust.Shared.Physics.Systems
}
_traversal.ProcessMovement();
_physicsManager.ClearTransforms();
}
}

View File

@@ -225,7 +225,6 @@ namespace Robust.UnitTesting.Server
container.Register<IEntitySystemManager, EntitySystemManager>();
container.Register<IManifoldManager, CollisionManager>();
container.Register<IMapManagerInternal, MapManager>();
container.Register<IPhysicsManager, PhysicsManager>();
container.Register<INetManager, NetManager>();
container.Register<IAuthManager, AuthManager>();
container.Register<ITileDefinitionManager, TileDefinitionManager>();