use gizmo_engine::bundles::RigidBodyBundle;
use gizmo_engine::core::world::World;
use gizmo_engine::math::Vec3;
use gizmo_engine::physics::components::{Collider, RigidBody};
use gizmo_engine::physics::world::PhysicsWorld;
use gizmo_engine::physics::Transform;
use gizmo_engine::systems::cpu_physics_step_system;
#[test]
fn with_ccd_sets_flag_and_prevents_tunnel_end_to_end() {
let mut w = World::new();
w.insert_resource(PhysicsWorld::new().with_gravity(Vec3::ZERO));
w.spawn_bundle((
Transform::new(Vec3::ZERO),
RigidBodyBundle::static_body()
.with_collider(Collider::box_collider(Vec3::new(0.02, 5.0, 5.0))),
));
let bullet = w.spawn_bundle((
Transform::new(Vec3::new(-5.0, 0.0, 0.0)),
RigidBodyBundle::dynamic(1.0)
.with_collider(Collider::sphere(0.05))
.with_velocity(Vec3::new(2400.0, 0.0, 0.0)) .with_ccd(),
));
assert!(
w.borrow::<RigidBody>().get(bullet.id()).unwrap().ccd_enabled,
"with_ccd() spawn edilen cismin ccd_enabled'ını set etmeli"
);
let mut peak = f32::MIN;
for _ in 0..240 {
cpu_physics_step_system(&w, 1.0 / 240.0);
peak = peak.max(w.borrow::<Transform>().get(bullet.id()).unwrap().position.x);
}
assert!(peak < 0.0, "idiomatik .with_ccd() tünellemeyi önlemeli, tepe_x={peak}");
}
#[test]
fn without_ccd_the_same_bullet_tunnels() {
let mut w = World::new();
w.insert_resource(PhysicsWorld::new().with_gravity(Vec3::ZERO));
w.spawn_bundle((
Transform::new(Vec3::ZERO),
RigidBodyBundle::static_body()
.with_collider(Collider::box_collider(Vec3::new(0.02, 5.0, 5.0))),
));
let bullet = w.spawn_bundle((
Transform::new(Vec3::new(-5.0, 0.0, 0.0)),
RigidBodyBundle::dynamic(1.0)
.with_collider(Collider::sphere(0.05))
.with_velocity(Vec3::new(2400.0, 0.0, 0.0)), ));
let mut peak = f32::MIN;
for _ in 0..30 {
cpu_physics_step_system(&w, 1.0 / 240.0);
peak = peak.max(w.borrow::<Transform>().get(bullet.id()).unwrap().position.x);
}
assert!(peak > 1.0, "CCD'siz idiomatik mermi tünellemeli (kontrast), tepe_x={peak}");
}