playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.65k stars 1.35k forks source link

Decouple physics engine #2801

Open LeXXik opened 3 years ago

LeXXik commented 3 years ago

Currently, Ammo is deeply integrated into rigidbody and collision components, making it an integral part of the PC engine. I would like to propose decoupling the physics engine into own backend provider.

backends/ammo

There would be no changes to the current components API. However, instead of processing the physics inside the component, a component would call appropriate method of the currently selected backend. For now, it would be Ammo.

For example, when a user does rigidbody.teleport(pos, rot), the component would call backend.teleport(pos, rot). Most of the general purpose physics engines do their simulations through iterating simulation steps, so their features are similar. PC component can abstract away the inner workings of the one or another backend. If some physics engine doesn't support a feature, it is easy for the backend to notify a user.

This makes it trivial to add support and switching to another physics engine:

backends/physx
backends/rapier
backends/...

It also makes it easier for the games to implement and add custom physics engine - it would be simply a matter of adding another backend. All backends could have the same API signature, which would make PC agnostic about which backend is currently handling the physics simulation.

mvaligursky commented 3 years ago

Agreed, we've discussed this internally as well. Also it'd be good to perhaps investigate an option of running the physics engine on a worker thread as an option.

willeastcott commented 3 years ago

I would love to do this - it's on our roadmap. But it's a big job.

LeXXik commented 3 years ago

I have some experience placing Ammo and Rapier in a worker. The method has both pros and cons.

The pros are obviously in the non-blocking nature of the parallel thread. For example, in Ammo there was a need to do a 1000 step forward-simulation. This introduces a tiny game freeze, when executed in the main thread, but has no such issues, when running in a worker. In general, though, you don't need to have forward simulations, or can cut them into smaller chunks. As such there is little benefit in a worker otherwise, unless you are fighting for 1-2ms in your frame budget for something else. A higher gain would be in using the backend that supports SIMD operations via Wasm. Even running in main thread.

The cons is that you lose a direct access to the state queries of the simulated bodies. For example, it becomes less trivial to check if the body is sleeping. You have to issue a message to the worker, which will do the query in the physics world and report back - that can easily take multiple frames, not mentioning simulation steps. Since the worker is running in own context, you also have no access to the objects there, so using custom callbacks becomes problematic, but can be solved through serializing a function into a string and sending to the worker, which deserializes it and executes as a callback within its own context.

insof commented 3 years ago

Any news about this feature? We need it!

yaustar commented 3 years ago

@insof I'm afraid this is not planned on the road map yet. The upcoming public Editor API should make it easier to integrate a 3rd party physics system though

querielo commented 1 year ago

Any update here? It would be great to have an adapter between the engine components and physics engine.

The latest news: https://developer.nvidia.com/blog/open-source-simulation-expands-with-nvidia-physx-5-release/

yaustar commented 1 year ago

I'm afraid no changes/updates. We are looking at implementing https://github.com/playcanvas/engine/issues/4767 and with that, some Editor updates to allow a more modular way of building a project. (Tree shaking etc) And with that, it will make it easier for others to add a Rapier Component System.

Combined with Editor Plugins/API, it could make swapping out the physics more possible on a per project basis, just not in the same way when this ticket was first created was envisioning it.

issacclee commented 1 year ago

Hi Guys,

The latest version of Babylon.js supports the newly released web version of Havok physic Engine. Some demos showed promising results with huge performance boost(three.js community put together a binding for Havok as well).

some examples https://playground.babylonjs.com/#PX6E6C

Maybe we should consider support Havok when we starts to make the effort to decouple physic engine from main playcanvas engine.

willeastcott commented 1 year ago

@issacclee In case you missed my tweet: https://twitter.com/willeastcott/status/1650931998146306072