Skip to content
This repository has been archived by the owner on Nov 29, 2022. It is now read-only.

Continuous Collision Detection support #199

Open
Kerollmops opened this issue Feb 26, 2022 · 2 comments
Open

Continuous Collision Detection support #199

Kerollmops opened this issue Feb 26, 2022 · 2 comments
Labels
enhancement New feature or improvement up-for-grabs Good for newcomers

Comments

@Kerollmops
Copy link

Kerollmops commented Feb 26, 2022

I am currently using heron for the Bevy Jam #1 and other projects too, I like it a lot.

But I am spawning some fast-moving entities in the world and was wondering if there were any way to enable the continuous-collision-detection options on a rigid body. I remember something in the heron documentation about being able to call raw rapier methods, am I right?

IIRC, it looks highly related to #43.

@jcornaz
Copy link
Owner

jcornaz commented Feb 26, 2022

There is no "first-class" abstraction for that.

But you may retrieve and mutate the rapier rigid body that is in the RigidBodySet resource via the RigidBodyHandle that is inserted in entities.

Example:

// Treat the following as pseudo-code, I didn't check if it would even compile!
fn enable_ccd(mut rigid_bodies: ResMut<RigidBodySet>, new_handles: Query<&RigidBodyHandle, Added<RigidBodyHandle>>) {
  for handle in new_handles.iter() {
    if let Some(body) = rigid_bodies.get_mut(handle.into_rapier()) {
       body.enable_ccd(true);
    }
  }
}

I leave this issue open as a request to add a "first-class" abstraction for enabling CCD. I guess the simplest approach would be to provide a CCD compnent. Inserting the component would enable CCD for the body, Removing the component would disable it.

@jcornaz jcornaz added enhancement New feature or improvement up-for-grabs Good for newcomers labels Feb 26, 2022
@jcornaz jcornaz changed the title Can CCD be enabled on rigid bodies somehow? Continuous Collision Detection support Feb 26, 2022
@jakoschiko
Copy link

jakoschiko commented Apr 6, 2022

Thanks!
This code compiles and solves the problem:

use bevy::prelude::*;
use heron::{
    prelude::*,
    rapier_plugin::{convert::IntoRapier, rapier2d::prelude::RigidBodySet, RigidBodyHandle},
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Component)]
pub enum Ccd {
    Disabled,
    Enabled,
}

impl Default for Ccd {
    fn default() -> Self {
        Self::Disabled
    }
}

pub struct PhysicsExtensionPlugin;

impl Plugin for PhysicsExtensionPlugin {
    fn build(&self, app: &mut App) {
        app.add_system_to_stage(CoreStage::First, update_ccd_for_body);
    }
}

fn update_ccd_for_body(
    mut rigid_bodies: ResMut<RigidBodySet>,
    new_handles: Query<(&RigidBodyHandle, &Ccd), Or<(Added<RigidBodyHandle>, Changed<Ccd>)>>,
) {
    for (&handle, &ccd) in new_handles.iter() {
        if let Some(body) = rigid_bodies.get_mut(handle.into_rapier()) {
            let enable = match ccd {
                Ccd::Enabled => true,
                Ccd::Disabled => false,
            };
            body.enable_ccd(enable);
        }
    }
}

Edit: Added the Or<...> because the Changed<Ccd> event can get lost for new bodies if heron is used with a fixed timestep.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or improvement up-for-grabs Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants