godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.06k stars 65 forks source link

Recognize "Godot Jolt" (Jolt Physics) as an officially endorsed add-on for 3D physics #7308

Open adamscott opened 10 months ago

adamscott commented 10 months ago

Describe the project you are working on

Godot Engine

Describe the problem or limitation you are having in your project

Maintaining a 3D physics engine is hard. Especially when you implement it from scratch.

Implementing a new engine was needed. In Godot 3.x, Godot used to handle it's physics with the Bullet physics engine, but too many issues riddled the general purpose engine, enough to be game breaking. To address that issue, a developer was hired to overhaul the Godot Physics engines, both 2D and 3D. Unfortunately, this developer is not available anymore.

Since then, Godot Physics is currently in a precarious situation. The few current maintainers sure are competent and diligent, but fixing physics engine issues requires deep physics and mathematics knowledge. Both fields that aren't easy nor simple.

As @reduz said on Twitter recently:

As you know, we had to patch up and use our own physics engine for Godot 4 in order to be able to release it, as there were bugs that just couldn't be solved on the Bullet side, but this still is too complex and we just don' t have the resources to maintain it properly. — @reduzio

So the problem or limitation the project is having is not having enough resources (including maintainers wise) to maintain a fully fledged 3D physics engine.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Jolt Physics is a physics engine created by Jorrit Rouwe (@jrouwe). It was first launched on January 23rd, 2022, but the engine was already known for being behind Horizon Forbidden West, a game by Guerrilla Games.

In constrast of Bullet Physics, it is a physics engine built up entirely from scratch with video games in mind. So it is built to handle interactivity and large worlds.

Unfortunately, the engine is not yet at feature parity with Godot Physics. But again, Godot Physics as game breaking issues that need to be fixed, if they are going to be fixed at all.

@jrouwe is actively working to add new features to the engine, such as soft bodies. Features are even being added with Godot in mind.


Enter Godot Jolt.

Since several months, Mikael Hermansson (@mihe) is working (successfully) to port Jolt to Godot with his GDExtension. The results are very interesting. Since last May, users can download and use Jolt in their games. Since then, numerous updates has been made and the proof has been made that Jolt could be potentially considered for Godot's physics engine needs.


Integrating Jolt Physics to the Godot Engine, by extension Godot Jolt, would serve two purposes:

By recognizing Godot Jolt as an officially endorsed add-on, we could battle test Jolt Physics, Godot Jolt and GDExtension.

Then, if everything goes well, we could eventually make Jolt Physics the default engine. But there's a lot of work to do to attain that level.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Ideally, it would be integrated to the engine as an official add-on following this proposal.

But this proposal is essentially about the recognition of the add-on/engine.

flowchart TD
    USER[User]
    GODOT(((Godot Engine)))

    subgraph ADDONS[Official addons]
        JOLT{{Godot Jolt}}
    end

    GODOT -.->|Promotes| ADDONS

    GODOT -->|Download| JOLT
    USER -->|Use| GODOT

If this enhancement will not be used often, can it be worked around with a few lines of script?

One does not simply maintain a physics engine with a few lines of script.

Is there a reason why this should be core and not an add-on in the asset library?

Jolt Physics and Godot Jolt are destined to be more than only be a simple add-on in the asset library.

mihe commented 10 months ago

Seeing as how there have been murmurs about this for a few weeks now, I guess this is as good of a place as any to express how flattered I am for this to be considered. It's been a staggering amount of (mostly full-time) work to get to this point, as part of a longer hiatus of mine, and while Godot Jolt isn't at feature-parity with Godot Physics just yet, it makes me very happy to see all that work being recognized in some capacity.

As mentioned elsewhere, I want to underline how instrumental @jrouwe has been in getting Godot Jolt to this point as well. While I may have started this project with a somewhat naive view of how this could be achieved, it's clear in hindsight that this project would have been largely dead in the water (or at least severely hampered) if not for his generous support over the past few months.

With that said, I think it's relevant to bring up that I'm by no means a physics programmer, nor someone who typically deals with physics engines. I'm also not particularly capable with physics or math in general. I hope this helps prove the point that creating and maintaining bindings to an existing physics engine results in a significantly lower barrier-to-entry for contributors compared to further developing something like Godot Physics, regardless of how primitive it may be in comparison to other physics engines. As such, I'd be happy to help steer Godot towards the proposed direction/outcome in whatever way I can.

I'd also like to bring up some of the discrepancies/compromises that Godot Jolt brings with it, which I think are important to highlight when considering this proposal and its potential future outcome, but I have to cut this short for now and will try to expand on this at a later point instead.

yosoyfreeman commented 10 months ago

I have no feelings one way or the other. I don't know about physics, just about usage and user experience, so i would like to ask what you people who actually know thing about this topics.

adamscott commented 10 months ago

If this is recommended as an official addon and seem like, in the long term, it could provide more advanced tech that godot physics, would that not imply a decrease activity on the development of the Godot physics engine?

