use bullet_physics::dynamics::{PhysicsWorld, RigidBody};
use bullet_physics::math::{Real, Vector3};
use bullet_physics::shapes::CollisionShape;
fn main() {
let mut world = PhysicsWorld::new();
world.set_gravity(Vector3::ZERO);
world.solver_info_mut().num_iterations = 20;
let wall = RigidBody::new_static(
CollisionShape::box_shape(Vector3::new(5.0, 5.0, 0.1)),
Vector3::new(0.0, 0.0, 0.0),
);
world.add_body(wall);
let ccd_ball = world.add_body(
RigidBody::new_dynamic(
CollisionShape::sphere(0.3),
Vector3::new(0.0, 0.0, 1.0),
1.0,
)
.velocity(Vector3::new(0.0, 0.0, -120.0))
.ccd(0.1, 0.3),
);
let plain_ball = world.add_body(
RigidBody::new_dynamic(
CollisionShape::sphere(0.3),
Vector3::new(2.0, 0.0, 1.0),
1.0,
)
.velocity(Vector3::new(0.0, 0.0, -120.0)),
);
let dt: Real = 1.0 / 60.0;
world.step_simulation(dt);
let ccd_z = world.body(ccd_ball).position.z;
let plain_z = world.body(plain_ball).position.z;
println!("after one step:");
println!(" ccd ball z = {:.4} (wall at z = 0, clamped at z = 0.4)", ccd_z);
println!(" plain ball z = {:.4} (tunnelled through)", plain_z);
assert!(
ccd_z > 0.35 && ccd_z < 0.45,
"ccd ball did not stop at the wall: z = {ccd_z}"
);
assert!(
plain_z < -0.5,
"plain ball should have tunnelled through: z = {plain_z}"
);
println!("OK: CCD stopped the fast ball at the wall; the plain ball tunnelled.");
}