882 lines
24 KiB
JavaScript
882 lines
24 KiB
JavaScript
import {
|
|
__privateAdd,
|
|
__privateGet,
|
|
__privateMethod,
|
|
__privateSet,
|
|
__publicField
|
|
} from "./chunk-HPRLEMBT.js";
|
|
|
|
// node_modules/rubiks-js/src/math/abstractVector.js
|
|
var Vector = class {
|
|
/**
|
|
* @abstract
|
|
* @param {number} _a
|
|
*/
|
|
scale(_a) {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
/**
|
|
* @abstract
|
|
* @param {V} _v
|
|
* @returns {V}
|
|
*/
|
|
add(_v) {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
/**
|
|
* @abstract
|
|
* @param {V} _v
|
|
* @return {V}
|
|
*/
|
|
sub(_v) {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
/**
|
|
* @abstract
|
|
* @param {V} _v
|
|
* @return {V}
|
|
*/
|
|
mult(_v) {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
/**
|
|
* @abstract
|
|
* @param {V} _v
|
|
* @return {number}
|
|
*/
|
|
dot(_v) {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
/**
|
|
* @abstract
|
|
* @return {number[]}
|
|
*/
|
|
toArray() {
|
|
throw new Error("must be implemented in subclass");
|
|
}
|
|
get squareMag() {
|
|
const t = this;
|
|
return this.dot(t);
|
|
}
|
|
get mag() {
|
|
return Math.sqrt(this.squareMag);
|
|
}
|
|
get normalized() {
|
|
return this.scale(1 / this.mag);
|
|
}
|
|
get negate() {
|
|
return this.scale(-1);
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/math/vector.js
|
|
var V2 = class _V2 extends Vector {
|
|
/**
|
|
* @param {number} x
|
|
* @param {number} y
|
|
*/
|
|
constructor(x, y) {
|
|
super();
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
/** @param {number} a */
|
|
scale(a) {
|
|
return new _V2(a * this.x, a * this.y);
|
|
}
|
|
/** @param {V2} v */
|
|
add({ x, y }) {
|
|
return new _V2(this.x + x, this.y + y);
|
|
}
|
|
/** @param {V2} v */
|
|
sub({ x, y }) {
|
|
return new _V2(this.x - x, this.y - y);
|
|
}
|
|
/** @param {V2} v */
|
|
mult({ x, y }) {
|
|
return new _V2(this.x * x, this.y * y);
|
|
}
|
|
/** @param {V2} v */
|
|
dot({ x, y }) {
|
|
return this.x * x + this.y * y;
|
|
}
|
|
toArray() {
|
|
return [this.x, this.y];
|
|
}
|
|
/**
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLUniformLocation} location
|
|
*/
|
|
setUniform(gl, location) {
|
|
gl.uniform2f(location, this.x, this.y);
|
|
}
|
|
static get zero() {
|
|
return new _V2(0, 0);
|
|
}
|
|
};
|
|
var V3 = class _V3 extends Vector {
|
|
/**
|
|
* @param {number} x
|
|
* @param {number} y
|
|
* @param {number} z
|
|
*/
|
|
constructor(x, y, z) {
|
|
super();
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
/** @param {number} a */
|
|
scale(a) {
|
|
return new _V3(a * this.x, a * this.y, a * this.z);
|
|
}
|
|
/** @param {V3} v */
|
|
add({ x, y, z }) {
|
|
return new _V3(this.x + x, this.y + y, this.z + z);
|
|
}
|
|
/** @param {V3} v */
|
|
sub({ x, y, z }) {
|
|
return new _V3(this.x - x, this.y - y, this.z - z);
|
|
}
|
|
/** @param {V3} v */
|
|
mult({ x, y, z }) {
|
|
return new _V3(this.x * x, this.y * y, this.z * z);
|
|
}
|
|
/** @param {V3} v */
|
|
cross({ x, y, z }) {
|
|
return new _V3(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x);
|
|
}
|
|
/** @param {V3} v */
|
|
dot({ x, y, z }) {
|
|
return this.x * x + this.y * y + this.z * z;
|
|
}
|
|
toArray() {
|
|
return [this.x, this.y, this.z];
|
|
}
|
|
/**
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLUniformLocation} location
|
|
*/
|
|
setUniform(gl, location) {
|
|
gl.uniform3f(location, this.x, this.y, this.z);
|
|
}
|
|
toV2() {
|
|
return new V2(this.x, this.y);
|
|
}
|
|
static get zero() {
|
|
return new _V3(0, 0, 0);
|
|
}
|
|
static get one() {
|
|
return new _V3(1, 1, 1);
|
|
}
|
|
static get up() {
|
|
return new _V3(0, 1, 0);
|
|
}
|
|
static get down() {
|
|
return new _V3(0, -1, 0);
|
|
}
|
|
static get left() {
|
|
return new _V3(1, 0, 0);
|
|
}
|
|
static get right() {
|
|
return new _V3(-1, 0, 0);
|
|
}
|
|
static get forward() {
|
|
return new _V3(0, 0, 1);
|
|
}
|
|
static get back() {
|
|
return new _V3(0, 0, -1);
|
|
}
|
|
/**
|
|
* @param {V3} v1
|
|
* @param {V3} v2
|
|
* @param {number} t
|
|
*/
|
|
static lerp(v1, v2, t) {
|
|
return v1.add(v2.sub(v1).scale(t));
|
|
}
|
|
/**
|
|
* @param {V3} v1
|
|
* @param {V3} v2
|
|
*/
|
|
static angle(v1, v2) {
|
|
return Math.acos(v1.dot(v2) / Math.sqrt(v1.squareMag * v2.squareMag));
|
|
}
|
|
/** @param {number} axis */
|
|
static getRotationAxis(axis) {
|
|
if (axis === 0)
|
|
return _V3.right;
|
|
if (axis === 1)
|
|
return _V3.down;
|
|
return _V3.back;
|
|
}
|
|
};
|
|
var V4 = class _V4 extends Vector {
|
|
/**
|
|
* @param {number} x
|
|
* @param {number} y
|
|
* @param {number} z
|
|
* @param {number} w
|
|
*/
|
|
constructor(x, y, z, w) {
|
|
super();
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.w = w;
|
|
}
|
|
/** @param {number} a */
|
|
scale(a) {
|
|
return new _V4(a * this.x, a * this.y, a * this.z, a * this.w);
|
|
}
|
|
/** @param {V4} v */
|
|
add({ x, y, z, w }) {
|
|
return new _V4(this.x + x, this.y + y, this.z + z, this.w + w);
|
|
}
|
|
/** @param {V4} v */
|
|
sub({ x, y, z, w }) {
|
|
return new _V4(this.x - x, this.y - y, this.z - z, this.w - w);
|
|
}
|
|
/** @param {V4} v */
|
|
mult({ x, y, z, w }) {
|
|
return new _V4(this.x * x, this.y * y, this.z * z, this.w * w);
|
|
}
|
|
/** @param {V4} v */
|
|
dot({ x, y, z, w }) {
|
|
return this.x * x + this.y * y + this.z * z + this.w * w;
|
|
}
|
|
toV3() {
|
|
return new V3(this.x, this.y, this.z);
|
|
}
|
|
toArray() {
|
|
return [this.x, this.y, this.z, this.w];
|
|
}
|
|
/**
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLUniformLocation} location
|
|
*/
|
|
setUniform(gl, location) {
|
|
gl.uniform4f(location, this.x, this.y, this.z, this.w);
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/math/matrix.js
|
|
var M44 = class _M44 {
|
|
/**
|
|
* @param {V4} r1
|
|
* @param {V4} r2
|
|
* @param {V4} r3
|
|
* @param {V4} r4
|
|
*/
|
|
constructor(r1, r2, r3, r4) {
|
|
this.r1 = r1;
|
|
this.r2 = r2;
|
|
this.r3 = r3;
|
|
this.r4 = r4;
|
|
}
|
|
/** @param {number} a */
|
|
scale(a) {
|
|
return new _M44(this.r1.scale(a), this.r2.scale(a), this.r3.scale(a), this.r4.scale(a));
|
|
}
|
|
/** @param {M44} m */
|
|
add({ r1, r2, r3, r4 }) {
|
|
return new _M44(this.r1.add(r1), this.r2.add(r2), this.r3.add(r3), this.r4.add(r4));
|
|
}
|
|
/** @param {M44} m */
|
|
sub({ r1, r2, r3, r4 }) {
|
|
return new _M44(this.r1.sub(r1), this.r2.sub(r2), this.r3.sub(r3), this.r4.sub(r4));
|
|
}
|
|
/**
|
|
* @overload
|
|
* @param {M44} m
|
|
* @return {M44}
|
|
*
|
|
* @overload
|
|
* @param {V4} m
|
|
* @return {V4}
|
|
*
|
|
* @param {M44 | V4} m
|
|
*/
|
|
mult(m) {
|
|
if ("x" in m) {
|
|
return new V4(
|
|
this.r1.dot(m),
|
|
this.r2.dot(m),
|
|
this.r3.dot(m),
|
|
this.r4.dot(m)
|
|
);
|
|
}
|
|
return new _M44(
|
|
new V4(this.r1.dot(m.c1), this.r1.dot(m.c2), this.r1.dot(m.c3), this.r1.dot(m.c4)),
|
|
new V4(this.r2.dot(m.c1), this.r2.dot(m.c2), this.r2.dot(m.c3), this.r2.dot(m.c4)),
|
|
new V4(this.r3.dot(m.c1), this.r3.dot(m.c2), this.r3.dot(m.c3), this.r3.dot(m.c4)),
|
|
new V4(this.r4.dot(m.c1), this.r4.dot(m.c2), this.r4.dot(m.c3), this.r4.dot(m.c4))
|
|
);
|
|
}
|
|
toArray() {
|
|
return [...this.r1.toArray(), ...this.r2.toArray(), ...this.r3.toArray(), ...this.r4.toArray()];
|
|
}
|
|
static get identity() {
|
|
return new _M44(
|
|
new V4(1, 0, 0, 0),
|
|
new V4(0, 1, 0, 0),
|
|
new V4(0, 0, 1, 0),
|
|
new V4(0, 0, 0, 1)
|
|
);
|
|
}
|
|
get c1() {
|
|
return new V4(this.r1.x, this.r2.x, this.r3.x, this.r4.x);
|
|
}
|
|
get c2() {
|
|
return new V4(this.r1.y, this.r2.y, this.r3.y, this.r4.y);
|
|
}
|
|
get c3() {
|
|
return new V4(this.r1.z, this.r2.z, this.r3.z, this.r4.z);
|
|
}
|
|
get c4() {
|
|
return new V4(this.r1.w, this.r2.w, this.r3.w, this.r4.w);
|
|
}
|
|
/**
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLUniformLocation} location
|
|
*/
|
|
setUniform(gl, location) {
|
|
const data = new Float32Array(this.toArray());
|
|
gl.uniformMatrix4fv(location, true, data);
|
|
}
|
|
get transpose() {
|
|
return new _M44(this.c1, this.c2, this.c3, this.c4);
|
|
}
|
|
get inverse() {
|
|
const [i00, i01, i02, i03] = this.r1.toArray();
|
|
const [i10, i11, i12, i13] = this.r2.toArray();
|
|
const [i20, i21, i22, i23] = this.r3.toArray();
|
|
const [i30, i31, i32, i33] = this.r4.toArray();
|
|
const s0 = i00 * i11 - i10 * i01;
|
|
const s1 = i00 * i12 - i10 * i02;
|
|
const s2 = i00 * i13 - i10 * i03;
|
|
const s3 = i01 * i12 - i11 * i02;
|
|
const s4 = i01 * i13 - i11 * i03;
|
|
const s5 = i02 * i13 - i12 * i03;
|
|
const c5 = i22 * i33 - i32 * i23;
|
|
const c4 = i21 * i33 - i31 * i23;
|
|
const c3 = i21 * i32 - i31 * i22;
|
|
const c2 = i20 * i33 - i30 * i23;
|
|
const c1 = i20 * i32 - i30 * i22;
|
|
const c0 = i20 * i31 - i30 * i21;
|
|
const det = s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0;
|
|
const invDet = 1 / det;
|
|
return new _M44(
|
|
new V4(
|
|
i11 * c5 - i12 * c4 + i13 * c3,
|
|
-i01 * c5 + i02 * c4 - i03 * c3,
|
|
i31 * s5 - i32 * s4 + i33 * s3,
|
|
-i21 * s5 + i22 * s4 - i23 * s3
|
|
),
|
|
new V4(
|
|
-i10 * c5 + i12 * c2 - i13 * c1,
|
|
i00 * c5 - i02 * c2 + i03 * c1,
|
|
-i30 * s5 + i32 * s2 - i33 * s1,
|
|
i20 * s5 - i22 * s2 + i23 * s1
|
|
),
|
|
new V4(
|
|
i10 * c4 - i11 * c2 + i13 * c0,
|
|
-i00 * c4 + i01 * c2 - i03 * c0,
|
|
i30 * s4 - i31 * s2 + i33 * s0,
|
|
-i20 * s4 + i21 * s2 - i23 * s0
|
|
),
|
|
new V4(
|
|
-i10 * c3 + i11 * c1 - i12 * c0,
|
|
i00 * c3 - i01 * c1 + i02 * c0,
|
|
-i30 * s3 + i31 * s1 - i32 * s0,
|
|
i20 * s3 - i21 * s1 + i22 * s0
|
|
)
|
|
).scale(invDet);
|
|
}
|
|
/**
|
|
* @param {number} fovy
|
|
* @param {number} aspect
|
|
* @param {number} near
|
|
* @param {number} far
|
|
*/
|
|
static perspective(fovy, aspect, near, far) {
|
|
const tanHalfFovy = Math.tan(fovy / 2);
|
|
const x = 1 / (aspect * tanHalfFovy);
|
|
const y = 1 / tanHalfFovy;
|
|
const fpn = far + near;
|
|
const fmn = far - near;
|
|
const oon = 0.5 / near;
|
|
const oof = 0.5 / far;
|
|
const z = -fpn / fmn;
|
|
const w = 1 / (oof - oon);
|
|
return new _M44(
|
|
new V4(x, 0, 0, 0),
|
|
new V4(0, y, 0, 0),
|
|
new V4(0, 0, z, w),
|
|
new V4(0, 0, -1, 0)
|
|
);
|
|
}
|
|
/**
|
|
* @param {V3} eye
|
|
* @param {V3} center
|
|
* @param {V3} up
|
|
*/
|
|
static lookAt(eye, center, up) {
|
|
const za = center.sub(eye).normalized;
|
|
const xa = za.cross(up).normalized;
|
|
const ya = xa.cross(za);
|
|
const xd = -xa.dot(eye);
|
|
const yd = -ya.dot(eye);
|
|
const zd = za.dot(eye);
|
|
return new _M44(
|
|
new V4(xa.x, xa.y, xa.z, xd),
|
|
new V4(ya.x, ya.y, ya.z, yd),
|
|
new V4(-za.x, -za.y, -za.z, zd),
|
|
new V4(0, 0, 0, 1)
|
|
);
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/math/quarternion.js
|
|
var Quaternion = class _Quaternion {
|
|
/**
|
|
* @param {number} real
|
|
* @param {V3} im
|
|
*/
|
|
constructor(real, im) {
|
|
this.real = real;
|
|
this.im = im;
|
|
}
|
|
/**
|
|
* @param {V3} axis
|
|
* @param {number} angle
|
|
* @param {boolean} [degree=true]
|
|
*/
|
|
static fromAngle(axis, angle, degree = true) {
|
|
if (degree) {
|
|
angle *= Math.PI / 180;
|
|
}
|
|
const half = angle / 2;
|
|
const real = Math.cos(half);
|
|
const im = axis.normalized.scale(Math.sin(half));
|
|
return new _Quaternion(real, im);
|
|
}
|
|
get matrix() {
|
|
const { x, y, z } = this.im;
|
|
const w = this.real;
|
|
const xx = x * x;
|
|
const yy = y * y;
|
|
const zz = z * z;
|
|
const xy = x * y;
|
|
const xz = x * z;
|
|
const xw = x * w;
|
|
const yz = y * z;
|
|
const yw = y * w;
|
|
const zw = z * w;
|
|
return new M44(
|
|
new V4(1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0),
|
|
new V4(2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0),
|
|
new V4(2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0),
|
|
new V4(0, 0, 0, 1)
|
|
);
|
|
}
|
|
/** @param {Quaternion} q */
|
|
mult({ real, im }) {
|
|
return new _Quaternion(this.real * real - this.im.dot(im), this.im.cross(im).add(im.scale(this.real)).add(this.im.scale(real)));
|
|
}
|
|
/** @param {V3} v */
|
|
rotate(v) {
|
|
return new _Quaternion(this.real, this.im.negate).mult(new _Quaternion(0, v)).mult(this).im;
|
|
}
|
|
get conjugate() {
|
|
return new _Quaternion(this.real, this.im.negate);
|
|
}
|
|
get mag() {
|
|
return Math.sqrt(this.real * this.real + this.im.squareMag);
|
|
}
|
|
/** @param {number} n */
|
|
power(n) {
|
|
const { mag } = this;
|
|
const phi = Math.acos(this.real / mag);
|
|
const unit = this.im.normalized;
|
|
const scalar = Math.pow(mag, n);
|
|
return new _Quaternion(scalar * Math.cos(phi * n), unit.scale(scalar * Math.sin(phi * n)));
|
|
}
|
|
static get identity() {
|
|
return new _Quaternion(1, V3.zero);
|
|
}
|
|
/**
|
|
* @param {Quaternion} q1
|
|
* @param {Quaternion} q2
|
|
* @param {number} t
|
|
*/
|
|
static slerp(q1, q2, t) {
|
|
return q1.mult(q1.conjugate.mult(q2).power(t));
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/ui/program.js
|
|
var _program, _uniformMap, _path, _gl, _Program_instances, createShader_fn;
|
|
var Program = class {
|
|
/**
|
|
* @param {string} path
|
|
* @param {string} vertexShaderSource
|
|
* @param {string} fragmentShaderSource
|
|
* @param {WebGL2RenderingContext} gl
|
|
*/
|
|
constructor(path, vertexShaderSource, fragmentShaderSource, gl) {
|
|
__privateAdd(this, _Program_instances);
|
|
/** @type {WebGLProgram} */
|
|
__privateAdd(this, _program);
|
|
/** @type {Map<string, WebGLUniformLocation>} */
|
|
__privateAdd(this, _uniformMap);
|
|
/** @type {string} */
|
|
__privateAdd(this, _path);
|
|
/** @type {WebGL2RenderingContext} */
|
|
__privateAdd(this, _gl);
|
|
__privateSet(this, _path, path);
|
|
__privateSet(this, _gl, gl);
|
|
const vertexShader = __privateMethod(this, _Program_instances, createShader_fn).call(this, vertexShaderSource, __privateGet(this, _gl).VERTEX_SHADER, "vertex");
|
|
const fragmentShader = __privateMethod(this, _Program_instances, createShader_fn).call(this, fragmentShaderSource, __privateGet(this, _gl).FRAGMENT_SHADER, "fragment");
|
|
const p = __privateGet(this, _gl).createProgram();
|
|
if (!p)
|
|
throw new Error("Fatal: webgl could not create program object!");
|
|
__privateSet(this, _program, p);
|
|
__privateGet(this, _gl).attachShader(__privateGet(this, _program), vertexShader);
|
|
__privateGet(this, _gl).attachShader(__privateGet(this, _program), fragmentShader);
|
|
__privateGet(this, _gl).linkProgram(__privateGet(this, _program));
|
|
const success = __privateGet(this, _gl).getProgramParameter(__privateGet(this, _program), __privateGet(this, _gl).LINK_STATUS);
|
|
if (!success) {
|
|
const info = __privateGet(this, _gl).getProgramInfoLog(__privateGet(this, _program));
|
|
__privateGet(this, _gl).deleteProgram(__privateGet(this, _program));
|
|
throw new Error(`Link Program: ${info}`);
|
|
}
|
|
const numUniforms = (
|
|
/** @type {number} */
|
|
__privateGet(this, _gl).getProgramParameter(__privateGet(this, _program), __privateGet(this, _gl).ACTIVE_UNIFORMS)
|
|
);
|
|
const uniformIndices = [...Array(numUniforms).keys()];
|
|
const uniformNames = uniformIndices.map((index) => {
|
|
const info = __privateGet(this, _gl).getActiveUniform(__privateGet(this, _program), index);
|
|
if (info == null) {
|
|
throw new Error("failed to get active uniform");
|
|
}
|
|
const location = __privateGet(this, _gl).getUniformLocation(__privateGet(this, _program), info.name);
|
|
if (location == null) {
|
|
throw new Error("failed to get uniform location");
|
|
}
|
|
return (
|
|
/** @type {[string, WebGLUniformLocation]} */
|
|
[info.name, location]
|
|
);
|
|
});
|
|
__privateSet(this, _uniformMap, new Map(uniformNames));
|
|
}
|
|
use() {
|
|
if (!__privateGet(this, _program)) {
|
|
throw new Error("Fatal: program does not exists!");
|
|
}
|
|
__privateGet(this, _gl).useProgram(__privateGet(this, _program));
|
|
}
|
|
/**
|
|
* @param {string} name
|
|
* @param {import('../types').Uniform} u
|
|
*/
|
|
uniform(name, u) {
|
|
const location = __privateGet(this, _uniformMap).get(name);
|
|
if (location == void 0) {
|
|
throw new Error(`Fatal: unkown name: ${name}`);
|
|
}
|
|
u.setUniform(__privateGet(this, _gl), location);
|
|
}
|
|
};
|
|
_program = new WeakMap();
|
|
_uniformMap = new WeakMap();
|
|
_path = new WeakMap();
|
|
_gl = new WeakMap();
|
|
_Program_instances = new WeakSet();
|
|
/**
|
|
* @param {string} source
|
|
* @param {number} type
|
|
* @param {string} typeStr
|
|
* @returns {WebGLShader}
|
|
*/
|
|
createShader_fn = function(source, type, typeStr) {
|
|
const shader = __privateGet(this, _gl).createShader(type);
|
|
if (!shader)
|
|
throw new Error("Fatal: webgl could not create shader object!");
|
|
__privateGet(this, _gl).shaderSource(shader, source);
|
|
__privateGet(this, _gl).compileShader(shader);
|
|
const success = (
|
|
/** @type {boolean} */
|
|
__privateGet(this, _gl).getShaderParameter(shader, __privateGet(this, _gl).COMPILE_STATUS)
|
|
);
|
|
if (success) {
|
|
return shader;
|
|
}
|
|
const info = __privateGet(this, _gl).getShaderInfoLog(shader);
|
|
__privateGet(this, _gl).deleteShader(shader);
|
|
throw new Error(`Compile '${__privateGet(this, _path)}': ${typeStr}: ${info}`);
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/ui/transform.js
|
|
var Transform = class _Transform {
|
|
/**
|
|
* @param {V3} position
|
|
* @param {Quaternion} rotation
|
|
* @param {TParent} parent
|
|
*/
|
|
constructor(position, rotation, parent) {
|
|
/** @type {M44} */
|
|
__publicField(this, "localTransform");
|
|
/** @type {M44} */
|
|
__publicField(this, "globalTransform");
|
|
/** @type {TChild[]} */
|
|
__publicField(this, "children", []);
|
|
this._position = position;
|
|
this._rotation = rotation;
|
|
this.parent = parent;
|
|
this.setTransforms();
|
|
}
|
|
/** @protected */
|
|
setTransforms() {
|
|
const localTransform = _Transform.getLocalTransform(this._position, this._rotation);
|
|
this.localTransform = localTransform;
|
|
if (!this.parent) {
|
|
this.globalTransform = localTransform;
|
|
} else {
|
|
const parentTransform = this.parent.transform.globalTransform;
|
|
this.globalTransform = parentTransform.mult(localTransform);
|
|
}
|
|
this.children.forEach((child) => child.transform.setTransforms());
|
|
}
|
|
/** @param {V3} v */
|
|
apply({ x, y, z }) {
|
|
return this.globalTransform.mult(new V4(x, y, z, 1)).toV3();
|
|
}
|
|
/**
|
|
* @param {V3} axis
|
|
* @param {number} angle
|
|
*/
|
|
rotate(axis, angle) {
|
|
this.rotation = this._rotation.mult(Quaternion.fromAngle(this._rotation.rotate(axis), angle));
|
|
}
|
|
/** @param {V3} value */
|
|
set position(value) {
|
|
this._position = value;
|
|
this.setTransforms();
|
|
}
|
|
/** @param {Quaternion} value */
|
|
set rotation(value) {
|
|
this._rotation = value;
|
|
this.setTransforms();
|
|
}
|
|
get position() {
|
|
return this._position;
|
|
}
|
|
get rotation() {
|
|
return this._rotation;
|
|
}
|
|
/**
|
|
* @param {V3} position
|
|
* @param {Quaternion} rotation
|
|
* @returns {M44}
|
|
*/
|
|
static getLocalTransform({ x, y, z }, rotation) {
|
|
const transform = rotation.matrix;
|
|
transform.r1.w = x;
|
|
transform.r2.w = y;
|
|
transform.r3.w = z;
|
|
return transform;
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/ui/facelet.js
|
|
var FaceletTransform = class extends Transform {
|
|
/**
|
|
* @param {V3} position
|
|
* @param {Quaternion} rotation
|
|
* @param {Cubie} parent
|
|
*/
|
|
constructor(position, rotation, parent) {
|
|
super(position, rotation, parent);
|
|
/** @type {V3} */
|
|
__publicField(this, "left");
|
|
/** @type {V3} */
|
|
__publicField(this, "top");
|
|
/** @type {V3} */
|
|
__publicField(this, "normal");
|
|
/** @type {V3} */
|
|
__publicField(this, "topLeft");
|
|
/** @type {V3} */
|
|
__publicField(this, "bottomRight");
|
|
this.setTransforms();
|
|
}
|
|
/** @protected */
|
|
setTransforms() {
|
|
super.setTransforms();
|
|
const rotationTransform = this.globalTransform.inverse.transpose;
|
|
this.left = rotationTransform.mult(new V4(0, 0, -1, 1)).toV3().normalized;
|
|
this.top = rotationTransform.mult(new V4(0, -1, 0, 1)).toV3().normalized;
|
|
this.normal = rotationTransform.mult(new V4(-1, 0, 0, 1)).toV3().normalized;
|
|
this.topLeft = this.globalTransform.mult(new V4(0, 0.5, 0.5, 1)).toV3();
|
|
this.bottomRight = this.topLeft.add(this.left).add(this.top);
|
|
}
|
|
};
|
|
var _hoveringMult;
|
|
var Facelet = class {
|
|
/**
|
|
* @param {FaceletTransform} transform
|
|
* @param {number} side
|
|
* @param {number[]} uvs
|
|
* @param {V3} hoveringMult
|
|
*/
|
|
constructor(transform, side, uvs, hoveringMult) {
|
|
__publicField(this, "hovering", false);
|
|
/** @type {V3} */
|
|
__privateAdd(this, _hoveringMult);
|
|
this.transform = transform;
|
|
this.side = side;
|
|
this.uvs = uvs;
|
|
__privateSet(this, _hoveringMult, hoveringMult);
|
|
}
|
|
/**
|
|
* @param {Program} program
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLBuffer} uvsVbo
|
|
*/
|
|
render(program, gl, uvsVbo) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, uvsVbo);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.uvs), gl.STATIC_DRAW);
|
|
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 8, 0);
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
program.uniform("model", this.transform.globalTransform);
|
|
program.uniform("colorMult", this.hovering ? __privateGet(this, _hoveringMult) : V3.one);
|
|
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
|
|
}
|
|
};
|
|
_hoveringMult = new WeakMap();
|
|
var InsideFacelet = class {
|
|
/** @param {Transform<any, Cubie>} transform */
|
|
constructor(transform) {
|
|
this.transform = transform;
|
|
}
|
|
/**
|
|
* @param {Program} program
|
|
* @param {WebGL2RenderingContext} gl
|
|
*/
|
|
render(program, gl) {
|
|
program.uniform("model", this.transform.globalTransform);
|
|
program.uniform("colorMult", V3.zero);
|
|
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
|
|
}
|
|
};
|
|
|
|
// node_modules/rubiks-js/src/ui/cubie.js
|
|
var positionForSide = [
|
|
V3.right,
|
|
V3.left,
|
|
V3.down,
|
|
V3.up,
|
|
V3.back,
|
|
V3.forward
|
|
].map((v) => v.scale(0.5));
|
|
var rotationForSide = [
|
|
Quaternion.identity,
|
|
Quaternion.identity,
|
|
Quaternion.fromAngle(V3.back, 90),
|
|
Quaternion.fromAngle(V3.back, 90),
|
|
Quaternion.fromAngle(V3.back, 90).mult(Quaternion.fromAngle(V3.down, 90)),
|
|
Quaternion.fromAngle(V3.back, 90).mult(Quaternion.fromAngle(V3.down, 90))
|
|
];
|
|
var isInside = (side, index) => {
|
|
const axis = Math.floor(side / 2);
|
|
const invert = side % 2;
|
|
const coordinate = Math.floor(index / Math.pow(3, axis)) % 3;
|
|
return coordinate === 1 || coordinate === 0 && invert === 1 || coordinate === 2 && invert === 0;
|
|
};
|
|
var indexToPosition = (index) => {
|
|
const x = Math.floor(index / 1) % 3;
|
|
const y = Math.floor(index / 3) % 3;
|
|
const z = Math.floor(index / 9) % 3;
|
|
return [x, y, z];
|
|
};
|
|
var positionToUvs = (pos, side, uvs) => {
|
|
const axis = Math.floor(side / 2);
|
|
const uvCoords = [];
|
|
for (let i = 0; i < 3; i++) {
|
|
if (i !== axis) {
|
|
uvCoords.push(pos[i]);
|
|
}
|
|
}
|
|
const sideIndex = uvCoords[0] + uvCoords[1] * 3;
|
|
return uvs[side][sideIndex];
|
|
};
|
|
var Cubie = class {
|
|
/**
|
|
* @param {number} index
|
|
* @param {number[][][]} uvs
|
|
* @param {V3[]} hoveringColors
|
|
* @param {import('./rubiks').Rubiks} parent
|
|
*/
|
|
constructor(index, uvs, hoveringColors, parent) {
|
|
/** @type {Facelet[]} */
|
|
__publicField(this, "facelets", []);
|
|
/** @type {Transform<Facelet | InsideFacelet, import('./rubiks').Rubiks>} */
|
|
__publicField(this, "transform");
|
|
this.index = index;
|
|
const pos = indexToPosition(index);
|
|
const position = new V3(pos[0], pos[1], pos[2]).sub(V3.one);
|
|
this.transform = new Transform(position, Quaternion.identity, parent);
|
|
for (let side = 0; side < 6; side++) {
|
|
const inside = isInside(side, this.index);
|
|
const position2 = positionForSide[side];
|
|
const rotation = rotationForSide[side];
|
|
if (inside) {
|
|
const transform2 = new Transform(position2, rotation, this);
|
|
const facelet2 = new InsideFacelet(transform2);
|
|
this.transform.children.push(facelet2);
|
|
continue;
|
|
}
|
|
const uv = positionToUvs(pos, side, uvs);
|
|
const transform = new FaceletTransform(position2, rotation, this);
|
|
const facelet = new Facelet(transform, side, uv, hoveringColors[side]);
|
|
this.transform.children.push(facelet);
|
|
this.facelets.push(facelet);
|
|
}
|
|
}
|
|
/**
|
|
* @param {number} side
|
|
* @returns {Facelet}
|
|
*/
|
|
getFaceletOfSide(side) {
|
|
return (
|
|
/** @type {Facelet} */
|
|
this.facelets.find((facelet) => facelet.side === side)
|
|
);
|
|
}
|
|
/**
|
|
* @param {import('./program').Program} program
|
|
* @param {WebGL2RenderingContext} gl
|
|
* @param {WebGLBuffer} uvsVbo
|
|
*/
|
|
render(program, gl, uvsVbo) {
|
|
this.transform.children.forEach((child) => child.render.call(child, program, gl, uvsVbo));
|
|
}
|
|
};
|
|
|
|
export {
|
|
V2,
|
|
V3,
|
|
V4,
|
|
M44,
|
|
Quaternion,
|
|
Program,
|
|
Transform,
|
|
isInside,
|
|
indexToPosition,
|
|
positionToUvs,
|
|
Cubie
|
|
};
|
|
//# sourceMappingURL=chunk-ROHLD3FA.js.map
|