If the add-on is successful enough and if there's a conversion of the add-on into a native Godot module, yes, it would mean a decreased activity on the development of the 3D Godot physics engine, especially if there's no maintainer that is able to maintain/upgrade our current engine.

If that is the case, as is my understanding that people deep in physics are only a few, how could this impact on the development of the integrated physics?

The development of the physics engine is already impacted. See the tweet of Juan in the proposal.

If the people who is currently working on godot physics eventually find that jolt is in fact a better option, and that leads to provide Godot with a limited or unmaintained physics engine, does it not make more sense to put this into the engine by default like Bullet was?

Yes, it makes a lot of sense. But as the Jolt Physics engine is not yet at feature parity with the 3D Godot Physics engine, we (the production team) think that there's no rush to replace the Godot Physics engine yet. Especially as the add-on works very well as a GDExtension. Once Jolt Physics, Godot Jolt and GDExtension will be battle tested, we'll think about merging the projects together. Until then, no.

I remember when we were talking about the Godot physics issues that two points were often pointed out: That using a library was easier to implement basic functions, but that it requires a bigger understanding to debug issues while implementing more advances features. This was notorious in move and slide. The other was that physics engines with margins were harder to work with. So, you think jolt is better to handle this? or we may end up in a situation similar to what we had in bullet?

We think that we'll know more about this if more and more users start to use Godot Jolt as their main physics engine. And as Jolt was made from the ground up to be a video game physics engine, we think that it will be more stable than Bullet, as it wasn't made with video games in mind.

yosoyfreeman commented 10 months ago

Thank you so much for taking the time to explaining this topic. I honestly feel like any possible concern is covered and seems like a good roadmap. As usually, awesome work from the team. Thank you all!

golddotasksquestions commented 10 months ago

Godot Physics is a disgrace of a bugfest. The only chance to get it halve-decently working is to limit your collision shapes to simple box and sphere primitives (not always a feasible option). In stark contrast to the much more performant Godot Jolt. Even with non-feature parity Godot Jolt is a much more viable physics engine. I really hope the combined efforts are focused on Godot Jolt going forward.

Previous discussion on this topic: https://github.com/godotengine/godot-proposals/discussions/5161

yosoyfreeman commented 10 months ago

well, I'm going to break a spear in favor of the Godot Physics engine. Yeah, it has serious troubles. But i just can't believe that a whole replacement for bullet was created in order to address the core functions for Godot 4.0 SO quickly. Not only Godot physics itself, but the work put into interface, a better API, more control of the bodies from the inspector, the whole new CharacterBody, which i think that while still could be improved (Like all things can) is an exponentially better solution for characters that what we had before. A huge effort went into testing and creating controllers in lots of ways to achieve something general enough for Godot while providing high level functionalities like snapping, constant velocity on slopes etc.

The physics engine is a thing, the implementation of it is another one and i think the team made huge steps on the right direction there. And just to be fair, the users who actually spend time creating reproduction projects for issues that were really hard to identify by the team was not so big.

Not so long ago just checking if a character was on the floor reported serious troubles and we are now far away from that. I don't think is fair to call the work a disgrace.

jrouwe commented 10 months ago

Hello,

I'm flattered that Jolt Physics is being considered for integration in godot. It has a been a lot of fun to develop it together with @mihe and I think it is amazing to see how quickly he implemented all of this!

The other was that physics engines with margins were harder to work with. So, you think jolt is better to handle this? or we may end up in a situation similar to what we had in bullet?

@yosoyfreeman I've heard multiple people say bad things about collision margins so far, but I have never experienced any issues with them. What is so bad about them?

B.t.w. I think the margins probably work differently in Jolt than in other physics engines. If you specify a margin, it gets subtracted from the shape and then re-added again, creating a shape with rounded corners of the same size as the original shape. The margins are only used to during the initial overlap test as a performance optimization, but not when calculating contact points/normals, these use the original shape. For ray casts they're not used at all. The only downside is that you may miss a hit if the overlap between two shapes falls between the original edge and the rounded off edge. I've not seen any artifacts due to this, but if this is important to you you can easily set the margin to 0 and pay some extra CPU cycles during the collision detection phase. For meshes / heightfields the margin is always zero, so I think this really only matters for boxes, convex hulls and cyclinders.

yosoyfreeman commented 10 months ago

I apologize, i totally forgot about thanking you! I officially extend my congrats to you and anyone who worked in this, just to be covered! haha

@yosoyfreeman I've heard multiple people say bad things about collision margins so far, but I have never experienced any issues with them. What is so bad about them?

i don't know from the programming side, but user side they seem a bit confusing to work with, but i see that they way they are handled is not equivalent to how bullet did it, so I'm not worried about them anymore. I started to try jolt and i was expecting something way more complicated bullet style. I'm honestly surprised in the best sense possible. You really did a great job here.

mihe commented 10 months ago

I've been curious about the differences between Bullet and Jolt with regards to margins, since this gets brought up in every discussion about the viability of Jolt and other GJK/EPA-based physics engines, so here are a few quick observations...

I think the margins probably work differently in Jolt than in other physics engines. If you specify a margin, it gets subtracted from the shape and then re-added again, creating a shape with rounded corners of the same size as the original shape.

