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

Add ColliderBackendPlugin and support generic colliders #311

Merged
merged 19 commits into from
Feb 17, 2024

Conversation

Jondolf
Copy link
Owner

@Jondolf Jondolf commented Jan 23, 2024

Objective

An improved version of #302.

Currently, collider logic is split across several plugins. The PreparePlugin initializes them and manages mass properties and collider parents, the SyncPlugin handles collider scale and transform propagation, the BroadPhasePlugin updates their AABBs and collects potential collision pairs, and the NarrowPhasePlugin uses them for actually computing contacts.

Using Collider in so many places isn't ideal since it couples collision logic with other plugins, and it also makes it very challenging to implement custom collision backends nicely. It would be useful to handle collider-specific background work in a single plugin and to support custom colliders through generics.

Solution

  • Add a ColliderBackendPlugin. It handles collider initialization, transform propagation, scaling, parents, mass property updates, AABB updates, and more.
  • Add the AnyCollider and ScalableCollider traits. Implementing these for a component makes it possible to use a completely custom collider component by passing the type to ColliderBackendPlugin and NarrowPhasePlugin through generics. There is a new custom_collider example that demonstrates this.

To avoid leaking too many implementation details related to system ordering, I also added more system sets like the BroadPhaseSet, NarrowPhaseSet and SyncSet enums.

Creating a custom collision backend is now straightforward. After implementing AnyCollider and ScalableCollider for a component, simply add the CollisionBackendPlugin and NarrowPhasePlugin with that type:

.add_plugins((
    DefaultPlugins,
    PhysicsPlugins::default(),
    ColliderBackendPlugin::<CircleCollider>::default(),
    NarrowPhasePlugin::<CircleCollider>::default(),
))

Changelog

Added

  • CollisionBackendPlugin
  • AnyCollider trait
  • ScalableCollider trait
  • scale_by method for colliders
  • Collider::swept_aabb
  • ColliderAabb::new
  • ColliderAabb::merged
  • BroadPhaseSet system sets
  • NarrowPhaseSet system sets
  • SyncSet system sets
  • custom_collider example

Changed

  • Moved collider module from components to collision module
  • NarrowPhasePlugin takes a generic type implementing AnyCollider
  • Moved collider systems from PreparePlugin, SyncPlugin and SleepingPlugin to ColliderBackendPlugin
  • Collider logic from upate_mass_properties is in a new update_collider_mass_properties system

Migration Guide

  • Replace NarrowPhasePlugin with NarrowPhasePlugin::<Collider> if you add it manually
  • Replace Collider::compute_aabb with Collider::aabb

@Jondolf Jondolf added C-Enhancement New feature or request A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality labels Jan 23, 2024
@Jondolf Jondolf marked this pull request as ready for review January 23, 2024 22:24
@Jondolf Jondolf merged commit ffc0006 into main Feb 17, 2024
4 checks passed
@Jondolf Jondolf deleted the collider-generics branch February 17, 2024 12:06
brianreavis pushed a commit to naturalatlas/bevy_xpbd that referenced this pull request Feb 17, 2024
An improved version of Jondolf#302.

Currently, collider logic is split across several plugins. The `PreparePlugin` initializes them and manages mass properties and collider parents, the `SyncPlugin` handles collider scale and transform propagation, the `BroadPhasePlugin` updates their AABBs and collects potential collision pairs, and the `NarrowPhasePlugin` uses them for actually computing contacts.

Using `Collider` in so many places isn't ideal since it couples collision logic with other plugins, and it also makes it very challenging to implement custom collision backends nicely. It would be useful to handle collider-specific background work in a single plugin and to support custom colliders through generics.

- Add a `ColliderBackendPlugin`. It handles collider initialization, transform propagation, scaling, parents, mass property updates, AABB updates, and more.
- Add the `AnyCollider` and `ScalableCollider` traits. Implementing these for a component makes it possible to use a completely custom collider component by passing the type to `ColliderBackendPlugin` and `NarrowPhasePlugin` through generics. There is a new `custom_collider` example that demonstrates this.

To avoid leaking too many implementation details related to system ordering, I also added more system sets like the `BroadPhaseSet`, `NarrowPhaseSet` and `SyncSet` enums.

Creating a custom collision backend is now straightforward. After implementing `AnyCollider` and `ScalableCollider` for a component, simply add the `CollisionBackendPlugin` and `NarrowPhasePlugin` with that type:

```rust
.add_plugins((
    DefaultPlugins,
    PhysicsPlugins::default(),
    ColliderBackendPlugin::<CircleCollider>::default(),
    NarrowPhasePlugin::<CircleCollider>::default(),
))
```

---

- `CollisionBackendPlugin`
- `AnyCollider` trait
- `ScalableCollider` trait
- `scale_by` method for colliders
- `Collider::swept_aabb`
- `ColliderAabb::new`
- `ColliderAabb::merged`
- `BroadPhaseSet` system sets
- `NarrowPhaseSet` system sets
- `SyncSet` system sets
- `custom_collider` example

- Moved `collider` module from `components` to `collision` module
- `NarrowPhasePlugin` takes a generic type implementing `AnyCollider`
- Moved collider systems from `PreparePlugin`, `SyncPlugin` and `SleepingPlugin` to `ColliderBackendPlugin`
- Collider logic from `upate_mass_properties` is in a new `update_collider_mass_properties` system

- Replace `NarrowPhasePlugin` with `NarrowPhasePlugin::<Collider>` if you add it manually
- Replace `Collider::compute_aabb` with `Collider::aabb`
Jondolf added a commit that referenced this pull request Feb 18, 2024
)

# Objective

#311 added support for custom collider backends. However, the default `Collider` still remains, which requires the Parry and Nalgebra dependencies which are unnecessary if your collision backend doesn't use them.

`Collider` and Parry should be optional.

## Solution

Add three feature flags: `default-collider`, `parry-f32`, and `parry-f64`. `parry-f32` is a default feature that also enables `default-collider`.

The Parry features are unfortunately necessary, because Parry is split into separate crates for f32 and f64, and we can't reuse the `f32` and `f64` feature flags, because then the dependencies wouldn't be optional.

Not having the `default-collider` feature disables `Collider`, the default collision backend using it, the `SpatialQueryPipeline`, the `SpatialQuery` system parameter, and `ShapeCaster`. The `RayCaster` is still available for now, but it doesn't actually raycast unless users implement the functionality themselves.

---

## Changelog

- Add three feature flags: `default-collider`, `parry-f32`, and `parry-f64`
- `ColliderAabb` no longer uses Parry's AABB, and it has new methods

## Migration Guide

- If using bevy_xpbd without default features, add either the `parry-f32` or `parry-f64` feature, unless you have a custom collision backend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality C-Enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant