bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
34.27k stars 3.35k forks source link

High Level Physics Api #83

Open cart opened 3 years ago

cart commented 3 years ago

Bevy should have a backend agnostic physics api

tristanpemble commented 3 years ago

frequent counter points to building an abstraction layer like this is that it can:

usually, having an escape hatch to access the underlying backend helps with the first. I think this will be an important point of discussion in designing a high level API.

food for thought:

thefuntastic commented 3 years ago

Unity is taking a somewhat similar approach. they've limited the scope to two APIs: an in house, and Havok

Addenum here: before Unity's move to ECS there was (and still is) PhysX for 3D, and then later Box2D for 2D games. These sensibly use similar but separate APIs within Unity, one each for 3D and 2D. Unity is working on new physics solution because, besides support for ECS, the previous generation couldn't do server side prediction and rollback, which is a non-starter for competitive multiplayer games.

I've got expereince on a large physics games built in Unity + PhysX (aka TerraTech). Agree with @tristanpemble and can confirm that not having an escape hatch to the underlying library is a real pain point. Often the Unity API chooses "sensible" defaults that either don't represent the latest innovations in the underlying library, or else manifests hard to optimise perf concerns.

CooCooCaCha commented 3 years ago

I'd also like to add that it's important for this API to include raycasting and triggers.

I say this because I've looked at the various Amethyst physics system prototypes out there and none of them have these APIs. I'd like to avoid this issue with Bevy since these APIs are essential to making many types of games.

CooCooCaCha commented 3 years ago

Also, nphysics now has support for fixed-point numbers which makes the simulation deterministic across platforms. https://github.com/dimforge/nphysics/pull/266

Ratysz commented 3 years ago

Rapier was just (unofficially?) announced. Seems like it's a sort of a successor to nphysics? It's made by the same author and docs look somewhat similar.

erlend-sh commented 3 years ago

I think Rapier will be an excellent default physics engine for Bevy. However, there are some more lightweight alternatives out there that might be more suitable for certain use cases (though there are varying degrees of porting effort required for any of these to work with Bevy):

You can look for more with this search: https://github.com/search?l=Rust&q=physics&type=Repositories

maplant commented 3 years ago

Hi there, thanks for mentioning my crate. I wouldn't recommend using my crate for a few reasons, including my terrible GJK implementation which I have fixed elsewhere but have yet to update in the crate itself. If you were to use it I'd recommend picking and choosing algorithms and extracting them. I'm fine with this, but if you need a new license or whatever just let me know. I don't think you'll be doing this, but thought I'd offer anyway.

Regardless, I would like to offer up some of my thoughts on implementing physics with ECS based game engines, something that I have a significant chunk of experience with. It is of my opinion that using one-stop shop solutions such as a separate World containing all of the pertinent information for the collection of rigid bodies usually ends up being quite a pain to integrate properly, and doesn't offer a whole lot of flexibility. With regards to rapier, I think you would be much better off using the individual parts of rapier rather than the whole simulation. My reasoning for this is that having a whole simulation world in conjunction with an ECS is largely redundant - you have one ECS for physics and one ECS for everything else, one with all the nice stuff Bevy has and one that probably does not. This for the most part throws flexibility out of the window, and it means that if you want items with position that don't behave physically, they have to be modelled in the separate Bevy ECS.

The solution to this is to recognize that there are two parts to the physics simulation process, and both of them can be implemented via Bevy systems. The first part, collision detection, is used to generate a list of contacts. I would like to stress that it is extremely important for this part to be customizable, as broad phase collision detection has a lot of parameters that can dramatically change performance.

The second part is the constraint solver, and I think it's important to stress that there is no reason that this cannot be integrated into an existing ECS. Fundamentally, a constraint solver is a vector of pairs of indices to an ECS that contains the necessary information (position, velocity, friction coefficients, etc). With separate world-based solutions such as Rapier, this is completely opaque to the user, meaning it can't be directly integrated into Bevy's ECS.

Separating the collision detection and constraint solving into two separate Bevy systems allows for the user to pick and choose what they want with a net increase in flexibility for the user (i.e. able to tune BVH or Grid based broad phased physics systems, tune baumgarte and penetration slop constants) and a probable increase in performance (no redundant ECSs).

In summary, I think Rapier-rs is an excellent choice based on the credibility of nphysics. However, if it does not provide the ability to extract the various components within - collision detection and a constraint solver - I would suggest filing an issue to have those components exposed and made generic or simply modifying the code and keeping a local copy. It's not necessarily going to be easy to remove the interdependencies in a way that makes rapier as accessible as it currently is.

I really hope that provided some amount of insight, it's not my intent to just throw a wall of text at ya'll. Bevy looks really awesome and I think it has the right momentum to be super successful!

P.S. If anyone is interested in knowing how I solve this in my own game engine, which is fairly similar to Bevy in its ECS based structure, please let me know and I can share the code with you.

maplant commented 3 years ago

One more thing: I noticed that Sébastien Crozet, the author of rapier3d and the head of the dimforge project, has already registered the bevy_rapier3d cate, so they might be already in the process of doing all of this for you.

tristanpemble commented 3 years ago

there was a conversation in the Discord about this yesterday; Sebastien is indeed offering to build out a Bevy plugin for Rapier. I believe @cart's intent is to defer to Sebastien for the time being while he focuses on other areas of the engine. it fits well with his approach to promote third-party experimentation before adopting something officially into the engine

maplant commented 3 years ago

I highly recommend this approach. In fact, I think a separate crate based approach to this problem in a way that is similar to serde distributing various parsers into separate crates (such as serde_json, serde_yaml) is an extremely good approach to continue with in the future.

Frankly I think that this approach is better than having some physics and collision systems be built into Bevy so long as there are some examples and documentation for people not well versed in physics and collision implementations to get themselves on the right track. This way, if someone needs to change bevy_rapier3d, they don't need to fork the entire Bevy repo and will continue to receive updates.

cart commented 3 years ago

Yup in the short term I think letting an expert like @sebcrozet explore what Bevy integration looks like is the right call. Others are free to do the same, but I think having at least one direct backend implementation will help inform what a high level interface looks like. Physics also isn't one of our focus areas for the time being.