Skip to content

Commit

Permalink
Contact QOL stuff (space-wizards#5385)
Browse files Browse the repository at this point in the history
* Contact QOL stuff

Only just made the enumerator version need to test with AI branch had an IEnumerable before.

* Fix
  • Loading branch information
metalgearsloth authored Aug 25, 2024
1 parent 140767c commit 0bc3c51
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
23 changes: 23 additions & 0 deletions Robust.Shared/Physics/Dynamics/Contacts/Contact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,29 @@ public override int GetHashCode()
// TODO: Need to suss this out
return HashCode.Combine(EntityA, EntityB);
}

/// <summary>
/// Gets the other ent for this contact.
/// </summary>
public EntityUid OtherEnt(EntityUid uid)
{
if (uid == EntityA)
return EntityB;
else if (uid == EntityB)
return EntityA;

throw new InvalidOperationException();
}

public (string Id, Fixture) OtherFixture(EntityUid uid)
{
if (uid == EntityA)
return (FixtureBId, FixtureB!);
else if (uid == EntityB)
return (FixtureAId, FixtureA!);

throw new InvalidOperationException();
}
}

[Flags]
Expand Down
1 change: 1 addition & 0 deletions Robust.Shared/Physics/Systems/FixtureSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ internal void CreateFixture(
// Don't need to ResetMassData as FixtureUpdate already does it.
Dirty(uid, manager);
}

// TODO: Set newcontacts to true.
}

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 @@ -416,7 +416,7 @@ public void RegenerateContacts(EntityUid uid, PhysicsComponent body, FixturesCom
}
}

private void TouchProxies(EntityUid mapId, Matrix3x2 broadphaseMatrix, Fixture fixture)
internal void TouchProxies(EntityUid mapId, Matrix3x2 broadphaseMatrix, Fixture fixture)
{
foreach (var proxy in fixture.Proxies)
{
Expand Down
93 changes: 93 additions & 0 deletions Robust.Shared/Physics/Systems/SharedPhysicsSystem.Contacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using JetBrains.Annotations;
using Microsoft.Extensions.ObjectPool;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
Expand Down Expand Up @@ -741,6 +744,96 @@ protected bool ShouldCollide(

return true;
}

/// <summary>
/// Will destroy all contacts and queue for rebuild.
/// Useful if you have one that may no longer be relevant and don't want to destroy it directly.
/// </summary>
public void RegenerateContacts(Entity<PhysicsComponent?> entity)
{
if (!PhysicsQuery.Resolve(entity.Owner, ref entity.Comp))
return;

_broadphase.RegenerateContacts(entity.Owner, entity.Comp);
}

/// <summary>
/// Returns the number of touching contacts this entity has.
/// </summary>
/// <param name="ignoredFixtureId">Fixture we should ignore if applicable</param>
[Pure]
public int GetTouchingContacts(Entity<FixturesComponent?> entity, string? ignoredFixtureId = null)
{
if (!_fixturesQuery.Resolve(entity.Owner, ref entity.Comp))
return 0;

var count = 0;

foreach (var (id, fixture) in entity.Comp.Fixtures)
{
if (ignoredFixtureId == id)
continue;

foreach (var contact in fixture.Contacts.Values)
{
if (!contact.IsTouching)
continue;

count++;
}
}

return count;
}

/// <summary>
/// Returns all of this entity's contacts.
/// </summary>
[Pure]
public ContactEnumerator GetContacts(Entity<FixturesComponent?> entity)
{
_fixturesQuery.Resolve(entity.Owner, ref entity.Comp);
return new ContactEnumerator(entity.Comp);
}
}

public record struct ContactEnumerator
{
public static readonly ContactEnumerator Empty = new(null);

private Dictionary<string, Fixture>.ValueCollection.Enumerator _fixtureEnumerator;
private Dictionary<Fixture, Contact>.ValueCollection.Enumerator _contactEnumerator;

public ContactEnumerator(FixturesComponent? fixtures)
{
if (fixtures == null || fixtures.Fixtures.Count == 0)
{
this = Empty;
return;
}

_fixtureEnumerator = fixtures.Fixtures.Values.GetEnumerator();
_fixtureEnumerator.MoveNext();
_contactEnumerator = _fixtureEnumerator.Current.Contacts.Values.GetEnumerator();
}

public bool MoveNext([NotNullWhen(true)] out Contact? contact)
{
if (!_contactEnumerator.MoveNext())
{
if (!_fixtureEnumerator.MoveNext())
{
contact = null;
return false;
}

_contactEnumerator = _fixtureEnumerator.Current.Contacts.Values.GetEnumerator();
return MoveNext(out contact);
}

contact = _contactEnumerator.Current;
return true;
}
}

internal enum ContactStatus : byte
Expand Down

0 comments on commit 0bc3c51

Please sign in to comment.