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

Scene colliders #104

Closed
Shatur opened this issue Jul 30, 2023 · 4 comments · Fixed by #190
Closed

Scene colliders #104

Shatur opened this issue Jul 30, 2023 · 4 comments · Fixed by #190
Labels
A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality C-Enhancement New feature or request

Comments

@Shatur
Copy link

Shatur commented Jul 30, 2023

Rapier have AsyncSceneCollider to automatically generate collision after scene spawn.
I would suggest to add a similar feature for convenience, but with the ability to specify collider layers.

@Jondolf Jondolf added C-Enhancement New feature or request A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality labels Jul 31, 2023
@Jondolf
Copy link
Owner

Jondolf commented Jul 31, 2023

Yeah I think this should be relatively straightforward to add. I think Rapier just waits until the mesh/scene is ready and then adds the collider.

However, I was wondering if it would be possible to generate colliders from meshes in advance once Assets V2 is ready. For convex decomposition, the VHACD algorithm that Parry uses is pretty expensive and can even take several minutes for large colliders, so ideally we would have a preprocessing step where colliders are generated at compile-time with configuration for things like detail.

I haven't taken a proper look at Assets V2 yet though so I don't know if this would even be possible or if it would require a cumbersome API, but it's worth considering. For now though we can just add normal async colliders, I'll add it on my todo list

@donkey-donkey
Copy link

Rapier have AsyncSceneCollider to automatically generate collision after scene spawn. I would suggest to add a similar feature for convenience, but with the ability to specify collider layers.

Have you implemented any workarounds for the time being? Im using rapier's AsyncSceneCollider atm and we would love to try out xpbd.

@Jondolf
Copy link
Owner

Jondolf commented Aug 15, 2023

Rapier have AsyncSceneCollider to automatically generate collision after scene spawn. I would suggest to add a similar feature for convenience, but with the ability to specify collider layers.

Have you implemented any workarounds for the time being? Im using rapier's AsyncSceneCollider atm and we would love to try out xpbd.

Not yet, but something lïke AsyncSceneCollider should be straightforward to add into your app even without forking the crate. You can basically copy Rapier's implementation by just adding an AsyncSceneCollider component and a system that initializes the actual colliders.

You can find AsyncSceneCollider here and the system here. Instead of Collider::from_bevy_mesh, you can use Collider::trimesh_from_bevy_mesh or Collider::convex_decomposition_from_bevy_mesh.

For normal AsyncColliders, you can find similar implementations.

Jondolf added a commit that referenced this issue Oct 27, 2023
# Objective

Fixes #104. Depends on #154 and #189.

Currently, there's no easy way to add colliders to meshes loaded from scenes (glTFs and so on). A very common request is to have a way to generate the colliders automatically.

## Solution

Add `AsyncCollider` and `AsyncSceneCollider`, which are essentially equivalents to bevy_rapier's components. Also add a `ComputedCollider` enum that determines if the colliders should be trimeshes or convex hulls. Because these rely on some Bevy features, there is a new `async-collider` feature that is enabled by default, but only in 3D because colliders can't be created from meshes in 2D currently.

### `AsyncCollider` example:

```rust
use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*;

fn setup(mut commands: Commands, mut assets: ResMut<AssetServer>) {
    // Spawn a cube with a convex hull collider generated from the mesh
    commands.spawn((
        AsyncCollider(ComputedCollider::ConvexHull),
        PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
            ..default(),
        },
    ));
}
```

### `AsyncSceneCollider` example:

```rust
use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*;

fn setup(mut commands: Commands, mut assets: ResMut<AssetServer>) {
    let scene = SceneBundle {
        scene: assets.load("my_model.gltf#Scene0"),
        ..default()
    };

    // Spawn the scene and automatically generate triangle mesh colliders
    commands.spawn((
        scene.clone(),
        AsyncSceneCollider::new(Some(ComputedCollider::TriMesh)),
    ));

    // Specify configuration for specific meshes by name
    commands.spawn((
        scene.clone(),
        AsyncSceneCollider::new(Some(ComputedCollider::TriMesh))
            .with_shape_for_name("Tree", ComputedCollider::ConvexHull)
            .with_layers_for_name("Tree", CollisionLayers::from_bits(0b0010))
            .with_density_for_name("Tree", 2.5),
    ));

    // Only generate colliders for specific meshes by name
    commands.spawn((
        scene.clone(),
        AsyncSceneCollider::new(None)
            .with_shape_for_name("Tree".to_string(), Some(ComputedCollider::ConvexHull)),
    ));

    // Generate colliders for everything except specific meshes by name
    commands.spawn((
        scene,
        AsyncSceneCollider::new(ComputedCollider::TriMesh)
            .without_shape_for_name("Tree"),
    ));
}
```

---

## Changes to methods

I also renamed and added some more methods to make things more consistent and simple. I removed `_bevy` from the names because this crate is already for Bevy so it's unnecessary to have the prefix.

### Renamed

- `trimesh_with_flags` → `trimesh_with_config`
- `convex_decomposition_with_params` → `convex_decomposition_with_config`
- `trimesh_from_bevy_mesh` → `trimesh_from_mesh`
- `trimesh_from_bevy_mesh_with_flags` → `trimesh_from_mesh_with_config`
- `convex_decomposition_from_bevy_mesh` → `convex_decomposition_from_mesh`

### Added

- `convex_decomposition_from_mesh_with_config`
- `convex_hull_from_mesh`
@sphinxc0re
Copy link

Hey 👋🏼 firstly: Thank you for creating Avian ❤️

Should this be reopened? I wasn't able to find anything related to scenes in the documentation 🤔

(I was so excited to have a simple solution, but it wasn't meant to be 🥲)

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 a pull request may close this issue.

4 participants