Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

Ball rolling on mesh hits edges.

Discussion in 'Physics for ECS' started by Sibz9000, Nov 6, 2019.

  1. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    149
    I am just using the plane mesh for now. I am using ApplyLinearImpulse to move a ball (sphere shape) forward. With the mesh collider on my plane, the ball hits the inner edges and bounces up a little. I have set Restitution to 0 for both Physics Shapes, and it's minimal but still noticeable. I also have linear damping set to 0 as I want my ball to free roll.
    It appears as if it's hitting the edges. Almost as if for a moment in between faces, it drops down due to gravity for a fraction and gets knocked up again. problem worsens with velocity.

    Anyone know why this could be happening, and even better a solution?
     
    Last edited: Nov 6, 2019
  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    This problem is due to speculative contacts created from Unity Physics' approach to continuous collision detection.
    See the Speculative CCD section here (https://docs.unity3d.com/Manual/ContinuousCollisionDetection.html) for equivalent information from the land of GameObjects.

    The ModifyNarrowphaseContacts sample (https://github.com/Unity-Technologi...er/UnityPhysicsSamples/Assets/Demos/5. Modify) shows a why to 'weld' triangles so the contacts are appropriate for a plane. Another option, for an undulating mesh terrain, would to turn the edge collision to point in the direction of the face normal instead.

    This fix up approach to triangle edge collisions can also be removed with the Havok Physics (https://docs.unity3d.com/Packages/com.havok.physics@0.1/manual/quickstart.html) simulation backend. Specifically see the brief 'Contact Point Welding' section in the configuration section of the docs (https://docs.unity3d.com/Packages/com.havok.physics@0.1/manual/configuration.html)
     
    tertle and Sibz9000 like this.
  3. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    149
    @steveeHavok Thank you for the informative reply.

    I think I understand the issue well now.
    The collision detection in Unity.Physics uses a continuous approach, it 'looks ahead' a fraction to detect a future collision and keeps the velocity the same until then. When traversing between two different triangles, it will look ahead and get the next triangle, then get the contact point. This contact point will be the edge, and is used to calculate the physics from. Because the edge has a normal direction perpendicular to face normal, the physics is calculated from this edge normal. Thus causes a little change in velocity which is seen as my ball 'bumping' over the joins.

    I think I understand the fix too:
    During the narrow phase, alter the contact information to change the normal to the face normal. This would be a slightly different from the example in:
    https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/UnityPhysicsSamples/Assets/Demos/5. Modify/Scripts/ModifyNarrowphaseContactsBehaviour.cs
    As we would need to use the face normal. The example uses the predefined surface normal, which would work fine but only for surfaces with a uniform surface normal - aka flat surface.

    I'll have a go and post back my results. Please update me if I have got anything wrong.
     
    Last edited: Nov 7, 2019
    steveeHavok likes this.
  4. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    149
    Not sure I got this right. I was expecting normals for edges to be -forward, and surface to be up.
    A normal detected before a 'bump' was float3(0f, 0.9456903f, -0.3250691f). So perhaps it's a computed normal. I went ahead and set to the surface normal (in my case up - just testing flat mesh) and no change.

    I am using code written base on the example on so far it's just to test, but in my ModifyNormalsJob I have this instead:

    Code (CSharp):
    1.  
    2. if ((contactHeader.Entities.EntityA.Equals(TargetEntity)
    3.      || contactHeader.Entities.EntityB.Equals(TargetEntity))
    4.       && contactHeader.Normal.y< 0.9999f)
    5. {
    6.     UnityEngine.Debug.Log(
    7.         $"Not Normal {contactPoint.Index}: {contactHeader.Normal}"+
    8.         $"Distance: { contactPoint.Distance}\n"+
    9.         $"PositionA: {math.round(contactPoint.Position * 10000)/ 10000}");
    10.  
    11.     var newNormal = new float3(0, 1, 0);
    12.     var distanceScale = math.dot(newNormal, contactHeader.Normal);
    13.     contactHeader.Normal = newNormal;
    14.     contactPoint.Distance *= distanceScale;
    15. }
    16.  
    With example output:
    Now, I tested with a box shape with 0 Bevel, and 0 friction. And it smoothly transitions across the edges, unlike before this script where it would tumble.
    Also went back to sphere shape, with 0 friction and bingo, it is smooth. However, If I add friction so it rolls, I get the bumping back again.
    So now we're having an issue with only rolling across these edges. Sliding is fine.
     
    Last edited: Nov 7, 2019
  5. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    149
    I conceded, Havok is working just fine. Glad it's free for personal/plus users.
     
  6. mpforce1

    mpforce1

    Joined:
    Apr 4, 2014
    Posts:
    34
    Hello, do you know how to go about finding the appropriate face normal for any given contact data? I've looked into that myself and was unable to figure it out.
     
  7. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    149
    I didn't get that far, but I had a quick look and couldn't see how, my best guess was going to raycast a bit further forward in the direction of movement, but then that isn't available either. so have to pass in list of PhysicVelocity Components and their respective entities to look up from the entity pair, and that's just to get the velocity. Next have to raycast, so need to pass in the PhysicsWorld. IMO this might be too much processing to be done here for anthing but a small scale simulation.
     
  8. mpforce1

    mpforce1

    Joined:
    Apr 4, 2014
    Posts:
    34