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!)
[v1] Sphere falling through StaticMesh with CCD
[v1] Sphere falling through StaticMesh with CCD
- Attachments
-
- ThroughGround.png (25.55 KiB) Viewed 40226 times
Re: [v1] Sphere falling through StaticMesh with CCD
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.
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.
Re: [v1] Sphere falling through StaticMesh with CCD
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 Single sided, softness 0.0, 1/60 time step, allowed penetration 0.0
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
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.
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 Single sided, softness 0.0, 1/60 time step, allowed penetration 0.0
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
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.
Re: [v1] Sphere falling through StaticMesh with CCD
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.When you say stepped 5 times, do you mean reduce the solvers iteration limit to 5?
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.
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.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.
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.
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.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.
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.
Re: [v1] Sphere falling through StaticMesh with CCD
Understood, thanks for the clarification.
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.
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
Re: [v1] Sphere falling through StaticMesh with CCD
Sometimes I forget how v1 works
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.)
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.)