Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 0 additions & 15 deletions src/dynamics/integration_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,6 @@ pub struct IntegrationParameters {
/// (default: `30.0`).
pub contact_natural_frequency: Real,

/// > 0: the natural frequency used by the springs for joint constraint regularization.
///
/// Increasing this value will make it so that penetrations get fixed more quickly.
/// (default: `1.0e6`).
pub joint_natural_frequency: Real,

/// The fraction of critical damping applied to the joint for constraints regularization.
///
/// Larger values make the constraints more compliant (allowing more joint
/// drift before stabilization).
/// (default `1.0`).
pub joint_damping_ratio: Real,

/// The coefficient in `[0, 1]` applied to warmstart impulses, i.e., impulses that are used as the
/// initial solution (instead of 0) at the next simulation step.
///
Expand Down Expand Up @@ -280,8 +267,6 @@ impl IntegrationParameters {
min_ccd_dt: 1.0 / 60.0 / 100.0,
contact_natural_frequency: 30.0,
contact_damping_ratio: 5.0,
joint_natural_frequency: 1.0e6,
joint_damping_ratio: 1.0,
warmstart_coefficient: 1.0,
num_internal_pgs_iterations: 1,
num_internal_stabilization_iterations: 2,
Expand Down
20 changes: 6 additions & 14 deletions src/dynamics/joint/generic_joint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,23 +251,15 @@ pub struct GenericJoint {
/// > 0: the natural frequency used by the springs for joint constraint regularization.
///
/// Increasing this value will make it so that penetrations get fixed more quickly.
/// (default: [`None`]).
///
/// If [`None`],
/// [`IntegrationParameters::joint_natural_frequency`](crate::prelude::IntegrationParameters::joint_natural_frequency)
/// is used.
pub joint_natural_frequency: Option<Real>,
/// (default: `1.0e6`).
pub joint_natural_frequency: Real,

/// The fraction of critical damping applied to the joint for constraints regularization.
///
/// Larger values make the constraints more compliant (allowing more joint
/// drift before stabilization).
/// (default [`None`]).
///
/// If [`None`],
/// [`IntegrationParameters::joint_damping_ratio`](crate::prelude::IntegrationParameters::joint_damping_ratio)
/// is used.
pub joint_damping_ratio: Option<Real>,
/// (default `1.0`).
pub joint_damping_ratio: Real,
}

impl Default for GenericJoint {
Expand All @@ -284,8 +276,8 @@ impl Default for GenericJoint {
contacts_enabled: true,
enabled: JointEnabled::Enabled,
user_data: 0,
joint_natural_frequency: None,
joint_damping_ratio: None,
joint_natural_frequency: 1.0e6,
joint_damping_ratio: 1.0,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/dynamics/joint/multibody_joint/multibody_joint_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,10 @@ impl MultibodyJointSet {
pub fn multibodies(&self) -> impl Iterator<Item = &Multibody> {
self.multibodies.iter().map(|e| e.1)
}
/// Iterates through all the multibodies on this set.
pub fn multibody_links_mut(&mut self) -> impl Iterator<Item = &mut MultibodyLink> {
self.multibodies.iter_mut().flat_map(|e| e.1.links_mut())
}
}

impl std::ops::Index<MultibodyIndex> for MultibodyJointSet {
Expand Down
5 changes: 2 additions & 3 deletions src/dynamics/joint/multibody_joint/unit_multibody_joint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ pub fn unit_joint_limit_constraint(
constraints: &mut [JointGenericOneBodyConstraint],
insert_at: &mut usize,
) {
// TODO: use joint_natural_frequency and joint_damping_ratio from multibodies GenericJoint.
let joint_natural_frequency = params.joint_natural_frequency;
let joint_damping_ratio = params.joint_damping_ratio;
let joint_natural_frequency = link.joint.data.joint_natural_frequency;
let joint_damping_ratio = link.joint.data.joint_damping_ratio;

let ndofs = multibody.ndofs();
let min_enabled = curr_pos < limits[0];
Expand Down
16 changes: 4 additions & 12 deletions src/dynamics/solver/joint_constraint/joint_generic_constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,8 @@ impl JointGenericTwoBodyConstraint {
locked_axes,
);

let joint_natural_frequency = joint
.joint_natural_frequency
.unwrap_or(params.joint_natural_frequency);
let joint_damping_ratio = joint
.joint_damping_ratio
.unwrap_or(params.joint_damping_ratio);
let joint_natural_frequency = joint.joint_natural_frequency;
let joint_damping_ratio = joint.joint_damping_ratio;

let start = len;
for i in DIM..SPATIAL_DIM {
Expand Down Expand Up @@ -392,12 +388,8 @@ impl JointGenericOneBodyConstraint {
locked_axes,
);

let joint_natural_frequency = joint
.joint_natural_frequency
.unwrap_or(params.joint_natural_frequency);
let joint_damping_ratio = joint
.joint_damping_ratio
.unwrap_or(params.joint_damping_ratio);
let joint_natural_frequency = joint.joint_natural_frequency;
let joint_damping_ratio = joint.joint_damping_ratio;

let start = len;
for i in DIM..SPATIAL_DIM {
Expand Down
16 changes: 4 additions & 12 deletions src/dynamics/solver/joint_constraint/joint_velocity_constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,8 @@ impl JointTwoBodyConstraint<Real, 1> {
let limit_axes = joint.limit_axes.bits() & !locked_axes;
let coupled_axes = joint.coupled_axes.bits();

let joint_natural_frequency = joint
.joint_natural_frequency
.unwrap_or(params.joint_natural_frequency);
let joint_damping_ratio = joint
.joint_damping_ratio
.unwrap_or(params.joint_damping_ratio);
let joint_natural_frequency = joint.joint_natural_frequency;
let joint_damping_ratio = joint.joint_damping_ratio;
// The has_lin/ang_coupling test is needed to avoid shl overflow later.
let has_lin_coupling = (coupled_axes & JointAxesMask::LIN_AXES.bits()) != 0;
let first_coupled_lin_axis_id =
Expand Down Expand Up @@ -532,12 +528,8 @@ impl JointOneBodyConstraint<Real, 1> {
let limit_axes = joint.limit_axes.bits() & !locked_axes;
let coupled_axes = joint.coupled_axes.bits();

let joint_natural_frequency = joint
.joint_natural_frequency
.unwrap_or(params.joint_natural_frequency);
let joint_damping_ratio = joint
.joint_damping_ratio
.unwrap_or(params.joint_damping_ratio);
let joint_natural_frequency = joint.joint_natural_frequency;
let joint_damping_ratio = joint.joint_damping_ratio;
// The has_lin/ang_coupling test is needed to avoid shl overflow later.
let has_lin_coupling = (coupled_axes & JointAxesMask::LIN_AXES.bits()) != 0;
let first_coupled_lin_axis_id =
Expand Down
53 changes: 51 additions & 2 deletions src_testbed/testbed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ pub struct TestbedState {
camera_locked: bool, // Used so that the camera can remain the same before and after we change backend or press the restart button.
}

#[derive(Resource, Clone, Debug, PartialEq)]
pub struct JointsConfiguration {
/// Sets [`rapier::prelude::GenericJoint::joint_natural_frequency`] for all joints.
pub joint_natural_frequency: Real,

/// Sets [`rapier::prelude::GenericJoint::joint_damping_ratio`] for all joints.
pub joint_damping_ratio: Real,
}

impl Default for JointsConfiguration {
fn default() -> Self {
Self {
joint_natural_frequency: 1.0e6,
joint_damping_ratio: 1.0,
}
}
}

#[derive(Resource)]
struct SceneBuilders(SimulationBuilders);

Expand Down Expand Up @@ -442,6 +460,7 @@ impl TestbedApp {
..Default::default()
})
.init_resource::<mouse::SceneMouse>()
.init_resource::<JointsConfiguration>()
.add_plugins(DefaultPlugins.set(window_plugin))
.add_plugins(OrbitCameraPlugin)
.add_plugins(WireframePlugin)
Expand All @@ -462,7 +481,11 @@ impl TestbedApp {
.insert_non_send_resource(self.plugins)
.add_systems(Update, update_testbed)
.add_systems(Update, egui_focus)
.add_systems(Update, track_mouse_state);
.add_systems(Update, track_mouse_state)
.add_systems(
Update,
update_joint_configuration.run_if(resource_changed::<JointsConfiguration>),
);

init(&mut app);
app.run();
Expand Down Expand Up @@ -1184,6 +1207,7 @@ fn update_testbed(
builders: ResMut<SceneBuilders>,
mut graphics: NonSendMut<GraphicsManager>,
mut state: ResMut<TestbedState>,
mut joints_configuration: ResMut<JointsConfiguration>,
mut debug_render: ResMut<DebugRenderPipelineResource>,
mut harness: NonSendMut<Harness>,
#[cfg(feature = "other-backends")] mut other_backends: NonSendMut<OtherBackends>,
Expand Down Expand Up @@ -1237,7 +1261,18 @@ fn update_testbed(
// Update UI
{
let harness = &mut *harness;
ui::update_ui(&mut ui_context, &mut state, harness, &mut debug_render);
// Bypass change detection, to avoid changing all joints data each frames.
let mut joints_configuration_cloned = joints_configuration.clone();
ui::update_ui(
&mut ui_context,
&mut state,
harness,
&mut debug_render,
&mut joints_configuration_cloned,
);
if joints_configuration_cloned != *joints_configuration {
*joints_configuration = joints_configuration_cloned;
}

for plugin in &mut plugins.0 {
plugin.update_ui(
Expand Down Expand Up @@ -1655,3 +1690,17 @@ fn highlight_hovered_body(
}
}
}

pub fn update_joint_configuration(
joints_configuration: Res<JointsConfiguration>,
mut harness: NonSendMut<Harness>,
) {
for joint in harness.physics.impulse_joints.iter_mut() {
joint.1.data.joint_natural_frequency = joints_configuration.joint_natural_frequency;
joint.1.data.joint_damping_ratio = joints_configuration.joint_damping_ratio;
}
for joint in harness.physics.multibody_joints.multibody_links_mut() {
joint.joint.data.joint_natural_frequency = joints_configuration.joint_natural_frequency;
joint.joint.data.joint_damping_ratio = joints_configuration.joint_damping_ratio;
}
}
9 changes: 5 additions & 4 deletions src_testbed/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::num::NonZeroUsize;
use crate::debug_render::DebugRenderPipelineResource;
use crate::harness::Harness;
use crate::testbed::{
RapierSolverType, RunMode, TestbedActionFlags, TestbedState, TestbedStateFlags,
PHYSX_BACKEND_PATCH_FRICTION, PHYSX_BACKEND_TWO_FRICTION_DIR,
JointsConfiguration, RapierSolverType, RunMode, TestbedActionFlags, TestbedState,
TestbedStateFlags, PHYSX_BACKEND_PATCH_FRICTION, PHYSX_BACKEND_TWO_FRICTION_DIR,
};

use crate::PhysicsState;
Expand All @@ -21,6 +21,7 @@ pub fn update_ui(
state: &mut TestbedState,
harness: &mut Harness,
debug_render: &mut DebugRenderPipelineResource,
joints_configuration: &mut JointsConfiguration,
) {
#[cfg(feature = "profiler_ui")]
{
Expand Down Expand Up @@ -231,13 +232,13 @@ pub fn update_ui(
);
ui.add(
Slider::new(
&mut integration_parameters.joint_natural_frequency,
&mut joints_configuration.joint_natural_frequency,
0.0..=1200000.0,
)
.text("joint erp"),
);
ui.add(
Slider::new(&mut integration_parameters.joint_damping_ratio, 0.0..=20.0)
Slider::new(&mut joints_configuration.joint_damping_ratio, 0.0..=20.0)
.text("joint damping ratio"),
);
}
Expand Down