import { Vec3 } from '../math/Vec3' import { Quaternion } from '../math/Quaternion' import { Heightfield } from '../shapes/Heightfield' import { Narrowphase } from './Narrowphase' import { Sphere } from '../shapes/Sphere' import { Body } from '../objects/Body' import { World } from '../world/World' import { ContactEquation } from '../equations/ContactEquation' describe('Narrowphase', () => { test('sphere + sphere contact', () => { const world = new World() const narrowPhase = new Narrowphase(world) const result: ContactEquation[] = [] const sphereShape = new Sphere(1) const bodyA = new Body({ mass: 1 }) const bodyB = new Body({ mass: 1 }) bodyA.addShape(sphereShape) bodyB.addShape(sphereShape) // Assumption: using World.defaultContactMaterial will be the same // as using `new ContactMaterial()` for narrowPhase.currentContactMaterial. narrowPhase.result = result narrowPhase.sphereSphere( sphereShape, sphereShape, new Vec3(0.5, 0, 0), new Vec3(-0.5, 0, 0), new Quaternion(), new Quaternion(), bodyA, bodyB ) expect(result.length).toBe(1) }) test('sphere + heightfield contact', () => { const world = new World() const narrowPhase = new Narrowphase(world) const result: ContactEquation[] = [] const hfShape = createHeightfield() const sphereShape = new Sphere(0.1) const bodyA = new Body({ mass: 1 }) const bodyB = new Body({ mass: 1 }) bodyA.addShape(hfShape) bodyB.addShape(sphereShape) narrowPhase.result = result narrowPhase.sphereHeightfield( sphereShape, hfShape, new Vec3(0.25, 0.25, 0.05), // hit the first triangle in the field new Vec3(0, 0, 0), new Quaternion(), new Quaternion(), bodyA, bodyB ) expect(result.length).toBe(1) }) }) function createHeightfield() { const matrix: number[][] = [] const size = 20 for (let i = 0; i < size; i++) { matrix.push([]) for (let j = 0; j < size; j++) { matrix[i].push(0) } } const hfShape = new Heightfield(matrix, { elementSize: 1, }) return hfShape }