bevy_xpbd icon indicating copy to clipboard operation
bevy_xpbd copied to clipboard

Feature request: position-based kinematic rigidbody

Open lotus128 opened this issue 1 year ago • 1 comments

I would like a position-based kinematic rigidbody type.

lotus128 avatar Nov 16 '24 23:11 lotus128

Here's a pretty basic (and completely untested and probably not working) example of how this might be implemented.

I hope this helps illustrate what is meant, and maybe someone can get it working properly:

// Add it like this: .add_systems(FixedPostUpdate, ImplicitVelocity::system.in_set(SyncSet::Last))
#[derive(Default, Component)]
pub struct ImplicitVelocity {
    pub previous_position: Position,
    pub previous_rotation: Rotation,
}
impl ImplicitVelocity {
    fn system(
        mut query: Query<(
            &mut ImplicitVelocity,
            &mut Position,
            &mut Rotation,
            &mut LinearVelocity,
            &mut AngularVelocity,
            &ComputedCenterOfMass,
        )>,
        time: Res<Time>,
    ) {
        let one_over_dt = 1.0 / time.delta_secs();
        for (mut implicit_vel, mut p1, mut r1, mut v_linear, mut v_angular, center_mass) in query {
            let ImplicitVelocity {
                previous_position: p0,
                previous_rotation: r0,
            } = *implicit_vel;

            let rotation_delta = r1.0 * r0.0.inverse();
            let position_delta = {
                let new_center_mass = (r1.0 * center_mass.0) + p1.0;
                let old_center_mass = (r0.0 * center_mass.0) + p0.0;
                new_center_mass - old_center_mass
            };

            v_linear.0 = one_over_dt * position_delta;
            v_angular.0 = {
                let (axis, angle) = rotation_delta.to_axis_angle();
                axis * (one_over_dt * angle)
            };

            swap(&mut implicit_vel.previous_position, &mut *p1);
            swap(&mut implicit_vel.previous_rotation, &mut *r1);
        }
    }
}

Cannedfood avatar May 19 '25 18:05 Cannedfood