Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LinearDamping and AngularDamping #56

Merged
merged 1 commit into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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