How to deal with ComputePenetration beyond 50% penetration

I have a use case where spherical projectiles collider with surfaces, and then grow. As the sphere grows, I’m using ComputePenetration to “unstick” it from the surface. In other words, as it grows it pushes itself out of any surfaces.

This generally works, except in cases where the collision causes the object to begin its life just a little too close to the wall. Or more specifically, just beyond the half way point into the wall. Once a sphere is more than 50% of the way through a surface, ComputePenetration no longer provides any results.

For example, here’s a sphere that’s almost 50% of the way into the floor. ComputePenetration provides reasonable results for moving this sphere back into the room:

3565713--287369--upload_2018-7-16_10-19-12.png

However, if I push the sphere just a little further into the floor, ComputePenetration no longer gives results, so the object remains there:

3565713--287370--upload_2018-7-16_10-20-0.png

Obviously it would be ideal if the spheres could never begin life just beyond the half way point like this, but I’d prefer not to make that assumption.

I considered an approach of using raycasting between opposite points along the diameter of the sphere, instead of using ComputePenetration, but choosing the right endpoints is tricky, since the sphere could be touching a wall/floor/ceiling/anything, and potentially multiple objects at once.

Is there some clever way to identify that the sphere has gone beyond the half way point using ComputePenetration? It’s worth noting that Physics.OverlapSphere returns true even in the >50% penetration case, so it’s surprising to me that ComputePenetration gives up.

That’s surprising to me too. I’d recommend you to file a bug, but I have the suspicion that ComputePenetration will work that way by design.

Are you using Continous Collision Detection for the projectiles? Maybe the starting point is better placed that way.

The starting point is determined using a raycast hit against the surface. However, maybe due to very small floating point inaccuracies, sometimes the hit.point seems to be just barely beyond the 50% mark, so if I instantiate the sphere there ComputePenetration doesn’t yield any results, and it stays embedded in the wall.

For now, I’m faking it by taking hit.point, and then backtracking just a bit from that point (like .01 units), and instantiating the sphere there. But I assume that will have some weird edge case issues at times.

Hard to say whether the 50% issue is a bug, or expected behavior. The docs do say something about not querying backfaces, so this is probably expected.

Hello,

Have you found any solution for this?
Or reported as a bug may be?

Nope. I’m still doing what I mentioned I would do: Spawning the spherical object a tiny bit away from the surface it hit (0.01 units away) instead of directly on the surface. This works for me, since the object spawns more or less when a projectile strikes the surface, and its easy to know the direction of the projectile, and to pull it back a tiny bit from the wall. This works fine for me.

It doesn’t seem like I ever reported this as a bug, so I don’t know if this is expected behavior or a bug. Probably expected behavior, so you might want to look for a workaround.

Thank you for the answer!
I’m required to make Overlap for such situations. Too many and too complex colliders.
And now I’m submitting a bug report about this. May be it is ‘expected behavior’ but it makes function almost useless to work with concave mesh. Will see what will be Unity decision.

For everyone still encounters this I finally submitted bug report:
https://fogbugz.unity3d.com/default.asp?1385191_r7rsvj2flo90mb4f

1 Like

For everyone who require this to be fixed.
The bug was moved to ‘issues’ by Unity support team.

Please vote for it to be fixed!
https://issuetracker.unity3d.com/issues/physics-dot-computepenetration-does-not-detect-overlap-consistently-when-using-convex-mesh-colliders

Update:
Initial bug was combines with this issue:

And it’s marked as ‘Fixed’ recently.

But it is NOT fixed for our part of the case.
Overlap on the half way inside mesh is still bug.

I’ve submitted new bug report about it:
https://unity3d.atlassian.net/servicedesk/customer/portal/2/IN-14809

1 Like

Update:

I’ll try to explain this… Our issue was combined with other one. But other was chosen as main example while our had 20 votes in tracker and other was invisible. And other finally fixed.
(Generally I’ve allready written about it.)

Our issue is still bug.

It was reopened after revision with ‘0’ votes.
Hope it will be fixed faster than 10 months of previous one…

Vote for it to be fixed here:

Indeed, i don’t think this is a bug. This happens because the sphere center sees the backface of the mesh. Also, this is why a rigidbody that hits a back face (penetration = 0) doesn’t get pushed away.

ComputePenetration is intended to be used as a way to fix an already good enough movement prediction. If for some reason the body ends up 50% inside an obstacle, then it is game over. Normally, if you handle movement by yourself (e.g. doing a bunch of casts), you would expect a small penetration that could range from 0 to “contact offset” units, no more than that.

At runtime this half-inside-the-plane sphere will bounce off the plane.
So core of the physics behave correctly while ComputePenetration not.
So it is a bug.

Let me explain a bit more.
For example in strategy game I need to check position for new building. Can player place it here or not?
This function is required to be 100% correct in all cases not only for movements.

Well, i made a simple test :slight_smile: :
A plane + 2 x 3 spheres. I’ve got two rows of 3 spheres each (yellow red and blue). One row contains dynamic rigidbodies (no gravity) and the other row has kinematic rigidbodies + RemovePenetration (script).
Yellow sphere → y = 0.0001
Red sphere → y = 0 (same as plane y)
Blue sphere → y = - 0.0001
Plane (ground) → y = 0
8503910--1132535--upload_2022-10-10_18-2-14.gif

As you can see, both rows of spheres behave the same.

Luckily for me :smile:, in this particular test, the results were as i predicted. However, this does not mean this works everytime. In fact, I tested the same thing half an hour later like 10 times and it was super random. Penetration was sometimes detected and sometimes it wasn’t. In other cases, the dynamic body was being pushed while the kinematic wasn’t detecting anything (there were both at the same height).

For example, have a look at this:
8503910--1132577--upload_2022-10-10_18-52-2.gif

The plane from before isn’t being detected at all by the red spheres. Btw, i haven’t touched anything :eyes:

In a way, i was expecting this to happen because the sphere position is way inside the obstacle.

1 Like

Sorry, I mentioned movement as a general concept. What i really meant was to represent the shape that you want as best as possible before projecting it onto a surface (a raycast for a projectile, a capsule/box for a character, etc)

Are you using a single raycast for that?

First of all thank you for testing and great visualization.

Think I got it. I think you miss a bit one thing that ComputePenetration is using for every type of colliders.

And in my example with strategy it is required to test:

  1. Convex MeshCollider for complex building.
  2. Concave MeshCollider for ground with mountains.

Workaround with raycast in this case is more difficult than write own ComputePenetration :slight_smile: If precision is required.

If performance is required it is even more important to have correct internal function which has access to triangles of MechCollider which we haven’t.

It is only example also. There are a lot of such cases in action with physics usage and so.
And as I mentioned core of physics at runtime deals with all of it absolutely correctly while ComputePenetration not.

This is by design.

These functions only compute an approximate depenetration vector, and work best when the amount of overlap between the geometry object and the mesh/heightfield is small. In particular, an intersection with a triangle will be ignored when the object’s center is behind the triangle, and if this holds for all intersecting triangles then no overlap is detected, and the functions do not compute an MTD vector.

2 Likes

It works correctly in run-time physics. And not from script. So it is definitely bug.

BTW this issue still requires votes:
https://issuetracker.unity3d.com/issues/physics-dot-computepenetration-returns-false-when-two-colliders-overlap

Seems like it by design after all. Will not be fixed.