aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2022-01-02 14:47:40 +0100
committerSébastien Crozet <developer@crozet.re>2022-01-02 16:58:36 +0100
commitf74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc (patch)
tree53ac492fea5942a7d466f58a0095f39505674ea4 /src/dynamics
parentb45d4b5ac2b31856c15e802b31e288a58940cbf2 (diff)
downloadrapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.tar.gz
rapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.tar.bz2
rapier-f74b8401ad9ef50b8cdbf1f43a2b21f6c42b0ebc.zip
Implement multibody joints and the new solver
Diffstat (limited to 'src/dynamics')
-rw-r--r--src/dynamics/integration_parameters.rs96
-rw-r--r--src/dynamics/island_manager.rs13
-rw-r--r--src/dynamics/joint/ball_joint.rs148
-rw-r--r--src/dynamics/joint/fixed_joint.rs73
-rw-r--r--src/dynamics/joint/generic_joint.rs144
-rw-r--r--src/dynamics/joint/impulse_joint/impulse_joint.rs20
-rw-r--r--src/dynamics/joint/impulse_joint/impulse_joint_set.rs (renamed from src/dynamics/joint/joint_set.rs)73
-rw-r--r--src/dynamics/joint/impulse_joint/mod.rs6
-rw-r--r--src/dynamics/joint/joint.rs143
-rw-r--r--src/dynamics/joint/joint_data.rs270
-rw-r--r--src/dynamics/joint/mod.rs27
-rw-r--r--src/dynamics/joint/motor_model.rs (renamed from src/dynamics/joint/spring_model.rs)36
-rw-r--r--src/dynamics/joint/multibody_joint/mod.rs15
-rw-r--r--src/dynamics/joint/multibody_joint/multibody.rs1021
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_joint.rs571
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_joint_set.rs352
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_link.rs173
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_workspace.rs27
-rw-r--r--src/dynamics/joint/multibody_joint/unit_multibody_joint.rs122
-rw-r--r--src/dynamics/joint/prismatic_joint.rs289
-rw-r--r--src/dynamics/joint/revolute_joint.rs220
-rw-r--r--src/dynamics/joint/spherical_joint.rs91
-rw-r--r--src/dynamics/mod.rs15
-rw-r--r--src/dynamics/rigid_body_components.rs168
-rw-r--r--src/dynamics/rigid_body_set.rs18
-rw-r--r--src/dynamics/solver/categorization.rs36
-rw-r--r--src/dynamics/solver/delta_vel.rs24
-rw-r--r--src/dynamics/solver/generic_velocity_constraint.rs377
-rw-r--r--src/dynamics/solver/generic_velocity_constraint_element.rs348
-rw-r--r--src/dynamics/solver/interaction_groups.rs13
-rw-r--r--src/dynamics/solver/island_solver.rs151
-rw-r--r--src/dynamics/solver/joint_constraint/ball_position_constraint.rs266
-rw-r--r--src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs216
-rw-r--r--src/dynamics/solver/joint_constraint/ball_velocity_constraint.rs660
-rw-r--r--src/dynamics/solver/joint_constraint/ball_velocity_constraint_wide.rs359
-rw-r--r--src/dynamics/solver/joint_constraint/fixed_position_constraint.rs151
-rw-r--r--src/dynamics/solver/joint_constraint/fixed_position_constraint_wide.rs71
-rw-r--r--src/dynamics/solver/joint_constraint/fixed_velocity_constraint.rs436
-rw-r--r--src/dynamics/solver/joint_constraint/fixed_velocity_constraint_wide.rs539
-rw-r--r--src/dynamics/solver/joint_constraint/generic_position_constraint.rs346
-rw-r--r--src/dynamics/solver/joint_constraint/generic_position_constraint_wide.rs60
-rw-r--r--src/dynamics/solver/joint_constraint/generic_velocity_constraint.rs706
-rw-r--r--src/dynamics/solver/joint_constraint/generic_velocity_constraint_wide.rs464
-rw-r--r--src/dynamics/solver/joint_constraint/joint_constraint.rs710
-rw-r--r--src/dynamics/solver/joint_constraint/joint_generic_velocity_constraint.rs529
-rw-r--r--src/dynamics/solver/joint_constraint/joint_generic_velocity_constraint_builder.rs853
-rw-r--r--src/dynamics/solver/joint_constraint/joint_position_constraint.rs280
-rw-r--r--src/dynamics/solver/joint_constraint/joint_velocity_constraint.rs608
-rw-r--r--src/dynamics/solver/joint_constraint/joint_velocity_constraint_builder.rs699
-rw-r--r--src/dynamics/solver/joint_constraint/mod.rs107
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_position_constraint.rs182
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_position_constraint_wide.rs71
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_velocity_constraint.rs859
-rw-r--r--src/dynamics/solver/joint_constraint/prismatic_velocity_constraint_wide.rs848
-rw-r--r--src/dynamics/solver/joint_constraint/revolute_position_constraint.rs295
-rw-r--r--src/dynamics/solver/joint_constraint/revolute_position_constraint_wide.rs71
-rw-r--r--src/dynamics/solver/joint_constraint/revolute_velocity_constraint.rs750
-rw-r--r--src/dynamics/solver/joint_constraint/revolute_velocity_constraint_wide.rs527
-rw-r--r--src/dynamics/solver/mod.rs27
-rw-r--r--src/dynamics/solver/parallel_island_solver.rs156
-rw-r--r--src/dynamics/solver/parallel_position_solver.rs107
-rw-r--r--src/dynamics/solver/parallel_solver_constraints.rs101
-rw-r--r--src/dynamics/solver/parallel_velocity_solver.rs111
-rw-r--r--src/dynamics/solver/position_constraint.rs168
-rw-r--r--src/dynamics/solver/position_constraint_wide.rs157
-rw-r--r--src/dynamics/solver/position_ground_constraint.rs121
-rw-r--r--src/dynamics/solver/position_ground_constraint_wide.rs143
-rw-r--r--src/dynamics/solver/position_solver.rs57
-rw-r--r--src/dynamics/solver/solver_constraints.rs317
-rw-r--r--src/dynamics/solver/velocity_constraint.rs131
-rw-r--r--src/dynamics/solver/velocity_constraint_element.rs114
-rw-r--r--src/dynamics/solver/velocity_constraint_wide.rs110
-rw-r--r--src/dynamics/solver/velocity_ground_constraint.rs77
-rw-r--r--src/dynamics/solver/velocity_ground_constraint_element.rs81
-rw-r--r--src/dynamics/solver/velocity_ground_constraint_wide.rs93
-rw-r--r--src/dynamics/solver/velocity_solver.rs222
76 files changed, 7809 insertions, 11227 deletions
diff --git a/src/dynamics/integration_parameters.rs b/src/dynamics/integration_parameters.rs
index 4725319..d998eec 100644
--- a/src/dynamics/integration_parameters.rs
+++ b/src/dynamics/integration_parameters.rs
@@ -18,18 +18,6 @@ pub struct IntegrationParameters {
/// to numerical instabilities.
pub min_ccd_dt: Real,
- /// The Error Reduction Parameter in `[0, 1]` is the proportion of
- /// the positional error to be corrected at each time step (default: `0.2`).
- pub erp: Real,
- /// The Error Reduction Parameter for joints in `[0, 1]` is the proportion of
- /// the positional error to be corrected at each time step (default: `0.2`).
- pub joint_erp: Real,
- /// Each cached impulse are multiplied by this coefficient in `[0, 1]`
- /// when they are re-used to initialize the solver (default `1.0`).
- pub warmstart_coeff: Real,
- /// Correction factor to avoid large warmstart impulse after a strong impact (default `10.0`).
- pub warmstart_correction_slope: Real,
-
/// 0-1: how much of the velocity to dampen out in the constraint solver?
/// (default `1.0`).
pub velocity_solve_fraction: Real,
@@ -40,23 +28,21 @@ pub struct IntegrationParameters {
/// If non-zero, you do not need the positional solver.
/// A good non-zero value is around `0.2`.
/// (default `0.0`).
- pub velocity_based_erp: Real,
+ pub erp: Real,
- /// Amount of penetration the engine wont attempt to correct (default: `0.005m`).
+ /// Amount of penetration the engine wont attempt to correct (default: `0.001m`).
pub allowed_linear_error: Real,
/// The maximal distance separating two objects that will generate predictive contacts (default: `0.002`).
pub prediction_distance: Real,
- /// Amount of angular drift of joint limits the engine wont
- /// attempt to correct (default: `0.001rad`).
- pub allowed_angular_error: Real,
- /// Maximum linear correction during one step of the non-linear position solver (default: `0.2`).
- pub max_linear_correction: Real,
- /// Maximum angular correction during one step of the non-linear position solver (default: `0.2`).
- pub max_angular_correction: Real,
- /// Maximum number of iterations performed by the velocity constraints solver (default: `4`).
+ /// Maximum number of iterations performed to solve non-penetration and joint constraints (default: `4`).
pub max_velocity_iterations: usize,
- /// Maximum number of iterations performed by the position-based constraints solver (default: `1`).
- pub max_position_iterations: usize,
+ /// Maximum number of iterations performed to solve friction constraints (default: `8`).
+ pub max_velocity_friction_iterations: usize,
+ /// Maximum number of iterations performed to remove the energy introduced by penetration corrections (default: `1`).
+ pub max_stabilization_iterations: usize,
+ /// If `false`, friction and non-penetration constraints will be solved in the same loop. Otherwise,
+ /// non-penetration constraints are solved first, and friction constraints are solved after (default: `true`).
+ pub interleave_restitution_and_friction_resolution: bool,
/// Minimum number of dynamic bodies in each active island (default: `128`).
pub min_island_size: usize,
/// Maximum number of substeps performed by the solver (default: `1`).
@@ -64,46 +50,6 @@ pub struct IntegrationParameters {
}
impl IntegrationParameters {
- /// Creates a set of integration parameters with the given values.
- #[deprecated = "Use `IntegrationParameters { dt: 60.0, ..Default::default() }` instead"]
- pub fn new(
- dt: Real,
- erp: Real,
- joint_erp: Real,
- warmstart_coeff: Real,
- allowed_linear_error: Real,
- allowed_angular_error: Real,
- max_linear_correction: Real,
- max_angular_correction: Real,
- prediction_distance: Real,
- max_velocity_iterations: usize,
- max_position_iterations: usize,
- max_ccd_substeps: usize,
- ) -> Self {
- IntegrationParameters {
- dt,
- erp,
- joint_erp,
- warmstart_coeff,
- allowed_linear_error,
- allowed_angular_error,
- max_linear_correction,
- max_angular_correction,
- prediction_distance,
- max_velocity_iterations,
- max_position_iterations,
- max_ccd_substeps,
- ..Default::default()
- }
- }
-
- /// The current time-stepping length.
- #[inline(always)]
- #[deprecated = "You can just read the `IntegrationParams::dt` value directly"]
- pub fn dt(&self) -> Real {
- self.dt
- }
-
/// The inverse of the time-stepping length, i.e. the steps per seconds (Hz).
///
/// This is zero if `self.dt` is zero.
@@ -136,10 +82,10 @@ impl IntegrationParameters {
}
}
- /// Convenience: `velocity_based_erp / dt`
+ /// Convenience: `erp / dt`
#[inline]
- pub(crate) fn velocity_based_erp_inv_dt(&self) -> Real {
- self.velocity_based_erp * self.inv_dt()
+ pub(crate) fn erp_inv_dt(&self) -> Real {
+ self.erp * self.inv_dt()
}
}
@@ -148,20 +94,14 @@ impl Default for IntegrationParameters {
Self {
dt: 1.0 / 60.0,
min_ccd_dt: 1.0 / 60.0 / 100.0,
- // multithreading_enabled: true,
- erp: 0.2,
- joint_erp: 0.2,
velocity_solve_fraction: 1.0,
- velocity_based_erp: 0.0,
- warmstart_coeff: 1.0,
- warmstart_correction_slope: 10.0,
- allowed_linear_error: 0.005,
+ erp: 0.8,
+ allowed_linear_error: 0.001, // 0.005
prediction_distance: 0.002,
- allowed_angular_error: 0.001,
- max_linear_correction: 0.2,
- max_angular_correction: 0.2,
max_velocity_iterations: 4,
- max_position_iterations: 1,
+ max_velocity_friction_iterations: 8,
+ max_stabilization_iterations: 1,
+ interleave_restitution_and_friction_resolution: true, // Enabling this makes a big difference for 2D stability.
// FIXME: what is the optimal value for min_island_size?
// It should not be too big so that we don't end up with
// huge islands that don't fit in cache.
diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs
index 10ac0f8..55b47c9 100644
--- a/src/dynamics/island_manager.rs
+++ b/src/dynamics/island_manager.rs
@@ -1,7 +1,7 @@
use crate::data::{BundleSet, ComponentSet, ComponentSetMut, ComponentSetOption};
use crate::dynamics::{
- JointSet, RigidBodyActivation, RigidBodyColliders, RigidBodyHandle, RigidBodyIds,
- RigidBodyType, RigidBodyVelocity,
+ ImpulseJointSet, MultibodyJointSet, RigidBodyActivation, RigidBodyColliders, RigidBodyHandle,
+ RigidBodyIds, RigidBodyType, RigidBodyVelocity,
};
use crate::geometry::{ColliderParent, NarrowPhase};
use crate::math::Real;
@@ -175,7 +175,8 @@ impl IslandManager {
bodies: &mut Bodies,
colliders: &Colliders,
narrow_phase: &NarrowPhase,
- joints: &JointSet,
+ impulse_joints: &ImpulseJointSet,
+ multibody_joints: &MultibodyJointSet,
min_island_size: usize,
) where
Bodies: ComponentSetMut<RigidBodyIds>
@@ -302,11 +303,15 @@ impl IslandManager {
// in contact or joined with this collider.
push_contacting_bodies(rb_colliders, colliders, narrow_phase, &mut self.stack);
- for inter in joints.joints_with(handle) {
+ for inter in impulse_joints.joints_with(handle) {
let other = crate::utils::select_other((inter.0, inter.1), handle);
self.stack.push(other);
}
+ for other in multibody_joints.attached_bodies(handle) {
+ self.stack.push(other);
+ }
+
bodies.map_mut_internal(handle.0, |activation: &mut RigidBodyActivation| {
activation.wake_up(false);
});
diff --git a/src/dynamics/joint/ball_joint.rs b/src/dynamics/joint/ball_joint.rs
deleted file mode 100644
index 0b626c0..0000000
--- a/src/dynamics/joint/ball_joint.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-use crate::dynamics::SpringModel;
-use crate::math::{Point, Real, Rotation, UnitVector, Vector};
-
-#[derive(Copy, Clone, PartialEq)]
-#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
-/// A joint that removes all relative linear motion between a pair of points on two bodies.
-pub struct BallJoint {
- /// Where the ball joint is attached on the first body, expressed in the first body local frame.
- pub local_anchor1: Point<Real>,
- /// Where the ball joint is attached on the second body, expressed in the second body local frame.
- pub local_anchor2: Point<Real>,
- /// The impulse applied by this joint on the first body.
- ///
- /// The impulse applied to the second body is given by `-impulse`.
- pub impulse: Vector<Real>,
-
- /// The target relative angular velocity the motor will attempt to reach.
- #[cfg(feature = "dim2")]
- pub motor_target_vel: Real,
- /// The target relative angular velocity the motor will attempt to reach.
- #[cfg(feature = "dim3")]
- pub motor_target_vel: Vector<Real>,
- /// The target angular position of this joint, expressed as an axis-angle.
- pub motor_target_pos: Rotation<Real>,
- /// The motor's stiffness.
- /// See the documentation of `SpringModel` for more information on this parameter.
- pub motor_stiffness: Real,
- /// The motor's damping.
- /// See the documentation of `SpringModel` for more information on this parameter.
- pub motor_damping: Real,
- /// The maximal impulse the motor is able to deliver.
- pub motor_max_impulse: Real,
- /// The angular impulse applied by the motor.
- #[cfg(feature = "dim2")]
- pub motor_impulse: Real,
- /// The angular impulse applied by the motor.
- #[cfg(feature = "dim3")]
- pub motor_impulse: Vector<Real>,
- /// The spring-like model used by the motor to reach the target velocity and .
- pub motor_model: SpringModel,
-
- /// Are the limits enabled for this joint?
- pub limits_enabled: bool,
- /// The axis of the limit cone for this joint, if the local-space of the first body.
- pub limits_local_axis1: UnitVector<Real>,
- /// The axis of the limit cone for this joint, if the local-space of the first body.
- pub limits_local_axis2: UnitVector<Real>,
- /// The maximum angle allowed between the two limit axes in world-space.
- pub limits_angle: Real,
- /// The impulse applied to enforce joint limits.
- pub limits_impulse: Real,
-}
-
-impl BallJoint {
- /// Creates a new Ball joint from two anchors given on the local spaces of the respective bodies.
- pub fn new(local_anchor1: Point<Real>, local_anchor2: Point<Real>) -> Self {
- Self::with_impulse(local_anchor1, local_anchor2, Vector::zeros())
- }
-
- pub(crate) fn with_impulse(
- local_anchor1: Point<Real>,
- local_anchor2: Point<Real>,
- impulse: Vector<Real>,
- ) -> Self {
- Self {
- local_anchor1,
- local_anchor2,
- impulse,
- motor_target_vel: na::zero(),
- motor_target_pos: Rotation::identity(),
- motor_stiffness: 0.0,
- motor_damping: 0.0,
- motor_impulse: na::zero(),
- motor_max_impulse: Real::MAX,
- motor_model: SpringModel::default(),
- limits_enabled: false,
- limits_local_axis1: Vector::x_axis(),
- limits_local_axis2: Vector::x_axis(),
- limits_angle: Real::MAX,
- limits_impulse: 0.0,
- }
- }
-
- /// Can a SIMD constraint be used for resolving this joint?
- pub fn supports_simd_constraints(&self) -> bool {
- // SIMD ball constraints don't support motors and limits right now.
- !self.limits_enabled
- && (self.motor_max_impulse == 0.0
- || (self.motor_stiffness == 0.0 && self.motor_damping == 0.0))
- }
-
- /// Set the spring-like model used by the motor to reach the desired target velocity and position.
- pub fn configure_motor_model(&mut self, model: SpringModel) {
- self.motor_model = model;
- }
-
- /// Sets the target velocity and velocity correction factor this motor.
- #[cfg(feature = "dim2")]
- pub fn configure_motor_velocity(&mut self, target_vel: Real, factor: Real) {
- self.configure_motor(self.motor_target_pos, target_vel, 0.0, factor)
- }
-
- /// Sets the target velocity and velocity correction factor this motor.
- #[cfg(feature = "dim3")]
- pub fn configure_motor_velocity(&mut self, target_vel: Vector<Real>, factor: Real) {
- self.configure_motor(self.motor_target_pos, target_vel, 0.0, factor)
- }
-
- /// Sets the target orientation this motor needs to reach.
- pub fn configure_motor_position(
- &mut self,
- target_pos: Rotation<Real>,
- stiffness: Real,
- damping: Real,
- ) {
- self.configure_motor(target_pos, na::zero(), stiffness, damping)
- }
-
- /// Sets the target orientation this motor needs to reach.
- #[cfg(feature = "dim2")]
- pub fn configure_motor(
- &mut self,
- target_pos: Rotation<Real>,
- target_vel: Real,
- stiffness: Real,
- damping: Real,
- ) {
- self.motor_target_vel = target_vel;
- self.motor_target_pos = target_pos;
- self.motor_stiffness = stiffness;
- self.motor_damping = damping;
- }
-
- /// Configure both the target orientation and target velocity of the motor.
- #[cfg(feature = "dim3")]
- pub fn configure_motor(
- &mut self,
- target_pos: Rotation<Real>,
- target_vel: Vector<Real>,
- stiffness: Real,
- damping: Real,
- ) {
- self.motor_target_vel = target_vel;
- self.motor_target_pos = target_pos;
- self.motor_stiffness = stiffness;
- self.motor_damping = damping