pub struct SpringJoint {
pub body_a: usize,
pub body_b: usize,
pub local_anchor_a: Vec3Fix,
pub local_anchor_b: Vec3Fix,
pub rest_length: Fix128,
pub stiffness: Fix128,
pub damping: Fix128,
pub break_force: Option<Fix128>,
}Expand description
Spring joint: a spring-damper between two anchor points
The joint applies the force (on B; A receives the opposite)
rest_length == 0:F = −k d − c u, withd = anchor_b − anchor_aandu = d'the relative anchor velocity. Spring and damper are both isotropic, so the damper removes the tangential relative velocity as well as the radial one and a body held by the spring does not orbit its anchor.rest_length > 0:F = −(k (|d| − L) + c (u · n)) n,n = d / |d|, the usual spring with a dashpot along its axis. The direction across the axis is free (a pendulum stays a pendulum), as for a physical spring-damper element; userest_length = 0to hold a body at a point.
For a body of mass m held against a static or kinematic anchor (or
two bodies with m_eff = 1 / (1/m_a + 1/m_b)), angular frequency ω
and damping ratio ζ, use stiffness = m_eff ω² and
damping = 2 ζ m_eff ω; ζ = 1 (damping = 2 √(k m_eff)) is critical
damping, x(t) = (x0 + (v0 + ω x0) t) e^(−ωt) with no overshoot.
It is solved once per substep as an XPBD constraint with damping
(Macklin, Müller, Chentanez 2016, eq. 26), which is a backward Euler step
of the force law: the result converges to the same continuous solution
for any substeps, does not depend on iterations, and is stable for
any k and c. Each joint carries its own stiffness / damping, so
springs of different ω can share one world. SolverConfig::damping
and the per-body damping factors are applied on top, once per frame.
Fields§
§body_a: usizeIndex of the first body
body_b: usizeIndex of the second body
local_anchor_a: Vec3FixAnchor point in body A’s local space
local_anchor_b: Vec3FixAnchor point in body B’s local space
rest_length: Fix128Rest length L of the spring in metres. 0 makes the spring and the
damper isotropic (see the type doc)
stiffness: Fix128Spring stiffness k in newtons per metre (m_eff ω² for angular
frequency ω). Independent of the step length and of substeps
damping: Fix128Damping coefficient c in newton-seconds per metre, acting on the
relative anchor velocity (every component for rest_length = 0, the
component along the spring otherwise). Critical damping is
c = 2 √(k m_eff)
break_force: Option<Fix128>Maximum spring force |k (|d| − L)| in newtons before the joint
breaks (None = unbreakable), see solve_joints_breakable
Implementations§
Trait Implementations§
Source§impl Clone for SpringJoint
impl Clone for SpringJoint
impl Copy for SpringJoint
Source§impl Debug for SpringJoint
impl Debug for SpringJoint
impl Eq for SpringJoint
Source§impl PartialEq for SpringJoint
impl PartialEq for SpringJoint
impl StructuralPartialEq for SpringJoint
Auto Trait Implementations§
impl Freeze for SpringJoint
impl RefUnwindSafe for SpringJoint
impl Send for SpringJoint
impl Sync for SpringJoint
impl Unpin for SpringJoint
impl UnsafeUnpin for SpringJoint
impl UnwindSafe for SpringJoint
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more