Skip to content

Commit

Permalink
Contact changes (#3946)
Browse files Browse the repository at this point in the history
  • Loading branch information
metalgearsloth authored Apr 20, 2023
1 parent e845233 commit b582b31
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 37 deletions.
3 changes: 3 additions & 0 deletions Robust.Shared/Physics/Dynamics/Contacts/Contact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public sealed class Contact : IEquatable<Contact>
/// </summary>
public readonly LinkedListNode<Contact> BodyBNode;

public EntityUid EntityA;
public EntityUid EntityB;

public Fixture? FixtureA;
public Fixture? FixtureB;

Expand Down
1 change: 1 addition & 0 deletions Robust.Shared/Physics/Dynamics/Fixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public string ID
[DataField("shape")]
public IPhysShape Shape { get; private set; } = new PhysShapeAabb();

[Obsolete("Use other means to obtain the PhysicsComponent for the fixture.")]
[ViewVariables]
[field:NonSerialized]
public PhysicsComponent Body { get; internal set; } = default!;
Expand Down
5 changes: 4 additions & 1 deletion Robust.Shared/Physics/Events/EndCollideEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ namespace Robust.Shared.Physics.Events;
[ByRefEvent]
public readonly struct EndCollideEvent
{
public readonly EntityUid OurEntity;
public readonly EntityUid OtherEntity;

public readonly Fixture OurFixture;
public readonly Fixture OtherFixture;

public EndCollideEvent(Fixture ourFixture, Fixture otherFixture)
public EndCollideEvent(EntityUid ourEntity, EntityUid otherEntity, Fixture ourFixture, Fixture otherFixture)
{
OurFixture = ourFixture;
OtherFixture = otherFixture;
Expand Down
7 changes: 6 additions & 1 deletion Robust.Shared/Physics/Events/StartCollideEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ namespace Robust.Shared.Physics.Events;
[ByRefEvent]
public readonly struct StartCollideEvent
{
public readonly EntityUid OurEntity;
public readonly EntityUid OtherEntity;

public readonly Fixture OurFixture;
public readonly Fixture OtherFixture;
public readonly Vector2 WorldPoint;

public StartCollideEvent(Fixture ourFixture, Fixture otherFixture, Vector2 worldPoint)
public StartCollideEvent(EntityUid ourEntity, EntityUid otherEntity, Fixture ourFixture, Fixture otherFixture, Vector2 worldPoint)
{
OurEntity = ourEntity;
OtherEntity = otherEntity;
OurFixture = ourFixture;
OtherFixture = otherFixture;
WorldPoint = worldPoint;
Expand Down
2 changes: 1 addition & 1 deletion Robust.Shared/Physics/Systems/SharedBroadphaseSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ private void HandleGridCollisions(
var otherAABB = otherFixture.Shape.ComputeAABB(otherTransform, j);

if (!fixAABB.Intersects(otherAABB)) continue;
_physicsSystem.AddPair(fixture, i, otherFixture, j, ContactFlags.Grid);
_physicsSystem.AddPair(grid.Owner, colliding.Owner, fixture, i, otherFixture, j, ContactFlags.Grid);
break;
}
}
Expand Down
75 changes: 41 additions & 34 deletions Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,21 @@ public Contact Create()

public bool Return(Contact obj)
{
SetContact(obj, null, 0, null, 0);
SetContact(obj, EntityUid.Invalid, EntityUid.Invalid, null, 0, null, 0);
return true;
}
}

private static void SetContact(Contact contact, Fixture? fixtureA, int indexA, Fixture? fixtureB, int indexB)
private static void SetContact(Contact contact, EntityUid uidA, EntityUid uidB, Fixture? fixtureA, int indexA, Fixture? fixtureB, int indexB)
{
contact.Enabled = true;
contact.IsTouching = false;
contact.Flags = ContactFlags.None;
// TOIFlag = false;

contact.EntityA = uidA;
contact.EntityB = uidB;

contact.FixtureA = fixtureA;
contact.FixtureB = fixtureB;

Expand Down Expand Up @@ -174,7 +177,7 @@ private void InitializePool()
}
}

private Contact CreateContact(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB)
private Contact CreateContact(EntityUid uidA, EntityUid uidB, Fixture fixtureA, int indexA, Fixture fixtureB, int indexB)
{
var type1 = fixtureA.Shape.ShapeType;
var type2 = fixtureB.Shape.ShapeType;
Expand All @@ -188,11 +191,11 @@ private Contact CreateContact(Fixture fixtureA, int indexA, Fixture fixtureB, in
// 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, fixtureA, indexA, fixtureB, indexB);
SetContact(contact, uidA, uidB, fixtureA, indexA, fixtureB, indexB);
}
else
{
SetContact(contact, fixtureB, indexB, fixtureA, indexA);
SetContact(contact, uidB, uidA, fixtureB, indexB, fixtureA, indexA);
}

contact.Type = _registers[(int)type1, (int)type2];
Expand All @@ -203,10 +206,10 @@ private Contact CreateContact(Fixture fixtureA, int indexA, Fixture fixtureB, in
/// <summary>
/// Try to create a contact between these 2 fixtures.
/// </summary>
internal void AddPair(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB, ContactFlags flags = ContactFlags.None)
internal void AddPair(EntityUid uidA, EntityUid uidB, Fixture fixtureA, int indexA, Fixture fixtureB, int indexB, ContactFlags flags = ContactFlags.None)
{
PhysicsComponent bodyA = fixtureA.Body;
PhysicsComponent bodyB = fixtureB.Body;
var bodyA = fixtureA.Body;
var bodyB = fixtureB.Body;

// Broadphase has already done the faster check for collision mask / layers
// so no point duplicating
Expand All @@ -222,7 +225,7 @@ internal void AddPair(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB
return;

// Call the factory.
var contact = CreateContact(fixtureA, indexA, fixtureB, indexB);
var contact = CreateContact(uidA, uidB, fixtureA, indexA, fixtureB, indexB);
contact.Flags = flags;

// Contact creation may swap fixtures.
Expand Down Expand Up @@ -250,7 +253,7 @@ internal void AddPair(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB
/// </summary>
internal void AddPair(in FixtureProxy proxyA, in FixtureProxy proxyB)
{
AddPair(proxyA.Fixture, proxyA.ChildIndex, proxyB.Fixture, proxyB.ChildIndex);
AddPair(proxyA.Fixture.Body.Owner, proxyB.Fixture.Body.Owner, proxyA.Fixture, proxyA.ChildIndex, proxyB.Fixture, proxyB.ChildIndex);
}

internal static bool ShouldCollide(Fixture fixtureA, Fixture fixtureB)
Expand All @@ -270,8 +273,8 @@ public void DestroyContact(Contact contact)

if (contact.IsTouching)
{
var ev1 = new EndCollideEvent(fixtureA, fixtureB);
var ev2 = new EndCollideEvent(fixtureB, fixtureA);
var ev1 = new EndCollideEvent(aUid, bUid, fixtureA, fixtureB);
var ev2 = new EndCollideEvent(bUid, aUid, fixtureB, fixtureA);
RaiseLocalEvent(aUid, ref ev1);
RaiseLocalEvent(bUid, ref ev2);
}
Expand Down Expand Up @@ -326,8 +329,10 @@ internal void CollideContacts()
int indexA = contact.ChildIndexA;
int indexB = contact.ChildIndexB;

PhysicsComponent bodyA = fixtureA.Body;
PhysicsComponent bodyB = fixtureB.Body;
var bodyA = fixtureA.Body;
var bodyB = fixtureB.Body;
var uidA = contact.EntityA;
var uidB = contact.EntityB;

// Do not try to collide disabled bodies
if (!bodyA.CanCollide || !bodyB.CanCollide)
Expand Down Expand Up @@ -360,8 +365,8 @@ internal void CollideContacts()
continue;
}

var xformA = xformQuery.GetComponent(bodyA.Owner);
var xformB = xformQuery.GetComponent(bodyB.Owner);
var xformA = xformQuery.GetComponent(uidA);
var xformB = xformQuery.GetComponent(uidB);

if (xformA.MapUid == null || xformA.MapUid != xformB.MapUid)
{
Expand All @@ -372,8 +377,8 @@ internal void CollideContacts()
// Special-case grid contacts.
if ((contact.Flags & ContactFlags.Grid) != 0x0)
{
var gridABounds = fixtureA.Shape.ComputeAABB(GetPhysicsTransform(bodyA.Owner, xformA, xformQuery), 0);
var gridBBounds = fixtureB.Shape.ComputeAABB(GetPhysicsTransform(bodyB.Owner, xformB, xformQuery), 0);
var gridABounds = fixtureA.Shape.ComputeAABB(GetPhysicsTransform(uidA, xformA, xformQuery), 0);
var gridBBounds = fixtureB.Shape.ComputeAABB(GetPhysicsTransform(uidB, xformB, xformQuery), 0);

if (!gridABounds.Intersects(gridBBounds))
{
Expand All @@ -395,14 +400,14 @@ internal void CollideContacts()

if (indexA >= fixtureA.Proxies.Length)
{
_sawmill.Error($"Found invalid contact index of {indexA} on {fixtureA.ID} / {ToPrettyString(bodyA.Owner)}, expected {fixtureA.Proxies.Length}");
_sawmill.Error($"Found invalid contact index of {indexA} on {fixtureA.ID} / {ToPrettyString(uidA)}, expected {fixtureA.Proxies.Length}");
DestroyContact(contact);
continue;
}

if (indexB >= fixtureB.Proxies.Length)
{
_sawmill.Error($"Found invalid contact index of {indexB} on {fixtureB.ID} / {ToPrettyString(bodyB.Owner)}, expected {fixtureB.Proxies.Length}");
_sawmill.Error($"Found invalid contact index of {indexB} on {fixtureB.ID} / {ToPrettyString(uidB)}, expected {fixtureB.Proxies.Length}");
DestroyContact(contact);
continue;
}
Expand Down Expand Up @@ -470,15 +475,15 @@ internal void CollideContacts()

var fixtureA = contact.FixtureA!;
var fixtureB = contact.FixtureB!;
var bodyA = fixtureA.Body;
var bodyB = fixtureB.Body;
var uidA = contact.EntityA;
var uidB = contact.EntityB;
var worldPoint = worldPoints[i];

var ev1 = new StartCollideEvent(fixtureA, fixtureB, worldPoint);
var ev2 = new StartCollideEvent(fixtureB, fixtureA, worldPoint);
var ev1 = new StartCollideEvent(uidA, uidB, fixtureA, fixtureB, worldPoint);
var ev2 = new StartCollideEvent(uidB, uidA, fixtureB, fixtureA, worldPoint);

RaiseLocalEvent(bodyA.Owner, ref ev1, true);
RaiseLocalEvent(bodyB.Owner, ref ev2, true);
RaiseLocalEvent(uidA, ref ev1, true);
RaiseLocalEvent(uidB, ref ev2, true);
break;
}
case ContactStatus.Touching:
Expand All @@ -494,12 +499,14 @@ internal void CollideContacts()

var bodyA = fixtureA.Body;
var bodyB = fixtureB.Body;
var uidA = contact.EntityA;
var uidB = contact.EntityB;

var ev1 = new EndCollideEvent(fixtureA, fixtureB);
var ev2 = new EndCollideEvent(fixtureB, fixtureA);
var ev1 = new EndCollideEvent(uidA, uidB, fixtureA, fixtureB);
var ev2 = new EndCollideEvent(uidB, uidA, fixtureB, fixtureA);

RaiseLocalEvent(bodyA.Owner, ref ev1);
RaiseLocalEvent(bodyB.Owner, ref ev2);
RaiseLocalEvent(uidA, ref ev1);
RaiseLocalEvent(uidB, ref ev2);
break;
}
case ContactStatus.NoContact:
Expand Down Expand Up @@ -544,8 +551,8 @@ private void BuildManifolds(Contact[] contacts, int count, ContactStatus[] statu
var contact = contacts[i];
var bodyA = contact.FixtureA!.Body;
var bodyB = contact.FixtureB!.Body;
var aUid = bodyA.Owner;
var bUid = bodyB.Owner;
var aUid = contact.EntityA;
var bUid = contact.EntityB;

SetAwake(aUid, bodyA, true);
SetAwake(bUid, bodyB, true);
Expand Down Expand Up @@ -573,8 +580,8 @@ private void UpdateContacts(Contact[] contacts, int start, int end, ContactStatu
continue;
}

var uidA = contact.FixtureA!.Body.Owner;
var uidB = contact.FixtureB!.Body.Owner;
var uidA = contact.EntityA;
var uidB = contact.EntityB;
var bodyATransform = GetPhysicsTransform(uidA, xformQuery.GetComponent(uidA), xformQuery);
var bodyBTransform = GetPhysicsTransform(uidB, xformQuery.GetComponent(uidB), xformQuery);

Expand Down

0 comments on commit b582b31

Please sign in to comment.