JirkaDellOro / FUDGE

Furtwangen University Didactic Game Editor
https://jirkadelloro.github.io/FUDGE
MIT License
33 stars 27 forks source link

Force overcomes rigidbodies #350

Open JirkaDellOro opened 1 year ago

JirkaDellOro commented 1 year ago

Depending on the shape of the collider, a high mass and gravity pushes it through a static collider. I assume, that happens with other forces as well. I created a little test, see attachment. MassTest.zip

Manipulate lines 33 and 38 of Internal.json to adjust start conditions, adjust mass with the input field in the upper left corner at runtime when the body is at rest.

This is a problem, since creating e.g. airplanes or tanks with realistic masses cannot park on the ground...

Dev-MarkoF commented 1 year ago

The simulation can be improved by increasing the solverIterations of the physics scene, or choose a different correction algorithm as described in the physics settings. The defaults are not good enough when it comes to calculate complex simulations where forces overcome a threshhold within one frame since there is no continous collision but discrete steps.

The quality does reach it's limits, i noticed, at around 50k iterations vs. 1000 tons, there is no increase in quality and other problems start to occure, especially in rotations. But these values would be enough for planes (maximum 640 tons and tanks 60 tons), where not too many objects are in the scene.

Now, that the precision in general is lacking, because of calculation shortcuts that allow it to not recalculate too many steps, fully, but partial, with bias, is a caveat of OIMO that i mentioned initially in choosing the engine. There are certain "improvements" in the inner workings that allow it to be fast and accurate in many use cases, but nearly useless in others, while others lack performance, or feasable integration in the systems of FUDGE. In case you can to make a realistic flight simulator based on accurate values, then i should probably look into bullet physics (binding library) again, or give physx (binding library) another try, since it got open sourced.

Within OIMO is suspect it's an issue of small values not being discarded, but kinda accumulated, resulting in many behaviours of low weight bodies or so it seems. With high mass, things like friction/restitution come close to 0, in the interaction with other massive objects (i.e. static), same goes for rotations (since when a supermassive body is falling of the edge it's also not correctly calculated in OIMO). I will look into it, but i'm starting to suspect that you expect more from a simple javascript engine than it can handle, and than FUDGE initially was in need of.

I can see the potential problem here in the described use case, but there is the option of scaling the whole system to a smaller factor to circumenvent most of the issue.

JirkaDellOro commented 1 year ago

I tinkered around with the solverIterations before and noticed the impact. I was hesitant to jank it up that much, expecting performance problems.

With "choosing a different algorithm" do you mean Physics.settings.defaultConstraintSolverType? That looka applicable to joints only.

Dev-MarkoF commented 1 year ago

settings.defaultCorrectionAlgorithm, it's either 0,1,2 for Baumgarte, Split-Impulse, non-linear Gaus-Seidel. Each with their own caveats. The jointConstraintType is only for joints, the other one is for general constraints.

OIMO is calling everything influencing the body outside of forces a constraint, since bodies "constrain" another body to not go through it. A contact is therefore a "contactConstraint" and if bodies are touching a default "PositionCorrectionAlgorithm" is used unless, the penetration is too deep, then it seems to always fallback to Split_Impulse. The fallback is influenced by OIMO.Setting.alternativeContactPositionCorrectionAlgorithm, which is not exposed in FUDGE since it's normally not needed.

OIMO solver iterations is tricky, since it does not actually do full iterations of the whole world, which is one of the reasons the precision is lacking, it's doing pseudo steps per island (group of bodies). So increasing the iterations in any other engine is severly influencing the performance. In OIMO it can safely be cranked up by a lot more until you notice a better simulation and a worse performance.

As said OIMO is lacking, but is to this day, the best option for easy integration, since the way it's programmed are not so biased towards specific ways things need to be set up to work, e.g. wasm binaries, transform vs physics etc. But it takes a lot of shortcuts to achieve what it does, which result in wrong behaviour beyond a certain point, partically because of floating point precision problems within javascript, which need to be caught but don't seem to be.

I will look into it, but it's really easier to work with small numbers, and scale whole scenes towards those. Meaning treat 10 maybe as 1 ton, same goes for restitutions/friction, scaling them accordingly to what is set as "heavy"

Dev-MarkoF commented 1 year ago

Update: Currently not so sure anymore that it is an OIMO problem or a problem of the communication between OIMO and FUDGE. Since the OIMO demo scenes seem stable with masses up to 300 tons * Math.random and also random restitutions. They also run on javascript so it's not a floating preceision problem, but they run only on OIMO+OIMO Debug Draw, so no outside communication with an external Framework/Engine.

Could be that FUDGE is somehow returning wrong values to OIMO that is introducing these problems, because of the interaction of transforms/rigidbodies.

Tbh. the problem seems to be something within the communication. My Fudgeball example https://github.com/Dev-MarkoF/FudgeBall_FudgePhysicsExample from a while ago with an older Fudge build works perfectly with changing the weights to well above multiple millions of kg (on only 10 physics iterations per frame), while also using my newest OIMO build. But still investigating.

Dev-MarkoF commented 1 year ago

Update: I'm still on it, but this seems to be a tough one.

I can not reproduce it within the OIMO Demos no matter the weight, or shape. I can reproduce it on FudgeBall_Example from April 2021, although with higher values than in the initial example. Also it only happens on shapes that are not spheres. Seemingly the player was unaffected while the "ball", as a box with heigh weight did fall through, which is an oddity i need to look at, since the player is a dynamic box in that game. I can easily reproduce it in your example also on every shape that is not a sphere.

In all 3 i use the same OIMO Version i used in the demos. Which leads to two conclusions, there are probably miscalculations within the implementation and as a result of it in the handling of the collision shape / inertia. That is not the case for spheres which can not be squished in their shape, they are always a perfect ball and therefore the inertia is always in the middle, which also makes a lot of physics calculations easier.

JirkaDellOro commented 1 year ago

So when I understand you correctly, you can take my MassTest and run it with different versions of FUDGE with different results. In that case, it should be possible (e.g. using Git Bisect) to find the commit that introduced the problem.

Dev-MarkoF commented 1 year ago

Did that, but it was never worked the way OIMO Demos (Demos that are independent of Fudge, therefore no outside transform is interfering). There was always a problem above certain weights, only the weight was higher, going back to 2020-2021, because of that have to find the actual root of the problem.

Since it sits somewhere between OIMO and Fudge, and it's a shape specific problem, i at least get closer to solving it. But i can only spare so much time for this, it takes time, just wanted to keep you posted.

JirkaDellOro commented 1 year ago

No haste... Is it possible, that the simulation step, the timing is a cause?