Skip to content

Commit

Permalink
Add LinearDamping and AngularDamping
Browse files Browse the repository at this point in the history
  • Loading branch information
Jondolf committed Jul 7, 2023
1 parent 263338c commit fa5ea98
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 8 deletions.
20 changes: 20 additions & 0 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,26 @@ impl From<Scalar> for Friction {
}
}

/// Automatically slows down a dynamic [rigid body](RigidBody), decreasing it's [linear velocity](LinearVelocity)
/// each frame. This can be used to simulate air resistance.
///
/// The default linear damping coefficient is `0.0`, which corresponds to no damping.
#[derive(
Component, Reflect, Debug, Clone, Copy, PartialEq, PartialOrd, Default, Deref, DerefMut,
)]
#[reflect(Component)]
pub struct LinearDamping(pub Scalar);

/// Automatically slows down a dynamic [rigid body](RigidBody), decreasing it's [angular velocity](AngularVelocity)
/// each frame. This can be used to simulate air resistance.
///
/// The default angular damping coefficient is `0.0`, which corresponds to no damping.
#[derive(
Component, Reflect, Debug, Clone, Copy, PartialEq, PartialOrd, Default, Deref, DerefMut,
)]
#[reflect(Component)]
pub struct AngularDamping(pub Scalar);

#[cfg(test)]
mod tests {
use crate::prelude::*;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
//! - [Sensor colliders](Sensor)
//! - [Collision layers](CollisionLayers)
//! - Material properties like [restitution](Restitution) and [friction](Friction)
//! - [Linear damping](LinearDamping) and [angular damping](AngularDamping) for simulating drag
//! - External [forces](ExternalForce) and [torque](ExternalTorque)
//! - [Gravity](Gravity)
//! - [Joints](joints)
Expand Down
49 changes: 41 additions & 8 deletions src/plugins/integrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type PosIntegrationComponents = (
&'static mut Position,
&'static mut PreviousPosition,
&'static mut LinearVelocity,
Option<&'static LinearDamping>,
&'static ExternalForce,
&'static Mass,
);
Expand All @@ -38,15 +39,20 @@ fn integrate_pos(
gravity: Res<Gravity>,
sub_dt: Res<SubDeltaTime>,
) {
for (rb, mut pos, mut prev_pos, mut lin_vel, external_force, mass) in &mut bodies {
for (rb, mut pos, mut prev_pos, mut lin_vel, lin_damping, external_force, mass) in &mut bodies {
prev_pos.0 = pos.0;

if rb.is_static() {
continue;
}

// Apply gravity and other external forces
// Apply damping, gravity and other external forces
if rb.is_dynamic() {
// Apply damping
if let Some(damping) = lin_damping {
lin_vel.0 *= 1.0 / (1.0 + sub_dt.0 * damping.0);
}

let gravitation_force = mass.0 * gravity.0;
let external_forces = gravitation_force + external_force.0;
lin_vel.0 += sub_dt.0 * external_forces / mass.0;
Expand All @@ -61,6 +67,7 @@ type RotIntegrationComponents = (
&'static mut Rotation,
&'static mut PreviousRotation,
&'static mut AngularVelocity,
Option<&'static AngularDamping>,
&'static ExternalTorque,
&'static Inertia,
&'static InverseInertia,
Expand All @@ -72,17 +79,30 @@ fn integrate_rot(
mut bodies: Query<RotIntegrationComponents, Without<Sleeping>>,
sub_dt: Res<SubDeltaTime>,
) {
for (rb, mut rot, mut prev_rot, mut ang_vel, external_torque, _inertia, inverse_inertia) in
&mut bodies
for (
rb,
mut rot,
mut prev_rot,
mut ang_vel,
ang_damping,
external_torque,
_inertia,
inverse_inertia,
) in &mut bodies
{
prev_rot.0 = *rot;

if rb.is_static() {
continue;
}

// Apply external torque
// Apply damping and external torque
if rb.is_dynamic() {
// Apply damping
if let Some(damping) = ang_damping {
ang_vel.0 *= 1.0 / (1.0 + sub_dt.0 * damping.0);
}

ang_vel.0 += sub_dt.0 * inverse_inertia.0 * external_torque.0;
}

Expand All @@ -96,17 +116,30 @@ fn integrate_rot(
mut bodies: Query<RotIntegrationComponents, Without<Sleeping>>,
sub_dt: Res<SubDeltaTime>,
) {
for (rb, mut rot, mut prev_rot, mut ang_vel, external_torque, inertia, inverse_inertia) in
&mut bodies
for (
rb,
mut rot,
mut prev_rot,
mut ang_vel,
ang_damping,
external_torque,
inertia,
inverse_inertia,
) in &mut bodies
{
prev_rot.0 = *rot;

if rb.is_static() {
continue;
}

// Apply external torque
// Apply damping and external torque
if rb.is_dynamic() {
// Apply damping
if let Some(damping) = ang_damping {
ang_vel.0 *= 1.0 / (1.0 + sub_dt.0 * damping.0);
}

let delta_ang_vel = sub_dt.0
* inverse_inertia.rotated(&rot).0
* (external_torque.0 - ang_vel.0.cross(inertia.rotated(&rot).0 * ang_vel.0));
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ impl Plugin for PhysicsSetupPlugin {
.register_type::<PreSolveAngularVelocity>()
.register_type::<Restitution>()
.register_type::<Friction>()
.register_type::<LinearDamping>()
.register_type::<AngularDamping>()
.register_type::<ExternalForce>()
.register_type::<ExternalTorque>()
.register_type::<Mass>()
Expand Down

0 comments on commit fa5ea98

Please sign in to comment.