mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Fix static ent collision spawn (#5933)
* Fix static ent collision spawn * Fix test * cool
This commit is contained in:
@@ -294,6 +294,14 @@ public abstract partial class SharedPhysicsSystem
|
||||
DebugTools.Assert(!fixB.Contacts.ContainsKey(fixA));
|
||||
fixB.Contacts.Add(fixA, contact);
|
||||
bodB.Contacts.AddLast(contact.BodyBNode);
|
||||
|
||||
// If it's a spawned static ent then need to wake any contacting entities.
|
||||
// The issue is that static ents can never be awake and if it spawns on an asleep entity never gets a contact.
|
||||
// Checking only bodyA should be okay because if bodyA is the other ent (i.e. dynamic / kinematic) then it should already be awake.
|
||||
if (bodyA.BodyType == BodyType.Static && !bodyB.Awake)
|
||||
{
|
||||
WakeBody(uidB, body: bodyB);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Collision.Shapes;
|
||||
@@ -17,6 +18,61 @@ namespace Robust.UnitTesting.Shared.Physics;
|
||||
[TestFixture]
|
||||
public sealed class Broadphase_Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests that spawned static ents properly collide with entities in range.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStaticSpawn()
|
||||
{
|
||||
var sim = RobustServerSimulation
|
||||
.NewSimulation()
|
||||
.InitializeInstance();
|
||||
|
||||
var entManager = sim.Resolve<IEntityManager>();
|
||||
var fixtureSystem = entManager.System<FixtureSystem>();
|
||||
var physicsSystem = entManager.System<SharedPhysicsSystem>();
|
||||
|
||||
var (mapEnt, mapId) = sim.CreateMap();
|
||||
|
||||
var dynamicEnt = entManager.SpawnAtPosition(null, new EntityCoordinates(mapEnt, Vector2.Zero));
|
||||
var dynamicBody = entManager.AddComponent<PhysicsComponent>(dynamicEnt);
|
||||
physicsSystem.SetBodyType(dynamicEnt, BodyType.Dynamic, body: dynamicBody);
|
||||
|
||||
fixtureSystem.TryCreateFixture(dynamicEnt, new PhysShapeCircle(1f), "fix1", collisionMask: 10);
|
||||
physicsSystem.WakeBody(dynamicEnt, body: dynamicBody);
|
||||
|
||||
Assert.That(dynamicBody.Awake);
|
||||
|
||||
physicsSystem.SetAwake((dynamicEnt, dynamicBody), false);
|
||||
Assert.That(!dynamicBody.Awake);
|
||||
|
||||
// Clear move buffer
|
||||
entManager.System<SharedBroadphaseSystem>().FindNewContacts(
|
||||
entManager.GetComponent<PhysicsMapComponent>(mapEnt),
|
||||
entManager.GetComponent<MapComponent>(mapEnt).MapId);
|
||||
|
||||
var staticEnt = entManager.SpawnAtPosition(null, new EntityCoordinates(mapEnt, Vector2.Zero));
|
||||
var staticBody = entManager.AddComponent<PhysicsComponent>(staticEnt);
|
||||
physicsSystem.SetBodyType(staticEnt, BodyType.Static, body: staticBody);
|
||||
|
||||
fixtureSystem.TryCreateFixture(staticEnt, new PhysShapeCircle(1f), "fix1", collisionLayer: 10);
|
||||
physicsSystem.SetCanCollide(staticEnt, true);
|
||||
|
||||
Assert.That(!staticBody.Awake);
|
||||
Assert.That(staticBody.ContactCount, Is.EqualTo(0));
|
||||
|
||||
entManager.System<SharedBroadphaseSystem>().FindNewContacts(
|
||||
entManager.GetComponent<PhysicsMapComponent>(mapEnt),
|
||||
entManager.GetComponent<MapComponent>(mapEnt).MapId);
|
||||
|
||||
Assert.That(staticBody.ContactCount, Is.EqualTo(1));
|
||||
|
||||
physicsSystem.CollideContacts();
|
||||
|
||||
// Make sure it's actually marked as touching and not just "well it's in range right".
|
||||
Assert.That(staticBody.Contacts.First!.Value.IsTouching, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If we reparent a sundries entity to another broadphase does it correctly update.
|
||||
/// </summary>
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace Robust.UnitTesting.Shared.Physics
|
||||
var server = StartServer();
|
||||
await server.WaitIdleAsync();
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var fixtureSystem = server.ResolveDependency<IEntitySystemManager>()
|
||||
.GetEntitySystem<FixtureSystem>();
|
||||
var physicsSystem = server.ResolveDependency<IEntitySystemManager>()
|
||||
|
||||
Reference in New Issue
Block a user