rapier3d/dynamics/joint/
motor_model.rs

1use crate::math::Real;
2
3/// The spring-like model used for constraints resolution.
4#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
5#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
6pub enum MotorModel {
7    /// The solved spring-like equation is:
8    /// `acceleration = stiffness * (pos - target_pos) + damping * (vel - target_vel)`
9    #[default]
10    AccelerationBased,
11    /// The solved spring-like equation is:
12    /// `force = stiffness * (pos - target_pos) + damping * (vel - target_vel)`
13    ForceBased,
14}
15
16impl MotorModel {
17    /// Combines the coefficients used for solving the spring equation.
18    ///
19    /// Returns the coefficients (erp_inv_dt, cfm_coeff, cfm_gain).
20    pub fn combine_coefficients(
21        self,
22        dt: Real,
23        stiffness: Real,
24        damping: Real,
25    ) -> (Real, Real, Real) {
26        match self {
27            MotorModel::AccelerationBased => {
28                let erp_inv_dt = stiffness * crate::utils::inv(dt * stiffness + damping);
29                let cfm_coeff = crate::utils::inv(dt * dt * stiffness + dt * damping);
30                (erp_inv_dt, cfm_coeff, 0.0)
31            }
32            MotorModel::ForceBased => {
33                let erp_inv_dt = stiffness * crate::utils::inv(dt * stiffness + damping);
34                let cfm_gain = crate::utils::inv(dt * dt * stiffness + dt * damping);
35                (erp_inv_dt, 0.0, cfm_gain)
36            }
37        }
38    }
39}