mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Purge IPhysicsManager (#3652)
This commit is contained in:
@@ -51,7 +51,7 @@ END TEMPLATE-->
|
||||
|
||||
### Internal
|
||||
|
||||
*None yet*
|
||||
* IPhysManager has been removed for a slight physics contacts optimisation.
|
||||
|
||||
|
||||
## 0.78.0.0
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user