avian_pickup 0.1.7

A plugin for implementing picking up dynamic rigid bodies in Avian physics for the Bevy engine.Modeled after Half Life 2's gravity gun.
Documentation
use avian3d::prelude::*;
use bevy::prelude::*;

pub(crate) const METERS_PER_INCH: f32 = 0.0254;
pub(crate) fn rigid_body_compound_collider(
    rigid_body_transform: &Transform,
    colliders: Option<&[Entity]>,
    q_collider: &Query<(&GlobalTransform, &Collider, Option<&CollisionLayers>)>,
    filter: &SpatialQueryFilter,
) -> Option<Collider> {
    let collider_entities = colliders?;
    let mut colliders = Vec::new();
    for &entity in collider_entities {
        let (transform, collider, layers) = q_collider.get(entity).ok()?;
        let transform = transform.compute_transform();
        let layers = layers.copied().unwrap_or_default();
        if filter.test(entity, layers) {
            let relative_translation = transform.translation - rigid_body_transform.translation;
            let relative_rotation = transform.rotation * rigid_body_transform.rotation.inverse();
            if let Some(compound) = collider.shape_scaled().as_compound() {
                // Need to unpack compound shapes because we are later returning a big compound collider for the whole rigid body
                // and parry crashes on nested compound shapes
                for (isometry, shape) in compound.shapes() {
                    let translation = Vec3::from(isometry.translation);
                    let rotation = Quat::from(isometry.rotation);
                    colliders.push((
                        relative_translation + translation,
                        relative_rotation * rotation,
                        shape.clone().into(),
                    ));
                }
            } else {
                colliders.push((relative_translation, relative_rotation, collider.clone()));
            }
        }
    }

    (!colliders.is_empty()).then(|| Collider::compound(colliders))
}