From what I can tell, the margins as used with Bullet in Godot 3 behave similar to Jolt when dealing with boxes and cylinders, where you'll get rounded edges but no extra margin/padding/skin around it. With convex hulls you do however (unlike Jolt) get this extra margin/padding/skin around it, which when skimming through Godot's list of issues here on GitHub seems to have been the source of some confusion/frustration (godotengine/godot#27427, godotengine/godot#55503).

The margins are only used to during the initial overlap test as a performance optimization, but not when calculating contact points/normals, these use the original shape.

This is actually confusing me a little bit, as this does not reflect what I've seen in Godot Jolt, but in the interest of not derailing this discussion too much I'll create a separate issue for this, since I might have misunderstood or screwed something up in my implementation.

In either case, from what I can tell with just some quick tests, Bullet in Godot 3 seems to again be inconsistent about this depending on the shape type, where contact normals for boxes don't seem affected by shape margins but convex hulls do.

For ray casts they're not used at all.

Without trying this in Godot 3 myself, this seems to be another discrepancy with Bullet, where margins do seem to affect ray-casts and seem to again have been the source of some confusion/frustration (godotengine/godot#28032).

if this is important to you you can easily set the margin to 0 and pay some extra CPU cycles during the collision detection phase

This was not the case with Bullet in Godot 3, which I think is where a lot of the apprehension comes from. The margin had to be a non-zero value, so you could never really opt out of this performance-for-accuracy trade-off.

In Godot Jolt I've also added a project setting to globally ignore the shape margins, if you don't feel like setting it to 0 for every single box/cylinder/hull.

I think this really only matters for boxes, convex hulls and cylinders.

This was the case with Bullet in Godot 3 as well, but for whatever reason the margin parameter is present on all shape types, but ignored for anything but boxes, cylinders and convex hulls.

mihe commented 10 months ago

Here are the discrepancies/compromises that I meant to bring up in my original reply. Apologies in advance for the wall of text.

These things are (hopefully) not blockers per se, for the purpose of recognizing Godot Jolt as an official add-on, but seeing as how this proposal is largely intended to be an intermediate step towards making Jolt a first-class physics implementation in Godot I do think it's important to keep these in mind.

Note that this likely isn't an exhaustive list, and I've probably left out something important, but it'll have to do for now.

TL;DR

Bindings (C#, C++, Rust, etc.)

I think this is an important point to keep in mind as I go through the rest of this list, which is that you currently cannot interact with custom nodes that are exposed through GDExtension from languages that require compiled bindings, such as C#, C++, Rust and others. This means that when there's a mismatch between the interface that Godot expects you to implement (through PhysicsServer3DExtension) and the interface that Jolt provides there isn't much available in terms of options other than to drop support for that feature for these compiled languages, since you're not able to patch those holes with new nodes.

My current (perhaps naive) plan for the custom joints (described below) is to work around this for C# by distributing a separate NuGet package containing some sort of handwritten bindings that utilizes things like Object.get, Object.set and Object.call, but even so it will likely be a point of friction both in terms of development and usage.

GDScript and (presumably) other dynamic scripting languages are unaffected by this limitation.

Joints

Godot Jolt supports the basic functionality of all the default joint nodes, meaning they're all constrainted on the expected axes and they all support whatever hard limits and motors that the joints offer.

The only exception is perhaps SliderJoint3D, which in Godot Physics (and Bullet) also supports rotating/motoring around the sliding axis. In Jolt this is instead (rightfully) left up to the 6DOF joint. It's of course entirely possible to just implement SliderJoint3D using Jolt's SixDOFConstraint instead, perhaps even dynamically based on the properties used, but I haven't felt the need to take on that complexity yet.

What's also not supported in all these default joint nodes (and likely never will be) are the parameters that tune how the joints behave as the bodies move around or when they run up against the joint's limits. This includes things like bias, damping, relaxation, softness, restitution and ERP. Attempts were made to try and translate these into the interface that Jolt expects, but due to the lack of a consistent/functioning reference implementation this was eventually abandoned.

The current plan is to instead expose Jolt-specific joint nodes, appropriately named JoltPinJoint3D, JoltHingeJoint3D, etc. These will look and behave much like the default joint nodes, but will instead use Jolt's frequency/damping to express things like springs and soft limits. This also opens up for things like breakable joints, since Jolt allows you to retrieve a joint's last applied impulse. You will also be able to override the number of solver iterations on a per-joint basis, allowing you to make certain important joints more stable.

SoftBody3D

As already pointed out earlier in this thread, this isn't currently a thing in Jolt, but seems to be in the pipeline.

It remains to be seen how the two interfaces will line up. SoftBody3D in Godot Physics seems to be based on the PBD implementation in Bullet, and seeing as how the pending implementation in Jolt is based on XPBD I'm thinking/hoping they might be similar enough for the Godot Jolt implementation to be functional at least, without having to go down the route of making a custom node.

WorldBoundaryShape3D

This shape represents a static infinite plane in Godot Physics, and judging by the name is meant to be used for expressing world boundaries.

This type of shape is explicitly not supported in Jolt due to the implications its infinite nature has on performance and floating-point accuracy. I made a naive attempt at implementing this (before seeing the linked issue) by triangulating the plane, similar to Bullet's btStaticPlaneShape, and I can attest to quickly running into those floating-point issues.

Seeing as how this shape doesn't really offer much that can't be achieved with other shapes or mechanisms, I don't personally have any issue with this being unsupported, but it's none the less a discrepancy to consider.

HeightMapShape3D

While this shape is supported and mostly functional in Godot Jolt, it does come with the restriction that you can only use square height maps with dimensions that are a power-of-two. So you're only allowed to use height maps like 1024x1024 and not 1024x512 or 1000x1000.

Double-precision

This is something I haven't had the chance to explore yet, and while Jolt does support double-precision, it does so in a more conservative manner than Godot's approach of making most things a double. As such, there might be some slight discrepancies here with regards to the precision by which you're able to perform certain operations. I doubt it'll be of any practical concern, but it's still somewhat unknown at the moment, for me at least.

Performance

While Godot Jolt does seem to perform better than Godot Physics in most cases, there are certain cases where it does not.

One such case is when you manipulate the shapes of a body (i.e. change their properties/transform) after it has entered a scene tree. This is due to the fact that I lazily build the (fairly expensive) underlying Jolt shapes only when necessary, so as long as the body is not inside a tree you can manipulate the shapes whichever way you want at virtually no cost, but once the body is inside a tree then I rebuild the shapes immediately on every single change.

This is prominently noticeable in the Voxel Game demo project, where the chunk streaming results in pretty severe stuttering as you move around due to the chunks being initialized with dummy shapes that later gets replaced with proper ones, leading to multiple expensive rebuilds of the body's StaticCompoundShape. In this particular case it can be resolved fairly easily with a few minor tweaks, but it's a non-obvious pitfall either way.

These pitfalls are not inherent to Jolt, and more of a conscious trade-off that I made to prioritize the performance of bodies that do not change their shapes very often. You could of course do all sorts of dirty-flagging to only rebuild once per tick, or use some sort of heuristic or project setting for deciding whether a MutableCompoundShape is more appropriate than the StaticCompoundShape I use currently, but this comes at the cost of complexity, which I just haven't felt the need for yet.

Another performance pitfall relates to how Area3D detects StaticBody3D, where you can end up shooting yourself in the foot from a performance/memory standpoint if you allow many/large Area3D to overlap with complex static geometry, such as ConcavePolygonShape3D or HeightMapShape3D, due to how Jolt implements its Sensor body. For this reason this feature is gated behind a project setting in Godot Jolt.

There might very well be more performance pitfalls/discrepancies that I'm not aware of, as well as low-hanging fruit in terms of performance gains, but I haven't had much time to focus on profiling/benchmarking yet.

Miscellaneous

There are some other discrepancies that I'll just quickly list off here:

dsnopek commented 10 months ago

I think this is an important point to keep in mind as I go through the rest of this list, which is that you currently cannot interact with custom nodes that are exposed through GDExtension from languages that require compiled bindings, such as C#, C++, Rust and others.

I think this is might be solvable, at least with GDExtension (I'm not sure about C#).

When you have the Jolt GDExtension enabled, you could run godot --dump-extension-api and use the resulting extension_api.json when building your own C++ or Rust (or whatever) GDExtension, and it would generate the necessary code to use the custom Node types from Jolt.

Unfortunately, thinking through this I suspect a recent-ish change that I made for Godot 4.1 may actually prevent this from working at the moment :-) but I haven't tested it. Anyway, if it does, that's just a bug that can be fixed!

mihe commented 10 months ago

When you have the Jolt GDExtension enabled, you could run godot --dump-extension-api and use the resulting extension_api.json when building your own C++ or Rust (or whatever) GDExtension, and it would generate the necessary code to use the custom Node types from Jolt.

That could be interesting. I guess one could then technically maintain a fork of godot-cpp (or whatever) that includes that modified extension_api.json. Obviously this wouldn't compound very well if multiple extensions start to take this approach, but it's something to consider.

I'm not sure about C#

I've seen mentions about something similar having been used for C# in the past, where you'd have the desired extensions loaded while generating the C# glue or something along those lines. I'm not sure how that would have worked exactly, but either way that is now also likely broken (by me) since godotengine/godot#75955, which causes the C# scripting to explicitly skip over GDExtension classes when instantiating its bindings.

reduz commented 10 months ago

My thinking here is that, eventually, we can break some compatibility on the Godot side to make this happen, given most of these features are probably not heavily used, but some things will have to be properly supported. Here are my feelings about this:

This is the list of things that can be adapted in Godot to work like Jolt, even at the cost of breaking compatibility:

This is the list of things that Godot can't adapt as well and we should figure out a better solution:

I think none of the above is serious, although probably the one that may need a more involved solution is WorldBoundaryShape3D. I think if Jolt can figure out a way to expose the right hooks to do it, even if its more work from our side, it should be fine.

mihe commented 10 months ago

Joints and motors: [...] For this, extra enums in the PhysicsServer3D joints need to be added to add the Jolt parameters. [...] Eventually, when GodotPhysics is removed, we deprecate the old parameters and remove them.

This sounds a lot like what I've already done with the custom joints I've added so far. The default and custom joints both share the same physics server implementation, and the custom ones just use a couple of extra enum values, which seems to be working well enough.

Compound Shapes: I don't understand this well, but it looks like Jolt has both mutable and static compound shapes? Godot users will modify anything they can dynamically because such is the nature of a general purpose game engine. [...]

I'm sure @jrouwe can be more specific here, but yes, Jolt's MutableCompoundShape is just a list of shapes that can be added/removed from whenever, and StaticCompoundShape is an immutable one that builds some sort of tree structure to speed things up.

Just to be clear, Godot Jolt supports adding/removing shapes whenever just fine, but in part to simplify the implementation I went with discarding and rebuilding the entire compound shape whenever this happens. I know I explored the (arguably more intuitive) option of just using a MutableCompoundShape that's simply kept around and mutated, but abandoned it for reasons I can't exactly remember right now. I'm sure it can be made to work somehow though.

HeightMapShape3D: [...] One thing we could do here is, if the parameters to create the height map are not supported by Jolt, use a triangle geometry fallback and push a warning (once) that this will be less efficient, suggesting the most efficient size.

@jrouwe also suggested this in godot-jolt/godot-jolt#502 yesterday, along with a few other things. This should be fairly straight-forward to resolve one way or another, if only just as a way to get to parity with Godot Physics.

Area3D against static bodies: I think this can be dropped as it does not have a lot of sense as a feature. IMO it should test against kinematic bodies, but for static it is unnecesary.

This was (to my surprise) some of the first issue reports that I got, multiple even, which made it seem to me like it was a pretty popular use-case, although I can't speak to how exactly it was being used. I suppose if a user attaches an Area3D to something dynamic they expect every overlapping body to be reported, including static ones. It can obviously be replaced on the user's side by something like intersect_shape just as well, but that's not as convenient I suppose.

I realize Area3D is already kind of implemented this way in Godot Physics, but maybe some node equivalent to intersect_shape could be added, similar to how there's a RayCast3D and ShapeCast3D node, seeing as how there seems to be some friction with using PhysicsDirectSpaceState3D.

WorldBoundaryShape3D: [...] One option could be to just put a lot of boxes as a compound shape, though not ideal. [...]

I assume this wouldn't do much to alleviate the issue of the shape causing trouble for the broad phase, considering that the bounds of compound shapes encapsulates the bounds of all its sub-shapes, but I'm out of my depth here. I'm curious about your other suggestions though.

Threading: I am not exactly sure how Jolt uses threads, but Godot has its own scheduler (and soon its own profiler), so it would be ideal (if not the case already) if Jolt could allow overriding the functions used to send work to threads and await it by providing some custom function pointers.

If by scheduler you're referring to WorkerThreadPool, then this is already hooked up in Godot Jolt.

Profiling Hooks: Again if not the case already, it would be great if Jolt would support profiling hooks (like broadphase, narrow phase, constraint solving, etc) so eventually it shows in Godot profiling properly.

From what I understand this is a thing through JPH_EXTERNAL_PROFILE, but I haven't looked at it even a little bit, so maybe @jrouwe can provide some more details here.

Memory Allocation: This is not a must, but it would also be great if Jolt would allow supplying custom functions to do memory allocation. Godot tracks all memory used in debug mode over time and right now it has tight control.

This is already a thing in Jolt, but due to Jolt also needing aligned allocations I wasn't able to use alloc_static/free_static exposed through godot-cpp, so I allocate memory through other means currently, thereby (unfortunately) bypassing Godot and its performance monitors. I assume this would be less of a problem if Jolt were brought in as a module though.

iOS/Wasm/etc: If Godot implements Jolt officially, we will just copy the entire Jolt codebase inside the Godot repository and do our own builds anyway, ensuring it works in all platforms. This is handled from our side, so it should be fine.

Yes. :)

jitspoe commented 10 months ago

B.t.w. I think the margins probably work differently in Jolt than in other physics engines. If you specify a margin, it gets subtracted from the shape and then re-added again, creating a shape with rounded corners of the same size as the original shape. The margins are only used to during the initial overlap test as a performance optimization, but not when calculating contact points/normals, these use the original shape. For ray casts they're not used at all. The only downside is that you may miss a hit if the overlap between two shapes falls between the original edge and the rounded off edge. I've not seen any artifacts due to this, but if this is important to you you can easily set the margin to 0 and pay some extra CPU cycles during the collision detection phase. For meshes / heightfields the margin is always zero, so I think this really only matters for boxes, convex hulls and cyclinders.

Really? Seems like I was getting non-flat normals using a cylinder character collider against a triangle mesh (all flat 90 degree angles for testing stair stepping), sometimes causing my character to bounce in the air. Disabling the margins fixed it.

reduz commented 10 months ago

@mihe Oh, great to know that most of this is taken care then!

Just some extra notes from what you answered then:

Just to be clear, Godot Jolt supports adding/removing shapes whenever just fine, but in part to simplify the implementation I went with discarding and rebuilding the entire compound shape whenever this happens.

Keep in mind also users often change the properties of the shapes (like making capsule shorter when character crouches)or animate them via AnimationPlayer. So I think my recommendation would be something like adding to PhysicsServer a flag to the body that specifies that you won't be doing changes often. As example, GridMap uses thousands of those and they are not changed, so it could optimize to have these static. Otherwise you may run into performance issues if users do too much of this.

This was (to my surprise) some of the first issue reports that I got, multiple even, which made it seem to me like it was a pretty popular use-case, although I can't speak to how exactly it was being used.

I am really surprised about this. It definitely should detect kinematic bodies (which are technically static) but I don't see the use of static collision either. I guess it makes sense to leave disabled by default.

WorldBoundaryShape3D

You really just need to skip the broadphase for it and just collide every non resting dynamic body forcibly against it. The collision is super simple, get the transformed shape support in the direction of -plane normal and check if under the plane. If so, it collides and you have to get the support features in that direction and use them against the plane and solve that. If a boundary shape is moved, wake up all bodies. Because this does not involve any broadphase and can be almost considered a constraint (except you have to query some supports at setup time), it should be relatively easy to implement "externally" or as a constraint if Jolt has the right hooks.

I also forgot to ask if you could handle the separator ray shapes. Users often use those to do stair stepping in characters (both dynamic and kinematic).

But this is really awesome anyway, it looks like you got pretty much all figured out !

mihe commented 10 months ago

I also forgot to ask if you could handle the separator ray shapes. Users often use those to do stair stepping in characters (both dynamic and kinematic).

Yes, these are implemented, and seem to work the same as in Godot Physics, at least when attached to kinematic bodies, including its slide_on_slope property.

I was under the impression that these were mostly intended for kinematic bodies, and while they technically work for dynamic bodies as well, I can't really give them a sensible mass/inertia, given their infinitely thin nature, so I currently just give it some arbitrary ones, which might differ from how they behave in Godot Physics. Although, I guess this shouldn't matter much for some RigidBody3D-based character, since they override mass anyway, and would likely use lock_rotation, which overrides the inertia as well.

reduz commented 10 months ago

@mihe They are used for dynamic character controllers too (mostly for stepping too), but its as you say it should be fine.

elvisish commented 10 months ago

Godot Physics is a disgrace of a bugfest. The only chance to get it halve-decently working is to limit your collision shapes to simple box and sphere primitives (not always a feasible option). In stark contrast to the much more performant Godot Jolt. Even with non-feature parity Godot Jolt is a much more viable physics engine. I really hope the combined efforts are focused on Godot Jolt going forward.

Previous discussion on this topic: https://github.com/godotengine/godot-proposals/discussions/5161

Not sure why this has been downvoted so much, it's very true that you have to use Box colliders exclusively if you don't want the physics to level-reset break (which is the first rule of physics to avoid, never get stuck in a place you can't get out). I'll reiterate that using a Safe Margin of 0.001 instead of the default 0.0001 fixes getting stuck entirely in my experience, however I am still using only box colliders and simple 45 and 90 degree angled colliders so it may not work for more complicated shapes.

I absolutely agree that Jolt should be developed as the built-in default physics though.

reduz commented 10 months ago

@elvisish Godot Physics can be fixed with a good amount of effort (There was a roadmap more or less in place, and all issues are well understood) but the truth is that this still needs a dedicated maintainer and se far this has not happened. As Jolt has improved so much and became more friendly to how Godot works, plus it is very actively maintained and developed, at this point it makes more sense to move to it. This is why I think the change of plans makes more sense.

elvisish commented 10 months ago

@elvisish Godot Physics can be fixed with a good amount of effort (There was a roadmap more or less in place, and all issues are well understood) but the truth is that this still needs a dedicated maintainer and se far this has not happened. As Jolt has improved so much and became more friendly to how Godot works, plus it is very actively maintained and developed, at this point it makes more sense to move to it. This is why I think the change of plans makes more sense.

I agree. Just thinking now, I wonder if this means that stair-stepping could be implemented in Jolt physics for performance purposes? I've been using https://github.com/mrezai/GodotStairs for extremely robust and fully working stair-stepping (it does multi-directional shapecasts using directspace) but the performance is terrible (here's a stress test of 250): image

Nvidia's PhysX has built-in stair-stepping as it's designed for games, I would expect Jolt to have similar built-in functionality and I think vastly improved performance would be an even better reason to have it built-in than convenience and the popularity of its use. Here's my 2+ year old proposal: https://github.com/godotengine/godot-proposals/issues/2751

reduz commented 10 months ago

@elvisish Just use a SeparationRayShape for stair stepping, this is what most users do. Also, we can move this discussion to your proposal, since you are going fully offtopic here.

yosoyfreeman commented 10 months ago

-This part removed to keep conversation clean-

I have one doubt: Is told here that testing is needed. I'm currently on it. But if you have any kind of feature that need specific feedback or heavy testing, a public list with things that need it would be great for us doing test controllers/scenes right now so we can be more helpful.

elvisish commented 10 months ago

it's very true that you have to use Box colliders exclusively if you don't want the physics to level-reset break.

That's at least inaccurate. I never seen nobody use a box for a controller, for example.

All Source and Quake 1 engine games use a box-collider, there was plenty of discussion about this here: https://github.com/godotengine/godot-proposals/discussions/5161#discussioncomment-3918058 https://github.com/godotengine/godot-proposals/discussions/5161#discussioncomment-3994741

reduz commented 10 months ago

@elvisish @yosoyfreeman please stop the offtopic in this proposal or it will have to be moderated. Continue on https://github.com/godotengine/godot-proposals/issues/2751.

elvisish commented 10 months ago

@elvisish @yosoyfreeman please stop the offtopic in this proposal or it will have to be moderated. Continue on #2751.

I think it's on-topic as I was referring to box-collider being necessary in Godot Physics for general movement (not stairs) and by comparison Jolt should be more than capable of using capsule, cylinder, convex/concave, etc. If Jolt still has issues and gets stuck in geometry that isn't just boxshapes, then it would still suffer the same issues that GP has (but would at least have improved performance I assume).

adamscott commented 10 months ago

I think it's on-topic as I was referring to box-collider being necessary in Godot Physics for general movement (not stairs) and by comparison Jolt should be more than capable of using capsule, cylinder, convex/concave, etc. If Jolt still has issues and gets stuck in geometry that isn't just boxshapes, then it would still suffer the same issues that GP has (but would at least have improved performance I assume).

@elvisish We are pretty far of the subject of recognizing "Godot Jolt" as an officially endorsed add-on.

Zireael07 commented 10 months ago

@elvisish The whole box-collider thing is already pretty far off topic since this is about Godot Jolt physics

elvisish commented 10 months ago

@elvisish We are pretty far of the subject of recognizing "Godot Jolt" as an officially endorsed add-on. @elvisish The whole box-collider thing is already pretty far off topic since this is about Godot Jolt physics

I guess the best thing to do would be to test if Jolt struggles with seams, gaps, getting stuck when pushed and trapped between a body and a wall and if it gets stuck when going up a ramp into a ceiling. If not, then it would definitely be the way to go as a default physics engine.

reduz commented 10 months ago

@elvisish By all means test it for your uses, but do it with the extension for now, which is freely available and leave feedback in that repository until merged or moved.

jrouwe commented 10 months ago

@jitspoe

Really? Seems like I was getting non-flat normals using a cylinder character collider against a triangle mesh (all flat 90 degree angles for testing stair stepping), sometimes causing my character to bounce in the air. Disabling the margins fixed it.

You're right, the story is a bit more complex, look at the discussion here: https://github.com/jrouwe/JoltPhysics/discussions/628

mrezai commented 10 months ago

Hi I have used Godot and followed its development from version 1.1 and contributed few times to the project and more recently have followed Jolt development and contributed small changes to it too. I suggest based on all my observation and information, Godot production team should make two plans, one short term and one long term. In short term one, support and develop Godot Jolt add-on without breaking compatibility or with small as possible in Godot 4 version. In long term plan for Godot 5, replace Physics Engine with Jolt and redesign Godot Physics API based on Jolt features. Maybe you ask why?! Because there are features that Godot hasn't similar ones currently like these:

My point is before any decision, at least runs Jolt samples and read its documentation with enough attention! I know most of the main Godot contributers using Linux as development environment. I contributed the possibility of running Jolt samples in Wine, you can use it to run samples in Linux: https://github.com/jrouwe/JoltPhysics/blob/master/Build/README.md#linux-debian-flavor-mingw-cross-compile

I think maybe after Godot 4.4/4.5 that worth it to release Godot 5 only for integration of Jolt with all of its features and nothing else!

Ughuuu commented 10 months ago

@yosoyfreeman

-This part removed to keep conversation clean-

I have one doubt: Is told here that testing is needed. I'm currently on it. But if you have any kind of feature that need specific feedback or heavy testing, a public list with things that need it would be great for us doing test controllers/scenes right now so we can be more helpful.

For this we could use the repo that already exists, fabriceci/Godot-Physics-Tests, and try to add here more tests that test all the api (or as much as possible).

Ughuuu commented 10 months ago

@reduz

  • Joints and motors: The way Jolt exposes joints makes more sense than the one Godot does. It is also far more robust. For this, extra enums in the PhysicsServer3D joints need to be added to add the Jolt parameters. Each physics engine will support its own. Likewise on the nodes, the new parameters need to be added and a small trick can be done to hide one or another parameter depending on the physics engine active. Eventually, when GodotPhysics is removed, we deprecate the old parameters and remove them.

I am also interested in this feature specifically (eg for PinJoint2D to have impulse method, similar to how the 3D one exposes in custom nodes.). Also, adding more properties/extending the api through a physics server extension. But how would it would?

timshannon commented 9 months ago

I've seen mentions about something similar having been used for C# in the past, where you'd have the desired extensions loaded while generating the C# glue or something along those lines. I'm not sure how that would have worked exactly, but either way that is now also likely broken (by me) since godotengine/godot#75955, which causes the C# scripting to explicitly skip over GDExtension classes when instantiating its bindings.

Apologies if this is off topic, but I can't find anywhere else this issue is discussed.

Is there an open issue somewhere for not being able to utilize GDExtension custom nodes from C#? I'd very much like to take advantage of some of the jolt-specific nodes @mihe has made available, but I'm using C#.

Thanks,

adamscott commented 9 months ago

Is there an open issue somewhere for not being able to utilize GDExtension custom nodes from C#?

CC. @raulsntos @dsnopek

raulsntos commented 9 months ago

Is there an open issue somewhere for not being able to utilize GDExtension custom nodes from C#?

You can use them, but there's no C# types generated for them. So, if you need to use jolt-specific functionality, right now you'll have to use the Get/Set/Call methods in GodotObject to access the available members.

I don't remember any issue about generating C# types for GDExtension classes, but we definitely want to improve the UX around using GDExtension classes from C# so it's in our roadmap.

GeorgeS2019 commented 9 months ago

@raulsntos

NativeStructs and Pointers in C#

Could you feedback how the above PR could improve the experience using C# to access exposed properties/methods from GDExtension written in c++

Could you elaborate with example for:

You can use them, but there's no C# types generated for them. So, if you need to use jolt-specific functionality, right now you'll have to use the Get/Set/Call methods in GodotObject to access the available members.

jams3223 commented 8 months ago

We really need this to happen.

Calinou commented 8 months ago

@jams3223 Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

AttackButton commented 8 months ago

Any chance to make an effort and bring Jolt to version 4.2 already? Maybe hire a contributor to help these heroes? lol I really believe this is the right time for that.

This project is making Godot 4 rise from the ashes. I'm using Generic6DOFJoint3D again.

Edit: this fixes https://github.com/godotengine/godot/issues/66335.

YuriSizov commented 8 months ago

@AttackButton 4.2 will be feature complete in two weeks. There is no chance something of this caliber can be finished before this. Besides, we are discussing recognizing an extension, which doesn't need to follow main engine releases (that's the beauty of extensions). It doesn't have to be timed to a particular Godot release.

Rinocrosser commented 8 months ago

Current Godot Physics may become good only under the supervision of a pro developer, who will mainly work on it. Jolt seems great in comparison to the current state of things.

PrinceMerluza commented 8 months ago

@AttackButton 4.2 will be feature complete in two weeks. There is no chance something of this caliber can be finished before this. Besides, we are discussing recognizing an extension, which doesn't need to follow main engine releases (that's the beauty of extensions). It doesn't have to be timed to a particular Godot release.

