Add joint softness per joint (#901)

This commit is contained in:
Dragos Daian
2025-11-21 16:48:52 +01:00
committed by GitHub
parent 5f687b0d29
commit e40d3a9dce
22 changed files with 442 additions and 200 deletions

View File

@@ -10,6 +10,12 @@ pub fn init_world(testbed: &mut Testbed) {
let mut impulse_joints = ImpulseJointSet::new();
let multibody_joints = MultibodyJointSet::new();
/*
* Enable/disable softness.
*/
let settings = testbed.example_settings_mut();
let variable_softness = settings.get_or_set_bool("Variable softness", false);
/*
* Create the balls
*/
@@ -41,10 +47,22 @@ pub fn init_world(testbed: &mut Testbed) {
let collider = ColliderBuilder::ball(rad);
colliders.insert_with_parent(collider, child_handle, &mut bodies);
let softness = if variable_softness {
// If variable softness is enabled, joints closer to the fixed body are softer.
SpringCoefficients {
natural_frequency: 5.0 * (i.max(k) + 1) as f32,
damping_ratio: 0.1 * (i.max(k) + 1) as f32,
}
} else {
SpringCoefficients::joint_defaults()
};
// Vertical joint.
if i > 0 {
let parent_handle = *body_handles.last().unwrap();
let joint = RevoluteJointBuilder::new().local_anchor2(point![0.0, shift]);
let joint = RevoluteJointBuilder::new()
.local_anchor2(point![0.0, shift])
.softness(softness);
impulse_joints.insert(parent_handle, child_handle, joint, true);
}
@@ -52,7 +70,9 @@ pub fn init_world(testbed: &mut Testbed) {
if k > 0 {
let parent_index = body_handles.len() - numi;
let parent_handle = body_handles[parent_index];
let joint = RevoluteJointBuilder::new().local_anchor2(point![-shift, 0.0]);
let joint = RevoluteJointBuilder::new()
.local_anchor2(point![-shift, 0.0])
.softness(softness);
impulse_joints.insert(parent_handle, child_handle, joint, true);
}

View File

@@ -1,5 +1,8 @@
use rapier2d::prelude::*;
use crate::utils::character;
use crate::utils::character::CharacterControlMode;
use rapier_testbed2d::Testbed;
use rapier2d::control::{KinematicCharacterController, PidController};
use rapier2d::prelude::*;
pub fn init_world(testbed: &mut Testbed) {
/*
@@ -77,10 +80,29 @@ pub fn init_world(testbed: &mut Testbed) {
.build();
impulse_joints.insert(character_handle, cube_handle, pin_slot_joint, true);
/*
* Callback to update the character based on user inputs.
*/
let mut control_mode = CharacterControlMode::Kinematic(0.1);
let mut controller = KinematicCharacterController::default();
let mut pid = PidController::default();
testbed.add_callback(move |graphics, physics, _, _| {
if let Some(graphics) = graphics {
character::update_character(
graphics,
physics,
&mut control_mode,
&mut controller,
&mut pid,
character_handle,
);
}
});
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
testbed.set_character_body(character_handle);
testbed.look_at(point![0.0, 1.0], 100.0);
}