38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { type AABB, vec } from "./given.ts";
|
|
import { rayVsAABB } from "./ray.ts";
|
|
|
|
test("direct hit moving right -> normal points left", () => {
|
|
// point at (0,5) moving +10 in x; box spans x:[5,8], y:[0,10]
|
|
const box: AABB = { x: 5, y: 0, w: 3, h: 10 };
|
|
const hit = rayVsAABB(vec(0, 5), vec(10, 0), box)!;
|
|
expect(hit.time).toBeCloseTo(0.5); // reaches x=5 at half the frame
|
|
expect(hit.normal).toEqual({ x: -1, y: 0 });
|
|
});
|
|
|
|
test("passes above the box (not moving in y, outside in y) -> null", () => {
|
|
const box: AABB = { x: 5, y: 0, w: 3, h: 10 };
|
|
expect(rayVsAABB(vec(0, 20), vec(10, 0), box)).toBeNull();
|
|
});
|
|
|
|
test("diagonal hit where y is the blocking axis -> vertical normal", () => {
|
|
// box x:[5,15], y:[8,18]; you enter x at t=0.5 but y only at t=0.8,
|
|
// so the real entry is 0.8 and the wall you hit is horizontal (top).
|
|
const box: AABB = { x: 5, y: 8, w: 10, h: 10 };
|
|
const hit = rayVsAABB(vec(0, 0), vec(10, 10), box)!;
|
|
expect(hit.time).toBeCloseTo(0.8);
|
|
expect(hit.normal).toEqual({ x: 0, y: -1 });
|
|
});
|
|
|
|
test("flies past the corner (windows never overlap) -> null", () => {
|
|
// inside x during [0.5,0.8], inside y during [0,0.1] — never both at once
|
|
const box: AABB = { x: 5, y: 0, w: 3, h: 1 };
|
|
expect(rayVsAABB(vec(0, 0), vec(10, 10), box)).toBeNull();
|
|
});
|
|
|
|
test("collision is real but lands after this frame -> null", () => {
|
|
// too slow: reaches the box at t=5, outside [0,1)
|
|
const box: AABB = { x: 5, y: 0, w: 2, h: 10 };
|
|
expect(rayVsAABB(vec(0, 0), vec(1, 0), box)).toBeNull();
|
|
});
|