Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion examples2d/character_controller2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Callback to update the character based on user inputs.
*/
let mut control_mode = CharacterControlMode::Kinematic;
let mut control_mode = CharacterControlMode::Kinematic(0.1);
let mut controller = KinematicCharacterController {
max_slope_climb_angle: impossible_slope_angle - 0.02,
min_slope_slide_angle: impossible_slope_angle - 0.02,
Expand Down
2 changes: 1 addition & 1 deletion examples2d/rope_joints2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Callback to update the character based on user inputs.
*/
let mut control_mode = CharacterControlMode::Kinematic;
let mut control_mode = CharacterControlMode::Kinematic(0.1);
let mut controller = KinematicCharacterController::default();
let mut pid = PidController::default();

Expand Down
63 changes: 39 additions & 24 deletions examples2d/utils/character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use rapier_testbed2d::{
KeyCode, PhysicsState, TestbedGraphics,
};

#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub type CharacterSpeed = Real;

#[derive(PartialEq, Clone, Copy, Debug)]
pub enum CharacterControlMode {
Kinematic,
Pid,
Kinematic(CharacterSpeed),
Pid(CharacterSpeed),
}

pub fn update_character(
Expand All @@ -27,28 +29,28 @@ pub fn update_character(

if *control_mode != prev_control_mode {
match control_mode {
CharacterControlMode::Kinematic => physics.bodies[character_handle]
CharacterControlMode::Kinematic(_) => physics.bodies[character_handle]
.set_body_type(RigidBodyType::KinematicPositionBased, false),
CharacterControlMode::Pid => {
CharacterControlMode::Pid(_) => {
physics.bodies[character_handle].set_body_type(RigidBodyType::Dynamic, true)
}
}
}

match *control_mode {
CharacterControlMode::Kinematic => {
update_kinematic_controller(graphics, physics, character_handle, controller)
CharacterControlMode::Kinematic(speed) => {
update_kinematic_controller(graphics, physics, character_handle, controller, speed)
}
CharacterControlMode::Pid => {
update_pid_controller(graphics, physics, character_handle, pid)
CharacterControlMode::Pid(speed) => {
update_pid_controller(graphics, physics, character_handle, pid, speed)
}
}
}

fn character_movement_from_inputs(
gfx: &TestbedGraphics,
mut speed: Real,
artificial_gravity: bool,
artificial_gravity: Option<Real>,
) -> Vector<Real> {
let mut desired_movement = Vector::zeros();

Expand All @@ -75,8 +77,8 @@ fn character_movement_from_inputs(

desired_movement *= speed;

if artificial_gravity {
desired_movement -= Vector::y() * speed;
if let Some(artificial_gravity) = artificial_gravity {
desired_movement += Vector::y() * artificial_gravity;
}

desired_movement
Expand All @@ -87,8 +89,10 @@ fn update_pid_controller(
phx: &mut PhysicsState,
character_handle: RigidBodyHandle,
pid: &mut PidController,
speed: Real,
) {
let desired_movement = character_movement_from_inputs(gfx, 0.1, false);
let desired_movement = character_movement_from_inputs(gfx, speed, None);

let character_body = &mut phx.bodies[character_handle];

// Adjust the controlled axis depending on the keys pressed by the user.
Expand Down Expand Up @@ -123,9 +127,9 @@ fn update_kinematic_controller(
phx: &mut PhysicsState,
character_handle: RigidBodyHandle,
controller: &KinematicCharacterController,
speed: Real,
) {
let speed = 0.1;
let desired_movement = character_movement_from_inputs(gfx, speed, true);
let desired_movement = character_movement_from_inputs(gfx, speed, Some(phx.gravity.y));

let character_body = &phx.bodies[character_handle];
let character_collider = &phx.colliders[character_body.colliders()[0]];
Expand All @@ -139,7 +143,7 @@ fn update_kinematic_controller(
&phx.query_pipeline,
character_collider.shape(),
character_collider.position(),
desired_movement.cast::<Real>(),
desired_movement,
QueryFilter::new().exclude_rigid_body(character_handle),
|c| collisions.push(c),
);
Expand Down Expand Up @@ -178,29 +182,34 @@ fn character_control_ui(
ComboBox::from_label("control mode")
.selected_text(format!("{:?}", *control_mode))
.show_ui(ui, |ui| {
ui.selectable_value(control_mode, CharacterControlMode::Kinematic, "Kinematic");
ui.selectable_value(control_mode, CharacterControlMode::Pid, "Pid");
ui.selectable_value(
control_mode,
CharacterControlMode::Kinematic(0.1),
"Kinematic",
);
ui.selectable_value(control_mode, CharacterControlMode::Pid(0.1), "Pid");
});

match control_mode {
CharacterControlMode::Kinematic => {
kinematic_control_ui(ui, character_controller);
CharacterControlMode::Kinematic(speed) => {
kinematic_control_ui(ui, character_controller, speed);
}
CharacterControlMode::Pid => {
pid_control_ui(ui, pid_controller);
CharacterControlMode::Pid(speed) => {
pid_control_ui(ui, pid_controller, speed);
}
}
});
}

fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController) {
fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController, speed: &mut Real) {
let mut lin_kp = pid_controller.pd.lin_kp.x;
let mut lin_ki = pid_controller.lin_ki.x;
let mut lin_kd = pid_controller.pd.lin_kd.x;
let mut ang_kp = pid_controller.pd.ang_kp;
let mut ang_ki = pid_controller.ang_ki;
let mut ang_kd = pid_controller.pd.ang_kd;

ui.add(Slider::new(speed, 0.0..=1.0).text("speed"));
ui.add(Slider::new(&mut lin_kp, 0.0..=100.0).text("linear Kp"));
ui.add(Slider::new(&mut lin_ki, 0.0..=10.0).text("linear Ki"));
ui.add(Slider::new(&mut lin_kd, 0.0..=1.0).text("linear Kd"));
Expand All @@ -216,7 +225,13 @@ fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController) {
pid_controller.pd.ang_kd = ang_kd;
}

fn kinematic_control_ui(ui: &mut Ui, character_controller: &mut KinematicCharacterController) {
fn kinematic_control_ui(
ui: &mut Ui,
character_controller: &mut KinematicCharacterController,
speed: &mut Real,
) {
ui.add(Slider::new(speed, 0.0..=1.0).text("Speed"))
.on_hover_text("The speed applied each simulation tick.");
ui.checkbox(&mut character_controller.slide, "slide")
.on_hover_text("Should the character try to slide against the floor if it hits it?");
#[allow(clippy::useless_conversion)]
Expand Down
2 changes: 1 addition & 1 deletion examples3d/character_controller3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Callback to update the character based on user inputs.
*/
let mut control_mode = CharacterControlMode::Kinematic;
let mut control_mode = CharacterControlMode::Kinematic(0.1);
let mut controller = KinematicCharacterController {
max_slope_climb_angle: impossible_slope_angle - 0.02,
min_slope_slide_angle: impossible_slope_angle - 0.02,
Expand Down
2 changes: 1 addition & 1 deletion examples3d/rope_joints3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Callback to update the character based on user inputs.
*/
let mut control_mode = CharacterControlMode::Kinematic;
let mut control_mode = CharacterControlMode::Kinematic(0.1);
let mut controller = KinematicCharacterController::default();
let mut pid = PidController::default();

Expand Down
60 changes: 37 additions & 23 deletions examples3d/utils/character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ use rapier_testbed3d::{
KeyCode, PhysicsState, TestbedGraphics,
};

#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub type CharacterSpeed = Real;

#[derive(PartialEq, Clone, Copy, Debug)]
pub enum CharacterControlMode {
Kinematic,
Pid,
Kinematic(CharacterSpeed),
Pid(CharacterSpeed),
}

pub fn update_character(
Expand All @@ -26,28 +28,28 @@ pub fn update_character(

if *control_mode != prev_control_mode {
match control_mode {
CharacterControlMode::Kinematic => physics.bodies[character_handle]
CharacterControlMode::Kinematic(_) => physics.bodies[character_handle]
.set_body_type(RigidBodyType::KinematicPositionBased, false),
CharacterControlMode::Pid => {
CharacterControlMode::Pid(_) => {
physics.bodies[character_handle].set_body_type(RigidBodyType::Dynamic, true)
}
}
}

match *control_mode {
CharacterControlMode::Kinematic => {
update_kinematic_controller(graphics, physics, character_handle, controller)
CharacterControlMode::Kinematic(speed) => {
update_kinematic_controller(graphics, physics, character_handle, controller, speed)
}
CharacterControlMode::Pid => {
update_pid_controller(graphics, physics, character_handle, pid)
CharacterControlMode::Pid(speed) => {
update_pid_controller(graphics, physics, character_handle, pid, speed)
}
}
}

fn character_movement_from_inputs(
gfx: &TestbedGraphics,
mut speed: Real,
artificial_gravity: bool,
artificial_gravity: Option<f32>,
) -> Vector<Real> {
let mut desired_movement = Vector::zeros();

Expand Down Expand Up @@ -86,8 +88,8 @@ fn character_movement_from_inputs(

desired_movement *= speed;

if artificial_gravity {
desired_movement -= Vector::y() * speed;
if let Some(artificial_gravity) = artificial_gravity {
desired_movement += Vector::y() * artificial_gravity;
}

desired_movement
Expand All @@ -98,8 +100,9 @@ fn update_pid_controller(
phx: &mut PhysicsState,
character_handle: RigidBodyHandle,
pid: &mut PidController,
speed: Real,
) {
let desired_movement = character_movement_from_inputs(gfx, 0.1, false);
let desired_movement = character_movement_from_inputs(gfx, speed, None);
let character_body = &mut phx.bodies[character_handle];

// Adjust the controlled axis depending on the keys pressed by the user.
Expand Down Expand Up @@ -134,9 +137,9 @@ fn update_kinematic_controller(
phx: &mut PhysicsState,
character_handle: RigidBodyHandle,
controller: &KinematicCharacterController,
speed: Real,
) {
let speed = 0.1;
let desired_movement = character_movement_from_inputs(gfx, speed, true);
let desired_movement = character_movement_from_inputs(gfx, speed, Some(phx.gravity.y));

let character_body = &phx.bodies[character_handle];
let character_collider = &phx.colliders[character_body.colliders()[0]];
Expand Down Expand Up @@ -189,29 +192,34 @@ fn character_control_ui(
ComboBox::from_label("control mode")
.selected_text(format!("{:?}", *control_mode))
.show_ui(ui, |ui| {
ui.selectable_value(control_mode, CharacterControlMode::Kinematic, "Kinematic");
ui.selectable_value(control_mode, CharacterControlMode::Pid, "Pid");
ui.selectable_value(
control_mode,
CharacterControlMode::Kinematic(0.1),
"Kinematic",
);
ui.selectable_value(control_mode, CharacterControlMode::Pid(0.1), "Pid");
});

match control_mode {
CharacterControlMode::Kinematic => {
kinematic_control_ui(ui, character_controller);
CharacterControlMode::Kinematic(speed) => {
kinematic_control_ui(ui, character_controller, speed);
}
CharacterControlMode::Pid => {
pid_control_ui(ui, pid_controller);
CharacterControlMode::Pid(speed) => {
pid_control_ui(ui, pid_controller, speed);
}
}
});
}

fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController) {
fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController, speed: &mut Real) {
let mut lin_kp = pid_controller.pd.lin_kp.x;
let mut lin_ki = pid_controller.lin_ki.x;
let mut lin_kd = pid_controller.pd.lin_kd.x;
let mut ang_kp = pid_controller.pd.ang_kp.x;
let mut ang_ki = pid_controller.ang_ki.x;
let mut ang_kd = pid_controller.pd.ang_kd.x;

ui.add(Slider::new(speed, 0.0..=1.0).text("speed"));
ui.add(Slider::new(&mut lin_kp, 0.0..=100.0).text("linear Kp"));
ui.add(Slider::new(&mut lin_ki, 0.0..=10.0).text("linear Ki"));
ui.add(Slider::new(&mut lin_kd, 0.0..=1.0).text("linear Kd"));
Expand All @@ -227,7 +235,13 @@ fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController) {
pid_controller.pd.ang_kd.fill(ang_kd);
}

fn kinematic_control_ui(ui: &mut Ui, character_controller: &mut KinematicCharacterController) {
fn kinematic_control_ui(
ui: &mut Ui,
character_controller: &mut KinematicCharacterController,
speed: &mut Real,
) {
ui.add(Slider::new(speed, 0.0..=1.0).text("Speed"))
.on_hover_text("The speed applied each simulation tick.");
ui.checkbox(&mut character_controller.slide, "slide")
.on_hover_text("Should the character try to slide against the floor if it hits it?");
#[allow(clippy::useless_conversion)]
Expand Down
7 changes: 7 additions & 0 deletions src_testbed/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ pub(crate) fn update_ui(

let mut frequency = integration_parameters.inv_dt().round() as u32;
ui.add(Slider::new(&mut frequency, 0..=240).text("frequency (Hz)"));
let mut gravity_y = harness.physics.gravity.y;
if ui
.add(Slider::new(&mut gravity_y, 0.0..=-200.0).text("Gravity"))
.changed()
{
harness.physics.gravity.y = gravity_y;
}
integration_parameters.set_inv_dt(frequency as Real);

let mut sleep = state.flags.contains(TestbedStateFlags::SLEEP);
Expand Down