test(physics): exercise every recovered collider
Probe both contact sides of all 109 recovered wall segments and every passive/scored circle. Verify each primitive detects overlap, separates the ball, and rejects inward maximum-speed motion. Test Plan: - cargo fmt --check - cargo test - cargo clippy --all-targets --all-features -- -D warnings - git diff --cached --check
This commit is contained in:
@@ -215,6 +215,7 @@ pub const BUMPERS: [StaticCircle; 3] = [
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::geometry::{circle_collision, segment_collision};
|
||||
|
||||
#[test]
|
||||
fn recovered_object_inventory_is_complete() {
|
||||
@@ -238,4 +239,65 @@ mod tests {
|
||||
assert_eq!(shooter_wall.segment.start, Vec2::new(328.0, 422.0));
|
||||
assert_eq!(shooter_wall.segment.end, Vec2::new(328.0, 58.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_recovered_wall_has_a_working_contact_surface_on_both_sides() {
|
||||
for wall in WALLS {
|
||||
let line = wall.segment.end - wall.segment.start;
|
||||
assert!(
|
||||
line.length_squared() > 0.0,
|
||||
"object {} is degenerate",
|
||||
wall.id
|
||||
);
|
||||
let normal = Vec2::new(-line.y, line.x).normalize();
|
||||
let midpoint = (wall.segment.start + wall.segment.end) * 0.5;
|
||||
|
||||
for side in [-1.0, 1.0] {
|
||||
let outward = normal * side;
|
||||
let mut position = midpoint + outward * 0.5;
|
||||
let mut velocity = -outward * 430.0;
|
||||
let hit = segment_collision(&mut position, &mut velocity, 1.0, wall.segment);
|
||||
|
||||
assert!(hit, "object {} missed its midpoint contact", wall.id);
|
||||
assert!(
|
||||
velocity.dot(outward) >= 0.0,
|
||||
"object {} did not reject an inward trajectory",
|
||||
wall.id
|
||||
);
|
||||
assert!(
|
||||
position.distance(midpoint) >= 0.99,
|
||||
"object {} did not separate the ball from its surface",
|
||||
wall.id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_recovered_circle_separates_and_reflects_the_ball() {
|
||||
for circle in PASSIVE_CIRCLES.iter().chain(BUMPERS.iter()) {
|
||||
let mut position = circle.center + Vec2::new(circle.contact_radius - 0.5, 0.0);
|
||||
let mut velocity = Vec2::new(-430.0, 0.0);
|
||||
let hit = circle_collision(
|
||||
&mut position,
|
||||
&mut velocity,
|
||||
0.0,
|
||||
circle.center,
|
||||
circle.contact_radius,
|
||||
0.0,
|
||||
);
|
||||
|
||||
assert!(hit, "object {} missed an overlapping ball", circle.id);
|
||||
assert!(
|
||||
position.x >= circle.center.x + circle.contact_radius,
|
||||
"object {} did not separate the ball",
|
||||
circle.id
|
||||
);
|
||||
assert!(
|
||||
velocity.x > 0.0,
|
||||
"object {} did not reflect inward velocity",
|
||||
circle.id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user