Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutable non-shared shapes #674

Open
IamTheCarl opened this issue Jul 8, 2024 · 0 comments
Open

Mutable non-shared shapes #674

IamTheCarl opened this issue Jul 8, 2024 · 0 comments

Comments

@IamTheCarl
Copy link

I am suggesting a feature that I am willing to implement, but this feature would have pretty significant impacts and I think warrants discussion before an attempt at implementing it is made.

Context

I wrote my own proof of concept physics engine for voxels
https://github.com/dimforge/rapier/assets/21977560/d570ee1d-48ff-42cd-be17-af11231dd7d8
It's a very limited implementation but I think the concept can be adapted into Rapier to be much better. The main advantage of this system is that the voxel data is used directly as the terrain shape. No mesh needs to be regenerated when the terrain is updated.

As a quick clarification, I do not think voxel physics should be a built in feature of Rapier. Voxel implementations vary too much to make a generic physics implementation. Instead my goal is to make rapier extensible enough that these custom implementations can easily be added by external libraries.

The problem

The current issue I am facing is that all shapes are shared immutable data. That design choice is correct 99% of the time but in the case of voxels is actually a hindrance. Voxel data is typically organized in chunks. I personally use 16x16x16 voxel chunks. My plan is to make each chunk into a collision shape.

Voxel chunks are rarely duplicated and frequently updated, making the overhead of the Arc non-beneficial since the memory is never shared, and updating the chunks expensive because the data will have to be copied from the old SharedShape into a new SharedShape every time the chunk is updated.

A workaround

Internal mutability would work. Just wrap your custom shape implementation's internals with a Mutex. That should work but it's going to look odd and add overhead. This feels wrong because any time the physics pipeline isn't being stepped, it's theoretically safe to manipulate the colliders and their shapes (if the shapes weren't immutable shared data).

The proposed solution

I think the simplest solution is to make the ColliderShape in Colliders a generic type that defaults to SharedShape.

pub(crate) shape: ColliderShape,

Doing this minimizes the code changes needed for end users (remember that SharedShape is the correct choice 99% of the time) but still gives the option to have mutable shapes in the rare cases that is needed.

That sounds sweet and simple at first but it's going to have issues with Bevy Rapier's Collider implementation:
https://github.com/dimforge/bevy_rapier/blob/f17bd5b04b3dc437152403c1d365cd56e75924ca/src/geometry/collider.rs#L80
https://github.com/dimforge/bevy_rapier/blob/f17bd5b04b3dc437152403c1d365cd56e75924ca/src/plugin/systems/collider.rs#L136

The Bevy -> Rapier bridge depends on the fact that collision shapes are cheaply cloned.
I also suspect there's a lot of generalized code that depends on the dyn Shape aspect of SharedShape, so that may also not work out the way I had hoped.

I've effectively talked myself out of this change and think "the workaround" may be the only practical solution, but am interested to see other opinions on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants