diff --git a/packages/vectors/src/api.ts b/packages/vectors/src/api.ts index 0ec4e910f6..cddbc9d511 100644 --- a/packages/vectors/src/api.ts +++ b/packages/vectors/src/api.ts @@ -16,3 +16,9 @@ export type Mat = number[] | TypedArray; export type ReadonlyMat = ArrayLike; export type VecOp = (a: Vec, b: ReadonlyVec, ia: number, ib: number, sa: number, sb: number) => Vec; + +export interface IVec { + buf: Vec; + i: number; + s: number; +} diff --git a/packages/vectors/src/common.ts b/packages/vectors/src/common.ts index eadd4b403d..24e9427a3b 100644 --- a/packages/vectors/src/common.ts +++ b/packages/vectors/src/common.ts @@ -1,5 +1,5 @@ import { ReadonlyVec, Vec, VecOp } from "./api"; -import { EPS, eqDelta } from "./math"; +import { EPS, eqDelta1 } from "./math"; export const x = (v: ReadonlyVec, i = 0, _?) => v[i]; export const y = (v: ReadonlyVec, i = 0, s = 1) => v[i + s]; @@ -43,9 +43,9 @@ export const sliceOpN = (fn: VecOp, a: Vec, b: ReadonlyVec, n: number, ia: numbe return a; }; -export const eqDeltaN = (a: Vec, b: Vec, n: number, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => { +export const eqDelta = (a: Vec, b: Vec, n: number, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => { for (; --n >= 0; ia += sa, ib += sb) { - if (!eqDelta(a[ia], b[ib], eps)) { + if (!eqDelta1(a[ia], b[ib], eps)) { return false; } } diff --git a/packages/vectors/src/mat23.ts b/packages/vectors/src/mat23.ts index f5e925e1e1..607f87627f 100644 --- a/packages/vectors/src/mat23.ts +++ b/packages/vectors/src/mat23.ts @@ -1,12 +1,12 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { Mat, ReadonlyMat, Vec } from "./api"; -import { eqDeltaN } from "./common"; +import { eqDelta } from "./common"; import { EPS } from "./math"; import { cross2, dot2, - set2s, + setS2, Vec2 } from "./vec2"; @@ -35,7 +35,7 @@ export const set23 = (a: Mat, b: Mat, ia = 0, ib = 0) => ( * @param m21 * @param i */ -export const set23s = (m: Mat, m00: number, m01: number, m10: number, m11: number, m20: number, m21: number, i = 0) => ( +export const setS23 = (m: Mat, m00: number, m01: number, m10: number, m11: number, m20: number, m21: number, i = 0) => ( m[i] = m00, m[i + 1] = m01, m[i + 2] = m10, @@ -46,48 +46,48 @@ export const set23s = (m: Mat, m00: number, m01: number, m10: number, m11: numbe ); export const identity23 = (m?: Mat, i = 0) => - set23s(m || [], 1, 0, 0, 1, 0, 0, i); + setS23(m || [], 1, 0, 0, 1, 0, 0, i); export const rotation23 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set23s(m || [], c, s, -s, c, 0, 0, i); + return setS23(m || [], c, s, -s, c, 0, 0, i); }; export const rotationAroundPoint23 = (m: Mat, p: Vec, theta: number, im = 0, iv = 0, sv = 1) => concat23( - translation23v(m || [], p, im, iv, sv), im, + translationV23(m || [], p, im, iv, sv), im, rotation23([], theta), - translation23s([], -p[iv], -p[iv + sv]) + translationS23([], -p[iv], -p[iv + sv]) ); -export const scale23v = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - scale23s(m, v[iv], v[iv + sv], i); +export const scaleV23 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => + scaleS23(m, v[iv], v[iv + sv], i); -export const scale23n = (m: Mat, n: number, i = 0) => - scale23s(m, n, n, i); +export const scaleN23 = (m: Mat, n: number, i = 0) => + scaleS23(m, n, n, i); -export const scale23s = (m: Mat, sx: number, sy: number, i = 0) => - set23s(m || [], sx, 0, 0, sy, 0, 0, i); +export const scaleS23 = (m: Mat, sx: number, sy: number, i = 0) => + setS23(m || [], sx, 0, 0, sy, 0, 0, i); export const scaleWithCenter23 = (m: Mat, p: Vec, sx: number, sy: number, im = 0, iv = 0, sv = 1) => concat23( - translation23v(m || [], p, im, iv, sv), im, - scale23s([], sx, sy), - translation23s([], -p[iv], -p[iv + sv]) + translationV23(m || [], p, im, iv, sv), im, + scaleS23([], sx, sy), + translationS23([], -p[iv], -p[iv + sv]) ); -export const translation23v = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - translation23s(m, v[iv], v[iv + sv], i); +export const translationV23 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => + translationS23(m, v[iv], v[iv + sv], i); -export const translation23s = (m: Mat, x: number, y: number, i = 0) => - set23s(m || [], 1, 0, 0, 1, x, y, i); +export const translationS23 = (m: Mat, x: number, y: number, i = 0) => + setS23(m || [], 1, 0, 0, 1, x, y, i); export const shearX23 = (m: Mat, x: number, i = 0) => - set23s(m || [], 1, 0, x, 1, 0, 0, i); + setS23(m || [], 1, 0, x, 1, 0, 0, i); export const shearY23 = (m: Mat, y: number, i = 0) => - set23s(m || [], 1, y, 0, 1, 0, 0, i); + setS23(m || [], 1, y, 0, 1, 0, 0, i); export const skewX23 = (m: Mat, theta: number, i = 0) => shearX23(m, Math.tan(theta), i); @@ -96,7 +96,7 @@ export const skewY23 = (m: Mat, theta: number, i = 0) => shearY23(m, Math.tan(theta), i); export const mul23 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - set23s( + setS23( a, dot2(a, b, ia, ib, 2), dot2(a, b, ia + 1, ib, 2), @@ -116,7 +116,7 @@ export const concat23 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, ); export const mulV23 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => - set2s( + setS2( v, dot2(m, v, im, iv, 2, sv) + m[im + 4], dot2(m, v, im + 1, iv, 2, sv) + m[im + 5], @@ -138,7 +138,7 @@ export const invert23 = (m: Mat, i = 0) => { return; } det = 1.0 / det; - return set23s( + return setS23( m, m11 * det, -m01 * det, @@ -168,8 +168,8 @@ export class Mat23 implements static scale(x: any, y = x) { return new Mat23( x instanceof Vec2 ? - scale23v([], x.buf, 0, x.i, x.s) : - scale23s([], x, y) + scaleV23([], x.buf, 0, x.i, x.s) : + scaleS23([], x, y) ); } @@ -182,8 +182,8 @@ export class Mat23 implements static translation(x: any, y?: any) { return new Mat23( x instanceof Vec2 ? - translation23v([], x.buf, 0, x.i) : - translation23s([], x, y) + translationV23([], x.buf, 0, x.i) : + translationS23([], x, y) ); } @@ -221,7 +221,7 @@ export class Mat23 implements } eqDelta(m: Mat23, eps = EPS) { - return eqDeltaN(this.buf, m.buf, 6, eps, this.i, m.i); + return eqDelta(this.buf, m.buf, 6, eps, this.i, m.i); } identity() { @@ -235,7 +235,7 @@ export class Mat23 implements } setS(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) { - set23s(this.buf, m00, m01, m10, m11, m20, m21, this.i); + setS23(this.buf, m00, m01, m10, m11, m20, m21, this.i); return this; } diff --git a/packages/vectors/src/mat33.ts b/packages/vectors/src/mat33.ts index 98417c03a9..357d2a879f 100644 --- a/packages/vectors/src/mat33.ts +++ b/packages/vectors/src/mat33.ts @@ -1,15 +1,15 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { Mat, ReadonlyMat, Vec } from "./api"; -import { eqDeltaN } from "./common"; +import { eqDelta } from "./common"; import { EPS } from "./math"; import { dot3, set3, - set3s, + setS3, Vec3 } from "./vec3"; -import { set4s } from "./vec4"; +import { setS4 } from "./vec4"; export const set33 = (a: Mat, b: Mat, ia = 0, ib = 0) => ( a[ia] = b[ib], @@ -43,7 +43,7 @@ export const set33 = (a: Mat, b: Mat, ia = 0, ib = 0) => ( * @param m22 * @param i */ -export const set33s = (m: Mat, m00: number, m01: number, m02: number, m10: number, m11: number, m12: number, m20: number, m21: number, m22: number, i = 0) => ( +export const setS33 = (m: Mat, m00: number, m01: number, m02: number, m10: number, m11: number, m12: number, m20: number, m21: number, m22: number, i = 0) => ( m[i] = m00, m[i + 1] = m01, m[i + 2] = m02, @@ -57,7 +57,7 @@ export const set33s = (m: Mat, m00: number, m01: number, m02: number, m10: numbe ); export const identity33 = (m?: Mat, i = 0) => - set33s(m || [], + setS33(m || [], 1, 0, 0, 0, 1, 0, 0, 0, 1, @@ -67,7 +67,7 @@ export const identity33 = (m?: Mat, i = 0) => export const rotationX33 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set33s(m || [], + return setS33(m || [], 1, 0, 0, 0, c, s, 0, -s, c, @@ -78,7 +78,7 @@ export const rotationX33 = (m: Mat, theta: number, i = 0) => { export const rotationY33 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set33s(m || [], + return setS33(m || [], c, 0, -s, 0, 1, 0, s, 0, c, @@ -89,7 +89,7 @@ export const rotationY33 = (m: Mat, theta: number, i = 0) => { export const rotationZ33 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set33s(m || [], + return setS33(m || [], c, s, 0, -s, c, 0, 0, 0, 1, @@ -97,14 +97,14 @@ export const rotationZ33 = (m: Mat, theta: number, i = 0) => { ); }; -export const scale33v = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - scale33s(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); +export const scaleV33 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => + scaleS33(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); -export const scale33n = (m: Mat, n: number, i = 0) => - scale33s(m, n, n, n, i); +export const scaleN33 = (m: Mat, n: number, i = 0) => + scaleS33(m, n, n, n, i); -export const scale33s = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - set33s(m || [], +export const scaleS33 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS33(m || [], sx, 0, 0, 0, sy, 0, 0, 0, sz, @@ -112,7 +112,7 @@ export const scale33s = (m: Mat, sx: number, sy: number, sz: number, i = 0) => ); export const mul33 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - set33s( + setS33( a, dot3(a, b, ia, ib, 3), dot3(a, b, ia + 1, ib, 3), @@ -135,7 +135,7 @@ export const concat33 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, ); export const mulV33 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => - set3s( + setS3( v, dot3(m, v, im, iv, 3, sv), dot3(m, v, im + 1, iv, 3, sv), @@ -177,7 +177,7 @@ export const invert33 = (m: Mat, i = 0) => { return; } det = 1.0 / det; - return set33s( + return setS33( m, d01 * det, (-m22 * m01 + m02 * m21) * det, @@ -193,7 +193,7 @@ export const invert33 = (m: Mat, i = 0) => { } export const transpose33 = (m: Mat, i = 0) => - set33s( + setS33( m, m[i], m[i + 3], m[i + 6], m[i + 1], m[i + 4], m[i + 7], @@ -205,8 +205,8 @@ export const mat33to44 = (m44: Mat, m33: Mat, ia = 0, ib = 0) => ( set3(m44, m33, ia, ib), set3(m44, m33, ia + 4, ib + 3), set3(m44, m33, ia + 8, ib + 6), - set3s(m44, 0, 0, 0, ia + 12), - set4s(m44, 0, 0, 0, 1, ia + 3, 4), + setS3(m44, 0, 0, 0, ia + 12), + setS4(m44, 0, 0, 0, 1, ia + 3, 4), m44 ); @@ -232,8 +232,8 @@ export class Mat33 implements static scale(x: any, y = x, z = x) { return new Mat33( x instanceof Vec3 ? - scale33v([], x.buf, 0, x.i) : - scale33s([], x, y, z) + scaleV33([], x.buf, 0, x.i) : + scaleS33([], x, y, z) ); } @@ -255,7 +255,7 @@ export class Mat33 implements } eqDelta(m: Mat33, eps = EPS) { - return eqDeltaN(this.buf, m.buf, 9, eps, this.i, m.i); + return eqDelta(this.buf, m.buf, 9, eps, this.i, m.i); } identity() { @@ -269,7 +269,7 @@ export class Mat33 implements } setS(m00: number, m01: number, m02: number, m10: number, m11: number, m12: number, m20: number, m21: number, m22: number) { - set33s(this.buf, m00, m01, m02, m10, m11, m12, m20, m21, m22, this.i); + setS33(this.buf, m00, m01, m02, m10, m11, m12, m20, m21, m22, this.i); return this; } diff --git a/packages/vectors/src/mat44.ts b/packages/vectors/src/mat44.ts index 5938c4b7c0..7b53d51886 100644 --- a/packages/vectors/src/mat44.ts +++ b/packages/vectors/src/mat44.ts @@ -1,7 +1,7 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { Mat, ReadonlyMat, Vec } from "./api"; -import { eqDeltaN } from "./common"; +import { eqDelta } from "./common"; import { Mat33 } from "./mat33"; import { EPS, rad } from "./math"; import { @@ -10,11 +10,11 @@ import { get3, normalize3, set3, - set3s, + setS3, sub3, Vec3 } from "./vec3"; -import { dot4, set4s, Vec4 } from "./vec4"; +import { dot4, setS4, Vec4 } from "./vec4"; export const set44 = (a: Mat, b: Mat, ia = 0, ib = 0) => { for (let i = 0; i < 16; i++) { @@ -31,7 +31,7 @@ export const set44 = (a: Mat, b: Mat, ia = 0, ib = 0) => { * m03 m13 m23 m33 * ``` */ -export const set44s = (m: Mat, m00: number, m01: number, m02: number, m03: number, +export const setS44 = (m: Mat, m00: number, m01: number, m02: number, m03: number, m10: number, m11: number, m12: number, m13: number, m20: number, m21: number, m22: number, m23: number, m30: number, m31: number, m32: number, m33: number, @@ -56,7 +56,7 @@ export const set44s = (m: Mat, m00: number, m01: number, m02: number, m03: numbe ); export const identity44 = (m?: Mat, i = 0) => - set44s(m || [], + setS44(m || [], 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, @@ -67,7 +67,7 @@ export const identity44 = (m?: Mat, i = 0) => export const rotationX44 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set44s(m || [], + return setS44(m || [], 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, @@ -79,7 +79,7 @@ export const rotationX44 = (m: Mat, theta: number, i = 0) => { export const rotationY44 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set44s(m || [], + return setS44(m || [], c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, @@ -91,7 +91,7 @@ export const rotationY44 = (m: Mat, theta: number, i = 0) => { export const rotationZ44 = (m: Mat, theta: number, i = 0) => { const s = Math.sin(theta); const c = Math.cos(theta); - return set44s(m || [], + return setS44(m || [], c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, @@ -100,14 +100,14 @@ export const rotationZ44 = (m: Mat, theta: number, i = 0) => { ); }; -export const scale44v = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - scale44s(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); +export const scaleV44 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => + scaleS44(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); -export const scale44n = (m: Mat, n: number, i = 0) => - scale44s(m, n, n, n, i); +export const scaleN44 = (m: Mat, n: number, i = 0) => + scaleS44(m, n, n, n, i); -export const scale44s = (m: Mat, sx: number, sy: number, sz: number, i = 0) => - set44s(m || [], +export const scaleS44 = (m: Mat, sx: number, sy: number, sz: number, i = 0) => + setS44(m || [], sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, @@ -117,16 +117,16 @@ export const scale44s = (m: Mat, sx: number, sy: number, sz: number, i = 0) => export const scaleWithCenter44 = (m: Mat, p: Vec, sx: number, sy: number, sz: number, im = 0, iv = 0, sv = 1) => concat44( - translation44v(m || [], p, im, iv, sv), im, - scale44s([], sx, sy, sz), - translation44s([], -p[iv], -p[iv + sv], -p[iv + 2 * sv]) + translationV44(m || [], p, im, iv, sv), im, + scaleS44([], sx, sy, sz), + translationS44([], -p[iv], -p[iv + sv], -p[iv + 2 * sv]) ); -export const translation44v = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => - translation44s(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); +export const translationV44 = (m: Mat, v: Vec, i = 0, iv = 0, sv = 1) => + translationS44(m, v[iv], v[iv + sv], v[iv + 2 * sv], i); -export const translation44s = (m: Mat, x: number, y: number, z: number, i = 0) => - set44s(m || [], +export const translationS44 = (m: Mat, x: number, y: number, z: number, i = 0) => + setS44(m || [], 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, @@ -138,7 +138,7 @@ export const frustum = (m: Mat, left: number, right: number, bottom: number, top const dx = 1 / (right - left); const dy = 1 / (top - bottom); const dz = 1 / (far - near); - return set44s(m || [], + return setS44(m || [], near * 2 * dx, 0, 0, 0, 0, near * 2 * dy, 0, 0, (right + left) * dx, (top + bottom) * dy, -(far + near) * dz, -1, @@ -169,7 +169,7 @@ export const ortho = (m: Mat, left: number, right: number, bottom: number, top: const dx = 1 / (right - left); const dy = 1 / (top - bottom); const dz = 1 / (far - near); - return set44s(m || [], + return setS44(m || [], 2 * dx, 0, 0, 0, 0, 2 * dy, 0, 0, 0, 0, -2 * dz, 0, @@ -185,7 +185,7 @@ export const lookAt = (m: Mat, eye: Vec, target: Vec, up: Vec, im = 0, ie = 0, i const z = normalize3(sub3([...eye], target)); const x = normalize3(cross3(up, z)); const y = normalize3(cross3([...z], x)); - return set44s(m || [], + return setS44(m || [], x[0], y[0], z[0], 0, x[1], y[1], z[1], 0, x[2], y[2], z[2], 0, @@ -195,7 +195,7 @@ export const lookAt = (m: Mat, eye: Vec, target: Vec, up: Vec, im = 0, ie = 0, i } export const mul44 = (a: Mat, b: ReadonlyMat, ia = 0, ib = 0) => - set44s( + setS44( a, dot4(a, b, ia, ib, 4), dot4(a, b, ia + 1, ib, 4), @@ -225,7 +225,7 @@ export const concat44 = (a: Mat, ia: number, ...xs: (ReadonlyMat | [ReadonlyMat, ); export const mulV344 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => - set3s( + setS3( v, dot3(m, v, im, iv, 4, sv) + m[12], dot3(m, v, im + 1, iv, 4, sv) + m[13], @@ -234,7 +234,7 @@ export const mulV344 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => ); export const mulV44 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => - set4s( + setS4( v, dot4(m, v, im, iv, 4, sv), dot4(m, v, im + 1, iv, 4, sv), @@ -243,7 +243,7 @@ export const mulV44 = (m: ReadonlyMat, v: Vec, im = 0, iv = 0, sv = 1) => iv, sv ); -export const detCoeffs44 = (m: ReadonlyMat, i = 0) => { +const detCoeffs44 = (m: ReadonlyMat, i = 0) => { const m00 = m[i]; const m01 = m[i + 1]; const m02 = m[i + 2]; @@ -317,7 +317,7 @@ export const invert44 = (m: Mat, i = 0) => { return; } det = 1.0 / det; - return set44s( + return setS44( m, (m11 * d11 - m12 * d10 + m13 * d09) * det, (-m01 * d11 + m02 * d10 - m03 * d09) * det, @@ -340,7 +340,7 @@ export const invert44 = (m: Mat, i = 0) => { } export const transpose44 = (m: Mat, i = 0) => - set44s( + setS44( m, m[i], m[i + 4], m[i + 8], m[i + 12], m[i + 1], m[i + 5], m[i + 9], m[i + 13], @@ -408,8 +408,8 @@ export class Mat44 implements static scale(x: any, y = x, z = x) { return new Mat44( x instanceof Vec3 ? - scale44v([], x.buf, 0, x.i) : - scale44s([], x, y, z) + scaleV44([], x.buf, 0, x.i) : + scaleS44([], x, y, z) ); } @@ -422,8 +422,8 @@ export class Mat44 implements static translation(x: any, y?: any, z?: any) { return new Mat44( x instanceof Vec3 ? - translation44v([], x.buf, 0, x.i) : - translation44s([], x, y, z) + translationV44([], x.buf, 0, x.i) : + translationS44([], x, y, z) ); } @@ -445,7 +445,7 @@ export class Mat44 implements } eqDelta(m: Mat44, eps = EPS) { - return eqDeltaN(this.buf, m.buf, 16, eps, this.i, m.i); + return eqDelta(this.buf, m.buf, 16, eps, this.i, m.i); } identity() { @@ -462,7 +462,7 @@ export class Mat44 implements m10: number, m11: number, m12: number, m13: number, m20: number, m21: number, m22: number, m23: number, m30: number, m31: number, m32: number, m33: number) { - set44s(this.buf, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33, this.i); + setS44(this.buf, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33, this.i); return this; } diff --git a/packages/vectors/src/math.ts b/packages/vectors/src/math.ts index a43f6574e7..6d48cdb2fe 100644 --- a/packages/vectors/src/math.ts +++ b/packages/vectors/src/math.ts @@ -8,6 +8,9 @@ export const RAD2DEG = 180 / PI; export let EPS = 1e-6; +export const absDiff = (x: number, y: number) => + Math.abs(x - y); + export const atan2Abs = (y: number, x: number) => { const theta = Math.atan2(y, x); return theta < 0 ? TAU + theta : theta; @@ -34,7 +37,7 @@ export const rad = (x: number) => x * DEG2RAD; * @param b right value * @param eps epsilon / tolerance */ -export const eqDelta = (a: number, b: number, eps = EPS) => { +export const eqDelta1 = (a: number, b: number, eps = EPS) => { const d = a - b; return (d * d) <= (eps * eps); }; @@ -45,16 +48,7 @@ export const eqDelta = (a: number, b: number, eps = EPS) => { * @param a * @param b */ -export const fmod = (a: number, b: number) => a - b * Math.floor(a / b); - -/** - * Linear interpolation: `a + (b - a) * t`. - * - * @param a start value - * @param b end value - * @param t interpolation factor (0.0 .. 1.0) - */ -export const mix = (a: number, b: number, t = 0.5) => a + (b - a) * t; +export const fmod1 = (a: number, b: number) => a - b * Math.floor(a / b); /** * Step/threshold function. @@ -63,7 +57,7 @@ export const mix = (a: number, b: number, t = 0.5) => a + (b - a) * t; * @param x test value * @returns 0, if `x < e`, else 1 */ -export const step = (edge: number, x: number) => x < edge ? 0 : 1; +export const step1 = (edge: number, x: number) => x < edge ? 0 : 1; /** * GLSL-style smoothStep threshold function. @@ -73,8 +67,8 @@ export const step = (edge: number, x: number) => x < edge ? 0 : 1; * @param x test value * @returns 0, if `x < edge1`, 1 if `x > edge2`, else sigmoid interpolation */ -export const smoothStep = (edge: number, edge2: number, x: number) => { - const t = clamp((x - edge) / (edge2 - edge), 0, 1); +export const smoothStep1 = (edge: number, edge2: number, x: number) => { + const t = clamp1((x - edge) / (edge2 - edge), 0, 1); return (3 - 2 * t) * t * t; }; @@ -117,22 +111,22 @@ export const max4id = (a, b, c, d) => * @param min lower bound * @param max upper bound */ -export const clamp = (x: number, min: number, max: number) => +export const clamp1 = (x: number, min: number, max: number) => x < min ? min : x > max ? max : x; -export const fit = (x: number, a: number, b: number, c: number, d: number) => +export const fit1 = (x: number, a: number, b: number, c: number, d: number) => c + (d - c) * (x - a) / (b - a); -export const fitClamped = (x: number, a: number, b: number, c: number, d: number) => - c + (d - c) * clamp((x - a) / (b - a), 0, 1); +export const fitClamped1 = (x: number, a: number, b: number, c: number, d: number) => + c + (d - c) * clamp1((x - a) / (b - a), 0, 1); -export const sign = (x: number, eps = EPS) => +export const sign1 = (x: number, eps = EPS) => x > eps ? 1 : x < -eps ? -1 : 0; -export const trunc = (x: number) => +export const trunc1 = (x: number) => x < 0 ? Math.ceil(x) : Math.floor(x); -export const roundTo = (x: number, prec = 1) => +export const roundTo1 = (x: number, prec = 1) => Math.round(x / prec) * prec; /** diff --git a/packages/vectors/src/vec2.ts b/packages/vectors/src/vec2.ts index c41971bc88..34100ad5cb 100644 --- a/packages/vectors/src/vec2.ts +++ b/packages/vectors/src/vec2.ts @@ -1,13 +1,13 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { ReadonlyVec, Vec } from "./api"; +import { ReadonlyVec, Vec, IVec } from "./api"; import { atan2Abs, EPS, - eqDelta, + eqDelta1, max2id, min2id, - smoothStep, - step + smoothStep1, + step1 } from "./math"; export const ZERO2 = Object.freeze([0, 0]); @@ -28,14 +28,23 @@ export const get2 = (a: ReadonlyVec, ia = 0, sa = 1) => export const set2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (a[ia] = b[ib], a[ia + sa] = b[ib + sb], a); -export const set2n = (a: Vec, n: number, ia = 0, sa = 1) => +export const setN2 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] = n, a[ia + sa] = n, a); -export const set2s = (a: Vec, x: number, y: number, ia = 0, sa = 1) => +export const setS2 = (a: Vec, x: number, y: number, ia = 0, sa = 1) => (a[ia] = x, a[ia + sa] = y, a); +export const swizzle2 = (a: Vec, b: Vec, x: number, y: number, ia = 0, ib = 0, sa = 1, sb = 1) => { + const xx = b[ib + x * sb]; + const yy = b[ib + y * sb]; + a[ia] = xx; + a[ia + sa] = yy; + return a; +}; + export const eqDelta2 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && eqDelta(a[ia + sa], b[ib + sb], eps); + eqDelta1(a[ia], b[ib], eps) && + eqDelta1(a[ia + sa], b[ib + sb], eps); export const add2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (a[ia] += b[ib], a[ia + sa] += b[ib + sb], a); @@ -49,20 +58,20 @@ export const sub2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => export const div2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => (a[ia] /= b[ib], a[ia + sa] /= b[ib + sb], a); -export const add2n = (a: Vec, n: number, ia = 0, sa = 1) => +export const addN2 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] += n, a[ia + sa] += n, a); -export const sub2n = (a: Vec, n: number, ia = 0, sa = 1) => +export const subN2 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] -= n, a[ia + sa] -= n, a); -export const mul2n = (a: Vec, n: number, ia = 0, sa = 1) => +export const mulN2 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] *= n, a[ia + sa] *= n, a); -export const div2n = (a: Vec, n: number, ia = 0, sa = 1) => +export const divN2 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] /= n, a[ia + sa] /= n, a); export const neg2 = (a: Vec, ia = 0, sa = 1) => - mul2n(a, -1, ia, sa); + mulN2(a, -1, ia, sa); export const abs2 = (a: Vec, ia = 0, sa = 1) => op2(Math.abs, a, ia, sa); @@ -91,7 +100,7 @@ export const pow2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => a ); -export const pow2n = (a: Vec, n: number, ia = 0, sa = 1) => ( +export const powN2 = (a: Vec, n: number, ia = 0, sa = 1) => ( a[ia] = Math.pow(a[ia], n), a[ia + sa] = Math.pow(a[ia + sa], n), a @@ -100,7 +109,7 @@ export const pow2n = (a: Vec, n: number, ia = 0, sa = 1) => ( export const madd2 = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => (a[ia] += b[ib] * c[ic], a[ia + sa] += b[ib + sb] * c[ic + sc], a); -export const madd2n = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => +export const maddN2 = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => (a[ia] += b[ib] * c, a[ia + sa] += b[ib + sb] * c, a); export const dot2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => @@ -115,7 +124,7 @@ export const mix2 = (a: Vec, b: ReadonlyVec, t: ReadonlyVec, ia = 0, ib = 0, it a ); -export const mix2n = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( +export const mixN2 = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += (b[ib] - a[ia]) * t, a[ia + sa] += (b[ib + sb] - a[ia + sa]) * t, a @@ -131,30 +140,30 @@ export const clamp2 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin max2(min2(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); export const step2 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, stridee = 1) => - (a[ia] = step(e[ie], a[ia]), a[ia + sa] = step(e[ie + stridee], a[ia + sa]), a); + (a[ia] = step1(e[ie], a[ia]), a[ia + sa] = step1(e[ie + stridee], a[ia + sa]), a); export const smoothStep2 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), + a[ia] = smoothStep1(e1[ie1], e2[ie2], a[ia]), + a[ia + sa] = smoothStep1(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), a ); -export const mag2sq = (a: ReadonlyVec, ia = 0, sa = 1) => { +export const magSq2 = (a: ReadonlyVec, ia = 0, sa = 1) => { const x = a[ia], y = a[ia + sa]; return x * x + y * y; }; export const mag2 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(mag2sq(a, ia, sa)); + Math.sqrt(magSq2(a, ia, sa)); -export const dist2sq = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { +export const distSq2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { const x = a[ia] - b[ib]; const y = a[ia + sa] - b[ib + sb]; return x * x + y * y; }; export const dist2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(dist2sq(a, b, ia, ib, sa, sb)); + Math.sqrt(distSq2(a, b, ia, ib, sa, sb)); export const distManhattan2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { return Math.abs(a[ia] - b[ib]) + Math.abs(a[ia + sa] - b[ib + sb]) @@ -166,25 +175,25 @@ export const distChebyshev2 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, s export const normalize2 = (a: Vec, n = 1, ia = 0, sa = 1) => { const m = mag2(a, ia, sa); - m >= EPS && mul2n(a, n / m, ia, sa); + m >= EPS && mulN2(a, n / m, ia, sa); return a; }; export const limit2 = (a: Vec, n: number, ia = 0, sa = 1) => { const m = mag2(a, ia, sa); - m >= n && mul2n(a, n / m, ia, sa); + m >= n && mulN2(a, n / m, ia, sa); return a; }; export const reflect2 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - madd2n(a, b, -2 * dot2(a, b, ia, ib, sa, sb), ia, ib, sa, sb); + maddN2(a, b, -2 * dot2(a, b, ia, ib, sa, sb), ia, ib, sa, sb); export const rotate2 = (a: Vec, theta: number, ia = 0, sa = 1) => { const s = Math.sin(theta); const c = Math.cos(theta); const x = a[ia]; const y = a[ia + sa]; - return set2s(a, x * c - y * s, x * s + y * c, ia, sa); + return setS2(a, x * c - y * s, x * s + y * c, ia, sa); }; export const heading2 = (a: ReadonlyVec, ia = 0, sa = 1) => @@ -192,12 +201,12 @@ export const heading2 = (a: ReadonlyVec, ia = 0, sa = 1) => export const toPolar = (a: Vec, ia = 0, sa = 1) => { const x = a[ia], y = a[ia + sa]; - return set2s(a, Math.sqrt(x * x + y * y), atan2Abs(y, x), ia, sa); + return setS2(a, Math.sqrt(x * x + y * y), atan2Abs(y, x), ia, sa); }; export const toCartesian2 = (a: Vec, b: ReadonlyVec = ZERO2, ia = 0, ib = 0, sa = 1, sb = 1) => { const r = a[ia], theta = a[ia + sa]; - return set2s( + return setS2( a, r * Math.cos(theta) + b[ib], r * Math.sin(theta) + b[ib + sb], @@ -289,12 +298,17 @@ export class Vec2 implements } setN(n: number) { - set2n(this.buf, n, this.i, this.s); + setN2(this.buf, n, this.i, this.s); return this; } setS(x: number, y: number) { - set2s(this.buf, x, y, this.i, this.s); + setS2(this.buf, x, y, this.i, this.s); + return this; + } + + swizzle(v: IVec, x: number, y: number) { + swizzle2(this.buf, v.buf, x, y, this.i, v.i, this.s, v.s); return this; } @@ -319,27 +333,27 @@ export class Vec2 implements } addN(n: number) { - add2n(this.buf, n, this.i, this.s); + addN2(this.buf, n, this.i, this.s); return this; } subN(n: number) { - sub2n(this.buf, n, this.i, this.s); + subN2(this.buf, n, this.i, this.s); return this; } mulN(n: number) { - mul2n(this.buf, n, this.i, this.s); + mulN2(this.buf, n, this.i, this.s); return this; } divN(n: number) { - div2n(this.buf, n, this.i, this.s); + divN2(this.buf, n, this.i, this.s); return this; } neg() { - mul2n(this.buf, -1, this.i, this.s); + mulN2(this.buf, -1, this.i, this.s); return this; } @@ -374,7 +388,7 @@ export class Vec2 implements } powN(n: number) { - pow2n(this.buf, n, this.i, this.s); + powN2(this.buf, n, this.i, this.s); return this; } @@ -394,7 +408,7 @@ export class Vec2 implements } maddN(b: Readonly, n: number) { - madd2n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + maddN2(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -404,7 +418,7 @@ export class Vec2 implements } mixN(b: Readonly, n: number) { - mix2n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + mixN2(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -454,7 +468,7 @@ export class Vec2 implements } magSq() { - return mag2sq(this.buf, this.i, this.s); + return magSq2(this.buf, this.i, this.s); } dist(v: Readonly) { @@ -462,7 +476,7 @@ export class Vec2 implements } distSq(v: Readonly) { - return dist2sq(this.buf, v.buf, this.i, v.i, this.s, v.s); + return distSq2(this.buf, v.buf, this.i, v.i, this.s, v.s); } distManhattan(v: Readonly) { @@ -473,13 +487,13 @@ export class Vec2 implements return distChebyshev2(this.buf, v.buf, this.i, v.i, this.s, v.s); } - normalize(n = 1) { - normalize2(this.buf, n, this.i, this.s); + normalize(len = 1) { + normalize2(this.buf, len, this.i, this.s); return this; } - limit(n: number) { - limit2(this.buf, n, this.i, this.s); + limit(len: number) { + limit2(this.buf, len, this.i, this.s); return this; } diff --git a/packages/vectors/src/vec3.ts b/packages/vectors/src/vec3.ts index 19ef25eb4f..69f551e211 100644 --- a/packages/vectors/src/vec3.ts +++ b/packages/vectors/src/vec3.ts @@ -1,13 +1,14 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { ReadonlyVec, Vec } from "./api"; +import { IVec, ReadonlyVec, Vec } from "./api"; import { atan2Abs, EPS, - eqDelta, + eqDelta1, max3id, min3id, - smoothStep, - step + sign1, + smoothStep1, + step1 } from "./math"; import { heading2, rotate2 } from "./vec2"; @@ -38,20 +39,30 @@ export const set3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => a ); -export const set3n = (a: Vec, n: number, ia = 0, sa = 1) => ( +export const setN3 = (a: Vec, n: number, ia = 0, sa = 1) => ( a[ia] = n, a[ia + sa] = n, a[ia + 2 * sa] = n, a ); -export const set3s = (a: Vec, x: number, y: number, z: number, ia = 0, sa = 1) => +export const setS3 = (a: Vec, x: number, y: number, z: number, ia = 0, sa = 1) => (a[ia] = x, a[ia + sa] = y, a[ia + 2 * sa] = z, a); +export const swizzle3 = (a: Vec, b: Vec, x: number, y: number, z: number, ia = 0, ib = 0, sa = 1, sb = 1) => { + const xx = b[ib + x * sb]; + const yy = b[ib + y * sb]; + const zz = b[ib + z * sb]; + a[ia] = xx; + a[ia + sa] = yy; + a[ia + 2 * sa] = zz; + return a; +}; + export const eqDelta3 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && - eqDelta(a[ia + sa], b[ib + sb], eps) && - eqDelta(a[ia + 2 * sa], b[ib + 2 * sb], eps); + eqDelta1(a[ia], b[ib], eps) && + eqDelta1(a[ia + sa], b[ib + sb], eps) && + eqDelta1(a[ia + 2 * sa], b[ib + 2 * sb], eps); export const add3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += b[ib], @@ -81,26 +92,26 @@ export const div3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => a ); -export const add3n = (a: Vec, n: number, ia = 0, sa = 1) => +export const addN3 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] += n, a[ia + sa] += n, a[ia + 2 * sa] += n, a); -export const sub3n = (a: Vec, n: number, ia = 0, sa = 1) => +export const subN3 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] -= n, a[ia + sa] -= n, a[ia + 2 * sa] -= n, a); -export const mul3n = (a: Vec, n: number, ia = 0, sa = 1) => +export const mulN3 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] *= n, a[ia + sa] *= n, a[ia + 2 * sa] *= n, a); -export const div3n = (a: Vec, n: number, ia = 0, sa = 1) => +export const divN3 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] /= n, a[ia + sa] /= n, a[ia + 2 * sa] /= n, a); export const neg3 = (a: Vec, ia = 0, sa = 1) => - mul3n(a, -1, ia, sa); + mulN3(a, -1, ia, sa); export const abs3 = (a: Vec, ia = 0, sa = 1) => op3(Math.abs, a, ia, sa); -export const sign3 = (a: Vec, ia = 0, sa = 1) => - op3(Math.sign, a, ia, sa); +export const sign3 = (a: Vec, eps = EPS, ia = 0, sa = 1) => + op3((x) => sign1(x, eps), a, ia, sa); export const floor3 = (a: Vec, ia = 0, sa = 1) => op3(Math.floor, a, ia, sa); @@ -120,7 +131,7 @@ export const sqrt3 = (a: Vec, ia = 0, sa = 1) => export const pow3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => op32(Math.pow, a, b, ia, ib, sa, sb); -export const pow3n = (a: Vec, n: number, ia = 0, sa = 1) => +export const powN3 = (a: Vec, n: number, ia = 0, sa = 1) => op3((x) => Math.pow(x, n), a, ia, sa); export const madd3 = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => ( @@ -130,7 +141,7 @@ export const madd3 = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, ia = 0, ib = 0, ic a ); -export const madd3n = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( +export const maddN3 = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += b[ib] * c, a[ia + sa] += b[ib + sb] * c, a[ia + 2 * sa] += b[ib + 2 * sb] * c, @@ -168,7 +179,7 @@ export const mix3 = (a: Vec, b: ReadonlyVec, t: ReadonlyVec, ia = 0, ib = 0, it a ); -export const mix3n = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( +export const mixN3 = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += (b[ib] - a[ia]) * t, a[ia + sa] += (b[ib + sb] - a[ia + sa]) * t, a[ia + 2 * sa] += (b[ib + 2 * sb] - a[ia + 2 * sa]) * t, @@ -185,20 +196,20 @@ export const clamp3 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin max3(min3(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); export const step3 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, se = 1) => ( - a[ia] = step(e[ie], a[ia]), - a[ia + sa] = step(e[ie + se], a[ia + sa]), - a[ia + 2 * sa] = step(e[ie + 2 * se], a[ia + 2 * sa]), + a[ia] = step1(e[ie], a[ia]), + a[ia + sa] = step1(e[ie + se], a[ia + sa]), + a[ia + 2 * sa] = step1(e[ie + 2 * se], a[ia + 2 * sa]), a ); export const smoothStep3 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), - a[ia + 2 * sa] = smoothStep(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), + a[ia] = smoothStep1(e1[ie1], e2[ie2], a[ia]), + a[ia + sa] = smoothStep1(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), + a[ia + 2 * sa] = smoothStep1(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), a ); -export const mag3sq = (a: ReadonlyVec, ia = 0, sa = 1) => { +export const magSq3 = (a: ReadonlyVec, ia = 0, sa = 1) => { const x = a[ia]; const y = a[ia + sa]; const z = a[ia + 2 * sa]; @@ -206,9 +217,9 @@ export const mag3sq = (a: ReadonlyVec, ia = 0, sa = 1) => { }; export const mag3 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(mag3sq(a, ia, sa)); + Math.sqrt(magSq3(a, ia, sa)); -export const dist3sq = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { +export const distSq3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { const x = a[ia] - b[ib]; const y = a[ia + sa] - b[ib + sb]; const z = a[ia + 2 * sa] - b[ib + 2 * sb]; @@ -216,7 +227,7 @@ export const dist3sq = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, }; export const dist3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(dist3sq(a, b, ia, ib, sa, sb)); + Math.sqrt(distSq3(a, b, ia, ib, sa, sb)); export const distManhattan3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => Math.abs(a[ia] - b[ib]) + @@ -232,41 +243,41 @@ export const distChebyshev3 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, s export const normalize3 = (a: Vec, n = 1, ia = 0, sa = 1) => { const m = mag3(a, ia, sa); - m >= EPS && mul3n(a, n / m, ia, sa); + m >= EPS && mulN3(a, n / m, ia, sa); return a; }; export const limit3 = (a: Vec, n: number, ia = 0, sa = 1) => { const m = mag3(a, ia, sa); - m >= n && mul3n(a, n / m, ia, sa); + m >= n && mulN3(a, n / m, ia, sa); return a; }; export const reflect3 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - madd3n(a, b, -2 * dot3(a, b, ia, ib, sa, sb), ia, ib, sa, sb); + maddN3(a, b, -2 * dot3(a, b, ia, ib, sa, sb), ia, ib, sa, sb); -export const rotate3x = (a: Vec, theta: number, ia = 0, sa = 1) => +export const rotateX3 = (a: Vec, theta: number, ia = 0, sa = 1) => rotate2(a, theta, ia + sa, sa); -export const rotate3y = (a: Vec, theta: number, ia = 0, sa = 1) => +export const rotateY3 = (a: Vec, theta: number, ia = 0, sa = 1) => rotate2(a, theta, ia + 2 * sa, -2 * sa); -export const rotate3z = rotate2; +export const rotateZ3 = rotate2; -export const heading3xy = heading2; +export const headingXY3 = heading2; -export const heading3xz = (a: ReadonlyVec, ia = 0, sa = 1) => +export const headingXZ3 = (a: ReadonlyVec, ia = 0, sa = 1) => atan2Abs(a[ia + 2 * sa], a[ia]); -export const heading3yz = (a: ReadonlyVec, ia = 0, sa = 1) => +export const headingYZ3 = (a: ReadonlyVec, ia = 0, sa = 1) => atan2Abs(a[ia + 2 * sa], a[ia + sa]); -export const toSpherical = (a: Vec, ia = 0, sa = 1) => { +export const toSpherical3 = (a: Vec, ia = 0, sa = 1) => { const x = a[ia]; const y = a[ia + sa]; const z = a[ia + 2 * sa]; const r = Math.sqrt(x * x + y * y + z * z); - return set3s(a, r, Math.asin(z / r), atan2Abs(y, x), ia, sa); + return setS3(a, r, Math.asin(z / r), atan2Abs(y, x), ia, sa); }; export const toCartesian3 = (a: Vec, b: ReadonlyVec = ZERO3, ia = 0, ib = 0, sa = 1, sb = 1) => { @@ -274,7 +285,7 @@ export const toCartesian3 = (a: Vec, b: ReadonlyVec = ZERO3, ia = 0, ib = 0, sa const theta = a[ia + sa]; const phi = a[ia + 2 * sa]; const ct = Math.cos(theta); - return set3s(a, + return setS3(a, r * ct * Math.cos(phi) + b[ib], r * ct * Math.sin(phi) + b[ib + sb], r * Math.sin(theta) + b[ib + 2 * sb], @@ -379,12 +390,17 @@ export class Vec3 implements } setN(n: number) { - set3n(this.buf, n, this.i, this.s); + setN3(this.buf, n, this.i, this.s); return this; } setS(x: number, y: number, z: number) { - set3s(this.buf, x, y, z, this.i, this.s); + setS3(this.buf, x, y, z, this.i, this.s); + return this; + } + + swizzle(v: IVec, x: number, y: number, z: number) { + swizzle3(this.buf, v.buf, x, y, z, this.i, v.i, this.s, v.s); return this; } @@ -409,27 +425,27 @@ export class Vec3 implements } addN(n: number) { - add3n(this.buf, n, this.i, this.s); + addN3(this.buf, n, this.i, this.s); return this; } subN(n: number) { - sub3n(this.buf, n, this.i, this.s); + subN3(this.buf, n, this.i, this.s); return this; } mulN(n: number) { - mul3n(this.buf, n, this.i, this.s); + mulN3(this.buf, n, this.i, this.s); return this; } divN(n: number) { - div3n(this.buf, n, this.i, this.s); + divN3(this.buf, n, this.i, this.s); return this; } neg() { - mul3n(this.buf, -1, this.i, this.s); + mulN3(this.buf, -1, this.i, this.s); return this; } @@ -464,7 +480,7 @@ export class Vec3 implements } powN(n: number) { - pow3n(this.buf, n, this.i, this.s); + powN3(this.buf, n, this.i, this.s); return this; } @@ -484,7 +500,7 @@ export class Vec3 implements } maddN(b: Readonly, n: number) { - madd3n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + maddN3(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -494,7 +510,7 @@ export class Vec3 implements } mixN(b: Readonly, n: number) { - mix3n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + mixN3(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -549,7 +565,7 @@ export class Vec3 implements } magSq() { - return mag3sq(this.buf, this.i, this.s); + return magSq3(this.buf, this.i, this.s); } dist(v: Readonly) { @@ -557,7 +573,7 @@ export class Vec3 implements } distSq(v: Readonly) { - return dist3sq(this.buf, v.buf, this.i, v.i, this.s, v.s); + return distSq3(this.buf, v.buf, this.i, v.i, this.s, v.s); } distManhattan(v: Readonly) { @@ -568,13 +584,13 @@ export class Vec3 implements return distChebyshev3(this.buf, v.buf, this.i, v.i, this.s, v.s); } - normalize(n = 1) { - normalize3(this.buf, n, this.i, this.s); + normalize(len = 1) { + normalize3(this.buf, len, this.i, this.s); return this; } - limit(n: number) { - limit3(this.buf, n, this.i, this.s); + limit(len: number) { + limit3(this.buf, len, this.i, this.s); return this; } @@ -584,34 +600,34 @@ export class Vec3 implements } rotateX(theta: number) { - rotate3x(this.buf, theta, this.i, this.s); + rotateX3(this.buf, theta, this.i, this.s); return this; } rotateY(theta: number) { - rotate3y(this.buf, theta, this.i, this.s); + rotateY3(this.buf, theta, this.i, this.s); return this; } rotateZ(theta: number) { - rotate3z(this.buf, theta, this.i, this.s); + rotateZ3(this.buf, theta, this.i, this.s); return this; } headingXY() { - return heading3xy(this.buf, this.i, this.s); + return headingXY3(this.buf, this.i, this.s); } headingXZ() { - return heading3xz(this.buf, this.i, this.s); + return headingXZ3(this.buf, this.i, this.s); } headingYZ() { - return heading3yz(this.buf, this.i, this.s); + return headingYZ3(this.buf, this.i, this.s); } toSpherical() { - toSpherical(this.buf, this.i, this.s); + toSpherical3(this.buf, this.i, this.s); return this; } diff --git a/packages/vectors/src/vec4.ts b/packages/vectors/src/vec4.ts index 80df6d4ec5..b84abfed96 100644 --- a/packages/vectors/src/vec4.ts +++ b/packages/vectors/src/vec4.ts @@ -1,12 +1,12 @@ import { ICopy, IEqualsDelta } from "@thi.ng/api/api"; -import { ReadonlyVec, Vec } from "./api"; +import { ReadonlyVec, Vec, IVec } from "./api"; import { EPS, - eqDelta, + eqDelta1, max4id, min4id, - smoothStep, - step + smoothStep1, + step1 } from "./math"; export const ZERO4 = Object.freeze([0, 0, 0, 0]); @@ -39,7 +39,7 @@ export const set4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => a ); -export const set4n = (a: Vec, n: number, ia = 0, sa = 1) => ( +export const setN4 = (a: Vec, n: number, ia = 0, sa = 1) => ( a[ia] = n, a[ia + sa] = n, a[ia + 2 * sa] = n, @@ -47,7 +47,7 @@ export const set4n = (a: Vec, n: number, ia = 0, sa = 1) => ( a ); -export const set4s = (a: Vec, x: number, y: number, z: number, w: number, ia = 0, sa = 1) => ( +export const setS4 = (a: Vec, x: number, y: number, z: number, w: number, ia = 0, sa = 1) => ( a[ia] = x, a[ia + sa] = y, a[ia + 2 * sa] = z, @@ -55,11 +55,23 @@ export const set4s = (a: Vec, x: number, y: number, z: number, w: number, ia = 0 a ); +export const swizzle4 = (a: Vec, b: Vec, x: number, y: number, z: number, w: number, ia = 0, ib = 0, sa = 1, sb = 1) => { + const xx = b[ib + x * sb]; + const yy = b[ib + y * sb]; + const zz = b[ib + z * sb]; + const ww = b[ib + w * sb]; + a[ia] = xx; + a[ia + sa] = yy; + a[ia + 2 * sa] = zz; + a[ia + 3 * sa] = ww; + return a; +}; + export const eqDelta4 = (a: ReadonlyVec, b: ReadonlyVec, eps = EPS, ia = 0, ib = 0, sa = 1, sb = 1) => - eqDelta(a[ia], b[ib], eps) && - eqDelta(a[ia + sa], b[ib + sb], eps) && - eqDelta(a[ia + 2 * sa], b[ib + 2 * sb], eps) && - eqDelta(a[ia + 3 * sa], b[ib + 3 * sb], eps); + eqDelta1(a[ia], b[ib], eps) && + eqDelta1(a[ia + sa], b[ib + sb], eps) && + eqDelta1(a[ia + 2 * sa], b[ib + 2 * sb], eps) && + eqDelta1(a[ia + 3 * sa], b[ib + 3 * sb], eps); export const add4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += b[ib], @@ -93,20 +105,20 @@ export const div4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => a ); -export const add4n = (a: Vec, n: number, ia = 0, sa = 1) => +export const addN4 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] += n, a[ia + sa] += n, a[ia + 2 * sa] += n, a[ia + 3 * sa] += n, a); -export const sub4n = (a: Vec, n: number, ia = 0, sa = 1) => +export const subN4 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] -= n, a[ia + sa] -= n, a[ia + 2 * sa] -= n, a[ia + 3 * sa] -= n, a); -export const mul4n = (a: Vec, n: number, ia = 0, sa = 1) => +export const mulN4 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] *= n, a[ia + sa] *= n, a[ia + 2 * sa] *= n, a[ia + 3 * sa] *= n, a); -export const div4n = (a: Vec, n: number, ia = 0, sa = 1) => +export const divN4 = (a: Vec, n: number, ia = 0, sa = 1) => (a[ia] /= n, a[ia + sa] /= n, a[ia + 2 * sa] /= n, a[ia + 3 * sa] /= n, a); export const neg4 = (a: Vec, ia = 0, sa = 1) => - mul4n(a, -1, ia, sa); + mulN4(a, -1, ia, sa); export const abs4 = (a: Vec, ia = 0, sa = 1) => op4(Math.abs, a, ia, sa); @@ -132,20 +144,22 @@ export const sqrt4 = (a: Vec, ia = 0, sa = 1) => export const pow4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => op42(Math.pow, a, b, ia, ib, sa, sb); -export const pow4n = (a: Vec, n: number, ia = 0, sa = 1) => +export const powN4 = (a: Vec, n: number, ia = 0, sa = 1) => op4((x) => Math.pow(x, n), a, ia, sa); export const madd4 = (a: Vec, b: ReadonlyVec, c: ReadonlyVec, ia = 0, ib = 0, ic = 0, sa = 1, sb = 1, sc = 1) => ( a[ia] += b[ib] * c[ic], a[ia + sa] += b[ib + sb] * c[ic + sc], a[ia + 2 * sa] += b[ib + 2 * sb] * c[ic + 2 * sc], + a[ia + 3 * sa] += b[ib + 3 * sb] * c[ic + 3 * sc], a ); -export const madd4n = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( +export const maddN4 = (a: Vec, b: ReadonlyVec, c: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += b[ib] * c, a[ia + sa] += b[ib + sb] * c, a[ia + 2 * sa] += b[ib + 2 * sb] * c, + a[ia + 3 * sa] += b[ib + 3 * sb] * c, a ); @@ -163,7 +177,7 @@ export const mix4 = (a: Vec, b: ReadonlyVec, t: ReadonlyVec, ia = 0, ib = 0, it a ); -export const mix4n = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( +export const mixN4 = (a: Vec, b: ReadonlyVec, t: number, ia = 0, ib = 0, sa = 1, sb = 1) => ( a[ia] += (b[ib] - a[ia]) * t, a[ia + sa] += (b[ib + sb] - a[ia + sa]) * t, a[ia + 2 * sa] += (b[ib + 2 * sb] - a[ia + 2 * sa]) * t, @@ -181,22 +195,22 @@ export const clamp4 = (a: Vec, min: ReadonlyVec, max: ReadonlyVec, ia = 0, imin max4(min4(a, max, ia, imax, sa, smax), min, ia, imin, sa, smin); export const step4 = (a: Vec, e: ReadonlyVec, ia = 0, ie = 0, sa = 1, se = 1) => ( - a[ia] = step(e[ie], a[ia]), - a[ia + sa] = step(e[ie + se], a[ia + sa]), - a[ia + 2 * sa] = step(e[ie + 2 * se], a[ia + 2 * sa]), - a[ia + 3 * sa] = step(e[ie + 3 * se], a[ia + 3 * sa]), + a[ia] = step1(e[ie], a[ia]), + a[ia + sa] = step1(e[ie + se], a[ia + sa]), + a[ia + 2 * sa] = step1(e[ie + 2 * se], a[ia + 2 * sa]), + a[ia + 3 * sa] = step1(e[ie + 3 * se], a[ia + 3 * sa]), a ); export const smoothStep4 = (a: Vec, e1: ReadonlyVec, e2: ReadonlyVec, ia = 0, ie1 = 0, ie2 = 0, sa = 1, se1 = 1, se2 = 1) => ( - a[ia] = smoothStep(e1[ie1], e2[ie2], a[ia]), - a[ia + sa] = smoothStep(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), - a[ia + 2 * sa] = smoothStep(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), - a[ia + 3 * sa] = smoothStep(e1[ie1 + 3 * se1], e2[ie2 + 2 * se2], a[ia + 3 * sa]), + a[ia] = smoothStep1(e1[ie1], e2[ie2], a[ia]), + a[ia + sa] = smoothStep1(e1[ie1 + se1], e2[ie2 + se2], a[ia + sa]), + a[ia + 2 * sa] = smoothStep1(e1[ie1 + 2 * se1], e2[ie2 + 2 * se2], a[ia + 2 * sa]), + a[ia + 3 * sa] = smoothStep1(e1[ie1 + 3 * se1], e2[ie2 + 2 * se2], a[ia + 3 * sa]), a ); -export const mag4sq = (a: ReadonlyVec, ia = 0, sa = 1) => { +export const magSq4 = (a: ReadonlyVec, ia = 0, sa = 1) => { const x = a[ia]; const y = a[ia + sa]; const z = a[ia + 2 * sa]; @@ -205,9 +219,9 @@ export const mag4sq = (a: ReadonlyVec, ia = 0, sa = 1) => { }; export const mag4 = (a: ReadonlyVec, ia = 0, sa = 1) => - Math.sqrt(mag4sq(a, ia, sa)); + Math.sqrt(magSq4(a, ia, sa)); -export const dist4sq = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { +export const distSq4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => { const x = a[ia] - b[ib]; const y = a[ia + sa] - b[ib + sb]; const z = a[ia + 2 * sa] - b[ib + 2 * sb]; @@ -216,7 +230,7 @@ export const dist4sq = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, }; export const dist4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - Math.sqrt(dist4sq(a, b, ia, ib, sa, sb)); + Math.sqrt(distSq4(a, b, ia, ib, sa, sb)); export const distManhattan4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => Math.abs(a[ia] - b[ib]) + @@ -234,18 +248,18 @@ export const distChebyshev4 = (a: ReadonlyVec, b: ReadonlyVec, ia = 0, ib = 0, s export const normalize4 = (a: Vec, n = 1, ia = 0, sa = 1) => { const m = mag4(a, ia, sa); - m >= EPS && mul4n(a, n / m, ia, sa); + m >= EPS && mulN4(a, n / m, ia, sa); return a; }; export const limit4 = (a: Vec, n: number, ia = 0, sa = 1) => { const m = mag4(a, ia, sa); - m >= n && mul4n(a, n / m, ia, sa); + m >= n && mulN4(a, n / m, ia, sa); return a; }; export const reflect4 = (a: Vec, b: ReadonlyVec, ia = 0, ib = 0, sa = 1, sb = 1) => - madd4n(a, b, -2 * dot4(a, b, ia, ib, sa, sb), ia, ib, sa, sb); + maddN4(a, b, -2 * dot4(a, b, ia, ib, sa, sb), ia, ib, sa, sb); export const minor4 = (a: Vec, ia = 0, sa = 1) => min4id(Math.abs(a[ia]), Math.abs(a[ia + sa]), Math.abs(a[ia + 2 * sa]), Math.abs(a[ia + 3 * sa])); @@ -349,12 +363,17 @@ export class Vec4 implements } setN(n: number) { - set4n(this.buf, n, this.i, this.s); + setN4(this.buf, n, this.i, this.s); return this; } setS(x: number, y: number, z: number, w: number) { - set4s(this.buf, x, y, z, w, this.i, this.s); + setS4(this.buf, x, y, z, w, this.i, this.s); + return this; + } + + swizzle(v: IVec, x: number, y: number, z: number, w: number) { + swizzle4(this.buf, v.buf, x, y, z, w, this.i, v.i, this.s, v.s); return this; } @@ -379,27 +398,27 @@ export class Vec4 implements } addN(n: number) { - add4n(this.buf, n, this.i, this.s); + addN4(this.buf, n, this.i, this.s); return this; } subN(n: number) { - sub4n(this.buf, n, this.i, this.s); + subN4(this.buf, n, this.i, this.s); return this; } mulN(n: number) { - mul4n(this.buf, n, this.i, this.s); + mulN4(this.buf, n, this.i, this.s); return this; } divN(n: number) { - div4n(this.buf, n, this.i, this.s); + divN4(this.buf, n, this.i, this.s); return this; } neg() { - mul4n(this.buf, -1, this.i, this.s); + mulN4(this.buf, -1, this.i, this.s); return this; } @@ -434,7 +453,7 @@ export class Vec4 implements } powN(n: number) { - pow4n(this.buf, n, this.i, this.s); + powN4(this.buf, n, this.i, this.s); return this; } @@ -454,7 +473,7 @@ export class Vec4 implements } maddN(b: Readonly, n: number) { - madd4n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + maddN4(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -464,7 +483,7 @@ export class Vec4 implements } mixN(b: Readonly, n: number) { - mix4n(this.buf, b.buf, n, this.i, b.i, this.s, b.s); + mixN4(this.buf, b.buf, n, this.i, b.i, this.s, b.s); return this; } @@ -510,7 +529,7 @@ export class Vec4 implements } magSq() { - return mag4sq(this.buf, this.i, this.s); + return magSq4(this.buf, this.i, this.s); } dist(v: Readonly) { @@ -518,7 +537,7 @@ export class Vec4 implements } distSq(v: Readonly) { - return dist4sq(this.buf, v.buf, this.i, v.i, this.s, v.s); + return distSq4(this.buf, v.buf, this.i, v.i, this.s, v.s); } distManhattan(v: Readonly) { @@ -529,13 +548,13 @@ export class Vec4 implements return distChebyshev4(this.buf, v.buf, this.i, v.i, this.s, v.s); } - normalize(n = 1) { - normalize4(this.buf, n, this.i, this.s); + normalize(len = 1) { + normalize4(this.buf, len, this.i, this.s); return this; } - limit(n: number) { - limit4(this.buf, n, this.i, this.s); + limit(len: number) { + limit4(this.buf, len, this.i, this.s); return this; } diff --git a/packages/vectors/test/swizzle.ts b/packages/vectors/test/swizzle.ts new file mode 100644 index 0000000000..dbf85f9df9 --- /dev/null +++ b/packages/vectors/test/swizzle.ts @@ -0,0 +1,88 @@ +import * as assert from "assert"; +import { Vec2, swizzle2 } from "../src/vec2"; +import { Vec3, swizzle3 } from "../src/vec3"; +import { Vec4, swizzle4 } from "../src/vec4"; + +describe("swizzle", () => { + + it("vec2", () => { + assert.deepEqual( + swizzle2([], [10, 20], 1, 0), + [20, 10] + ); + assert.deepEqual( + swizzle2([], [10, 20], 1, 1), + [20, 20] + ); + assert.deepEqual( + swizzle2([0, 0, 0, 0], [10, 20], 1, 0, 1, 0, 2, 1), + [0, 20, 0, 10] + ); + assert.deepEqual( + swizzle2([], [0, 10, 0, 0, 0, 20], 1, 0, 0, 1, 1, 4), + [20, 10] + ); + assert.deepEqual( + new Vec2([]).swizzle(new Vec2([10, 0, 20, 0], 0, 2), 1, 0).buf, + [20, 10] + ); + assert.deepEqual( + new Vec2([0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 0).buf, + [0, 20, 0, 10, 0] + ); + }); + + it("vec3", () => { + assert.deepEqual( + swizzle3([], [10, 20, 30], 2, 1, 0), + [30, 20, 10] + ); + assert.deepEqual( + swizzle3([], [10, 20, 30], 1, 1, 1), + [20, 20, 20] + ); + assert.deepEqual( + swizzle3([0, 0, 0, 0, 0, 0], [10, 20, 30], 2, 1, 0, 1, 0, 2, 1), + [0, 30, 0, 20, 0, 10] + ); + assert.deepEqual( + swizzle3([], [0, 10, 0, 0, 0, 20, 0, 0, 0, 30], 2, 1, 0, 0, 1, 1, 4), + [30, 20, 10] + ); + assert.deepEqual( + new Vec3([]).swizzle(new Vec3([10, 0, 20, 0, 30, 0], 0, 2), 2, 1, 0).buf, + [30, 20, 10] + ); + assert.deepEqual( + new Vec3([0, 0, 0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 1, 0).buf, + [0, 20, 0, 20, 0, 10, 0] + ); + }); + + it("vec4", () => { + assert.deepEqual( + swizzle4([], [10, 20, 30, 40], 3, 2, 1, 0), + [40, 30, 20, 10] + ); + assert.deepEqual( + swizzle4([], [10, 20, 30, 40], 1, 1, 1, 1), + [20, 20, 20, 20] + ); + assert.deepEqual( + swizzle4([0, 0, 0, 0, 0, 0, 0, 0], [10, 20, 30, 40], 3, 2, 1, 0, 1, 0, 2, 1), + [0, 40, 0, 30, 0, 20, 0, 10] + ); + assert.deepEqual( + swizzle4([], [0, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 40], 3, 2, 1, 0, 0, 1, 1, 4), + [40, 30, 20, 10] + ); + assert.deepEqual( + new Vec4([]).swizzle(new Vec4([10, 0, 20, 0, 30, 0, 40, 0], 0, 2), 3, 2, 1, 0).buf, + [40, 30, 20, 10] + ); + assert.deepEqual( + new Vec4([0, 0, 0, 0, 0, 0, 0, 0, 0], 1, 2).swizzle(new Vec2([10, 0, 0, 0, 20, 0, 0, 0], 0, 4), 1, 1, 0, 0).buf, + [0, 20, 0, 20, 0, 10, 0, 10, 0] + ); + }); +}); diff --git a/packages/vectors/test/vec2.ts b/packages/vectors/test/vec2.ts index 967d5daa13..5c6e1c15a9 100644 --- a/packages/vectors/test/vec2.ts +++ b/packages/vectors/test/vec2.ts @@ -30,10 +30,33 @@ describe("vec2", () => { it("mul", () => op2(v.mul2, 10, 40)); it("div", () => op2(v.div2, 0.1, 0.1)); - it("addn", () => opn(v.add2n, 11, 12)); - it("subn", () => opn(v.sub2n, -9, -8)); - it("muln", () => opn(v.mul2n, 10, 20)); - it("divn", () => opn(v.div2n, 0.1, 0.2)); + it("addn", () => opn(v.addN2, 11, 12)); + it("subn", () => opn(v.subN2, -9, -8)); + it("muln", () => opn(v.mulN2, 10, 20)); + it("divn", () => opn(v.divN2, 0.1, 0.2)); + + it("madd", () => { + assert.deepEqual( + v.madd2([1, 2], [10, 20], [0.5, 0.25]), + [1 + 10 * 0.5, 2 + 20 * 0.25] + ); + assert.deepEqual( + v.madd2([1, 2], [10, 0, 20, 0], [0.5, 0, 0, 0.25], 0, 0, 0, 1, 2, 3), + [1 + 10 * 0.5, 2 + 20 * 0.25] + ); + }); + + it("maddn", () => { + assert.deepEqual( + v.maddN2([1, 2], [10, 20], 0.5), + [1 + 10 * 0.5, 2 + 20 * 0.5] + ); + assert.deepEqual( + v.maddN2([1, 2], [10, 0, 20, 0], 0.5, 0, 0, 1, 2), + [1 + 10 * 0.5, 2 + 20 * 0.5] + ); + }); + it("eqdelta", () => { assert(v.eqDelta2([0, 1.001, 0, 1.999, 0], [1, 2], 0.01, 1, 0, 2, 1)); diff --git a/packages/vectors/test/vec3.ts b/packages/vectors/test/vec3.ts index abfa0e1ab5..c3e7528d2f 100644 --- a/packages/vectors/test/vec3.ts +++ b/packages/vectors/test/vec3.ts @@ -30,10 +30,32 @@ describe("vec3", () => { it("mul", () => op2(v.mul3, 10, 40, 90)); it("div", () => op2(v.div3, 0.1, 0.1, 0.1)); - it("addn", () => opn(v.add3n, 11, 12, 13)); - it("subn", () => opn(v.sub3n, -9, -8, -7)); - it("muln", () => opn(v.mul3n, 10, 20, 30)); - it("divn", () => opn(v.div3n, 0.1, 0.2, 0.3)); + it("addn", () => opn(v.addN3, 11, 12, 13)); + it("subn", () => opn(v.subN3, -9, -8, -7)); + it("muln", () => opn(v.mulN3, 10, 20, 30)); + it("divn", () => opn(v.divN3, 0.1, 0.2, 0.3)); + + it("madd", () => { + assert.deepEqual( + v.madd3([1, 2, 3], [10, 20, 30], [0.5, 0.25, 0.75]), + [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75] + ); + assert.deepEqual( + v.madd3([1, 2, 3], [10, 0, 20, 0, 30], [0.5, 0, 0, 0.25, 0, 0, 0.75], 0, 0, 0, 1, 2, 3), + [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75] + ); + }); + + it("maddn", () => { + assert.deepEqual( + v.maddN3([1, 2, 3], [10, 20, 30], 0.5), + [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5] + ); + assert.deepEqual( + v.maddN3([1, 2, 3], [10, 0, 20, 0, 30], 0.5, 0, 0, 1, 2), + [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5] + ); + }); it("eqdelta", () => { assert(v.eqDelta3([0, 1.001, 0, 1.999, 0, 3.0099], [1, 2, 3], 0.01, 1, 0, 2, 1)); diff --git a/packages/vectors/test/vec4.ts b/packages/vectors/test/vec4.ts index 85ec31f5ba..6fcc22aacd 100644 --- a/packages/vectors/test/vec4.ts +++ b/packages/vectors/test/vec4.ts @@ -30,10 +30,32 @@ describe("vec4", () => { it("mul", () => op2(v.mul4, 10, 40, 90, 160)); it("div", () => op2(v.div4, 0.1, 0.1, 0.1, 0.1)); - it("addn", () => opn(v.add4n, 11, 12, 13, 14)); - it("subn", () => opn(v.sub4n, -9, -8, -7, -6)); - it("muln", () => opn(v.mul4n, 10, 20, 30, 40)); - it("divn", () => opn(v.div4n, 0.1, 0.2, 0.3, 0.4)); + it("addn", () => opn(v.addN4, 11, 12, 13, 14)); + it("subn", () => opn(v.subN4, -9, -8, -7, -6)); + it("muln", () => opn(v.mulN4, 10, 20, 30, 40)); + it("divn", () => opn(v.divN4, 0.1, 0.2, 0.3, 0.4)); + + it("madd", () => { + assert.deepEqual( + v.madd4([1, 2, 3, 4], [10, 20, 30, 40], [0.5, 0.25, 0.75, 0.125]), + [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] + ); + assert.deepEqual( + v.madd4([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], [0.5, 0, 0, 0.25, 0, 0, 0.75, 0, 0, 0.125], 0, 0, 0, 1, 2, 3), + [1 + 10 * 0.5, 2 + 20 * 0.25, 3 + 30 * 0.75, 4 + 40 * 0.125] + ); + }); + + it("maddn", () => { + assert.deepEqual( + v.maddN4([1, 2, 3, 4], [10, 20, 30, 40], 0.5), + [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] + ); + assert.deepEqual( + v.maddN4([1, 2, 3, 4], [10, 0, 20, 0, 30, 0, 40], 0.5, 0, 0, 1, 2), + [1 + 10 * 0.5, 2 + 20 * 0.5, 3 + 30 * 0.5, 4 + 40 * 0.5] + ); + }); it("eqdelta", () => { assert(v.eqDelta4([0, 1.001, 0, 1.999, 0, 3.0099, 0, 3.991], [1, 2, 3, 4], 0.01, 1, 0, 2, 1));