use bullet_physics::dynamics::{KinematicCharacterController, PhysicsWorld, RigidBody};
use bullet_physics::math::{Real, Vector3};
use bullet_physics::shapes::CollisionShape;
fn main() {
let mut world = PhysicsWorld::new();
world.set_gravity(Vector3::new(0.0, -9.81, 0.0));
world.add_body(RigidBody::new_static(
CollisionShape::plane(Vector3::Y, 0.0),
Vector3::ZERO,
));
world.add_body(RigidBody::new_static(
CollisionShape::box_shape(Vector3::new(0.5, 0.2, 5.0)),
Vector3::new(3.5, 0.2, 0.0),
));
world.add_body(RigidBody::new_static(
CollisionShape::box_shape(Vector3::new(0.5, 5.0, 5.0)),
Vector3::new(8.0, 5.0, 0.0),
));
let shape = CollisionShape::capsule(0.4, 0.8);
let body = world.add_body(RigidBody::new_static(
shape.clone(),
Vector3::new(0.0, 1.2, 0.0),
));
let mut controller = KinematicCharacterController::new(body, shape, 0.5, Vector3::Y);
controller.set_walk_direction(Vector3::new(0.02, 0.0, 0.0));
let dt: Real = 1.0 / 60.0;
let mut max_y: Real = 1.2;
let mut time = 0.0;
println!("t x y on_ground");
while time < 8.0 {
world.step_simulation(dt);
controller.update(&mut world, dt);
time += dt;
max_y = max_y.max(controller.position().y);
if controller.position().x > 4.5 && controller.position().x < 5.0 && controller.on_ground() {
controller.jump();
}
if (time * 30.0).round() as i64 % 30 == 0 {
println!(
"{:.2} {:.3} {:.3} {}",
time,
controller.position().x,
controller.position().y,
controller.on_ground()
);
}
}
let pos = controller.position();
println!("final x = {:.3}, y = {:.3}, max_y = {:.3}", pos.x, pos.y, max_y);
assert!(pos.x > 2.5, "did not cross the step: x = {}", pos.x);
assert!(max_y > 1.7, "jump apex too low: {max_y}");
assert!(pos.x < 7.6, "walked through the wall: x = {}", pos.x);
assert!(
controller.on_ground() && (pos.y - 1.2).abs() < 0.05,
"not resting on the ground: y = {}",
pos.y
);
println!("OK: character walked, stepped up, jumped and stopped at the wall.");
}