bepu / bepuphysics2

Pure C# 3D real time physics simulation library, now with a higher version number.
Apache License 2.0
2.35k stars 272 forks source link

Detecting a collision #155

Closed Valdiralita closed 2 years ago

Valdiralita commented 3 years ago

I'm trying to create a kinematic entity (A) that can detect when another entity (B) is inside or intersecting with it. Like a trigger or sensor object, it doesn't interact with the other (dynamic or kinematic) entity B, that should be detected, in any way.

So I use the ConfigureContactManifold callback to see if there is a collision. Just assuming that we have a collision inside that function yields collisions for objects that dont collide. I've tried to add a check wether they really collide:

var hasNonNegativeContact = false;
for (var i = 0; i < manifold.Count; i++)
{
    if (manifold.GetDepth(ref manifold, i) >= 0)
    {
        hasNonNegativeContact = true;
        break;
    }
}
if(hasNonNegativeContact)
{
    // we have collided
}

That works for simple stuff, but if the entity B uses a mesh collider that check doesn't work.

I made two observations: 1: Sometimes there are more than 4 contacts and the contacts are "cleaned up" inside of unsafe void ChooseMostDistinct(NonconvexContactManifold* manifold, BufferPool pool) which reduces it to 4 contacts. In some cases it chooses the "wrong" contacts and only contacts with negative depth remain.

2: manifold.Count is 0 (Demo)

What would you recommend for filtering out non colliding entities?

RossNordby commented 3 years ago

2: manifold.Count is 0

Depending on what version you're using, this is likely caused by one of two things:

  1. Triangles are one sided; any contacts against the backside (or close enough to the backside) will not generate contacts. In this demo, the beam is inserted deeply enough that the shortest path out of the triangle is sideways, which may not generate a contact because the normal is perpendicular. More recent versions expanded the threshold to allow perfectly perpendicular contacts to be generated.
  2. MeshReduction removes contacts that are outside the original query bounds as a part of its efforts to avoid bumps. So even if contacts are generated, this configuration could still result in the contact being removed since it's on the edge of the triangle away from the box. I'd like to improve this heuristic in the future: https://github.com/bepu/bepuphysics2/issues/149

In some cases it chooses the "wrong" contacts and only contacts with negative depth remain.

Do you have a repro of this happening (contacts with positive depth which pass MeshReduction being removed in favor of only contacts with negative depth in NonconvexReduction)? This technically isn't impossible by design intent, but reduction should strongly favor depth.

What would you recommend for filtering out non colliding entities?

That depth test is the correct way to filter out speculative contacts.

Given that meshes are one sided and have no volume, you may want to consider using a convex decomposition instead.

RossNordby commented 3 years ago

As of 8a3461db2b1650f2a37d4b80f2b2d0566fcd82f3, the issue reproduced in the pastebin should be addressed. MeshReduction has been updated and no longer does the contact filtering step that was removing the contact.

Valdiralita commented 2 years ago

@RossNordby I can reproduce the issue with this updated Demo with the latest master eb10ea1b9e59c488c1306c72fa543312ad31243c. Just put a breakpoint in line 78.

RossNordby commented 2 years ago

Thanks for trying it; looks like there's a subsequent issue that b7566c2aa0bfa0ecb6b878bdf64e0a59dce86664 should help with.

Valdiralita commented 2 years ago

Thanks for trying it; looks like there's a subsequent issue that b7566c2 should help with.

I've tested the latest master (a5049c6cb06797a9bb3dfad9a6cb86775cf3f91b) and the issue is fixed! 🎉 Can't wait for the next release on nuget ;)