Giter Site home page Giter Site logo

Comments (7)

mihe avatar mihe commented on June 10, 2024 2

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.

mihe avatar mihe commented on June 10, 2024 1

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.

mihe avatar mihe commented on June 10, 2024

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.

jrouwe avatar jrouwe commented on June 10, 2024

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.

mihe avatar mihe commented on June 10, 2024

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.

jrouwe avatar jrouwe commented on June 10, 2024

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.

mihe avatar mihe commented on June 10, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.