import { Collision } from '../model/data/collision'; import { Circle } from '../math/circle'; import { Collidable } from '../math/collision'; import { LineSegment, Movement } from '../math/line'; import { Point } from '../math/point'; import { vec2 } from 'gl-matrix'; export function mkCollision(collision: Collision[]): Collidable[] { const ret: Collidable[] = []; for (const c of collision) { switch (c.type) { case 'polygon': if (!c.vertices.length) continue; let prev = c.vertices[c.vertices.length - 1]; for (const v of c.vertices) { ret.push(LineSegment.fromPoints(vec2.clone(prev), vec2.clone(v))); prev = v; } for (const v of c.vertices) { ret.push(new Point(vec2.clone(v))); prev = v; } break; case 'circle': ret.push(new Circle(vec2.clone(c.center), c.radius)); break; } } return ret; } export interface CollidableGroup { getTranslation(): vec2|null; getCollidables(): Collidable[]; } export function collide(collision: CollidableGroup, out: vec2, move: Movement, radius: number): boolean { const t = collision.getTranslation(); if (t) move = move.translate(vec2.negate(vec2.create(), t)); for (const c of collision.getCollidables()) { if (!c.collide(out, move, radius)) continue; if (vec2.squaredDistance(move.src, out) >= vec2.squaredDistance(move.src, move.dest)) continue; if (t) vec2.add(out, out, t); return true; } return false; }