Wait so this is going to be an add-on and not replace the Godot in-house Physics? I suppose it could be a project option like the renderers. But I dunno, replacing the in-house completely seems like a good idea too

YuriSizov commented 8 months ago

@PrinceMerluza It is an extension already. What we want is to make it easy to install it into your projects and officially recognize it as a supported alternative. Down the line this can be made a module and a default option for new projects, but that's beyond the next step.

We don't have plans to completely remove Godot Physics as far as I know.

AThousandShips commented 8 months ago

Jolt doesn't support 2D physics, and Godot Physics has dedicated 2D physics, as opposed to just faking it by ignoring the Z axis, so Jolt could only replace the 3D physics, meaning that the 2D and 3D physics would diverge, probably making it harder to maintain

GeorgeS2019 commented 8 months ago

If jolt now serve as GDextension. This will not affect core. We now have more GDEXTENSION c# bindings WIP . Though not official bindings, this will allow c# users NOW without waiting, especially those from unity, to start trying the jolt physics in 3D, which I think the main concern for many users like me and those from Unity.

mrezai commented 8 months ago

Jolt doesn't support 2D physics, and Godot Physics has dedicated 2D physics, as opposed to just faking it by ignoring the Z axis, so Jolt could only replace the 3D physics, meaning that the 2D and 3D physics would diverge, probably making it harder to maintain

May be 2D physics could be replaced with box2c someday when there be a stable release: https://github.com/erincatto/box2c

https://box2d.org/posts/2023/01/starting-box2d-3.0/

AThousandShips commented 8 months ago

That would make it even more complicated to maintain 🙃, having upstream dependencies increases maintenance overhead, not reduces, when you already have a fully functional system for it

mrezai commented 8 months ago

I mentioned before that I'm following Godot development from 2015 and what I'd seen through these years is physics bugs didn't fixed at a good speed so I don't know really which one is better, custom physics engine or external one. If someone specialist in 2D physics engine can work on a custom one I think he can work on external one instead and use it in Godot code, of course when there is a 2D physics that features align with Godot vision, something like Jolt that its main developer had implement lots of things for Godot and other 3D engines.

List of current open issues in 2D engine: https://github.com/godotengine/godot/issues/45334