UNPKG

planck-js

Version:

2D JavaScript/TypeScript physics engine for cross-platform HTML5 game development

267 lines (225 loc) 6.75 kB
/* * Planck.js * * Copyright (c) Ali Shakiba * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** @internal */ const math_sin = Math.sin; /** @internal */ const math_cos = Math.cos; /** @internal */ const math_sqrt = Math.sqrt; import { RotValue } from "./Rot"; import { TransformValue } from "./Transform"; import { Vec2Value } from "./Vec2"; import { Vec3Value } from "./Vec3"; export function vec2(x: number, y: number): Vec2Value { return { x, y }; } export function vec3(x: number, y: number, z: number): Vec3Value { return { x, y, z }; } export function rotation(angle: number): RotValue { return { s: math_sin(angle), c: math_cos(angle) }; } export function setVec2(out: Vec2Value, x: number, y: number): Vec2Value { out.x = x; out.y = y; return out; } export function copyVec2(out: Vec2Value, w: Vec2Value): Vec2Value { out.x = w.x; out.y = w.y; return out; } export function zeroVec2(out: Vec2Value): Vec2Value { out.x = 0; out.y = 0; return out; } export function negVec2(out: Vec2Value): Vec2Value { out.x = -out.x; out.y = -out.y; return out; } export function plusVec2(out: Vec2Value, w: Vec2Value): Vec2Value { out.x += w.x; out.y += w.y; return out; } export function addVec2(out: Vec2Value, v: Vec2Value, w: Vec2Value): Vec2Value { out.x = v.x + w.x; out.y = v.x + w.y; return out; } export function minusVec2(out: Vec2Value, w: Vec2Value): Vec2Value { out.x -= w.x; out.y -= w.y; return out; } export function subVec2(out: Vec2Value, v: Vec2Value, w: Vec2Value): Vec2Value { out.x = v.x - w.x; out.y = v.y - w.y; return out; } export function mulVec2(out: Vec2Value, m: number): Vec2Value { out.x *= m; out.y *= m; return out; } export function scaleVec2(out: Vec2Value, m: number, w: Vec2Value): Vec2Value { out.x = m * w.x; out.y = m * w.y; return out; } export function plusScaleVec2(out: Vec2Value, m: number, w: Vec2Value): Vec2Value { out.x += m * w.x; out.y += m * w.y; return out; } export function minusScaleVec2(out: Vec2Value, m: number, w: Vec2Value): Vec2Value { out.x -= m * w.x; out.y -= m * w.y; return out; } export function combine2Vec2(out: Vec2Value, am: number, a: Vec2Value, bm: number, b: Vec2Value): Vec2Value { out.x = am * a.x + bm * b.x; out.y = am * a.y + bm * b.y; return out; } export function combine3Vec2(out: Vec2Value, am: number, a: Vec2Value, bm: number, b: Vec2Value, cm: number, c: Vec2Value): Vec2Value { out.x = am * a.x + bm * b.x + cm * c.x; out.y = am * a.y + bm * b.y + cm * c.y; return out; } export function normalizeVec2Length(out: Vec2Value): number { const length = math_sqrt(out.x * out.x + out.y * out.y); if (length !== 0) { const invLength = 1 / length; out.x *= invLength; out.y *= invLength; } return length; } export function normalizeVec2(out: Vec2Value): Vec2Value { const length = math_sqrt(out.x * out.x + out.y * out.y); if (length > 0) { const invLength = 1 / length; out.x *= invLength; out.y *= invLength; } return out; } export function crossVec2Num(out: Vec2Value, v: Vec2Value, w: number): Vec2Value { const x = w * v.y; const y = -w * v.x; out.x = x; out.y = y; return out; } export function crossNumVec2(out: Vec2Value, w: number, v: Vec2Value): Vec2Value { const x = -w * v.y; const y = w * v.x; out.x = x; out.y = y; return out; } export function crossVec2Vec2(a: Vec2Value, b: Vec2Value): number { return a.x * b.y - a.y * b.x; } export function dotVec2(a: Vec2Value, b: Vec2Value): number { return a.x * b.x + a.y * b.y; } export function lengthVec2(a: Vec2Value): number { return math_sqrt(a.x * a.x + a.y * a.y); } export function lengthSqrVec2(a: Vec2Value): number { return a.x * a.x + a.y * a.y; } export function distVec2(a: Vec2Value, b: Vec2Value): number { const dx = a.x - b.x; const dy = a.y - b.y; return math_sqrt(dx * dx + dy * dy); } export function distSqrVec2(a: Vec2Value, b: Vec2Value): number { const dx = a.x - b.x; const dy = a.y - b.y; return dx * dx + dy * dy; } export function dotVec3(v: Vec3Value, w: Vec3Value): number { return v.x * w.x + v.y * w.y + v.z * w.z; } export function setRotAngle(out: RotValue, a: number): RotValue { out.c = math_cos(a); out.s = math_sin(a); return out; } export function rotVec2(out: Vec2Value, q: RotValue, v: Vec2Value): Vec2Value { out.x = q.c * v.x - q.s * v.y; out.y = q.s * v.x + q.c * v.y; return out; } export function derotVec2(out: Vec2Value, q: RotValue, v: Vec2Value): Vec2Value { const x = q.c * v.x + q.s * v.y; const y = -q.s * v.x + q.c * v.y; out.x = x; out.y = y; return out; } export function rerotVec2(out: Vec2Value, before: RotValue, after: RotValue, v: Vec2Value): Vec2Value { const x0 = before.c * v.x + before.s * v.y; const y0 = -before.s * v.x + before.c * v.y; const x = after.c * x0 - after.s * y0; const y = after.s * x0 + after.c * y0; out.x = x; out.y = y; return out; } export function transform(x: number, y: number, a: number): TransformValue { return { p: vec2(x, y), q: rotation(a) }; } export function copyTransform(out: TransformValue, transform: TransformValue): TransformValue { out.p.x = transform.p.x; out.p.y = transform.p.y; out.q.s = transform.q.s; out.q.c = transform.q.c; return out; } export function transformVec2(out: Vec2Value, xf: TransformValue, v: Vec2Value): Vec2Value { const x = xf.q.c * v.x - xf.q.s * v.y + xf.p.x; const y = xf.q.s * v.x + xf.q.c * v.y + xf.p.y; out.x = x; out.y = y; return out; } export function detransformVec2(out: Vec2Value, xf: TransformValue, v: Vec2Value): Vec2Value { const px = v.x - xf.p.x; const py = v.y - xf.p.y; const x = (xf.q.c * px + xf.q.s * py); const y = (-xf.q.s * px + xf.q.c * py); out.x = x; out.y = y; return out; } export function retransformVec2(out: Vec2Value, from: TransformValue, to: TransformValue, v: Vec2Value): Vec2Value { const x0 = from.q.c * v.x - from.q.s * v.y + from.p.x; const y0 = from.q.s * v.x + from.q.c * v.y + from.p.y; const px = x0 - to.p.x; const py = y0 - to.p.y; const x = to.q.c * px + to.q.s * py; const y = -to.q.s * px + to.q.c * py; out.x = x; out.y = y; return out; } export function detransformTransform(out: TransformValue, a: TransformValue, b: TransformValue): TransformValue { const c = a.q.c * b.q.c + a.q.s * b.q.s; const s = a.q.c * b.q.s - a.q.s * b.q.c; const x = a.q.c * (b.p.x - a.p.x) + a.q.s * (b.p.y - a.p.y); const y = -a.q.s * (b.p.x - a.p.x) + a.q.c * (b.p.y - a.p.y); out.q.c = c; out.q.s = s; out.p.x = x; out.p.y = y; return out; }