Files
healer-man/src/game/inputMath.test.ts
T
2026-08-14 15:56:39 -04:00

63 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
applyRadialDeadzone,
cameraRelativeMovement,
cameraYawAfterHorizontalLook,
clampCameraPitch,
DEFAULT_CAMERA_PITCH,
normalizePlanar,
wrapAngle,
} from "./inputMath";
describe("input math", () => {
it("removes stick drift and remaps motion outside the deadzone", () => {
expect(applyRadialDeadzone(0.08, -0.05)).toEqual([0, 0]);
const [x, y] = applyRadialDeadzone(0.59, 0);
expect(x).toBeCloseTo(0.5, 2);
expect(y).toBe(0);
});
it("caps diagonal movement at unit length", () => {
const [x, z] = normalizePlanar(1, 1);
expect(Math.hypot(x, z)).toBeCloseTo(1);
});
it("rotates +Z-forward movement by camera yaw", () => {
expect(cameraRelativeMovement(0, 1, 0)).toEqual([0, 1]);
const [x, z] = cameraRelativeMovement(0, 1, -Math.PI / 2);
expect(x).toBeCloseTo(-1);
expect(z).toBeCloseTo(0);
});
it("maps positive lateral input to the rendered camera's screen-right direction", () => {
expect(cameraRelativeMovement(1, 0, 0)).toEqual([-1, 0]);
expect(cameraRelativeMovement(-1, 0, 0)).toEqual([1, 0]);
const yaw = 0.73;
const [worldX, worldZ] = cameraRelativeMovement(1, 0, yaw);
const screenRight = [-Math.cos(yaw), Math.sin(yaw)] as const;
expect(worldX * screenRight[0] + worldZ * screenRight[1]).toBeCloseTo(1);
});
it("turns toward screen-right for positive mouse or right-stick look", () => {
expect(cameraYawAfterHorizontalLook(0, 0.25)).toBeCloseTo(-0.25);
expect(cameraYawAfterHorizontalLook(0, -0.25)).toBeCloseTo(0.25);
expect(cameraYawAfterHorizontalLook(0.7, Number.NaN)).toBeCloseTo(0.7);
});
it("clamps pitch and wraps yaw", () => {
expect(clampCameraPitch(-3)).toBe(-0.18);
expect(clampCameraPitch(3)).toBe(0.88);
expect(wrapAngle(Math.PI * 3)).toBeCloseTo(Math.PI);
});
it("recovers from non-finite controller and camera values", () => {
expect(applyRadialDeadzone(Number.NaN, 0)).toEqual([0, 0]);
expect(normalizePlanar(Number.POSITIVE_INFINITY, 1)).toEqual([0, 0]);
expect(cameraRelativeMovement(0, 1, Number.NaN)).toEqual([0, 1]);
expect(cameraYawAfterHorizontalLook(Number.NaN, 1)).toBeCloseTo(-1);
expect(clampCameraPitch(Number.NaN)).toBe(DEFAULT_CAMERA_PITCH);
expect(wrapAngle(Number.NaN)).toBe(0);
});
});