bevy_xpbd
bevy_xpbd copied to clipboard
Feature request: position-based kinematic rigidbody
I would like a position-based kinematic rigidbody type.
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);
}
}
}