Search Unity

How to deal with ComputePenetration beyond 50% penetration

Discussion in 'Physics' started by dgoyette, Jul 16, 2018.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    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:

    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:

    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.
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    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.
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    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.
     
  4. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    Hello,

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

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    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.
     
  6. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    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.
     
  7. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    kana1939 likes this.
  8. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
  9. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    Last edited: Aug 25, 2022
    Edy likes this.
  10. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    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:
    https://issuetracker.unity3d.com/is...tion-returns-false-when-two-colliders-overlap
     
  11. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    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.
     
    Last edited: Oct 10, 2022
  12. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    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.
     
  13. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    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.
     
    Last edited: Oct 10, 2022
  14. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    Well, i made a simple test :) :
    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
    upload_2022-10-10_18-2-14.gif

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

    Luckily for me :D, 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:
    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 o_O

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

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    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?
     
  16. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    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 :) 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.
     
    Last edited: Oct 11, 2022
  17. kana1939

    kana1939

    Joined:
    Jan 4, 2022
    Posts:
    13
  18. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    Last edited: Jan 13, 2024
  19. Santa

    Santa

    Joined:
    Dec 4, 2009
    Posts:
    42
    Seems like it by design after all. Will not be fixed.