Make phys contacts per-world rather than per-map (#3619)

This commit is contained in:
metalgearsloth
2022-12-28 13:54:36 +11:00
committed by GitHub
parent 360db24f0a
commit 6c4b71e06b
10 changed files with 615 additions and 703 deletions

View File

@@ -22,11 +22,15 @@
using System;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Physics.Systems;
using Robust.UnitTesting.Server;
namespace Robust.UnitTesting.Shared.Physics;
@@ -84,4 +88,47 @@ public sealed class Collision_Test
Assert.That(MathF.Abs(massData2.Mass - mass), Is.LessThan(20.0f * (absTol + relTol * mass)));
Assert.That(MathF.Abs(massData2.I - inertia), Is.LessThan(40.0f * (absTol + relTol * inertia)));
}
/// <summary>
/// Asserts that cross-map contacts correctly destroy
/// </summary>
[Test]
public void CrossMapContacts()
{
var sim = RobustServerSimulation.NewSimulation().InitializeInstance();
var entManager = sim.Resolve<IEntityManager>();
var mapManager = sim.Resolve<IMapManager>();
var fixtures = entManager.System<FixtureSystem>();
var physics = entManager.System<SharedPhysicsSystem>();
var xformSystem = entManager.System<SharedTransformSystem>();
var mapId = mapManager.CreateMap();
var mapId2 = mapManager.CreateMap();
var ent1 = entManager.SpawnEntity(null, new MapCoordinates(Vector2.Zero, mapId));
var ent2 = entManager.SpawnEntity(null, new MapCoordinates(Vector2.Zero, mapId));
var body1 = entManager.AddComponent<PhysicsComponent>(ent1);
physics.SetBodyType(body1, BodyType.Dynamic);
var body2 = entManager.AddComponent<PhysicsComponent>(ent2);
physics.SetBodyType(body2, BodyType.Dynamic);
fixtures.CreateFixture(body1, new Fixture(new PhysShapeCircle() { Radius = 1f }, 1, 0, true));
fixtures.CreateFixture(body2, new Fixture(new PhysShapeCircle() { Radius = 1f }, 0, 1, true));
physics.WakeBody(body1);
physics.WakeBody(body2);
Assert.That(body1.Awake && body2.Awake);
Assert.That(body1.ContactCount == 0 && body2.ContactCount == 0);
physics.Update(0.01f);
Assert.That(body1.ContactCount == 1 && body2.ContactCount == 1);
// Reparent body2 and assert the contact is destroyed
xformSystem.SetParent(ent2, mapManager.GetMapEntityId(mapId2));
physics.Update(0.01f);
Assert.That(body1.ContactCount == 0 && body2.ContactCount == 0);
}
}

View File

@@ -61,15 +61,13 @@ public sealed class GridMovement_Test : RobustIntegrationTest
physSystem.WakeBody(offGridBody);
// Alright just a quick validation then we start the actual damn test.
var physicsMap = entManager.GetComponent<PhysicsMapComponent>(mapManager.GetMapEntityId(mapId));
physSystem.Step(physicsMap, 0.001f, false);
physSystem.Update(0.001f);
Assert.That(onGridBody.ContactCount, Is.EqualTo(0));
// Alright now move the grid on top of the off grid body, run physics for a frame and see if they contact
entManager.GetComponent<TransformComponent>(grid.Owner).LocalPosition = new Vector2(10f, 10f);
physSystem.Step(physicsMap, 0.001f, false);
physSystem.Update(0.001f);
Assert.That(onGridBody.ContactCount, Is.EqualTo(1));
});