From f05ed9646124e1914ac512a7ddac4de22886d36e Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 23 Aug 2023 18:50:48 +1000 Subject: [PATCH] Remove FixtureId from fixtures (#4270) --- .../GridChunkBoundsDebugSystem.cs | 2 +- .../Console/Commands/ScaleCommand.cs | 9 ++-- .../Console/Commands/TestbedCommand.cs | 28 +++++----- .../GameObjects/Systems/EntityLookupSystem.cs | 16 +++--- .../Systems/SharedGridFixtureSystem.cs | 46 +++++++++------- .../Systems/SharedMapSystem.Grid.cs | 4 +- Robust.Shared/Map/MapChunk.cs | 2 +- Robust.Shared/Map/MapManager.Queries.cs | 2 +- .../Physics/Dynamics/Contacts/Contact.cs | 3 ++ Robust.Shared/Physics/Dynamics/Fixture.cs | 21 +------- .../Physics/Dynamics/FixtureProxy.cs | 5 +- .../Physics/Events/EndCollideEvent.cs | 7 +++ .../Physics/Events/StartCollideEvent.cs | 7 +++ Robust.Shared/Physics/FixtureSerializer.cs | 3 -- Robust.Shared/Physics/FixturesComponent.cs | 9 ++++ .../Physics/Systems/FixtureSystem.cs | 53 +++++++++---------- .../Physics/Systems/SharedBroadphaseSystem.cs | 7 +-- .../Systems/SharedPhysicsSystem.Contacts.cs | 38 +++++++------ .../Systems/SharedPhysicsSystem.Fixtures.cs | 26 ++++----- .../Systems/SharedPhysicsSystem.Shapes.cs | 25 +++++---- .../Physics/BroadphaseNetworkingTest.cs | 4 +- .../Shared/Physics/Broadphase_Test.cs | 17 +++--- .../Shared/Physics/Collision_Test.cs | 4 +- .../Shared/Physics/Fixtures_Test.cs | 9 ++-- .../Shared/Physics/GridMovement_Test.cs | 4 +- .../Shared/Physics/JointDeletion_Test.cs | 2 +- .../Shared/Physics/Joints_Test.cs | 4 +- .../Shared/Physics/PhysicsComponent_Test.cs | 2 +- .../Shared/Physics/PhysicsMap_Test.cs | 4 +- .../Shared/Physics/Stack_Test.cs | 12 ++--- 30 files changed, 200 insertions(+), 175 deletions(-) diff --git a/Robust.Client/GameObjects/EntitySystems/GridChunkBoundsDebugSystem.cs b/Robust.Client/GameObjects/EntitySystems/GridChunkBoundsDebugSystem.cs index eb937e75f..7d8a17b38 100644 --- a/Robust.Client/GameObjects/EntitySystems/GridChunkBoundsDebugSystem.cs +++ b/Robust.Client/GameObjects/EntitySystems/GridChunkBoundsDebugSystem.cs @@ -81,7 +81,7 @@ namespace Robust.Client.GameObjects while (chunkEnumerator.MoveNext(out var chunk)) { - foreach (var fixture in chunk.Fixtures) + foreach (var fixture in chunk.Fixtures.Values) { var poly = (PolygonShape) fixture.Shape; diff --git a/Robust.Server/Console/Commands/ScaleCommand.cs b/Robust.Server/Console/Commands/ScaleCommand.cs index 1e2f6a99d..c3a0ee73d 100644 --- a/Robust.Server/Console/Commands/ScaleCommand.cs +++ b/Robust.Server/Console/Commands/ScaleCommand.cs @@ -59,19 +59,20 @@ public sealed class ScaleCommand : LocalizedCommands if (_entityManager.TryGetComponent(uid, out FixturesComponent? manager)) { - foreach (var fixture in manager.Fixtures.Values) + foreach (var (id, fixture) in manager.Fixtures) { switch (fixture.Shape) { case EdgeShape edge: - physics.SetVertices(uid, fixture, edge, + physics.SetVertices(uid, id, fixture, + edge, edge.Vertex0 * scale, edge.Vertex1 * scale, edge.Vertex2 * scale, edge.Vertex3 * scale, manager); break; case PhysShapeCircle circle: - physics.SetPositionRadius(uid, fixture, circle, circle.Position * scale, circle.Radius * scale, manager); + physics.SetPositionRadius(uid, id, fixture, circle, circle.Position * scale, circle.Radius * scale, manager); break; case PolygonShape poly: var verts = poly.Vertices; @@ -81,7 +82,7 @@ public sealed class ScaleCommand : LocalizedCommands verts[i] *= scale; } - physics.SetVertices(uid, fixture, poly, verts, manager); + physics.SetVertices(uid, id, fixture, poly, verts, manager); break; default: throw new NotImplementedException(); diff --git a/Robust.Server/Console/Commands/TestbedCommand.cs b/Robust.Server/Console/Commands/TestbedCommand.cs index e0012838f..e18a22ad8 100644 --- a/Robust.Server/Console/Commands/TestbedCommand.cs +++ b/Robust.Server/Console/Commands/TestbedCommand.cs @@ -137,10 +137,10 @@ namespace Robust.Server.Console.Commands var ground = _ent.AddComponent(groundUid); var horizontal = new EdgeShape(new Vector2(-40, 0), new Vector2(40, 0)); - fixtures.CreateFixture(groundUid, new Fixture("fix1", horizontal, 2, 2, true), body: ground); + fixtures.CreateFixture(groundUid, "fix1", new Fixture(horizontal, 2, 2, true), body: ground); var vertical = new EdgeShape(new Vector2(10, 0), new Vector2(10, 10)); - fixtures.CreateFixture(groundUid, new Fixture("fix2", vertical, 2, 2, true), body: ground); + fixtures.CreateFixture(groundUid, "fix2", new Fixture(vertical, 2, 2, true), body: ground); var xs = new[] { @@ -166,7 +166,7 @@ namespace Robust.Server.Console.Commands shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); physics.SetFixedRotation(boxUid, false, body: box); - fixtures.CreateFixture(boxUid, new Fixture("fix1", shape, 2, 2, true), body: box); + fixtures.CreateFixture(boxUid, "fix1", new Fixture(shape, 2, 2, true), body: box); physics.WakeBody(boxUid, body: box); } @@ -184,10 +184,10 @@ namespace Robust.Server.Console.Commands var ground = _ent.AddComponent(groundUid); var horizontal = new EdgeShape(new Vector2(-40, 0), new Vector2(40, 0)); - fixtures.CreateFixture(groundUid, new Fixture("fix1", horizontal, 2, 2, true), body: ground); + fixtures.CreateFixture(groundUid, "fix1", new Fixture(horizontal, 2, 2, true), body: ground); var vertical = new EdgeShape(new Vector2(20, 0), new Vector2(20, 20)); - fixtures.CreateFixture(groundUid, new Fixture("fix2", vertical, 2, 2, true), body: ground); + fixtures.CreateFixture(groundUid, "fix2", new Fixture(vertical, 2, 2, true), body: ground); var xs = new[] { @@ -213,7 +213,7 @@ namespace Robust.Server.Console.Commands physics.SetFixedRotation(boxUid, false, body: box); // TODO: Need to detect shape and work out if we need to use fixedrotation - fixtures.CreateFixture(boxUid, new Fixture("fix1", shape, 2, 2, true, 5f)); + fixtures.CreateFixture(boxUid, "fix1", new Fixture(shape, 2, 2, true, 5f)); physics.WakeBody(boxUid, body: box); } } @@ -232,7 +232,7 @@ namespace Robust.Server.Console.Commands var ground = _ent.AddComponent(groundUid); var horizontal = new EdgeShape(new Vector2(40, 0), new Vector2(-40, 0)); - fixtures.CreateFixture(groundUid, new Fixture("fix1", horizontal, 2, 2, true), body: ground); + fixtures.CreateFixture(groundUid, "fix1", new Fixture(horizontal, 2, 2, true), body: ground); physics.WakeBody(groundUid, body: ground); // Setup boxes @@ -255,7 +255,7 @@ namespace Robust.Server.Console.Commands var box = _ent.AddComponent(boxUid); physics.SetBodyType(boxUid, BodyType.Dynamic, body: box); - fixtures.CreateFixture(boxUid, new Fixture("fix1", shape, 2, 2, true, 5f), body: box); + fixtures.CreateFixture(boxUid, "fix1", new Fixture(shape, 2, 2, true, 5f), body: box); y += deltaY; physics.WakeBody(boxUid, body: box); @@ -275,7 +275,7 @@ namespace Robust.Server.Console.Commands var ground = _ent.AddComponent(groundUid); // Due to lookup changes fixtureless bodies are invalid, so var cShape = new PhysShapeCircle(1f); - fixtures.CreateFixture(groundUid, new Fixture("fix1", cShape, 0, 0, false)); + fixtures.CreateFixture(groundUid, "fix1", new Fixture(cShape, 0, 0, false)); var bodyUid = _ent.SpawnEntity(null, new MapCoordinates(0f, 10f, mapId)); var body = _ent.AddComponent(bodyUid); @@ -288,19 +288,19 @@ namespace Robust.Server.Console.Commands // TODO: Box2D just deref, bleh shape structs someday var shape1 = new PolygonShape(); shape1.SetAsBox(0.5f, 10.0f, new Vector2(10.0f, 0.0f), 0.0f); - fixtures.CreateFixture(bodyUid, new Fixture("fix1", shape1, 2, 0, true, 20f)); + fixtures.CreateFixture(bodyUid, "fix1", new Fixture(shape1, 2, 0, true, 20f)); var shape2 = new PolygonShape(); shape2.SetAsBox(0.5f, 10.0f, new Vector2(-10.0f, 0.0f), 0f); - fixtures.CreateFixture(bodyUid, new Fixture("fix2", shape2, 2, 0, true, 20f)); + fixtures.CreateFixture(bodyUid, "fix2", new Fixture(shape2, 2, 0, true, 20f)); var shape3 = new PolygonShape(); shape3.SetAsBox(10.0f, 0.5f, new Vector2(0.0f, 10.0f), 0f); - fixtures.CreateFixture(bodyUid, new Fixture("fix3", shape3, 2, 0, true, 20f)); + fixtures.CreateFixture(bodyUid, "fix3", new Fixture(shape3, 2, 0, true, 20f)); var shape4 = new PolygonShape(); shape4.SetAsBox(10.0f, 0.5f, new Vector2(0.0f, -10.0f), 0f); - fixtures.CreateFixture(bodyUid, new Fixture("fix4", shape4, 2, 0, true, 20f)); + fixtures.CreateFixture(bodyUid, "fix4", new Fixture(shape4, 2, 0, true, 20f)); physics.WakeBody(groundUid, body: ground); physics.WakeBody(bodyUid, body: body); @@ -328,7 +328,7 @@ namespace Robust.Server.Console.Commands physics.SetFixedRotation(boxUid, false, body: box); var shape = new PolygonShape(); shape.SetAsBox(0.125f, 0.125f); - fixtures.CreateFixture(boxUid, new Fixture("fix1", shape, 2, 2, true, 0.0625f), body: box); + fixtures.CreateFixture(boxUid, "fix1", new Fixture(shape, 2, 2, true, 0.0625f), body: box); physics.WakeBody(boxUid, body: box); }); } diff --git a/Robust.Shared/GameObjects/Systems/EntityLookupSystem.cs b/Robust.Shared/GameObjects/Systems/EntityLookupSystem.cs index 9e44e31fa..b13b92bb8 100644 --- a/Robust.Shared/GameObjects/Systems/EntityLookupSystem.cs +++ b/Robust.Shared/GameObjects/Systems/EntityLookupSystem.cs @@ -221,7 +221,8 @@ public sealed partial class EntityLookupSystem : EntitySystem return _transform.GetInvWorldMatrix(treeXform).TransformBox(GetWorldAABB(entity, xform)); } - internal void CreateProxies(EntityUid uid, TransformComponent xform, Fixture fixture, PhysicsComponent body) + internal void CreateProxies(EntityUid uid, string fixtureId, Fixture fixture, TransformComponent xform, + PhysicsComponent body) { if (!TryGetCurrentBroadphase(xform, out var broadphase)) return; @@ -237,10 +238,10 @@ public sealed partial class EntityLookupSystem : EntitySystem var tree = body.BodyType == BodyType.Static ? broadphase.StaticTree : broadphase.DynamicTree; DebugTools.Assert(fixture.ProxyCount == 0); - AddOrMoveProxies(uid, fixture, body, tree, broadphaseTransform, mapTransform, physMap.MoveBuffer); + AddOrMoveProxies(uid, fixtureId, fixture, body, tree, broadphaseTransform, mapTransform, physMap.MoveBuffer); } - internal void DestroyProxies(EntityUid uid, Fixture fixture, TransformComponent xform, BroadphaseComponent broadphase, PhysicsMapComponent? physicsMap) + internal void DestroyProxies(EntityUid uid, string fixtureId, Fixture fixture, TransformComponent xform, BroadphaseComponent broadphase, PhysicsMapComponent? physicsMap) { DebugTools.AssertNotNull(xform.Broadphase); DebugTools.Assert(xform.Broadphase!.Value.Uid == broadphase.Owner); @@ -250,7 +251,7 @@ public sealed partial class EntityLookupSystem : EntitySystem if (fixture.ProxyCount == 0) { - Log.Warning($"Tried to destroy fixture {fixture.ID} on {ToPrettyString(uid)} that already has no proxies?"); + Log.Warning($"Tried to destroy fixture {fixtureId} on {ToPrettyString(uid)} that already has no proxies?"); return; } @@ -381,14 +382,15 @@ public sealed partial class EntityLookupSystem : EntitySystem // TODO BROADPHASE PARENTING this just assumes local = world var broadphaseTransform = new Transform(broadphaseXform.InvLocalMatrix.Transform(mapTransform.Position), mapTransform.Quaternion2D.Angle - broadphaseXform.LocalRotation); - foreach (var fixture in manager.Fixtures.Values) + foreach (var (id, fixture) in manager.Fixtures) { - AddOrMoveProxies(uid, fixture, body, tree, broadphaseTransform, mapTransform, physicsMap.MoveBuffer); + AddOrMoveProxies(uid, id, fixture, body, tree, broadphaseTransform, mapTransform, physicsMap.MoveBuffer); } } private void AddOrMoveProxies( EntityUid uid, + string fixtureId, Fixture fixture, PhysicsComponent body, IBroadPhase tree, @@ -417,7 +419,7 @@ public sealed partial class EntityLookupSystem : EntitySystem for (var i = 0; i < count; i++) { var bounds = fixture.Shape.ComputeAABB(broadphaseTransform, i); - var proxy = new FixtureProxy(uid, body, bounds, fixture, i); + var proxy = new FixtureProxy(uid, body, bounds, fixtureId, fixture, i); proxy.ProxyId = tree.AddProxy(ref proxy); proxy.AABB = bounds; proxies[i] = proxy; diff --git a/Robust.Shared/GameObjects/Systems/SharedGridFixtureSystem.cs b/Robust.Shared/GameObjects/Systems/SharedGridFixtureSystem.cs index 7ace818e6..e0f85b07a 100644 --- a/Robust.Shared/GameObjects/Systems/SharedGridFixtureSystem.cs +++ b/Robust.Shared/GameObjects/Systems/SharedGridFixtureSystem.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Numerics; +using Robust.Shared.Collections; using Robust.Shared.Configuration; using Robust.Shared.IoC; using Robust.Shared.Log; @@ -95,12 +96,16 @@ namespace Robust.Shared.GameObjects return; } - var fixtures = new List(mapChunks.Count); + var fixtures = new Dictionary(mapChunks.Count); foreach (var (chunk, rectangles) in mapChunks) { UpdateFixture(uid, chunk, rectangles, body, manager, xform); - fixtures.AddRange(chunk.Fixtures); + + foreach (var (id, fixture) in chunk.Fixtures) + { + fixtures[id] = fixture; + } } EntityManager.EventBus.RaiseLocalEvent(uid,new GridFixtureChangeEvent {NewFixtures = fixtures}, true); @@ -126,7 +131,7 @@ namespace Robust.Shared.GameObjects // Additionally, we need to handle map deserialization where content may have stored its own data // on the grid (e.g. mass) which we want to preserve. - var newFixtures = new List(); + var newFixtures = new ValueList<(string Id, Fixture Fixture)>(); Span vertices = stackalloc Vector2[4]; @@ -144,21 +149,20 @@ namespace Robust.Shared.GameObjects #pragma warning disable CS0618 var newFixture = new Fixture( - $"grid_chunk-{bounds.Left}-{bounds.Bottom}", poly, MapGridHelpers.CollisionGroup, MapGridHelpers.CollisionGroup, true) { Body = body}; #pragma warning restore CS0618 - newFixtures.Add(newFixture); + newFixtures.Add(($"grid_chunk-{bounds.Left}-{bounds.Bottom}", newFixture)); } - var toRemove = new RemQueue(); + var toRemove = new ValueList<(string Id, Fixture Fixture)>(); // Check if we even need to issue an eventbus event var updated = false; - foreach (var oldFixture in chunk.Fixtures) + foreach (var (oldId, oldFixture) in chunk.Fixtures) { var existing = false; @@ -166,8 +170,10 @@ namespace Robust.Shared.GameObjects // (TODO: Check IDs and cross-reference for updates?) for (var i = newFixtures.Count - 1; i >= 0; i--) { - var fixture = newFixtures[i]; - if (!oldFixture.Equals(fixture)) continue; + var fixture = newFixtures[i].Fixture; + if (!oldFixture.Equals(fixture)) + continue; + existing = true; newFixtures.RemoveSwap(i); break; @@ -176,36 +182,36 @@ namespace Robust.Shared.GameObjects // Doesn't align with any new fixtures so delete if (existing) continue; - toRemove.Add(oldFixture); + toRemove.Add((oldId, oldFixture)); } - foreach (var fixture in toRemove) + foreach (var (id, fixture) in toRemove) { // TODO add a DestroyFixture() override that takes in a list. // reduced broadphase lookups - chunk.Fixtures.Remove(fixture); - _fixtures.DestroyFixture(uid, fixture, false, body: body, manager: manager, xform: xform); + chunk.Fixtures.Remove(id); + _fixtures.DestroyFixture(uid, id, fixture, false, body: body, manager: manager, xform: xform); } - if (newFixtures.Count > 0 || toRemove.List?.Count > 0) + if (newFixtures.Count > 0 || toRemove.Count > 0) { updated = true; } // Anything remaining is a new fixture (or at least, may have not serialized onto the chunk yet). - foreach (var fixture in newFixtures) + foreach (var (id, fixture) in newFixtures) { - var existingFixture = _fixtures.GetFixtureOrNull(uid, fixture.ID, manager: manager); + var existingFixture = _fixtures.GetFixtureOrNull(uid, id, manager: manager); // Check if it's the same (otherwise remove anyway). if (existingFixture?.Shape is PolygonShape poly && poly.EqualsApprox((PolygonShape) fixture.Shape)) { - chunk.Fixtures.Add(existingFixture); + chunk.Fixtures.Add(id, existingFixture); continue; } - chunk.Fixtures.Add(fixture); - _fixtures.CreateFixture(uid, fixture, false, manager, body, xform); + chunk.Fixtures.Add(id, fixture); + _fixtures.CreateFixture(uid, id, fixture, false, manager, body, xform); } return updated; @@ -218,7 +224,7 @@ namespace Robust.Shared.GameObjects /// public sealed class GridFixtureChangeEvent : EntityEventArgs { - public List NewFixtures { get; init; } = default!; + public Dictionary NewFixtures { get; init; } = default!; } [Serializable, NetSerializable] diff --git a/Robust.Shared/GameObjects/Systems/SharedMapSystem.Grid.cs b/Robust.Shared/GameObjects/Systems/SharedMapSystem.Grid.cs index d85234602..1af7cbf20 100644 --- a/Robust.Shared/GameObjects/Systems/SharedMapSystem.Grid.cs +++ b/Robust.Shared/GameObjects/Systems/SharedMapSystem.Grid.cs @@ -540,9 +540,9 @@ public abstract partial class SharedMapSystem PhysicsComponent? body = null; TransformComponent? xform = null; - foreach (var fixture in mapChunk.Fixtures) + foreach (var (id, fixture) in mapChunk.Fixtures) { - _fixtures.DestroyFixture(uid, fixture, false, manager: manager, body: body, xform: xform); + _fixtures.DestroyFixture(uid, id, fixture, false, manager: manager, body: body, xform: xform); } RemoveChunk(uid, grid, mapChunk.Indices); diff --git a/Robust.Shared/Map/MapChunk.cs b/Robust.Shared/Map/MapChunk.cs index c2f893696..8160eddc9 100644 --- a/Robust.Shared/Map/MapChunk.cs +++ b/Robust.Shared/Map/MapChunk.cs @@ -42,7 +42,7 @@ namespace Robust.Shared.Map /// /// Physics fixtures that make up this grid chunk. /// - public List Fixtures { get; } = new(); + public Dictionary Fixtures { get; } = new(); /// /// The last game simulation tick that a tile on this chunk was modified. diff --git a/Robust.Shared/Map/MapManager.Queries.cs b/Robust.Shared/Map/MapManager.Queries.cs index 1dc3d6ade..85ecda9a7 100644 --- a/Robust.Shared/Map/MapManager.Queries.cs +++ b/Robust.Shared/Map/MapManager.Queries.cs @@ -125,7 +125,7 @@ internal partial class MapManager while (enumerator.MoveNext(out var chunk)) { - foreach (var fixture in chunk.Fixtures) + foreach (var fixture in chunk.Fixtures.Values) { for (var j = 0; j < fixture.Shape.ChildCount; j++) { diff --git a/Robust.Shared/Physics/Dynamics/Contacts/Contact.cs b/Robust.Shared/Physics/Dynamics/Contacts/Contact.cs index 6ade90ccf..e21f90dc3 100644 --- a/Robust.Shared/Physics/Dynamics/Contacts/Contact.cs +++ b/Robust.Shared/Physics/Dynamics/Contacts/Contact.cs @@ -69,6 +69,9 @@ namespace Robust.Shared.Physics.Dynamics.Contacts public EntityUid EntityA; public EntityUid EntityB; + public string FixtureAId = string.Empty; + public string FixtureBId = string.Empty; + public Fixture? FixtureA; public Fixture? FixtureB; diff --git a/Robust.Shared/Physics/Dynamics/Fixture.cs b/Robust.Shared/Physics/Dynamics/Fixture.cs index 9ee8a4c85..9789a5906 100644 --- a/Robust.Shared/Physics/Dynamics/Fixture.cs +++ b/Robust.Shared/Physics/Dynamics/Fixture.cs @@ -31,7 +31,6 @@ using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -using Robust.Shared.Utility; using Robust.Shared.ViewVariables; namespace Robust.Shared.Physics.Dynamics @@ -40,19 +39,6 @@ namespace Robust.Shared.Physics.Dynamics [DataDefinition] public sealed partial class Fixture : IEquatable, ISerializationHooks { - /// - /// Allows us to reference a specific fixture when we contain multiple - /// This is useful for stuff like slippery objects that might have a non-hard layer for mob collisions and - /// a hard layer for wall collisions. - /// - /// We can also use this for networking to make cross-referencing fixtures easier. - /// Won't call Dirty() by default - /// Not a DataField as the component already stores the key and we would have to double it in yaml. - /// - /// - [ViewVariables(VVAccess.ReadWrite)] - public string ID; - [ViewVariables] [field: NonSerialized] public FixtureProxy[] Proxies { get; set; } = Array.Empty(); @@ -142,7 +128,6 @@ namespace Robust.Shared.Physics.Dynamics } internal Fixture( - string id, IPhysShape shape, int collisionLayer, int collisionMask, @@ -151,7 +136,6 @@ namespace Robust.Shared.Physics.Dynamics float friction = PhysicsConstants.DefaultContactFriction, float restitution = PhysicsConstants.DefaultRestitution) { - ID = id; Shape = shape; CollisionLayer = collisionLayer; CollisionMask = collisionMask; @@ -163,7 +147,6 @@ namespace Robust.Shared.Physics.Dynamics public Fixture() { - ID = string.Empty; } /// @@ -172,7 +155,6 @@ namespace Robust.Shared.Physics.Dynamics /// internal void CopyTo(Fixture fixture) { - fixture.ID = ID; fixture.Shape = Shape; fixture.Friction = Friction; fixture.Restitution = Restitution; @@ -187,8 +169,7 @@ namespace Robust.Shared.Physics.Dynamics /// public bool Equivalent(Fixture other) { - return ID.Equals(other.ID) && - Hard == other.Hard && + return Hard == other.Hard && CollisionLayer == other.CollisionLayer && CollisionMask == other.CollisionMask && Shape.Equals(other.Shape) && diff --git a/Robust.Shared/Physics/Dynamics/FixtureProxy.cs b/Robust.Shared/Physics/Dynamics/FixtureProxy.cs index 1b792d1fe..219b0490a 100644 --- a/Robust.Shared/Physics/Dynamics/FixtureProxy.cs +++ b/Robust.Shared/Physics/Dynamics/FixtureProxy.cs @@ -41,6 +41,8 @@ namespace Robust.Shared.Physics.Dynamics [ViewVariables] public int ChildIndex; + public string FixtureId; + /// /// Our parent fixture /// @@ -52,11 +54,12 @@ namespace Robust.Shared.Physics.Dynamics [ViewVariables] public DynamicTree.Proxy ProxyId = DynamicTree.Proxy.Free; - public FixtureProxy(EntityUid uid, PhysicsComponent body, Box2 aabb, Fixture fixture, int childIndex) + public FixtureProxy(EntityUid uid, PhysicsComponent body, Box2 aabb, string fixtureId, Fixture fixture, int childIndex) { Entity = uid; Body = body; AABB = aabb; + FixtureId = fixtureId; Fixture = fixture; ChildIndex = childIndex; } diff --git a/Robust.Shared/Physics/Events/EndCollideEvent.cs b/Robust.Shared/Physics/Events/EndCollideEvent.cs index f1345f00c..9e3250e71 100644 --- a/Robust.Shared/Physics/Events/EndCollideEvent.cs +++ b/Robust.Shared/Physics/Events/EndCollideEvent.cs @@ -13,12 +13,17 @@ public readonly struct EndCollideEvent public readonly PhysicsComponent OurBody; public readonly PhysicsComponent OtherBody; + public readonly string OurFixtureId; + public readonly string OtherFixtureId; + public readonly Fixture OurFixture; public readonly Fixture OtherFixture; public EndCollideEvent( EntityUid ourEntity, EntityUid otherEntity, + string ourFixtureId, + string otherFixtureId, Fixture ourFixture, Fixture otherFixture, PhysicsComponent ourBody, @@ -26,6 +31,8 @@ public readonly struct EndCollideEvent { OurEntity = ourEntity; OtherEntity = otherEntity; + OurFixtureId = ourFixtureId; + OtherFixtureId = otherFixtureId; OurFixture = ourFixture; OtherFixture = otherFixture; OtherBody = otherBody; diff --git a/Robust.Shared/Physics/Events/StartCollideEvent.cs b/Robust.Shared/Physics/Events/StartCollideEvent.cs index 2e5235dcd..8f551ddca 100644 --- a/Robust.Shared/Physics/Events/StartCollideEvent.cs +++ b/Robust.Shared/Physics/Events/StartCollideEvent.cs @@ -15,6 +15,9 @@ public readonly struct StartCollideEvent public readonly PhysicsComponent OurBody; public readonly PhysicsComponent OtherBody; + public readonly string OurFixtureId; + public readonly string OtherFixtureId; + public readonly Fixture OurFixture; public readonly Fixture OtherFixture; public readonly Vector2 WorldPoint; @@ -22,6 +25,8 @@ public readonly struct StartCollideEvent public StartCollideEvent( EntityUid ourEntity, EntityUid otherEntity, + string ourFixtureId, + string otherFixtureId, Fixture ourFixture, Fixture otherFixture, PhysicsComponent ourBody, @@ -30,6 +35,8 @@ public readonly struct StartCollideEvent { OurEntity = ourEntity; OtherEntity = otherEntity; + OurFixtureId = ourFixtureId; + OtherFixtureId = otherFixtureId; OurFixture = ourFixture; OtherFixture = otherFixture; WorldPoint = worldPoint; diff --git a/Robust.Shared/Physics/FixtureSerializer.cs b/Robust.Shared/Physics/FixtureSerializer.cs index d5b1f9613..a16e01465 100644 --- a/Robust.Shared/Physics/FixtureSerializer.cs +++ b/Robust.Shared/Physics/FixtureSerializer.cs @@ -52,7 +52,6 @@ public sealed class FixtureSerializer : ITypeSerializer(subNode.Value, hookCtx, context, notNullableOverride: true); - fixture.ID = key.Value; value.Add(key.Value, fixture); } @@ -67,8 +66,6 @@ public sealed class FixtureSerializer : ITypeSerializer Fixtures.Count; + /// + /// Allows us to reference a specific fixture when we contain multiple + /// This is useful for stuff like slippery objects that might have a non-hard layer for mob collisions and + /// a hard layer for wall collisions. + /// + /// We can also use this for networking to make cross-referencing fixtures easier. + /// Won't call Dirty() by default + /// + /// [ViewVariables(VVAccess.ReadWrite), DataField("fixtures", customTypeSerializer:typeof(FixtureSerializer))] [NeverPushInheritance] [Access(typeof(FixtureSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends diff --git a/Robust.Shared/Physics/Systems/FixtureSystem.cs b/Robust.Shared/Physics/Systems/FixtureSystem.cs index faba7d3c4..90fd0cc61 100644 --- a/Robust.Shared/Physics/Systems/FixtureSystem.cs +++ b/Robust.Shared/Physics/Systems/FixtureSystem.cs @@ -70,14 +70,14 @@ namespace Robust.Shared.Physics.Systems if (manager.Fixtures.ContainsKey(id)) return false; - var fixture = new Fixture(id, shape, collisionLayer, collisionMask, hard, density, friction, restitution); - fixture.ID = id; - CreateFixture(uid, fixture, updates, manager, body, xform); + var fixture = new Fixture(shape, collisionLayer, collisionMask, hard, density, friction, restitution); + CreateFixture(uid, id, fixture, updates, manager, body, xform); return true; } internal void CreateFixture( EntityUid uid, + string fixtureId, Fixture fixture, bool updates = true, FixturesComponent? manager = null, @@ -92,17 +92,17 @@ namespace Robust.Shared.Physics.Systems return; } - if (string.IsNullOrEmpty(fixture.ID)) + if (string.IsNullOrEmpty(fixtureId)) { throw new InvalidOperationException($"Tried to create a fixture without an ID!"); } - manager.Fixtures.Add(fixture.ID, fixture); + manager.Fixtures.Add(fixtureId, fixture); fixture.Body = body; if (body.CanCollide && Resolve(uid, ref xform)) { - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } // Supposed to be wrapped in density but eh @@ -147,7 +147,7 @@ namespace Robust.Shared.Physics.Systems if (fixture == null) return; - DestroyFixture(uid, fixture, updates, body, manager, xform); + DestroyFixture(uid, id, fixture, updates, body, manager, xform); } /// @@ -156,6 +156,7 @@ namespace Robust.Shared.Physics.Systems /// Whether to update mass etc. Set false if you're doing a bulk operation public void DestroyFixture( EntityUid uid, + string fixtureId, Fixture fixture, bool updates = true, PhysicsComponent? body = null, @@ -170,7 +171,7 @@ namespace Robust.Shared.Physics.Systems // TODO: Assert world locked DebugTools.Assert(manager.FixtureCount > 0); - if (!manager.Fixtures.Remove(fixture.ID)) + if (!manager.Fixtures.Remove(fixtureId)) { Log.Error($"Tried to remove fixture from {ToPrettyString(uid)} that was already removed."); return; @@ -185,7 +186,7 @@ namespace Robust.Shared.Physics.Systems { var map = Transform(broadphase.Owner).MapUid; TryComp(map, out var physicsMap); - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); } @@ -226,7 +227,7 @@ namespace Robust.Shared.Physics.Systems { args.State = new FixtureManagerComponentState { - Fixtures = component.Fixtures.Values.ToArray(), + Fixtures = component.Fixtures, }; } @@ -244,28 +245,26 @@ namespace Robust.Shared.Physics.Systems // Alternatively if this is necessary just add it to FixtureSerializer. foreach (var (id, fixture) in component.Fixtures) { - DebugTools.Assert(id == fixture.ID); #pragma warning disable CS0618 fixture.Body = physics; #pragma warning restore CS0618 } - var toAddFixtures = new ValueList(); - var toRemoveFixtures = new ValueList(); + var toAddFixtures = new ValueList<(string Id, Fixture Fixture)>(); + var toRemoveFixtures = new ValueList<(string Id, Fixture Fixture)>(); var computeProperties = false; // Given a bunch of data isn't serialized need to sort of re-initialise it - var newFixtures = new Dictionary(state.Fixtures.Length); + var newFixtures = new Dictionary(state.Fixtures.Count()); - for (var i = 0; i < state.Fixtures.Length; i++) + foreach (var (id, fixture) in state.Fixtures) { - var fixture = state.Fixtures[i]; var newFixture = new Fixture(); fixture.CopyTo(newFixture); #pragma warning disable CS0618 newFixture.Body = physics; #pragma warning restore CS0618 - newFixtures.Add(newFixture.ID, newFixture); + newFixtures.Add(id, newFixture); } TransformComponent? xform = null; @@ -279,12 +278,12 @@ namespace Robust.Shared.Physics.Systems { if (!component.Fixtures.TryGetValue(id, out var existing)) { - toAddFixtures.Add(fixture); + toAddFixtures.Add((id, fixture)); } else if (!existing.Equivalent(fixture)) { - toRemoveFixtures.Add(existing); - toAddFixtures.Add(fixture); + toRemoveFixtures.Add((id, existing)); + toAddFixtures.Add((id, fixture)); } } @@ -293,25 +292,25 @@ namespace Robust.Shared.Physics.Systems { if (!newFixtures.ContainsKey(existingId)) { - toRemoveFixtures.Add(existing); + toRemoveFixtures.Add((existingId, existing)); } } // TODO add a DestroyFixture() override that takes in a list. // reduced broadphase lookups - foreach (var fixture in toRemoveFixtures) + foreach (var (id, fixture) in toRemoveFixtures) { computeProperties = true; - DestroyFixture(uid, fixture, false, physics, component); + DestroyFixture(uid, id, fixture, false, physics, component); } // TODO: We also still need event listeners for shapes (Probably need C# events) // Or we could just make it so shapes can only be updated via fixturesystem which handles it // automagically (friends or something?) - foreach (var fixture in toAddFixtures) + foreach (var (id, fixture) in toAddFixtures) { computeProperties = true; - CreateFixture(uid, fixture, false, component, physics, xform); + CreateFixture(uid, id, fixture, false, component, physics, xform); } if (computeProperties) @@ -322,7 +321,7 @@ namespace Robust.Shared.Physics.Systems #region Restitution - public void SetRestitution(EntityUid uid, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) + public void SetRestitution(EntityUid uid, string fixtureId, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) { fixture.Restitution = value; if (update && Resolve(uid, ref manager)) @@ -387,7 +386,7 @@ namespace Robust.Shared.Physics.Systems [Serializable, NetSerializable] private sealed class FixtureManagerComponentState : ComponentState { - public Fixture[] Fixtures = default!; + public Dictionary Fixtures = default!; } } } diff --git a/Robust.Shared/Physics/Systems/SharedBroadphaseSystem.cs b/Robust.Shared/Physics/Systems/SharedBroadphaseSystem.cs index 1a5b2014c..e75230c52 100644 --- a/Robust.Shared/Physics/Systems/SharedBroadphaseSystem.cs +++ b/Robust.Shared/Physics/Systems/SharedBroadphaseSystem.cs @@ -255,7 +255,7 @@ namespace Robust.Shared.Physics.Systems _physicsSystem.WakeBody(other.Entity, force: true, body: otherBody); } - _physicsSystem.AddPair(proxyA, other); + _physicsSystem.AddPair(proxyA.FixtureId, other.FixtureId, proxyA, other); } _bufferPool.Return(contactBuffer[i]); @@ -330,13 +330,13 @@ namespace Robust.Shared.Physics.Systems while (collidingChunks.MoveNext(out var collidingChunk)) { - foreach (var fixture in ourChunk.Fixtures) + foreach (var (ourId, fixture) in ourChunk.Fixtures) { for (var i = 0; i < fixture.Shape.ChildCount; i++) { var fixAABB = fixture.Shape.ComputeAABB(tuple.transform, i); - foreach (var otherFixture in collidingChunk.Fixtures) + foreach (var (otherId, otherFixture) in collidingChunk.Fixtures) { for (var j = 0; j < otherFixture.Shape.ChildCount; j++) { @@ -344,6 +344,7 @@ namespace Robust.Shared.Physics.Systems if (!fixAABB.Intersects(otherAABB)) continue; tuple._physicsSystem.AddPair(tuple.gridUid, uid, + ourId, otherId, fixture, i, otherFixture, j, physicsA, physicsB, diff --git a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs index 74c0db0e0..513d73c6e 100644 --- a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs +++ b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs @@ -121,12 +121,12 @@ public abstract partial class SharedPhysicsSystem public bool Return(Contact obj) { - SetContact(obj, EntityUid.Invalid, EntityUid.Invalid, null, 0, null, 0); + SetContact(obj, EntityUid.Invalid, EntityUid.Invalid, string.Empty, string.Empty, null, 0, null, 0); return true; } } - private static void SetContact(Contact contact, EntityUid uidA, EntityUid uidB, Fixture? fixtureA, int indexA, Fixture? fixtureB, int indexB) + private static void SetContact(Contact contact, EntityUid uidA, EntityUid uidB, string fixtureAId, string fixtureBId, Fixture? fixtureA, int indexA, Fixture? fixtureB, int indexB) { contact.Enabled = true; contact.IsTouching = false; @@ -136,6 +136,9 @@ public abstract partial class SharedPhysicsSystem contact.EntityA = uidA; contact.EntityB = uidB; + contact.FixtureAId = fixtureAId; + contact.FixtureBId = fixtureBId; + contact.FixtureA = fixtureA; contact.FixtureB = fixtureB; @@ -196,7 +199,7 @@ public abstract partial class SharedPhysicsSystem } } - private Contact CreateContact(EntityUid uidA, EntityUid uidB, Fixture fixtureA, int indexA, Fixture fixtureB, int indexB) + private Contact CreateContact(EntityUid uidA, EntityUid uidB, string fixtureAId, string fixtureBId, Fixture fixtureA, int indexA, Fixture fixtureB, int indexB) { var type1 = fixtureA.Shape.ShapeType; var type2 = fixtureB.Shape.ShapeType; @@ -210,11 +213,11 @@ public abstract partial class SharedPhysicsSystem // Edge+Polygon is non-symmetrical due to the way Erin handles collision type registration. if ((type1 >= type2 || (type1 == ShapeType.Edge && type2 == ShapeType.Polygon)) && !(type2 == ShapeType.Edge && type1 == ShapeType.Polygon)) { - SetContact(contact, uidA, uidB, fixtureA, indexA, fixtureB, indexB); + SetContact(contact, uidA, uidB, fixtureAId, fixtureBId, fixtureA, indexA, fixtureB, indexB); } else { - SetContact(contact, uidB, uidA, fixtureB, indexB, fixtureA, indexA); + SetContact(contact, uidB, uidA, fixtureBId, fixtureAId, fixtureB, indexB, fixtureA, indexA); } contact.Type = _registers[(int)type1, (int)type2]; @@ -225,7 +228,9 @@ public abstract partial class SharedPhysicsSystem /// /// Try to create a contact between these 2 fixtures. /// - internal void AddPair(EntityUid uidA, EntityUid uidB, + internal void AddPair( + EntityUid uidA, EntityUid uidB, + string fixtureAId, string fixtureBId, Fixture fixtureA, int indexA, Fixture fixtureB, int indexB, PhysicsComponent bodyA, PhysicsComponent bodyB, @@ -248,7 +253,7 @@ public abstract partial class SharedPhysicsSystem return; // Call the factory. - var contact = CreateContact(uidA, uidB, fixtureA, indexA, fixtureB, indexB); + var contact = CreateContact(uidA, uidB, fixtureAId, fixtureBId, fixtureA, indexA, fixtureB, indexB); contact.Flags = flags; // Contact creation may swap fixtures. @@ -274,9 +279,10 @@ public abstract partial class SharedPhysicsSystem /// /// Go through the cached broadphase movement and update contacts. /// - internal void AddPair(in FixtureProxy proxyA, in FixtureProxy proxyB) + internal void AddPair(string fixtureAId, string fixtureBId, in FixtureProxy proxyA, in FixtureProxy proxyB) { AddPair(proxyA.Entity, proxyB.Entity, + fixtureAId, fixtureBId, proxyA.Fixture, proxyA.ChildIndex, proxyB.Fixture, proxyB.ChildIndex, proxyA.Body, proxyB.Body); @@ -299,8 +305,8 @@ public abstract partial class SharedPhysicsSystem if (contact.IsTouching) { - var ev1 = new EndCollideEvent(aUid, bUid, fixtureA, fixtureB, bodyA, bodyB); - var ev2 = new EndCollideEvent(bUid, aUid, fixtureB, fixtureA, bodyB, bodyA); + var ev1 = new EndCollideEvent(aUid, bUid, contact.FixtureAId, contact.FixtureBId ,fixtureA, fixtureB, bodyA, bodyB); + var ev2 = new EndCollideEvent(bUid, aUid, contact.FixtureBId, contact.FixtureAId, fixtureB, fixtureA, bodyB, bodyA); RaiseLocalEvent(aUid, ref ev1); RaiseLocalEvent(bUid, ref ev2); } @@ -426,14 +432,14 @@ public abstract partial class SharedPhysicsSystem if (indexA >= fixtureA.Proxies.Length) { - Log.Error($"Found invalid contact index of {indexA} on {fixtureA.ID} / {ToPrettyString(uidA)}, expected {fixtureA.Proxies.Length}"); + Log.Error($"Found invalid contact index of {indexA} on {contact.FixtureAId} / {ToPrettyString(uidA)}, expected {fixtureA.Proxies.Length}"); DestroyContact(contact); continue; } if (indexB >= fixtureB.Proxies.Length) { - Log.Error($"Found invalid contact index of {indexB} on {fixtureB.ID} / {ToPrettyString(uidB)}, expected {fixtureB.Proxies.Length}"); + Log.Error($"Found invalid contact index of {indexB} on {contact.FixtureBId} / {ToPrettyString(uidB)}, expected {fixtureB.Proxies.Length}"); DestroyContact(contact); continue; } @@ -511,8 +517,8 @@ public abstract partial class SharedPhysicsSystem var uidB = contact.EntityB; var worldPoint = worldPoints[i]; - var ev1 = new StartCollideEvent(uidA, uidB, fixtureA, fixtureB, bodyA, bodyB, worldPoint); - var ev2 = new StartCollideEvent(uidB, uidA, fixtureB, fixtureA, bodyB, bodyA, worldPoint); + var ev1 = new StartCollideEvent(uidA, uidB, contact.FixtureAId, contact.FixtureBId, fixtureA, fixtureB, bodyA, bodyB, worldPoint); + var ev2 = new StartCollideEvent(uidB, uidA, contact.FixtureBId, contact.FixtureAId, fixtureB, fixtureA, bodyB, bodyA, worldPoint); RaiseLocalEvent(uidA, ref ev1, true); RaiseLocalEvent(uidB, ref ev2, true); @@ -534,8 +540,8 @@ public abstract partial class SharedPhysicsSystem var uidA = contact.EntityA; var uidB = contact.EntityB; - var ev1 = new EndCollideEvent(uidA, uidB, fixtureA, fixtureB, bodyA, bodyB); - var ev2 = new EndCollideEvent(uidB, uidA, fixtureB, fixtureA, bodyB, bodyA); + var ev1 = new EndCollideEvent(uidA, uidB, contact.FixtureAId, contact.FixtureBId, fixtureA, fixtureB, bodyA, bodyB); + var ev2 = new EndCollideEvent(uidB, uidA, contact.FixtureBId, contact.FixtureAId, fixtureB, fixtureA, bodyB, bodyA); RaiseLocalEvent(uidA, ref ev1); RaiseLocalEvent(uidB, ref ev2); diff --git a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Fixtures.cs b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Fixtures.cs index 9eaca48bf..72ce22a5e 100644 --- a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Fixtures.cs +++ b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Fixtures.cs @@ -10,7 +10,7 @@ public abstract partial class SharedPhysicsSystem { [Dependency] private readonly FixtureSystem _fixtures = default!; - public void SetDensity(EntityUid uid, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) + public void SetDensity(EntityUid uid, string fixtureId, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) { DebugTools.Assert(value >= 0f); @@ -26,7 +26,7 @@ public abstract partial class SharedPhysicsSystem _fixtures.FixtureUpdate(uid, manager: manager); } - public void SetFriction(EntityUid uid, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) + public void SetFriction(EntityUid uid, string fixtureId, Fixture fixture, float value, bool update = true, FixturesComponent? manager = null) { DebugTools.Assert(value >= 0f); @@ -73,14 +73,14 @@ public abstract partial class SharedPhysicsSystem #region Collision Masks & Layers - public void AddCollisionMask(EntityUid uid, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void AddCollisionMask(EntityUid uid, string fixtureId, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) { if ((fixture.CollisionMask & mask) == mask) return; if (!Resolve(uid, ref manager)) return; - DebugTools.Assert(manager.Fixtures.ContainsKey(fixture.ID)); + DebugTools.Assert(manager.Fixtures.ContainsKey(fixtureId)); fixture.CollisionMask |= mask; if (body != null || TryComp(uid, out body)) @@ -91,14 +91,14 @@ public abstract partial class SharedPhysicsSystem _broadphase.Refilter(uid, fixture); } - public void SetCollisionMask(EntityUid uid, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void SetCollisionMask(EntityUid uid, string fixtureId, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) { if (fixture.CollisionMask == mask) return; if (!Resolve(uid, ref manager)) return; - DebugTools.Assert(manager.Fixtures.ContainsKey(fixture.ID)); + DebugTools.Assert(manager.Fixtures.ContainsKey(fixtureId)); fixture.CollisionMask = mask; if (body != null || TryComp(uid, out body)) @@ -109,14 +109,14 @@ public abstract partial class SharedPhysicsSystem _broadphase.Refilter(uid, fixture); } - public void RemoveCollisionMask(EntityUid uid, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void RemoveCollisionMask(EntityUid uid, string fixtureId, Fixture fixture, int mask, FixturesComponent? manager = null, PhysicsComponent? body = null) { if ((fixture.CollisionMask & mask) == 0x0) return; if (!Resolve(uid, ref manager)) return; - DebugTools.Assert(manager.Fixtures.ContainsKey(fixture.ID)); + DebugTools.Assert(manager.Fixtures.ContainsKey(fixtureId)); fixture.CollisionMask &= ~mask; if (body != null || TryComp(uid, out body)) @@ -127,14 +127,14 @@ public abstract partial class SharedPhysicsSystem _broadphase.Refilter(uid, fixture); } - public void AddCollisionLayer(EntityUid uid, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void AddCollisionLayer(EntityUid uid, string fixtureId, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) { if ((fixture.CollisionLayer & layer) == layer) return; if (!Resolve(uid, ref manager)) return; - DebugTools.Assert(manager.Fixtures.ContainsKey(fixture.ID)); + DebugTools.Assert(manager.Fixtures.ContainsKey(fixtureId)); fixture.CollisionLayer |= layer; if (body != null || TryComp(uid, out body)) @@ -145,7 +145,7 @@ public abstract partial class SharedPhysicsSystem _broadphase.Refilter(uid, fixture); } - public void SetCollisionLayer(EntityUid uid, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void SetCollisionLayer(EntityUid uid, string fixtureId, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) { if (fixture.CollisionLayer.Equals(layer)) return; @@ -163,11 +163,11 @@ public abstract partial class SharedPhysicsSystem _broadphase.Refilter(uid, fixture); } - public void RemoveCollisionLayer(EntityUid uid, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) + public void RemoveCollisionLayer(EntityUid uid, string fixtureId, Fixture fixture, int layer, FixturesComponent? manager = null, PhysicsComponent? body = null) { if ((fixture.CollisionLayer & layer) == 0x0 || !Resolve(uid, ref manager)) return; - DebugTools.Assert(manager.Fixtures.ContainsKey(fixture.ID)); + DebugTools.Assert(manager.Fixtures.ContainsKey(fixtureId)); fixture.CollisionLayer &= ~layer; if (body != null || TryComp(uid, out body)) diff --git a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Shapes.cs b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Shapes.cs index 604343ccd..b6854bc0d 100644 --- a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Shapes.cs +++ b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Shapes.cs @@ -13,6 +13,7 @@ public abstract partial class SharedPhysicsSystem { public void SetRadius( EntityUid uid, + string fixtureId, Fixture fixture, IPhysShape shape, float radius, @@ -29,8 +30,8 @@ public abstract partial class SharedPhysicsSystem TryComp(xform.Broadphase?.Uid, out var broadphase) && TryComp(xform.MapUid, out var physicsMap)) { - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } _fixtures.FixtureUpdate(uid, manager: manager, body: body); @@ -40,6 +41,7 @@ public abstract partial class SharedPhysicsSystem public void SetPositionRadius( EntityUid uid, + string fixtureId, Fixture fixture, PhysShapeCircle shape, Vector2 position, @@ -59,8 +61,8 @@ public abstract partial class SharedPhysicsSystem TryComp(xform.Broadphase?.Uid, out var broadphase) && TryComp(xform.MapUid, out var physicsMap)) { - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } Dirty(manager); @@ -68,6 +70,7 @@ public abstract partial class SharedPhysicsSystem public void SetPosition( EntityUid uid, + string fixtureId, Fixture fixture, PhysShapeCircle circle, Vector2 position, @@ -84,8 +87,8 @@ public abstract partial class SharedPhysicsSystem TryComp(xform.Broadphase?.Uid, out var broadphase) && TryComp(xform.MapUid, out var physicsMap)) { - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } Dirty(manager); @@ -97,6 +100,7 @@ public abstract partial class SharedPhysicsSystem public void SetVertices( EntityUid uid, + string fixtureId, Fixture fixture, EdgeShape edge, Vector2 vertex0, @@ -119,8 +123,8 @@ public abstract partial class SharedPhysicsSystem TryComp(xform.Broadphase?.Uid, out var broadphase) && TryComp(xform.MapUid, out var physicsMap)) { - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } _fixtures.FixtureUpdate(uid, manager: manager, body: body); @@ -132,6 +136,7 @@ public abstract partial class SharedPhysicsSystem public void SetVertices( EntityUid uid, + string fixtureId, Fixture fixture, PolygonShape poly, Vector2[] vertices, @@ -148,8 +153,8 @@ public abstract partial class SharedPhysicsSystem TryComp(xform.Broadphase?.Uid, out var broadphase) && TryComp(xform.MapUid, out var physicsMap)) { - _lookup.DestroyProxies(uid, fixture, xform, broadphase, physicsMap); - _lookup.CreateProxies(uid, xform, fixture, body); + _lookup.DestroyProxies(uid, fixtureId, fixture, xform, broadphase, physicsMap); + _lookup.CreateProxies(uid, fixtureId, fixture, xform, body); } _fixtures.FixtureUpdate(uid, manager: manager, body: body); diff --git a/Robust.UnitTesting/Shared/Physics/BroadphaseNetworkingTest.cs b/Robust.UnitTesting/Shared/Physics/BroadphaseNetworkingTest.cs index c2402fed3..cb500733a 100644 --- a/Robust.UnitTesting/Shared/Physics/BroadphaseNetworkingTest.cs +++ b/Robust.UnitTesting/Shared/Physics/BroadphaseNetworkingTest.cs @@ -81,8 +81,8 @@ public sealed class BroadphaseNetworkingTest : RobustIntegrationTest var xform = sEntMan.GetComponent(player); var shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); - var fixture = new Fixture("fix1", shape, 0, 0, true); - fixturesSystem.CreateFixture(player, fixture, body: physics, xform: xform); + var fixture = new Fixture(shape, 0, 0, true); + fixturesSystem.CreateFixture(player, "fix1", fixture, body: physics, xform: xform); physicsSystem.SetCanCollide(player, true, body: physics); physicsSystem.SetBodyType(player, BodyType.Dynamic); Assert.That(physics.CanCollide); diff --git a/Robust.UnitTesting/Shared/Physics/Broadphase_Test.cs b/Robust.UnitTesting/Shared/Physics/Broadphase_Test.cs index 305028593..7a32abfa5 100644 --- a/Robust.UnitTesting/Shared/Physics/Broadphase_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/Broadphase_Test.cs @@ -66,23 +66,24 @@ public sealed class Broadphase_Test var mapId = mapManager.CreateMap(); var mapEnt = mapManager.GetMapEntityId(mapId); var grid = mapManager.CreateGrid(mapId); + var gridUid = grid.Owner; grid.SetTile(Vector2i.Zero, new Tile(1)); - Assert.That(entManager.HasComponent(grid.Owner)); - var broadphase = entManager.GetComponent(grid.Owner); + Assert.That(entManager.HasComponent(gridUid)); + var broadphase = entManager.GetComponent(gridUid); - var ent = entManager.SpawnEntity(null, new EntityCoordinates(grid.Owner, new Vector2(0.5f, 0.5f))); + var ent = entManager.SpawnEntity(null, new EntityCoordinates(gridUid, new Vector2(0.5f, 0.5f))); var physics = entManager.AddComponent(ent); var xform = entManager.GetComponent(ent); // If we're not collidable we're still on the sundries tree. Assert.That(broadphase.StaticSundriesTree, Does.Contain(ent)); - Assert.That(xform.Broadphase!.Value.Uid, Is.EqualTo(grid.Owner)); + Assert.That(xform.Broadphase!.Value.Uid, Is.EqualTo(gridUid)); var shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); - var fixture = new Fixture("fix1", shape, 0, 0, true); - fixturesSystem.CreateFixture(ent, fixture, body: physics, xform: xform); + var fixture = new Fixture(shape, 0, 0, true); + fixturesSystem.CreateFixture(ent, "fix1", fixture, body: physics, xform: xform); physicsSystem.SetCanCollide(ent, true, body: physics); Assert.That(physics.CanCollide); @@ -224,7 +225,7 @@ public sealed class Broadphase_Test // enable collision for the child var shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); - fixtures.CreateFixture(child, new Fixture("fix1", shape, 0, 0, false), body: childBody, xform: childXform); + fixtures.CreateFixture(child, "fix1", new Fixture(shape, 0, 0, false), body: childBody, xform: childXform); physSystem.SetCanCollide(child, true, body: childBody); Assert.That(childBody.CanCollide); @@ -342,7 +343,7 @@ public sealed class Broadphase_Test var shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); - fixtures.CreateFixture(child1, new Fixture("fix1", shape, 0, 0, false), body: child1Body, xform: child1Xform); + fixtures.CreateFixture(child1, "fix1", new Fixture(shape, 0, 0, false), body: child1Body, xform: child1Xform); physSystem.SetCanCollide(child1, true, body: child1Body); Assert.That(child1Body.CanCollide); diff --git a/Robust.UnitTesting/Shared/Physics/Collision_Test.cs b/Robust.UnitTesting/Shared/Physics/Collision_Test.cs index 47908008f..08bc6b807 100644 --- a/Robust.UnitTesting/Shared/Physics/Collision_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/Collision_Test.cs @@ -113,8 +113,8 @@ public sealed class Collision_Test var body2 = entManager.AddComponent(ent2); physics.SetBodyType(ent2, BodyType.Dynamic, body: body2); - fixtures.CreateFixture(ent1, new Fixture("fix1", new PhysShapeCircle(1f), 1, 0, true), body: body1); - fixtures.CreateFixture(ent2, new Fixture("fix1", new PhysShapeCircle(1f), 0, 1, true), body: body2); + fixtures.CreateFixture(ent1, "fix1", new Fixture(new PhysShapeCircle(1f), 1, 0, true), body: body1); + fixtures.CreateFixture(ent2, "fix1", new Fixture(new PhysShapeCircle(1f), 0, 1, true), body: body2); physics.WakeBody(ent1, body: body1); physics.WakeBody(ent2, body: body2); diff --git a/Robust.UnitTesting/Shared/Physics/Fixtures_Test.cs b/Robust.UnitTesting/Shared/Physics/Fixtures_Test.cs index f5311337a..443830fcd 100644 --- a/Robust.UnitTesting/Shared/Physics/Fixtures_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/Fixtures_Test.cs @@ -29,13 +29,10 @@ public sealed class Fixtures_Test var ent = sim.SpawnEntity(null, new MapCoordinates(Vector2.Zero, map)); var body = entManager.AddComponent(ent); physicsSystem.SetBodyType(ent, BodyType.Dynamic, body: body); - var fixture = new Fixture() - { - ID = "fix1" - }; - fixturesSystem.CreateFixture(ent, fixture); + var fixture = new Fixture(); + fixturesSystem.CreateFixture(ent, "fix1", fixture); - physicsSystem.SetDensity(ent, fixture, 10f); + physicsSystem.SetDensity(ent, "fix1", fixture, 10f); Assert.That(fixture.Density, Is.EqualTo(10f)); Assert.That(body.Mass, Is.EqualTo(10f)); diff --git a/Robust.UnitTesting/Shared/Physics/GridMovement_Test.cs b/Robust.UnitTesting/Shared/Physics/GridMovement_Test.cs index 744464d0b..4f9cafa66 100644 --- a/Robust.UnitTesting/Shared/Physics/GridMovement_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/GridMovement_Test.cs @@ -44,7 +44,7 @@ public sealed class GridMovement_Test : RobustIntegrationTest physSystem.SetBodyType(onGrid, BodyType.Dynamic, body: onGridBody); var shapeA = new PolygonShape(); shapeA.SetAsBox(0.5f, 0.5f); - fixtureSystem.CreateFixture(onGrid, new Fixture("fix1", shapeA, 1, 0, false), body: onGridBody); + fixtureSystem.CreateFixture(onGrid, "fix1", new Fixture(shapeA, 1, 0, false), body: onGridBody); Assert.That(fixtureSystem.GetFixtureCount(onGrid), Is.EqualTo(1)); Assert.That(entManager.GetComponent(onGrid).ParentUid, Is.EqualTo(grid.Owner)); physSystem.WakeBody(onGrid, body: onGridBody); @@ -55,7 +55,7 @@ public sealed class GridMovement_Test : RobustIntegrationTest physSystem.SetBodyType(offGrid, BodyType.Dynamic, body: offGridBody); var shapeB = new PolygonShape(); shapeB.SetAsBox(0.5f, 0.5f); - fixtureSystem.CreateFixture(offGrid, new Fixture("fix1", shapeB, 0, 1, false), body: offGridBody); + fixtureSystem.CreateFixture(offGrid, "fix1", new Fixture(shapeB, 0, 1, false), body: offGridBody); Assert.That(fixtureSystem.GetFixtureCount(offGrid), Is.EqualTo(1)); Assert.That(entManager.GetComponent(offGrid).ParentUid, Is.Not.EqualTo((grid.Owner))); physSystem.WakeBody(offGrid, body: offGridBody); diff --git a/Robust.UnitTesting/Shared/Physics/JointDeletion_Test.cs b/Robust.UnitTesting/Shared/Physics/JointDeletion_Test.cs index a897bd377..5a3833a4e 100644 --- a/Robust.UnitTesting/Shared/Physics/JointDeletion_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/JointDeletion_Test.cs @@ -56,7 +56,7 @@ public sealed class JointDeletion_Test : RobustIntegrationTest var shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); - fixSystem.CreateFixture(ent2, new Fixture("fix1", shape, 0, 0, false), manager: manager2, body: body2); + fixSystem.CreateFixture(ent2, "fix1", new Fixture(shape, 0, 0, false), manager: manager2, body: body2); joint = jointSystem.CreateDistanceJoint(ent1, ent2, id: "distance-joint"); joint.CollideConnected = false; diff --git a/Robust.UnitTesting/Shared/Physics/Joints_Test.cs b/Robust.UnitTesting/Shared/Physics/Joints_Test.cs index 813f85feb..d29c665e2 100644 --- a/Robust.UnitTesting/Shared/Physics/Joints_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/Joints_Test.cs @@ -86,8 +86,8 @@ public sealed class Joints_Test physicsSystem.SetBodyType(ent1, BodyType.Dynamic, manager: manager1, body: body1); physicsSystem.SetBodyType(ent2, BodyType.Dynamic, manager: manager2, body: body2); - fixtureSystem.CreateFixture(ent1, new Fixture("fix1", new PhysShapeCircle(0.1f), 1, 1, false), manager: manager1, body: body1); - fixtureSystem.CreateFixture(ent2, new Fixture("fix1", new PhysShapeCircle(0.1f), 1, 1, false), manager: manager2, body: body2); + fixtureSystem.CreateFixture(ent1, "fix1", new Fixture(new PhysShapeCircle(0.1f), 1, 1, false), manager: manager1, body: body1); + fixtureSystem.CreateFixture(ent2, "fix1", new Fixture(new PhysShapeCircle(0.1f), 1, 1, false), manager: manager2, body: body2); var joint = jointSystem.CreateDistanceJoint(ent1, ent2); Assert.That(joint.CollideConnected, Is.EqualTo(true)); diff --git a/Robust.UnitTesting/Shared/Physics/PhysicsComponent_Test.cs b/Robust.UnitTesting/Shared/Physics/PhysicsComponent_Test.cs index 206c551cc..afe7b769c 100644 --- a/Robust.UnitTesting/Shared/Physics/PhysicsComponent_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/PhysicsComponent_Test.cs @@ -37,7 +37,7 @@ namespace Robust.UnitTesting.Shared.Physics var box = entManager.AddComponent(boxEnt); var poly = new PolygonShape(); poly.SetAsBox(0.5f, 0.5f); - fixtureSystem.CreateFixture(boxEnt, new Fixture("fix1", poly, 0, 0, false), body: box); + fixtureSystem.CreateFixture(boxEnt, "fix1", new Fixture(poly, 0, 0, false), body: box); physicsSystem.SetFixedRotation(boxEnt, false, body: box); physicsSystem.SetBodyType(boxEnt, BodyType.Dynamic, body: box); Assert.That(box.InvI, Is.GreaterThan(0f)); diff --git a/Robust.UnitTesting/Shared/Physics/PhysicsMap_Test.cs b/Robust.UnitTesting/Shared/Physics/PhysicsMap_Test.cs index 67756de12..def98fbb7 100644 --- a/Robust.UnitTesting/Shared/Physics/PhysicsMap_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/PhysicsMap_Test.cs @@ -43,7 +43,7 @@ public sealed class PhysicsMap_Test physSystem.SetBodyType(parent, BodyType.Dynamic); physSystem.SetSleepingAllowed(parent, parentBody, false); - fixtureSystem.CreateFixture(parent, new Fixture("fix1", new PhysShapeCircle(0.5f), 0, 0, false), body: parentBody); + fixtureSystem.CreateFixture(parent, "fix1", new Fixture(new PhysShapeCircle(0.5f), 0, 0, false), body: parentBody); physSystem.WakeBody(parent); Assert.That(physicsMap.AwakeBodies, Does.Contain(parentBody)); @@ -52,7 +52,7 @@ public sealed class PhysicsMap_Test physSystem.SetBodyType(child, BodyType.Dynamic); physSystem.SetSleepingAllowed(child, childBody, false); - fixtureSystem.CreateFixture(child, new Fixture("fix1", new PhysShapeCircle(0.5f), 0, 0, false), body: childBody); + fixtureSystem.CreateFixture(child, "fix1", new Fixture(new PhysShapeCircle(0.5f), 0, 0, false), body: childBody); physSystem.WakeBody(child, body: childBody); Assert.That(physicsMap.AwakeBodies, Does.Contain(childBody)); diff --git a/Robust.UnitTesting/Shared/Physics/Stack_Test.cs b/Robust.UnitTesting/Shared/Physics/Stack_Test.cs index a1911a9d3..713aef0ba 100644 --- a/Robust.UnitTesting/Shared/Physics/Stack_Test.cs +++ b/Robust.UnitTesting/Shared/Physics/Stack_Test.cs @@ -76,10 +76,10 @@ public sealed class PhysicsTestBedTest : RobustIntegrationTest var groundManager = entityManager.EnsureComponent(groundUid); var horizontal = new EdgeShape(new Vector2(-40, 0), new Vector2(40, 0)); - fixtureSystem.CreateFixture(groundUid, new Fixture("fix1", horizontal, 1, 1, true), manager: groundManager, body: ground); + fixtureSystem.CreateFixture(groundUid, "fix1", new Fixture(horizontal, 1, 1, true), manager: groundManager, body: ground); var vertical = new EdgeShape(new Vector2(10, 0), new Vector2(10, 10)); - fixtureSystem.CreateFixture(groundUid, new Fixture("fix2", vertical, 1, 1, true), manager: groundManager, body: ground); + fixtureSystem.CreateFixture(groundUid, "fix2", new Fixture(vertical, 1, 1, true), manager: groundManager, body: ground); physSystem.WakeBody(groundUid, manager: groundManager, body: ground); @@ -109,7 +109,7 @@ public sealed class PhysicsTestBedTest : RobustIntegrationTest new(-0.5f, -0.5f), }); - fixtureSystem.CreateFixture(boxUid, new Fixture("fix1", poly, 1, 1, true), manager: manager, body: box); + fixtureSystem.CreateFixture(boxUid, "fix1", new Fixture(poly, 1, 1, true), manager: manager, body: box); physSystem.WakeBody(boxUid, manager: manager, body: box); bodies[j * rowCount + i] = box; @@ -182,10 +182,10 @@ public sealed class PhysicsTestBedTest : RobustIntegrationTest var groundManager = entityManager.EnsureComponent(groundUid); var horizontal = new EdgeShape(new Vector2(-40, 0), new Vector2(40, 0)); - fixtureSystem.CreateFixture(groundUid, new Fixture("fix1", horizontal, 1, 1, true), manager: groundManager, body: ground); + fixtureSystem.CreateFixture(groundUid, "fix1", new Fixture(horizontal, 1, 1, true), manager: groundManager, body: ground); var vertical = new EdgeShape(new Vector2(10, 0), new Vector2(10, 10)); - fixtureSystem.CreateFixture(groundUid, new Fixture("fix2", vertical, 1, 1, true), manager: groundManager, body: ground); + fixtureSystem.CreateFixture(groundUid, "fix2", new Fixture(vertical, 1, 1, true), manager: groundManager, body: ground); physSystem.WakeBody(groundUid, manager: groundManager, body: ground); @@ -210,7 +210,7 @@ public sealed class PhysicsTestBedTest : RobustIntegrationTest physSystem.SetLinearDamping(circle, 0.05f); physSystem.SetBodyType(circleUid, BodyType.Dynamic, manager: manager, body: circle); shape = new PhysShapeCircle(0.5f); - fixtureSystem.CreateFixture(circleUid, new Fixture("fix1", shape, 1, 1, true), manager: manager, body: circle); + fixtureSystem.CreateFixture(circleUid, "fix1", new Fixture(shape, 1, 1, true), manager: manager, body: circle); physSystem.WakeBody(circleUid, manager: manager, body: circle); bodies[j * rowCount + i] = circle;