@playcanvas/splat-transform
Version:
CLI tool for 3D Gaussian splat format conversion and transformation
2,023 lines (2,013 loc) • 3.4 MB
JavaScript
import { open } from 'node:fs/promises';
import { resolve as resolve$2, dirname } from 'node:path';
import { stdout, hrtime, exit } from 'node:process';
import { parseArgs } from 'node:util';
import { Buffer as Buffer$1 } from 'node:buffer';
import sharp from 'sharp';
import { Worker as Worker$1 } from 'node:worker_threads';
import { JSDOM } from 'jsdom';
import { globals, create } from 'webgpu';
const math$1 = {
DEG_TO_RAD: Math.PI / 180,
RAD_TO_DEG: 180 / Math.PI};
let Vec3$1 = class Vec3 {
constructor(x = 0, y = 0, z = 0){
if (x.length === 3) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
} else {
this.x = x;
this.y = y;
this.z = z;
}
}
add(rhs) {
this.x += rhs.x;
this.y += rhs.y;
this.z += rhs.z;
return this;
}
add2(lhs, rhs) {
this.x = lhs.x + rhs.x;
this.y = lhs.y + rhs.y;
this.z = lhs.z + rhs.z;
return this;
}
addScalar(scalar) {
this.x += scalar;
this.y += scalar;
this.z += scalar;
return this;
}
addScaled(rhs, scalar) {
this.x += rhs.x * scalar;
this.y += rhs.y * scalar;
this.z += rhs.z * scalar;
return this;
}
clone() {
const cstr = this.constructor;
return new cstr(this.x, this.y, this.z);
}
copy(rhs) {
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
return this;
}
cross(lhs, rhs) {
const lx = lhs.x;
const ly = lhs.y;
const lz = lhs.z;
const rx = rhs.x;
const ry = rhs.y;
const rz = rhs.z;
this.x = ly * rz - ry * lz;
this.y = lz * rx - rz * lx;
this.z = lx * ry - rx * ly;
return this;
}
distance(rhs) {
const x = this.x - rhs.x;
const y = this.y - rhs.y;
const z = this.z - rhs.z;
return Math.sqrt(x * x + y * y + z * z);
}
div(rhs) {
this.x /= rhs.x;
this.y /= rhs.y;
this.z /= rhs.z;
return this;
}
div2(lhs, rhs) {
this.x = lhs.x / rhs.x;
this.y = lhs.y / rhs.y;
this.z = lhs.z / rhs.z;
return this;
}
divScalar(scalar) {
this.x /= scalar;
this.y /= scalar;
this.z /= scalar;
return this;
}
dot(rhs) {
return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z;
}
equals(rhs) {
return this.x === rhs.x && this.y === rhs.y && this.z === rhs.z;
}
equalsApprox(rhs, epsilon = 1e-6) {
return Math.abs(this.x - rhs.x) < epsilon && Math.abs(this.y - rhs.y) < epsilon && Math.abs(this.z - rhs.z) < epsilon;
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
lengthSq() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
lerp(lhs, rhs, alpha) {
this.x = lhs.x + alpha * (rhs.x - lhs.x);
this.y = lhs.y + alpha * (rhs.y - lhs.y);
this.z = lhs.z + alpha * (rhs.z - lhs.z);
return this;
}
mul(rhs) {
this.x *= rhs.x;
this.y *= rhs.y;
this.z *= rhs.z;
return this;
}
mul2(lhs, rhs) {
this.x = lhs.x * rhs.x;
this.y = lhs.y * rhs.y;
this.z = lhs.z * rhs.z;
return this;
}
mulScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
return this;
}
normalize(src = this) {
const lengthSq = src.x * src.x + src.y * src.y + src.z * src.z;
if (lengthSq > 0) {
const invLength = 1 / Math.sqrt(lengthSq);
this.x = src.x * invLength;
this.y = src.y * invLength;
this.z = src.z * invLength;
}
return this;
}
floor(src = this) {
this.x = Math.floor(src.x);
this.y = Math.floor(src.y);
this.z = Math.floor(src.z);
return this;
}
ceil(src = this) {
this.x = Math.ceil(src.x);
this.y = Math.ceil(src.y);
this.z = Math.ceil(src.z);
return this;
}
round(src = this) {
this.x = Math.round(src.x);
this.y = Math.round(src.y);
this.z = Math.round(src.z);
return this;
}
min(rhs) {
if (rhs.x < this.x) this.x = rhs.x;
if (rhs.y < this.y) this.y = rhs.y;
if (rhs.z < this.z) this.z = rhs.z;
return this;
}
max(rhs) {
if (rhs.x > this.x) this.x = rhs.x;
if (rhs.y > this.y) this.y = rhs.y;
if (rhs.z > this.z) this.z = rhs.z;
return this;
}
project(rhs) {
const a_dot_b = this.x * rhs.x + this.y * rhs.y + this.z * rhs.z;
const b_dot_b = rhs.x * rhs.x + rhs.y * rhs.y + rhs.z * rhs.z;
const s = a_dot_b / b_dot_b;
this.x = rhs.x * s;
this.y = rhs.y * s;
this.z = rhs.z * s;
return this;
}
set(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
sub(rhs) {
this.x -= rhs.x;
this.y -= rhs.y;
this.z -= rhs.z;
return this;
}
sub2(lhs, rhs) {
this.x = lhs.x - rhs.x;
this.y = lhs.y - rhs.y;
this.z = lhs.z - rhs.z;
return this;
}
subScalar(scalar) {
this.x -= scalar;
this.y -= scalar;
this.z -= scalar;
return this;
}
fromArray(arr, offset = 0) {
this.x = arr[offset] ?? this.x;
this.y = arr[offset + 1] ?? this.y;
this.z = arr[offset + 2] ?? this.z;
return this;
}
toString() {
return `[${this.x}, ${this.y}, ${this.z}]`;
}
toArray(arr = [], offset = 0) {
arr[offset] = this.x;
arr[offset + 1] = this.y;
arr[offset + 2] = this.z;
return arr;
}
static{
this.ZERO = Object.freeze(new Vec3(0, 0, 0));
}
static{
this.HALF = Object.freeze(new Vec3(0.5, 0.5, 0.5));
}
static{
this.ONE = Object.freeze(new Vec3(1, 1, 1));
}
static{
this.UP = Object.freeze(new Vec3(0, 1, 0));
}
static{
this.DOWN = Object.freeze(new Vec3(0, -1, 0));
}
static{
this.RIGHT = Object.freeze(new Vec3(1, 0, 0));
}
static{
this.LEFT = Object.freeze(new Vec3(-1, 0, 0));
}
static{
this.FORWARD = Object.freeze(new Vec3(0, 0, -1));
}
static{
this.BACK = Object.freeze(new Vec3(0, 0, 1));
}
};
let Mat3$1 = class Mat3 {
constructor(){
this.data = new Float32Array(9);
this.data[0] = this.data[4] = this.data[8] = 1;
}
clone() {
const cstr = this.constructor;
return new cstr().copy(this);
}
copy(rhs) {
const src = rhs.data;
const dst = this.data;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
return this;
}
set(src) {
const dst = this.data;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
return this;
}
getX(x = new Vec3$1()) {
return x.set(this.data[0], this.data[1], this.data[2]);
}
getY(y = new Vec3$1()) {
return y.set(this.data[3], this.data[4], this.data[5]);
}
getZ(z = new Vec3$1()) {
return z.set(this.data[6], this.data[7], this.data[8]);
}
equals(rhs) {
const l = this.data;
const r = rhs.data;
return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8];
}
isIdentity() {
const m = this.data;
return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 0 && m[4] === 1 && m[5] === 0 && m[6] === 0 && m[7] === 0 && m[8] === 1;
}
setIdentity() {
const m = this.data;
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 1;
m[5] = 0;
m[6] = 0;
m[7] = 0;
m[8] = 1;
return this;
}
toString() {
return `[${this.data.join(', ')}]`;
}
transpose(src = this) {
const s = src.data;
const t = this.data;
if (s === t) {
let tmp;
tmp = s[1];
t[1] = s[3];
t[3] = tmp;
tmp = s[2];
t[2] = s[6];
t[6] = tmp;
tmp = s[5];
t[5] = s[7];
t[7] = tmp;
} else {
t[0] = s[0];
t[1] = s[3];
t[2] = s[6];
t[3] = s[1];
t[4] = s[4];
t[5] = s[7];
t[6] = s[2];
t[7] = s[5];
t[8] = s[8];
}
return this;
}
setFromMat4(m) {
const src = m.data;
const dst = this.data;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[4];
dst[4] = src[5];
dst[5] = src[6];
dst[6] = src[8];
dst[7] = src[9];
dst[8] = src[10];
return this;
}
setFromQuat(r) {
const qx = r.x;
const qy = r.y;
const qz = r.z;
const qw = r.w;
const x2 = qx + qx;
const y2 = qy + qy;
const z2 = qz + qz;
const xx = qx * x2;
const xy = qx * y2;
const xz = qx * z2;
const yy = qy * y2;
const yz = qy * z2;
const zz = qz * z2;
const wx = qw * x2;
const wy = qw * y2;
const wz = qw * z2;
const m = this.data;
m[0] = 1 - (yy + zz);
m[1] = xy + wz;
m[2] = xz - wy;
m[3] = xy - wz;
m[4] = 1 - (xx + zz);
m[5] = yz + wx;
m[6] = xz + wy;
m[7] = yz - wx;
m[8] = 1 - (xx + yy);
return this;
}
invertMat4(src) {
const s = src.data;
const a0 = s[0];
const a1 = s[1];
const a2 = s[2];
const a4 = s[4];
const a5 = s[5];
const a6 = s[6];
const a8 = s[8];
const a9 = s[9];
const a10 = s[10];
const b11 = a10 * a5 - a6 * a9;
const b21 = -a10 * a1 + a2 * a9;
const b31 = a6 * a1 - a2 * a5;
const b12 = -a10 * a4 + a6 * a8;
const b22 = a10 * a0 - a2 * a8;
const b32 = -a6 * a0 + a2 * a4;
const b13 = a9 * a4 - a5 * a8;
const b23 = -a9 * a0 + a1 * a8;
const b33 = a5 * a0 - a1 * a4;
const det = a0 * b11 + a1 * b12 + a2 * b13;
if (det === 0) {
this.setIdentity();
} else {
const invDet = 1 / det;
const t = this.data;
t[0] = b11 * invDet;
t[1] = b21 * invDet;
t[2] = b31 * invDet;
t[3] = b12 * invDet;
t[4] = b22 * invDet;
t[5] = b32 * invDet;
t[6] = b13 * invDet;
t[7] = b23 * invDet;
t[8] = b33 * invDet;
}
return this;
}
transformVector(vec, res = new Vec3$1()) {
const m = this.data;
const { x, y, z } = vec;
res.x = x * m[0] + y * m[3] + z * m[6];
res.y = x * m[1] + y * m[4] + z * m[7];
res.z = x * m[2] + y * m[5] + z * m[8];
return res;
}
static{
this.IDENTITY = Object.freeze(new Mat3());
}
static{
this.ZERO = Object.freeze(new Mat3().set([
0,
0,
0,
0,
0,
0,
0,
0,
0
]));
}
};
let Vec2$1 = class Vec2 {
constructor(x = 0, y = 0){
if (x.length === 2) {
this.x = x[0];
this.y = x[1];
} else {
this.x = x;
this.y = y;
}
}
add(rhs) {
this.x += rhs.x;
this.y += rhs.y;
return this;
}
add2(lhs, rhs) {
this.x = lhs.x + rhs.x;
this.y = lhs.y + rhs.y;
return this;
}
addScalar(scalar) {
this.x += scalar;
this.y += scalar;
return this;
}
addScaled(rhs, scalar) {
this.x += rhs.x * scalar;
this.y += rhs.y * scalar;
return this;
}
clone() {
const cstr = this.constructor;
return new cstr(this.x, this.y);
}
copy(rhs) {
this.x = rhs.x;
this.y = rhs.y;
return this;
}
cross(rhs) {
return this.x * rhs.y - this.y * rhs.x;
}
distance(rhs) {
const x = this.x - rhs.x;
const y = this.y - rhs.y;
return Math.sqrt(x * x + y * y);
}
div(rhs) {
this.x /= rhs.x;
this.y /= rhs.y;
return this;
}
div2(lhs, rhs) {
this.x = lhs.x / rhs.x;
this.y = lhs.y / rhs.y;
return this;
}
divScalar(scalar) {
this.x /= scalar;
this.y /= scalar;
return this;
}
dot(rhs) {
return this.x * rhs.x + this.y * rhs.y;
}
equals(rhs) {
return this.x === rhs.x && this.y === rhs.y;
}
equalsApprox(rhs, epsilon = 1e-6) {
return Math.abs(this.x - rhs.x) < epsilon && Math.abs(this.y - rhs.y) < epsilon;
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
lengthSq() {
return this.x * this.x + this.y * this.y;
}
lerp(lhs, rhs, alpha) {
this.x = lhs.x + alpha * (rhs.x - lhs.x);
this.y = lhs.y + alpha * (rhs.y - lhs.y);
return this;
}
mul(rhs) {
this.x *= rhs.x;
this.y *= rhs.y;
return this;
}
mul2(lhs, rhs) {
this.x = lhs.x * rhs.x;
this.y = lhs.y * rhs.y;
return this;
}
mulScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
}
normalize(src = this) {
const lengthSq = src.x * src.x + src.y * src.y;
if (lengthSq > 0) {
const invLength = 1 / Math.sqrt(lengthSq);
this.x = src.x * invLength;
this.y = src.y * invLength;
}
return this;
}
rotate(degrees) {
const angle = Math.atan2(this.x, this.y) + degrees * math$1.DEG_TO_RAD;
const len = Math.sqrt(this.x * this.x + this.y * this.y);
this.x = Math.sin(angle) * len;
this.y = Math.cos(angle) * len;
return this;
}
angle() {
return Math.atan2(this.x, this.y) * math$1.RAD_TO_DEG;
}
angleTo(rhs) {
return Math.atan2(this.x * rhs.y + this.y * rhs.x, this.x * rhs.x + this.y * rhs.y) * math$1.RAD_TO_DEG;
}
floor(src = this) {
this.x = Math.floor(src.x);
this.y = Math.floor(src.y);
return this;
}
ceil(src = this) {
this.x = Math.ceil(src.x);
this.y = Math.ceil(src.y);
return this;
}
round(src = this) {
this.x = Math.round(src.x);
this.y = Math.round(src.y);
return this;
}
min(rhs) {
if (rhs.x < this.x) this.x = rhs.x;
if (rhs.y < this.y) this.y = rhs.y;
return this;
}
max(rhs) {
if (rhs.x > this.x) this.x = rhs.x;
if (rhs.y > this.y) this.y = rhs.y;
return this;
}
set(x, y) {
this.x = x;
this.y = y;
return this;
}
sub(rhs) {
this.x -= rhs.x;
this.y -= rhs.y;
return this;
}
sub2(lhs, rhs) {
this.x = lhs.x - rhs.x;
this.y = lhs.y - rhs.y;
return this;
}
subScalar(scalar) {
this.x -= scalar;
this.y -= scalar;
return this;
}
fromArray(arr, offset = 0) {
this.x = arr[offset] ?? this.x;
this.y = arr[offset + 1] ?? this.y;
return this;
}
toString() {
return `[${this.x}, ${this.y}]`;
}
toArray(arr = [], offset = 0) {
arr[offset] = this.x;
arr[offset + 1] = this.y;
return arr;
}
static angleRad(lhs, rhs) {
return Math.atan2(lhs.x * rhs.y - lhs.y * rhs.x, lhs.x * rhs.x + lhs.y * rhs.y);
}
static{
this.ZERO = Object.freeze(new Vec2(0, 0));
}
static{
this.HALF = Object.freeze(new Vec2(0.5, 0.5));
}
static{
this.ONE = Object.freeze(new Vec2(1, 1));
}
static{
this.UP = Object.freeze(new Vec2(0, 1));
}
static{
this.DOWN = Object.freeze(new Vec2(0, -1));
}
static{
this.RIGHT = Object.freeze(new Vec2(1, 0));
}
static{
this.LEFT = Object.freeze(new Vec2(-1, 0));
}
};
let Vec4$1 = class Vec4 {
constructor(x = 0, y = 0, z = 0, w = 0){
if (x.length === 4) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[3];
} else {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}
add(rhs) {
this.x += rhs.x;
this.y += rhs.y;
this.z += rhs.z;
this.w += rhs.w;
return this;
}
add2(lhs, rhs) {
this.x = lhs.x + rhs.x;
this.y = lhs.y + rhs.y;
this.z = lhs.z + rhs.z;
this.w = lhs.w + rhs.w;
return this;
}
addScalar(scalar) {
this.x += scalar;
this.y += scalar;
this.z += scalar;
this.w += scalar;
return this;
}
addScaled(rhs, scalar) {
this.x += rhs.x * scalar;
this.y += rhs.y * scalar;
this.z += rhs.z * scalar;
this.w += rhs.w * scalar;
return this;
}
clone() {
const cstr = this.constructor;
return new cstr(this.x, this.y, this.z, this.w);
}
copy(rhs) {
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
this.w = rhs.w;
return this;
}
div(rhs) {
this.x /= rhs.x;
this.y /= rhs.y;
this.z /= rhs.z;
this.w /= rhs.w;
return this;
}
div2(lhs, rhs) {
this.x = lhs.x / rhs.x;
this.y = lhs.y / rhs.y;
this.z = lhs.z / rhs.z;
this.w = lhs.w / rhs.w;
return this;
}
divScalar(scalar) {
this.x /= scalar;
this.y /= scalar;
this.z /= scalar;
this.w /= scalar;
return this;
}
dot(rhs) {
return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z + this.w * rhs.w;
}
equals(rhs) {
return this.x === rhs.x && this.y === rhs.y && this.z === rhs.z && this.w === rhs.w;
}
equalsApprox(rhs, epsilon = 1e-6) {
return Math.abs(this.x - rhs.x) < epsilon && Math.abs(this.y - rhs.y) < epsilon && Math.abs(this.z - rhs.z) < epsilon && Math.abs(this.w - rhs.w) < epsilon;
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
lengthSq() {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
}
lerp(lhs, rhs, alpha) {
this.x = lhs.x + alpha * (rhs.x - lhs.x);
this.y = lhs.y + alpha * (rhs.y - lhs.y);
this.z = lhs.z + alpha * (rhs.z - lhs.z);
this.w = lhs.w + alpha * (rhs.w - lhs.w);
return this;
}
mul(rhs) {
this.x *= rhs.x;
this.y *= rhs.y;
this.z *= rhs.z;
this.w *= rhs.w;
return this;
}
mul2(lhs, rhs) {
this.x = lhs.x * rhs.x;
this.y = lhs.y * rhs.y;
this.z = lhs.z * rhs.z;
this.w = lhs.w * rhs.w;
return this;
}
mulScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
this.w *= scalar;
return this;
}
normalize(src = this) {
const lengthSq = src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w;
if (lengthSq > 0) {
const invLength = 1 / Math.sqrt(lengthSq);
this.x = src.x * invLength;
this.y = src.y * invLength;
this.z = src.z * invLength;
this.w = src.w * invLength;
}
return this;
}
floor(src = this) {
this.x = Math.floor(src.x);
this.y = Math.floor(src.y);
this.z = Math.floor(src.z);
this.w = Math.floor(src.w);
return this;
}
ceil(src = this) {
this.x = Math.ceil(src.x);
this.y = Math.ceil(src.y);
this.z = Math.ceil(src.z);
this.w = Math.ceil(src.w);
return this;
}
round(src = this) {
this.x = Math.round(src.x);
this.y = Math.round(src.y);
this.z = Math.round(src.z);
this.w = Math.round(src.w);
return this;
}
min(rhs) {
if (rhs.x < this.x) this.x = rhs.x;
if (rhs.y < this.y) this.y = rhs.y;
if (rhs.z < this.z) this.z = rhs.z;
if (rhs.w < this.w) this.w = rhs.w;
return this;
}
max(rhs) {
if (rhs.x > this.x) this.x = rhs.x;
if (rhs.y > this.y) this.y = rhs.y;
if (rhs.z > this.z) this.z = rhs.z;
if (rhs.w > this.w) this.w = rhs.w;
return this;
}
set(x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
}
sub(rhs) {
this.x -= rhs.x;
this.y -= rhs.y;
this.z -= rhs.z;
this.w -= rhs.w;
return this;
}
sub2(lhs, rhs) {
this.x = lhs.x - rhs.x;
this.y = lhs.y - rhs.y;
this.z = lhs.z - rhs.z;
this.w = lhs.w - rhs.w;
return this;
}
subScalar(scalar) {
this.x -= scalar;
this.y -= scalar;
this.z -= scalar;
this.w -= scalar;
return this;
}
fromArray(arr, offset = 0) {
this.x = arr[offset] ?? this.x;
this.y = arr[offset + 1] ?? this.y;
this.z = arr[offset + 2] ?? this.z;
this.w = arr[offset + 3] ?? this.w;
return this;
}
toString() {
return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`;
}
toArray(arr = [], offset = 0) {
arr[offset] = this.x;
arr[offset + 1] = this.y;
arr[offset + 2] = this.z;
arr[offset + 3] = this.w;
return arr;
}
static{
this.ZERO = Object.freeze(new Vec4(0, 0, 0, 0));
}
static{
this.HALF = Object.freeze(new Vec4(0.5, 0.5, 0.5, 0.5));
}
static{
this.ONE = Object.freeze(new Vec4(1, 1, 1, 1));
}
};
const _halfSize$2 = new Vec2$1();
const x$1 = new Vec3$1();
const y$1 = new Vec3$1();
const z$1 = new Vec3$1();
const scale$1 = new Vec3$1();
let Mat4$1 = class Mat4 {
constructor(){
this.data = new Float32Array(16);
this.data[0] = this.data[5] = this.data[10] = this.data[15] = 1;
}
static _getPerspectiveHalfSize(halfSize, fov, aspect, znear, fovIsHorizontal) {
if (fovIsHorizontal) {
halfSize.x = znear * Math.tan(fov * Math.PI / 360);
halfSize.y = halfSize.x / aspect;
} else {
halfSize.y = znear * Math.tan(fov * Math.PI / 360);
halfSize.x = halfSize.y * aspect;
}
}
add2(lhs, rhs) {
const a = lhs.data, b = rhs.data, r = this.data;
r[0] = a[0] + b[0];
r[1] = a[1] + b[1];
r[2] = a[2] + b[2];
r[3] = a[3] + b[3];
r[4] = a[4] + b[4];
r[5] = a[5] + b[5];
r[6] = a[6] + b[6];
r[7] = a[7] + b[7];
r[8] = a[8] + b[8];
r[9] = a[9] + b[9];
r[10] = a[10] + b[10];
r[11] = a[11] + b[11];
r[12] = a[12] + b[12];
r[13] = a[13] + b[13];
r[14] = a[14] + b[14];
r[15] = a[15] + b[15];
return this;
}
add(rhs) {
return this.add2(this, rhs);
}
clone() {
const cstr = this.constructor;
return new cstr().copy(this);
}
copy(rhs) {
const src = rhs.data, dst = this.data;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
dst[9] = src[9];
dst[10] = src[10];
dst[11] = src[11];
dst[12] = src[12];
dst[13] = src[13];
dst[14] = src[14];
dst[15] = src[15];
return this;
}
equals(rhs) {
const l = this.data, r = rhs.data;
return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8] && l[9] === r[9] && l[10] === r[10] && l[11] === r[11] && l[12] === r[12] && l[13] === r[13] && l[14] === r[14] && l[15] === r[15];
}
isIdentity() {
const m = this.data;
return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 0 && m[4] === 0 && m[5] === 1 && m[6] === 0 && m[7] === 0 && m[8] === 0 && m[9] === 0 && m[10] === 1 && m[11] === 0 && m[12] === 0 && m[13] === 0 && m[14] === 0 && m[15] === 1;
}
mul2(lhs, rhs) {
const a = lhs.data;
const b = rhs.data;
const r = this.data;
const a00 = a[0];
const a01 = a[1];
const a02 = a[2];
const a03 = a[3];
const a10 = a[4];
const a11 = a[5];
const a12 = a[6];
const a13 = a[7];
const a20 = a[8];
const a21 = a[9];
const a22 = a[10];
const a23 = a[11];
const a30 = a[12];
const a31 = a[13];
const a32 = a[14];
const a33 = a[15];
let b0, b1, b2, b3;
b0 = b[0];
b1 = b[1];
b2 = b[2];
b3 = b[3];
r[0] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;
r[1] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;
r[2] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;
r[3] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;
b0 = b[4];
b1 = b[5];
b2 = b[6];
b3 = b[7];
r[4] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;
r[5] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;
r[6] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;
r[7] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;
b0 = b[8];
b1 = b[9];
b2 = b[10];
b3 = b[11];
r[8] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;
r[9] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;
r[10] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;
r[11] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;
b0 = b[12];
b1 = b[13];
b2 = b[14];
b3 = b[15];
r[12] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;
r[13] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;
r[14] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;
r[15] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;
return this;
}
mulAffine2(lhs, rhs) {
const a = lhs.data;
const b = rhs.data;
const r = this.data;
const a00 = a[0];
const a01 = a[1];
const a02 = a[2];
const a10 = a[4];
const a11 = a[5];
const a12 = a[6];
const a20 = a[8];
const a21 = a[9];
const a22 = a[10];
const a30 = a[12];
const a31 = a[13];
const a32 = a[14];
let b0, b1, b2;
b0 = b[0];
b1 = b[1];
b2 = b[2];
r[0] = a00 * b0 + a10 * b1 + a20 * b2;
r[1] = a01 * b0 + a11 * b1 + a21 * b2;
r[2] = a02 * b0 + a12 * b1 + a22 * b2;
r[3] = 0;
b0 = b[4];
b1 = b[5];
b2 = b[6];
r[4] = a00 * b0 + a10 * b1 + a20 * b2;
r[5] = a01 * b0 + a11 * b1 + a21 * b2;
r[6] = a02 * b0 + a12 * b1 + a22 * b2;
r[7] = 0;
b0 = b[8];
b1 = b[9];
b2 = b[10];
r[8] = a00 * b0 + a10 * b1 + a20 * b2;
r[9] = a01 * b0 + a11 * b1 + a21 * b2;
r[10] = a02 * b0 + a12 * b1 + a22 * b2;
r[11] = 0;
b0 = b[12];
b1 = b[13];
b2 = b[14];
r[12] = a00 * b0 + a10 * b1 + a20 * b2 + a30;
r[13] = a01 * b0 + a11 * b1 + a21 * b2 + a31;
r[14] = a02 * b0 + a12 * b1 + a22 * b2 + a32;
r[15] = 1;
return this;
}
mul(rhs) {
return this.mul2(this, rhs);
}
transformPoint(vec, res = new Vec3$1()) {
const m = this.data;
const { x, y, z } = vec;
res.x = x * m[0] + y * m[4] + z * m[8] + m[12];
res.y = x * m[1] + y * m[5] + z * m[9] + m[13];
res.z = x * m[2] + y * m[6] + z * m[10] + m[14];
return res;
}
transformVector(vec, res = new Vec3$1()) {
const m = this.data;
const { x, y, z } = vec;
res.x = x * m[0] + y * m[4] + z * m[8];
res.y = x * m[1] + y * m[5] + z * m[9];
res.z = x * m[2] + y * m[6] + z * m[10];
return res;
}
transformVec4(vec, res = new Vec4$1()) {
const m = this.data;
const { x, y, z, w } = vec;
res.x = x * m[0] + y * m[4] + z * m[8] + w * m[12];
res.y = x * m[1] + y * m[5] + z * m[9] + w * m[13];
res.z = x * m[2] + y * m[6] + z * m[10] + w * m[14];
res.w = x * m[3] + y * m[7] + z * m[11] + w * m[15];
return res;
}
setLookAt(position, target, up) {
z$1.sub2(position, target).normalize();
y$1.copy(up).normalize();
x$1.cross(y$1, z$1).normalize();
y$1.cross(z$1, x$1);
const r = this.data;
r[0] = x$1.x;
r[1] = x$1.y;
r[2] = x$1.z;
r[3] = 0;
r[4] = y$1.x;
r[5] = y$1.y;
r[6] = y$1.z;
r[7] = 0;
r[8] = z$1.x;
r[9] = z$1.y;
r[10] = z$1.z;
r[11] = 0;
r[12] = position.x;
r[13] = position.y;
r[14] = position.z;
r[15] = 1;
return this;
}
setFrustum(left, right, bottom, top, znear, zfar) {
const temp1 = 2 * znear;
const temp2 = right - left;
const temp3 = top - bottom;
const temp4 = zfar - znear;
const r = this.data;
r[0] = temp1 / temp2;
r[1] = 0;
r[2] = 0;
r[3] = 0;
r[4] = 0;
r[5] = temp1 / temp3;
r[6] = 0;
r[7] = 0;
r[8] = (right + left) / temp2;
r[9] = (top + bottom) / temp3;
r[10] = (-zfar - znear) / temp4;
r[11] = -1;
r[12] = 0;
r[13] = 0;
r[14] = -temp1 * zfar / temp4;
r[15] = 0;
return this;
}
setPerspective(fov, aspect, znear, zfar, fovIsHorizontal) {
Mat4._getPerspectiveHalfSize(_halfSize$2, fov, aspect, znear, fovIsHorizontal);
return this.setFrustum(-_halfSize$2.x, _halfSize$2.x, -_halfSize$2.y, _halfSize$2.y, znear, zfar);
}
setOrtho(left, right, bottom, top, near, far) {
const r = this.data;
r[0] = 2 / (right - left);
r[1] = 0;
r[2] = 0;
r[3] = 0;
r[4] = 0;
r[5] = 2 / (top - bottom);
r[6] = 0;
r[7] = 0;
r[8] = 0;
r[9] = 0;
r[10] = -2 / (far - near);
r[11] = 0;
r[12] = -(right + left) / (right - left);
r[13] = -(top + bottom) / (top - bottom);
r[14] = -(far + near) / (far - near);
r[15] = 1;
return this;
}
setFromAxisAngle(axis, angle) {
angle *= math$1.DEG_TO_RAD;
const { x, y, z } = axis;
const c = Math.cos(angle);
const s = Math.sin(angle);
const t = 1 - c;
const tx = t * x;
const ty = t * y;
const m = this.data;
m[0] = tx * x + c;
m[1] = tx * y + s * z;
m[2] = tx * z - s * y;
m[3] = 0;
m[4] = tx * y - s * z;
m[5] = ty * y + c;
m[6] = ty * z + s * x;
m[7] = 0;
m[8] = tx * z + s * y;
m[9] = ty * z - x * s;
m[10] = t * z * z + c;
m[11] = 0;
m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
return this;
}
setTranslate(x, y, z) {
const m = this.data;
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;
m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;
m[12] = x;
m[13] = y;
m[14] = z;
m[15] = 1;
return this;
}
setScale(x, y, z) {
const m = this.data;
m[0] = x;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 0;
m[5] = y;
m[6] = 0;
m[7] = 0;
m[8] = 0;
m[9] = 0;
m[10] = z;
m[11] = 0;
m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
return this;
}
setViewport(x, y, width, height) {
const m = this.data;
m[0] = width * 0.5;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 0;
m[5] = height * 0.5;
m[6] = 0;
m[7] = 0;
m[8] = 0;
m[9] = 0;
m[10] = 0.5;
m[11] = 0;
m[12] = x + width * 0.5;
m[13] = y + height * 0.5;
m[14] = 0.5;
m[15] = 1;
return this;
}
setReflection(normal, distance) {
const a = normal.x;
const b = normal.y;
const c = normal.z;
const data = this.data;
data[0] = 1.0 - 2 * a * a;
data[1] = -2 * a * b;
data[2] = -2 * a * c;
data[3] = 0;
data[4] = -2 * a * b;
data[5] = 1.0 - 2 * b * b;
data[6] = -2 * b * c;
data[7] = 0;
data[8] = -2 * a * c;
data[9] = -2 * b * c;
data[10] = 1.0 - 2 * c * c;
data[11] = 0;
data[12] = -2 * a * distance;
data[13] = -2 * b * distance;
data[14] = -2 * c * distance;
data[15] = 1;
return this;
}
invert(src = this) {
const s = src.data;
const a00 = s[0];
const a01 = s[1];
const a02 = s[2];
const a03 = s[3];
const a10 = s[4];
const a11 = s[5];
const a12 = s[6];
const a13 = s[7];
const a20 = s[8];
const a21 = s[9];
const a22 = s[10];
const a23 = s[11];
const a30 = s[12];
const a31 = s[13];
const a32 = s[14];
const a33 = s[15];
const b00 = a00 * a11 - a01 * a10;
const b01 = a00 * a12 - a02 * a10;
const b02 = a00 * a13 - a03 * a10;
const b03 = a01 * a12 - a02 * a11;
const b04 = a01 * a13 - a03 * a11;
const b05 = a02 * a13 - a03 * a12;
const b06 = a20 * a31 - a21 * a30;
const b07 = a20 * a32 - a22 * a30;
const b08 = a20 * a33 - a23 * a30;
const b09 = a21 * a32 - a22 * a31;
const b10 = a21 * a33 - a23 * a31;
const b11 = a22 * a33 - a23 * a32;
const det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (det === 0) {
this.setIdentity();
} else {
const invDet = 1 / det;
const t = this.data;
t[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
t[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
t[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
t[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
t[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
t[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
t[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
t[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
t[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
t[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
t[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
t[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
t[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
t[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
t[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
t[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
}
return this;
}
set(src) {
const dst = this.data;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
dst[9] = src[9];
dst[10] = src[10];
dst[11] = src[11];
dst[12] = src[12];
dst[13] = src[13];
dst[14] = src[14];
dst[15] = src[15];
return this;
}
setIdentity() {
const m = this.data;
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;
m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;
m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
return this;
}
setTRS(t, r, s) {
const qx = r.x;
const qy = r.y;
const qz = r.z;
const qw = r.w;
const sx = s.x;
const sy = s.y;
const sz = s.z;
const x2 = qx + qx;
const y2 = qy + qy;
const z2 = qz + qz;
const xx = qx * x2;
const xy = qx * y2;
const xz = qx * z2;
const yy = qy * y2;
const yz = qy * z2;
const zz = qz * z2;
const wx = qw * x2;
const wy = qw * y2;
const wz = qw * z2;
const m = this.data;
m[0] = (1 - (yy + zz)) * sx;
m[1] = (xy + wz) * sx;
m[2] = (xz - wy) * sx;
m[3] = 0;
m[4] = (xy - wz) * sy;
m[5] = (1 - (xx + zz)) * sy;
m[6] = (yz + wx) * sy;
m[7] = 0;
m[8] = (xz + wy) * sz;
m[9] = (yz - wx) * sz;
m[10] = (1 - (xx + yy)) * sz;
m[11] = 0;
m[12] = t.x;
m[13] = t.y;
m[14] = t.z;
m[15] = 1;
return this;
}
transpose(src = this) {
const s = src.data;
const t = this.data;
if (s === t) {
let tmp;
tmp = s[1];
t[1] = s[4];
t[4] = tmp;
tmp = s[2];
t[2] = s[8];
t[8] = tmp;
tmp = s[3];
t[3] = s[12];
t[12] = tmp;
tmp = s[6];
t[6] = s[9];
t[9] = tmp;
tmp = s[7];
t[7] = s[13];
t[13] = tmp;
tmp = s[11];
t[11] = s[14];
t[14] = tmp;
} else {
t[0] = s[0];
t[1] = s[4];
t[2] = s[8];
t[3] = s[12];
t[4] = s[1];
t[5] = s[5];
t[6] = s[9];
t[7] = s[13];
t[8] = s[2];
t[9] = s[6];
t[10] = s[10];
t[11] = s[14];
t[12] = s[3];
t[13] = s[7];
t[14] = s[11];
t[15] = s[15];
}
return this;
}
getTranslation(t = new Vec3$1()) {
return t.set(this.data[12], this.data[13], this.data[14]);
}
getX(x = new Vec3$1()) {
return x.set(this.data[0], this.data[1], this.data[2]);
}
getY(y = new Vec3$1()) {
return y.set(this.data[4], this.data[5], this.data[6]);
}
getZ(z = new Vec3$1()) {
return z.set(this.data[8], this.data[9], this.data[10]);
}
getScale(scale = new Vec3$1()) {
this.getX(x$1);
this.getY(y$1);
this.getZ(z$1);
scale.set(x$1.length(), y$1.length(), z$1.length());
return scale;
}
get scaleSign() {
this.getX(x$1);
this.getY(y$1);
this.getZ(z$1);
x$1.cross(x$1, y$1);
return x$1.dot(z$1) < 0 ? -1 : 1;
}
setFromEulerAngles(ex, ey, ez) {
ex *= math$1.DEG_TO_RAD;
ey *= math$1.DEG_TO_RAD;
ez *= math$1.DEG_TO_RAD;
const s1 = Math.sin(-ex);
const c1 = Math.cos(-ex);
const s2 = Math.sin(-ey);
const c2 = Math.cos(-ey);
const s3 = Math.sin(-ez);
const c3 = Math.cos(-ez);
const m = this.data;
m[0] = c2 * c3;
m[1] = -c2 * s3;
m[2] = s2;
m[3] = 0;
m[4] = c1 * s3 + c3 * s1 * s2;
m[5] = c1 * c3 - s1 * s2 * s3;
m[6] = -c2 * s1;
m[7] = 0;
m[8] = s1 * s3 - c1 * c3 * s2;
m[9] = c3 * s1 + c1 * s2 * s3;
m[10] = c1 * c2;
m[11] = 0;
m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
return this;
}
getEulerAngles(eulers = new Vec3$1()) {
this.getScale(scale$1);
const sx = scale$1.x;
const sy = scale$1.y;
const sz = scale$1.z;
if (sx === 0 || sy === 0 || sz === 0) {
return eulers.set(0, 0, 0);
}
const m = this.data;
const y = Math.asin(-m[2] / sx);
const halfPi = Math.PI * 0.5;
let x, z;
if (y < halfPi) {
if (y > -halfPi) {
x = Math.atan2(m[6] / sy, m[10] / sz);
z = Math.atan2(m[1] / sx, m[0] / sx);
} else {
z = 0;
x = -Math.atan2(m[4] / sy, m[5] / sy);
}
} else {
z = 0;
x = Math.atan2(m[4] / sy, m[5] / sy);
}
return eulers.set(x, y, z).mulScalar(math$1.RAD_TO_DEG);
}
toString() {
return `[${this.data.join(', ')}]`;
}
static{
this.IDENTITY = Object.freeze(new Mat4());
}
static{
this.ZERO = Object.freeze(new Mat4().set([
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]));
}
};
let Quat$1 = class Quat {
constructor(x = 0, y = 0, z = 0, w = 1){
if (x.length === 4) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[3];
} else {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}
clone() {
const cstr = this.constructor;
return new cstr(this.x, this.y, this.z, this.w);
}
conjugate(src = this) {
this.x = src.x * -1;
this.y = src.y * -1;
this.z = src.z * -1;
this.w = src.w;
return this;
}
copy(rhs) {
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
this.w = rhs.w;
return this;
}
dot(other) {
return this.x * other.x + this.y * other.y + this.z * other.z + this.w * other.w;
}
equals(rhs) {
return this.x === rhs.x && this.y === rhs.y && this.z === rhs.z && this.w === rhs.w;
}
equalsApprox(rhs, epsilon = 1e-6) {
return Math.abs(this.x - rhs.x) < epsilon && Math.abs(this.y - rhs.y) < epsilon && Math.abs(this.z - rhs.z) < epsilon && Math.abs(this.w - rhs.w) < epsilon;
}
getAxisAngle(axis) {
let rad = Math.acos(this.w) * 2;
const s = Math.sin(rad / 2);
if (s !== 0) {
axis.x = this.x / s;
axis.y = this.y / s;
axis.z = this.z / s;
if (axis.x < 0 || axis.y < 0 || axis.z < 0) {
axis.x *= -1;
axis.y *= -1;
axis.z *= -1;
rad *= -1;
}
} else {
axis.x = 1;
axis.y = 0;
axis.z = 0;
}
return rad * math$1.RAD_TO_DEG;
}
getEulerAngles(eulers = new Vec3$1()) {
let x, y, z;
const qx = this.x;
const qy = this.y;
const qz = this.z;
const qw = this.w;
const a2 = 2 * (qw * qy - qx * qz);
if (a2 <= -0.99999) {
x = 2 * Math.atan2(qx, qw);
y = -Math.PI / 2;
z = 0;
} else if (a2 >= 0.99999) {
x = 2 * Math.atan2(qx, qw);
y = Math.PI / 2;
z = 0;
} else {
x = Math.atan2(2 * (qw * qx + qy * qz), 1 - 2 * (qx * qx + qy * qy));
y = Math.asin(a2);
z = Math.atan2(2 * (qw * qz + qx * qy), 1 - 2 * (qy * qy + qz * qz));
}
return eulers.set(x, y, z).mulScalar(math$1.RAD_TO_DEG);
}
invert(src = this) {
return this.conjugate(src).normalize();
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
lengthSq() {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
}
lerp(lhs, rhs, alpha) {
const omt = (1 - alpha) * (lhs.dot(rhs) < 0 ? -1 : 1);
this.x = lhs.x * omt + rhs.x * alpha;
this.y = lhs.y * omt + rhs.y * alpha;
this.z = lhs.z * omt + rhs.z * alpha;
this.w = lhs.w * omt + rhs.w * alpha;
return this.normalize();
}
mul(rhs) {
const q1x = this.x;
const q1y = this.y;
const q1z = this.z;
const q1w = this.w;
const q2x = rhs.x;
const q2y = rhs.y;
const q2z = rhs.z;
const q2w = rhs.w;
this.x = q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y;
this.y = q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z;
this.z = q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x;
this.w = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z;
return this;
}
mulScalar(scalar, src = this) {
this.x = src.x * scalar;
this.y = src.y * scalar;
this.z = src.z * scalar;
this.w = src.w * scalar;
return this;
}
mul2(lhs, rhs) {
const q1x = lhs.x;
const q1y = lhs.y;
const q1z = lhs.z;
const q1w = lhs.w;
const q2x = rhs.x;
const q2y = rhs.y;
const q2z = rhs.z;
const q2w = rhs.w;
this.x = q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y;
this.y = q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z;
this.z = q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x;
this.w = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z;
return this;
}
normalize(src = this) {
let len = src.length();
if (len === 0) {
this.x = this.y = this.z = 0;
this.w = 1;
} else {
len = 1 / len;
this.x = src.x * len;
this.y = src.y * len;
this.z = src.z * len;
this.w = src.w * len;
}
return this;
}
set(x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
}
setFromAxisAngle(axis, angle) {
angle *= 0.5 * math$1.DEG_TO_RAD;
const sa = Math.sin(angle);
const ca = Math.cos(angle);
this.x = sa * axis.x;
this.y = sa * axis.y;
this.z = sa * axis.z;
this.w = ca;
return this;
}
setFromEulerAngles(ex, ey, ez) {
if (ex instanceof Vec3$1) {
const vec = ex;
ex = vec.x;
ey = vec.y;
ez = vec.z;
}
const halfToRad = 0.5 * math$1.DEG_TO_RAD;
ex *= halfToRad;
ey *= halfToRad;
ez *= halfToRad;
const sx = Math.sin(ex);
const cx = Math.cos(ex);
const sy = Math.sin(ey);
const cy = Math.cos(ey);
const sz = Math.sin(ez);
const cz = Math.cos(ez);
this.x = sx * cy * cz - cx * sy * sz;
this.y = cx * sy * cz + sx * cy * sz;
this.z = cx * cy * sz - sx * sy * cz;
this.w = cx * cy * cz + sx * sy * sz;
return this;
}
setFromMat4(m) {
const d = m.data;
let m00 = d[0];
let m01 = d[1];
let m02 = d[2];
let m10 = d[4];
let m11 = d[5];
let m12 = d[6];
let m20 = d[8];
let m21 = d[9];
let m22 = d[10];
let l;
l = m00 * m00 + m01 * m01 + m02 * m02;
if (l === 0) return this.set(0, 0, 0, 1);
l = 1 / Math.sqrt(l);
m00 *= l;
m01 *= l;
m02 *= l;
l = m10 * m10 + m11 * m11 + m12 * m12;
if (l === 0) return this.set(0, 0, 0, 1);
l = 1 / Math.sqrt(l);
m10 *= l;
m11 *= l;
m12 *= l;
l = m20 * m20 + m21 * m21 + m22 * m22;
if (l === 0) return this.set(0, 0, 0, 1);
l = 1 / Math.sqrt(l);
m20 *= l;
m21 *= l;
m22 *= l;
if (m22 < 0) {
if (m00 > m11) {
this.set(1 + m00 - m11 - m22, m01 + m10, m20 + m02, m12 - m21);
} else {
this.set(m01 + m10, 1 - m00 + m11 - m22, m12 + m21, m20 - m02);
}
} else {
if (m00 < -m11) {
this.set(m20 + m02, m12 + m21, 1 - m00 - m11 + m22, m01 - m10);
} else {
this.set(m12 - m21, m20 - m02, m01 - m10, 1 + m00 + m11 + m22);
}
}
return this.mulScalar(1.0 / this.length());
}
setFromDirections(from, to) {
const dotProduct = 1 + from.dot(to);
if (dotProduct < Number.EPSILON) {
if (Math.abs(from.x) > Math.abs(from.y)) {
this.x = -from.z;
this.y = 0;
this.z = from.x;
this.w = 0;
} else {
this.x = 0;
this.y = -from.z;
this.z = from.y;
this.w = 0;
}
} else {
this.x = from.y * to.z - from.z * to.y;
this.y = from.z * to.x - from.x * to.z;
this.z = from.x * to.y - from.y * to.x;
this.w = dotProduct;
}
return this.normalize();
}
slerp(lhs, rhs, alpha) {
const lx = lhs.x;
const ly = lhs.y;
const lz = lhs.z;
const lw = lhs.w;
let rx = rhs.x;
let ry = rhs.y;
let rz = rhs.z;
let rw = rhs.w;
let cosHalfTheta = lw * rw + lx * rx + ly * ry + lz * rz;
if (cosHalfTheta < 0) {
rw = -rw;
rx = -rx;
ry = -ry;
rz = -rz;
cosHalfTheta = -cosHalfTheta;
}
if (Math.abs(cosHalfTheta) >= 1) {
this.w = lw;
this.x = lx;
this.y = ly;
this.z = lz;
return this;
}
const halfTheta = Math.acos(cosHalfTheta);
const sinHalfTheta = Math.sqrt(1 - cosHalfTheta * cosHalfTheta);
if (Math.abs(sinHalfTheta) < 0.001) {
this.w = lw * 0.5 + rw * 0.5;
this.x = lx * 0.5 + rx * 0.5;
this.y = ly * 0.5 + ry * 0.5;
this.z = lz * 0.5 + rz * 0.5;
return this;
}
const ratioA = Math.sin((1 - alpha) * halfTheta) / sinHalfTheta;
const ratioB = Math.sin(alpha * halfTheta) / sinHalfTheta;
this.w = lw * ratioA + rw * ratioB;
this.x = lx * ratioA + rx * ratioB;
this.y = ly * ratioA + ry * ratioB;
this.z = lz * ratioA + rz * ratioB;
return this;
}
transformVector(vec, res = new Vec3$1()) {
const x = vec.x, y = vec.y, z = vec.z;
const qx = this.x, qy = this.y, qz = this.z, qw = this.w;
const ix = qw * x + qy * z - qz * y;
const iy = qw * y + qz * x - qx * z;
const iz = qw * z + qx * y - qy * x;
const iw = -qx * x - qy * y - qz * z;
res.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
res.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
res.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return res;
}
fromArray(arr, offset = 0) {
this.x = arr[offset] ?? this.x;
this.y = arr[offset + 1] ?? this.y;
this.z = arr[offset + 2] ?? this.z;
this.w = arr[offset + 3] ?? this.w;
return this;
}
toString() {
return `[${this.x}, ${this.y}, ${this.z}, ${this.w}]`;
}
toArray(arr = [], offset = 0) {
arr[offset] = this.x;
arr[offset + 1] = this.y;
arr[offset + 2] = this.z;
arr[offset + 3] = this.w;
return arr;
}
static{
this.IDENTITY = Object.freeze(new Quat(0, 0, 0, 1));
}
static{
this.ZERO = Object.freeze(new Quat(0, 0, 0, 0));
}
};
var version$1 = "0.5.4";
class Column {
name;
data;
constructor(name, data) {
this.name = name;
this.data = data;
}
get dataType() {
switch (this.data.constructor) {
case Int8Array: return 'int8';
case Uint8Array: return 'uint8';
case Int16Array: return 'int16';
case Uint16Array: return 'uint16';
case Int32Array: return 'int32';
case Uint32Array: return 'uint32';
case Float32Array: return 'float32';
case Float64Array: return 'float64';
}
return null;
}
clone() {
return new Column(this.name, this.data.slice());
}
filter(length, filter) {
const constructor = this.data.constructor;
const data = new constructor(length);
let j = 0;
for (let i = 0; i < this.data.length; i++) {
if (filter[i]) {
data[j++] = this.data[i];
}
}
return new Column(this.name, data);
}
}
class DataTable {
columns;
constructor(columns) {
if (columns.length === 0) {
throw new Error('DataTable must have at least one column');
}
// check all columns have the same lengths
for (let i = 1; i < columns.length; i++) {
if (columns[i].data.length !== columns[0].data.length) {
throw new Error(`Column '${columns[i].name}' has inconsistent number of rows: expected ${columns[0].data.length}, got ${columns[i].data.length}`);
}
}
this.columns = columns;
}
// rows
get numRows() {
return this.columns[0].data.length;
}
getRow(index, row = {}, columns = this.columns) {
for (const column of columns) {
row[column.name] = column.data[index];
}
return row;
}
setRow(index, row, columns = this.columns) {
for (const column of columns) {
if (row.hasOwnProperty(column.name)) {
column.data[index] = row[column.name];
}
}
}
// columns
get numColumns() {
return this.columns.length;
}
get columnNames() {
return this.columns.map(column => column.name);
}
get columnData() {
return this.columns.map(column => column.data);
}
get columnTypes() {
return this.columns.map(column => column.dataType);
}
getColumn(index) {
return this.columns[index];
}
getColumnIndex(name) {
return this.columns.findIndex(column => column.name === name);
}
getColumnByName(name) {
return this.columns.find(column => column.name === name);
}
hasColumn(name) {
return this.columns.some(column => column.name === name);
}
addColumn(column) {
if (column.data.length !== this.numRows) {
throw new Error(`Column '${column.name}' has inconsistent number of rows: expected ${this.numRows}, got ${column.data.length}`);
}
this.columns.push(column);
}
removeColumn(name) {
const index = this.columns.findIndex(column => column.name === name);
if (index === -1) {
return false;
}
this.columns.splice(index, 1);
return true;
}
// general
clone() {
return new DataTable(this.columns.map(c => c.clone()));
}
filter(predicate) {
const flags = new Uint8Array(this.numRows);
const row = {};
let numRows = 0;
for (let i = 0; i < this.numRows; i++) {
this.getRow(i, row);
flags[i] = predicate(i, row) ? 1 : 0;
numRows += flags[i];
}
if (numRows === 0) {
return null;
}
if (numRows === this.numRows) {
return this;
}
return new DataTable(this.columns.map(c => c.filter(numRows, flags)));
}
}
/* eslint-disable indent */
const kSqrt03_02 = Math.sqrt(3.0 / 2.0);
const kSqrt01_03 = Math.sqrt(1.0 / 3.0);
const kSqrt02_03 = Math.sqrt(2.0 / 3.0);
const kSqrt04_03 = Math.sqrt(4.0 / 3.0);
const kSqrt01_04 = Math.sqrt(1.0 / 4.0);
const