[v1] Sphere falling through StaticMesh with CCD

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
tomskuse
Posts: 3
Joined: Wed Nov 18, 2020 7:09 pm

[v1] Sphere falling through StaticMesh with CCD

Post by tomskuse »

I've been trying to make a golf like game in Unity using v1 BEPUphysics but have noticed on rare occasions the ball just falls completely through the static mesh ground (always on impact from a high, not while rolling along).

download/file.php?mode=view&id=360

The vast majoity of the time it bounces correctly and rolls off as expected. The only modification I have made is updated the libraries to target .Net framework 4.6. I have tried both v1.5.1 off GitHub and also the fixed point math version (https://github.com/sam-vdp/bepuphysics1int) - they both exhibit the same issue.

The ball is created using the Sphere class:
Radius 0.036322
Mass 0.148835
Angular/linear damping 0.0 (just for this test)
Friction 0.5
Bounciness 0.9
Position update mode continuous

Ground is created using the StaticMesh class:
Friction 0.5
Bounciness 0.5

Global:
DeactivationManager.VelocityLowerLimit 0.3
DeactivationManager.LowVelocityTimeMinimum 0.1
CollisionDetectionSettings.AllowedPenetration 0.0
Gravity {0.0f, -9.8, 0.0f}

I've also tried messing with the various settings in the MotionSettings class but haven't had any luck.

Any advice or suggestions would be massively appreciated! (I have a 2019.4 Unity test project if anyone fancies having a look!)
Attachments
ThroughGround.png
ThroughGround.png (25.55 KiB) Viewed 40226 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: [v1] Sphere falling through StaticMesh with CCD

Post by Norbo »

If I had to guess, it's related to the size of the ball, the timestep, and the default slight softness of collisions. If it hits hard enough, the constraint may not fully eliminate all penetrating velocity in one timestep. Once the object is in contact, CCD can't help, so if enough velocity is left over, it may tunnel.

1. Try setting CollisionResponseSettings.Softness to a lower value, maybe 0 for testing purposes.
2. Try a smaller timestep duration with more frequent timesteps to compensate. For example, 1/300 stepped 5 times instead of instead of 1/60 once.

Note that 0 softness and 0 AllowedPenetration will likely cause jitter. You may want to increase the allowed penetration to some small nonzero value.
tomskuse
Posts: 3
Joined: Wed Nov 18, 2020 7:09 pm

Re: [v1] Sphere falling through StaticMesh with CCD

Post by tomskuse »

Thank you for such a fast response!

CollisionResponseSettings.Softness did not seem to help the issue, but 1/300 did. When you say stepped 5 times, do you mean reduce the solvers iteration limit to 5?

Its working great now, but the added cost of reducing the time step hurts a bit - I run the entire simulation in advance to find out where the ball will end up for various gameplay reasons.

I tried stepping through the code, it's all a bit over my head, but I did notice that time of impact is calculated differently based on if the static mesh is double sided or not (StaticMeshPairHandler.cs line 146).

After changing StaticMesh.Sidedness to TriangleSidedness.Clockwise the ball no longer falls through the ground, even at 1/60, but the ball does occasionally sink into the static mesh for one frame.

I've added some extra debug visualisation, updating the rendered ball position on each Space.EndOfTimeStepUpdateables.Finishing callback. The ball's linear velocity is ~11ms.

Example of where it would go through the ground if double sided, but just intersects ground single sided
Double sided, softness 0.0, 1/60 time step, allowed penetration 0.0
DoubleSided.jpg
DoubleSided.jpg (17.25 KiB) Viewed 40219 times
Single sided, softness 0.0, 1/60 time step, allowed penetration 0.0
SingleSided.jpg
SingleSided.jpg (19.36 KiB) Viewed 40219 times

Example of how it correctly works the majority of the time when single sided
Single sided, softness 0.0, 1/60 time step, allowed penetration 0.0
WorkingWell.jpg
WorkingWell.jpg (15.5 KiB) Viewed 40218 times

Aside from reducing the time step, do you have any further advice on how I could reduce the intersection? I had hoped CCD would help with this.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: [v1] Sphere falling through StaticMesh with CCD

Post by Norbo »

When you say stepped 5 times, do you mean reduce the solvers iteration limit to 5?
No, just calling Space.Update() more frequently to compensate for the lower amount of time simulated per timestep. If you're using internal timestepping (Space.Update(dt)), it'll happen automatically.

The solver iteration count is the number of times constraints are evaluated per timestep. It won't have much impact on this behavior. If you use shorter timesteps, you can, however, reduce the number of velocity iterations to save some performance. Short timesteps are an extremely powerful stabilizer.
Its working great now, but the added cost of reducing the time step hurts a bit - I run the entire simulation in advance to find out where the ball will end up for various gameplay reasons.
While v1 isn't v2, I wouldn't expect a simulation of a single ball to take much time at all. If you're using multithreading, try using single threaded updates. Multithreading can't do much to help tiny simulations and actually just adds overhead due to the repeated thread synchronization.

For reference, in release mode, a single such 300hz step with 1 solver iteration should take around 20 microseconds in v1. Running several hundred such steps can still get expensive if they're run every frame, of course, but if you're seeing numbers dramatically higher than that something might be wonky.
Aside from reducing the time step, do you have any further advice on how I could reduce the intersection? I had hoped CCD would help with this.
CCD in v1 is based on an internal sphere test that should be 80% of the minimum radius of a shape by default. That will allow some intersection, but it should still stop soon enough to avoid falling through. The double sided case is apparently getting enough intersection despite zero softness that it's getting all the way through. I'm not entirely sure what's happening there.

In order to get a good idea of what's going on there, I'd probably need a minimal reproduction in the Demos to look at.
tomskuse
Posts: 3
Joined: Wed Nov 18, 2020 7:09 pm

Re: [v1] Sphere falling through StaticMesh with CCD

Post by tomskuse »

Norbo wrote: Thu Nov 19, 2020 7:06 pm Space.Update() more frequently to compensate for the lower amount of time simulated per timestep
Understood, thanks for the clarification.
Norbo wrote: Thu Nov 19, 2020 7:06 pm While v1 isn't v2, I wouldn't expect a simulation of a single ball to take much time at all
You are right, it really doesn't take long at all, I'm really pleased with the performance. Ideally I'm looking to run the whole simulation per frame (or every few frames) as the player adjusts their aim. Moving from 1/60 to 1/300 just adds more challenges to that goal.
Norbo wrote: Thu Nov 19, 2020 7:06 pm In order to get a good idea of what's going on there, I'd probably need a minimal reproduction in the Demos to look at.
As suggested I've made a demo within your BEPUphysicsDemos project (please see attached). I've set it up so it keeps firing a ball at the ground with specific conditions I copied from my Unity project that demonstrates the issue. Of course completely understand if you do not have time to take a look!
Attachments
SphereStaticMeshIssue.zip
(30.98 KiB) Downloaded 1391 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: [v1] Sphere falling through StaticMesh with CCD

Post by Norbo »

Sometimes I forget how v1 works :P

It's a numerical issue caused by the small scales involved. By default, there are thresholds configured to work well with sizes ranging from 0.5 to 10. Values significantly outside that will be more likely to encounter issues.

For a simulation primarily concerned with shapes of a different scale, you can use something like the demos ConfigurationHelper.ApplyScale function to adjust these thresholds. A value of 0.05 seems to work well for this simulation.

(This is one of those things that v2 simply doesn't care about for the most part.)
Post Reply