Comments (7)
The fix for this can now be found in the latest pre-release, 0.13.0-beta1, which you'll find here.
Note that this version targets the just recently released Godot 4.3-beta1, so won't work with Godot 4.2. Also note that this version is not available through the Godot Asset Library, so you'll need to download it through GitHub.
A proper release will be out some time around Godot 4.3-stable.
from godot-jolt.
I cooked up a tentative solution in #834, which seems to resolve the issue, by queueing up an OptimizeBroadPhase()
call for the next frame (call_deferred
) for any simulation that has bodies added/removed, but only if that simulation is not being actively stepped (i.e. editor stuff typically).
It's a fairly scary change, but I don't really see any other way out of this.
from godot-jolt.
I was wondering when this was gonna come back to haunt me.
The problem seems to be related to the fact that I never call Jolt's JPH::PhysicsSystem::OptimizeBroadPhase()
method, which means that physics queries within the editor end up traversing an incredibly inefficient broadphase (quadtree) and subsequently blows out its fixed-size stack of 128, resulting in largely arbitrarily broken results.
I had left this out somewhat deliberately, since at runtime the broadphase gets rebuilt/optimized at the first physics tick anyway, which seemed as good of a time as any to do it. The editor itself never actually steps its own simulation though, but I figured it wouldn't matter a whole lot if the editor queries were a bit slower than they should be. Obviously this ends up actually breaking things rather than just being slow though, so I'll need to do something about this.
Perhaps I can start/reset some quick timer whenever a new body is added to the scene and run OptimizeBroadPhase()
when it finishes.
I'd love to hear your thoughts on this @jrouwe.
from godot-jolt.
I'd love to hear your thoughts on this @jrouwe.
As an alternative to your current solution, you could also keep a simple counter that counts the number of bodies that got added since the last physics update and if it gets close to the danger zone (128 * 3) you could trigger the optimize call.
from godot-jolt.
I'm a bit hesitant to make assumptions about the particular broad-phase structure Jolt uses, but that is undoubtedly a less scary (and probably more robust) solution.
I figured since this is (and correct me if I'm wrong) theoretically also an issue at runtime (meaning we've likely run PhysicsSystem::Update
at some point) if someone decides to add a few hundred bodies, and then immediately perform a physics query on them, I would instead check the counter at the start of every physics query, as opposed to when bodies are added. I then reset the counter whenever OptimizeBroadPhase
or PhysicsSystem::Update
is run.
That way you shouldn't have any OptimizeBroadPhase
calls during normal runtime use unless absolutely necessary, but it will always run in the editor viewport as-needed if you're dealing with a few hundred bodies.
from godot-jolt.
I would instead check the counter at the start of every physics query, as opposed to when bodies are added. I then reset the counter whenever OptimizeBroadPhase or PhysicsSystem::Update is run.
That sounds like it will work (and apparently it did, given you just submitted the change 😄).
Another thing I just thought of is that you could delay the adding of bodies. Basically you would batch up BodyIDs in an array and you would call AddBodiesPrepare
/ AddBodiesFinalize
on the batch just before doing a collision check, before removing a body (it could be in the 'to add' list) or before stepping the simulation (and maybe a few other places). For the most part, the Jolt interface doesn't care if a body has been added or not (search for IsInBroadPhase
), the biggest thing is you can't activate a body before it has been added. Obviously this change is a bit bigger and riskier than the one you just did, but it is more efficient.
from godot-jolt.
Another thing I just thought of is that you could delay the adding of bodies. Basically you would batch up BodyIDs in an array and you would call AddBodiesPrepare / AddBodiesFinalize on the batch just before doing a collision check, before removing a body (it could be in the 'to add' list) or before stepping the simulation (and maybe a few other places). For the most part, the Jolt interface doesn't care if a body has been added or not (search for IsInBroadPhase), the biggest thing is you can't activate a body before it has been added. Obviously this change is a bit bigger and riskier than the one you just did, but it is more efficient.
I did contemplate deferring/batching the creation of the bodies, but I failed to realize that I could just defer/batch the adding of them instead. I do however suspect that it would complicate the logic surrounding the association between a body and its physics space/world/system, given that it could then be in three states (none/created/added) rather than two (none/added), but maybe not by much.
But yeah, deferring stuff in general is scary, and tends to be where bugs show up in my experience, hence why I also chose not to go with the previous call_deferred
solution.
I think this counter thing should be fine, even if it warrants some explanation in the code.
Thanks for the help!
from godot-jolt.
Related Issues (20)
- Increase precision of sliders for Contact Allowed Penetration and Contact Speculative Distance HOT 1
- Softbody properties cannot be changed HOT 3
- Double-Precision-Engine crashes upon loading project HOT 2
- CharacterBody-RigidBody collision is broken HOT 1
- Support for tapered capsule shape HOT 1
- GodotJolt is crashing the project and can't be opened in the editor, when Godot is a custom 4.2.2 build HOT 1
- JoltGeneric6DOFJoint3D angular limit gizmo not correct HOT 11
- Inconsistent behaviour between placed and instantiated `RigidBody3D` HOT 22
- Applying force/torque to `RigidBody3D` does not reset its sleep timer HOT 9
- Several crashes when running with fuzzer HOT 1
- `mouse_entered` and `mouse_exited` for CollisionObject3D do not work HOT 2
- Add support for AddressSanitizer HOT 1
- Improve doc for using a non-stable version of godot HOT 3
- Add CMake option for providing a custom extension API HOT 6
- version 0.13 beta1 doesnt open in brand new project HOT 4
- Can't lock all axes of `PhysicalBone3D` HOT 1
- Shape collision check methods return only one collision point per other collider HOT 1
- Crash when `SeparationRayShape3D` collides with compound shape HOT 8
- `body_test_motion` does not report recovery collisions HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from godot-jolt.