dimforge / dimforge/bevy_rapier
bevy task to run physics
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 282
- PR merge metrics
- No merged PRs in 30d
Description
It would be interesting to have physics running in a background task over a few frames, and using interpolation to smooth results.
We could have a physics world simulating at 30 or 20 fps ; while rendering would go at 60 fps.
## TODO
- [ ] Study physx does its double buffering: when is the new buffer written exactly ?
- https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Threading.html#double-buffering
- extract / writeback approach similar to what I'm implementing, with an additional overwriting by user changes ; I think we can provide an option to allow changes only between writeback and the new task, then build on top of that to add the user overwriting (which could be done by the user with this approach).
## Plan
```mermaid
flowchart TD
A[Set to allow user to change physics data] --> COPY(Copy physics into background)
COPY --> FORK(Start bevy task)
FORK --> Loop{Elapsed time}
FORK --> SIM["Rapier physics simulation (50ms ; 20fps)"]
Loop -->|"-50ms"| BU["Bevy update (16.6ms ; 60FPS)"]
BU --> Loop
Loop -->|"+50ms"| J(join)
SIM --> J(Join bevy task)
J --> WRITE(Write physics from background task into bevy)
WRITE --> A
```

### Implementation
- Add a "background mode" to the plugin.
- `step_simulation()` is expected to provide the end result of our simulation, It makes sense for it to be the system reading the result of the background computation.
- Add a `start_simulation` system to dump physics state and start the simulation.
- re-order the `apply_*_user_changes` to be before that `start_simulation` system. Clarify in the docs that any value modified **outside** of expected set will be without effect.
### Difficulties
#### Passing data out of ECS
- A naive approach is to copy the whole `RapierContext` ; but `IslandSolver` doesn´t implement Clone, and this goes quite deep ( to `SolverConstraintsSet` ) ; we should keep in mind simd and enhanced-determinism features compatibility.
- we might not need SolverConstraintsSet (and `physicsPipeline` in general) so try to clone everything but that.
- This should be possible but adding Clone to those traits should probably be behind a feature?
- Another approach is to unsafely copy :scream:
- Another approach would be to `mem::swap` the RapierContext with an empty/incorrect one for the ECS, while the simulation is ongoing.
- This could be made more sound by using an `Option` + `.take()` :thinking:
### Attempts
- background simulation: See https://github.com/dimforge/bevy_rapier/issues/596
- interpolation experiments: https://github.com/vrixyz/bevy_rapier/pull/28
- rapier-agnostic approach: https://github.com/Jondolf/bevy_transform_interpolation/pull/7
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.