Files
rubic-cube/node_modules/.vite/deps/rubiks-js.js

1546 lines
52 KiB
JavaScript

import {
State,
clamp,
convertAiaToTurn,
lerp,
mod,
sidesShiftMapper,
uvsTransformerPresets
} from "./chunk-YIK32INT.js";
import {
Cubie,
M44,
Program,
Quaternion,
Transform,
V2,
V3,
V4
} from "./chunk-ROHLD3FA.js";
import {
__privateAdd,
__privateGet,
__privateMethod,
__privateSet,
__publicField
} from "./chunk-HPRLEMBT.js";
// node_modules/rubiks-js/src/ui/camera.js
var _position, _lookAt, _forward, _right, _up, _fov, _aspect, _width, _height, _near, _far, _projectionMatrix, _worldToCameraMatrix, _projectionMatrixInverse, _cameraToWorldMatrix, _worldProjectionMatrix;
var Camera = class {
/**
* @param {V3} position
* @param {V3} lookAt
* @param {V3} up
* @param {number} fov
* @param {number} width
* @param {number} height
* @param {number} near
* @param {number} far
*/
constructor(position, lookAt, up, fov, width, height, near, far) {
/** @type {V3} */
__privateAdd(this, _position);
/** @type {V3} */
__privateAdd(this, _lookAt);
/** @type {V3} */
__privateAdd(this, _forward);
/** @type {V3} */
__privateAdd(this, _right);
/** @type {V3} */
__privateAdd(this, _up);
/** @type {number} */
__privateAdd(this, _fov);
/** @type {number} */
__privateAdd(this, _aspect);
/** @type {number} */
__privateAdd(this, _width);
/** @type {number} */
__privateAdd(this, _height);
/** @type {number} */
__privateAdd(this, _near);
/** @type {number} */
__privateAdd(this, _far);
/** @type {M44} */
__privateAdd(this, _projectionMatrix);
/** @type {M44} */
__privateAdd(this, _worldToCameraMatrix);
/** @type {M44} */
__privateAdd(this, _projectionMatrixInverse);
/** @type {M44} */
__privateAdd(this, _cameraToWorldMatrix);
/** @type {M44} */
__privateAdd(this, _worldProjectionMatrix);
__privateSet(this, _position, position);
__privateSet(this, _lookAt, lookAt);
__privateSet(this, _up, up);
__privateSet(this, _fov, fov);
__privateSet(this, _width, width);
__privateSet(this, _height, height);
__privateSet(this, _aspect, width / height);
__privateSet(this, _near, near);
__privateSet(this, _far, far);
this.calcCameraDirections();
this.calcWorldToCameraMatrix();
this.calcProjectionMatrix();
}
/** @param {V3} value */
set position(value) {
__privateSet(this, _position, value);
this.calcCameraDirections();
this.calcWorldToCameraMatrix();
}
/** @param {V3} value */
set lookAt(value) {
__privateSet(this, _lookAt, value);
this.calcCameraDirections();
this.calcWorldToCameraMatrix();
}
/** @param {V3} value */
set up(value) {
__privateSet(this, _up, value);
this.calcCameraDirections();
this.calcWorldToCameraMatrix();
}
get position() {
return __privateGet(this, _position);
}
get lookAt() {
return __privateGet(this, _lookAt);
}
get up() {
return __privateGet(this, _up);
}
get forward() {
return __privateGet(this, _forward);
}
get right() {
return __privateGet(this, _right);
}
/** @param {number} value */
set fov(value) {
__privateSet(this, _fov, value);
this.calcProjectionMatrix();
}
/** @param {number} value */
set near(value) {
__privateSet(this, _near, value);
this.calcProjectionMatrix();
}
/** @param {number} value */
set far(value) {
__privateSet(this, _far, value);
this.calcProjectionMatrix();
}
get fov() {
return __privateGet(this, _fov);
}
get aspect() {
return __privateGet(this, _aspect);
}
get near() {
return __privateGet(this, _near);
}
get far() {
return __privateGet(this, _far);
}
get width() {
return __privateGet(this, _width);
}
get height() {
return __privateGet(this, _height);
}
/**
* @param {number} width
* @param {number} height
*/
screenSize(width, height) {
__privateSet(this, _width, width);
__privateSet(this, _height, height);
__privateSet(this, _aspect, width / height);
this.calcProjectionMatrix();
}
get projectionMatrix() {
return __privateGet(this, _projectionMatrix);
}
get projectionMatrixInverse() {
return __privateGet(this, _projectionMatrixInverse);
}
get worldToCameraMatrix() {
return __privateGet(this, _worldToCameraMatrix);
}
get cameraToWorldMatrix() {
return __privateGet(this, _cameraToWorldMatrix);
}
get worldProjectionMatrix() {
return __privateGet(this, _worldProjectionMatrix);
}
/** @param {V3} v */
worldToScreen({ x, y, z }) {
const point4d = this.worldProjectionMatrix.mult(new V4(x, y, z, 1));
const screenPoint = point4d.toV3().scale(1 / point4d.w).toV2().add(new V2(1, 1)).scale(0.5).mult(new V2(this.width, this.height));
return screenPoint;
}
// worldDirectionToScreen({x, y, z}: V3) {
// // const rotationTransform = this.cameraToWorldMatrix.transpose
// const cameraPoint = this.worldToCameraMatrix.mult(new V4(x, y, z, 1))
// const projectedPoint = this.projectionMatrix.mult(cameraPoint)
// const viewportPoint = projectedPoint.toV3().scale(1 / projectedPoint.w).toV2()
// const screenPoint = viewportPoint.add(new V2(1, 1)).scale(.5).mult(new V2(this.width, this.height))
// // console.log(this.projectionMatrix)
// console.table({cameraPoint, projectedPoint, viewportPoint, screenPoint})
// return screenPoint
// }
calcProjectionMatrix() {
var _a3;
__privateSet(this, _projectionMatrix, M44.perspective(__privateGet(this, _fov) * Math.PI / 180, __privateGet(this, _aspect), __privateGet(this, _near), __privateGet(this, _far)));
__privateSet(this, _projectionMatrixInverse, __privateGet(this, _projectionMatrix).inverse);
__privateSet(this, _worldProjectionMatrix, (_a3 = __privateGet(this, _projectionMatrix)) == null ? void 0 : _a3.mult(__privateGet(this, _worldToCameraMatrix)));
}
calcWorldToCameraMatrix() {
var _a3;
__privateSet(this, _worldToCameraMatrix, M44.lookAt(__privateGet(this, _position), __privateGet(this, _lookAt), __privateGet(this, _up)));
__privateSet(this, _cameraToWorldMatrix, __privateGet(this, _worldToCameraMatrix).inverse);
__privateSet(this, _worldProjectionMatrix, (_a3 = __privateGet(this, _projectionMatrix)) == null ? void 0 : _a3.mult(__privateGet(this, _worldToCameraMatrix)));
}
calcCameraDirections() {
__privateSet(this, _forward, __privateGet(this, _lookAt).sub(__privateGet(this, _position)).normalized);
__privateSet(this, _right, __privateGet(this, _up).cross(__privateGet(this, _forward)).normalized);
}
};
_position = new WeakMap();
_lookAt = new WeakMap();
_forward = new WeakMap();
_right = new WeakMap();
_up = new WeakMap();
_fov = new WeakMap();
_aspect = new WeakMap();
_width = new WeakMap();
_height = new WeakMap();
_near = new WeakMap();
_far = new WeakMap();
_projectionMatrix = new WeakMap();
_worldToCameraMatrix = new WeakMap();
_projectionMatrixInverse = new WeakMap();
_cameraToWorldMatrix = new WeakMap();
_worldProjectionMatrix = new WeakMap();
// node_modules/rubiks-js/src/ui/rubiks.js
var rotationAxis = [
V3.getRotationAxis(0),
V3.getRotationAxis(1),
V3.getRotationAxis(2)
];
var cubeRotationOnMiddle = {
0: {
2: 90,
3: -90,
4: -90,
5: 90
},
1: {
0: -90,
1: 90,
4: 90,
5: -90
},
2: {
0: 90,
1: -90,
2: -90,
3: 90
}
};
var uvsTransformers = {
0: {
0: uvsTransformerPresets.rcR2Rcc,
1: uvsTransformerPresets.rcR2Rcc,
2: uvsTransformerPresets.flipV23,
3: uvsTransformerPresets.flipV23,
4: uvsTransformerPresets.flipV12,
5: uvsTransformerPresets.flipV12
},
1: {
0: uvsTransformerPresets.rcfhFvRcc,
1: uvsTransformerPresets.rcfhFvRcc,
2: uvsTransformerPresets.rcR2Rcc,
3: uvsTransformerPresets.rcR2Rcc,
4: uvsTransformerPresets.rcFhRcfh,
5: uvsTransformerPresets.rcFhRcfh
},
2: {
0: uvsTransformerPresets.flipH23,
1: uvsTransformerPresets.flipH23,
2: uvsTransformerPresets.flipH12,
3: uvsTransformerPresets.flipH12,
4: uvsTransformerPresets.rcR2Rcc,
5: uvsTransformerPresets.rcR2Rcc
}
};
var shouldInvertAngle = (axis, side) => {
return side === 0 || side === 2 && axis === 0 || side === 3 && axis === 2 || side === 5;
};
var RubiksTransform = class extends Transform {
/**
* @param {V3} position
* @param {Quaternion} rotation
*/
constructor(position, rotation) {
super(position, rotation, null);
/** @type {[V3, V3, V3]} */
__publicField(this, "rotationAxis");
this.setTransforms();
}
/** @property */
setTransforms() {
super.setTransforms();
this.rotationAxis = /** @type {[V3, V3, V3]} */
rotationAxis.map((axis) => {
return this.apply(axis);
});
}
};
var _turnCallback, _axisDeltasMap, _Rubiks_instances, turn_fn, swapOuterFacelets_fn, swapInnerFacelets_fn, _rotatingCubies, _rotationAxis, _rotationCenter, _currentAngle, _initialAngle, _rotatingAutomatic, _turnProgress, _turnSpeed, _targetAngle, _rotationIndex, _rotationAxisIndex, _side;
var _Rubiks = class _Rubiks {
/**
* @param {Quaternion} rotation
* @param {number[][][]} uvs
* @param {V3[]} hoveringColors
* @param {TurnCallback} turnCallback
*/
constructor(rotation, uvs, hoveringColors, turnCallback) {
__privateAdd(this, _Rubiks_instances);
/** @type {RubiksTransform} */
__publicField(this, "transform");
/** @type {Cubie[]} */
__publicField(this, "cubies");
/** @type {TurnCallback} */
__privateAdd(this, _turnCallback);
// manual rotation
/** @type {Array<{cubie: Cubie, backupPosition: V3, backupRotation: Quaternion, directionFromCenter: V3}>} */
__privateAdd(this, _rotatingCubies, []);
__privateAdd(this, _rotationAxis, V3.zero);
__privateAdd(this, _rotationCenter, V3.zero);
__privateAdd(this, _currentAngle, 0);
// automatic rotation
__privateAdd(this, _initialAngle, 0);
__privateAdd(this, _rotatingAutomatic, false);
__privateAdd(this, _turnProgress, 0);
__privateAdd(this, _turnSpeed, 4);
__privateAdd(this, _targetAngle, 0);
__privateAdd(this, _rotationIndex, 0);
__privateAdd(this, _rotationAxisIndex, 0);
__privateAdd(this, _side, 0);
__privateSet(this, _turnCallback, turnCallback);
this.transform = new RubiksTransform(V3.zero, rotation);
this.cubies = [];
for (let i = 0; i < 27; i++) {
const cubie = new Cubie(
i,
uvs,
hoveringColors,
this
);
this.cubies.push(cubie);
this.transform.children.push(cubie);
}
}
/**
* @param {import('./program').Program} program
* @param {WebGL2RenderingContext} gl
* @param {WebGLBuffer} uvsVbo
*/
render(program, gl, uvsVbo) {
this.cubies.forEach((cubie) => cubie.render(program, gl, uvsVbo));
}
/**
* @param {number} axis
* @param {number} index
* @returns {Cubie[]}
*/
getPlane(axis, index) {
const [d1, d2] = __privateGet(_Rubiks, _axisDeltasMap)[axis];
const initial = Math.pow(3, axis) * index;
const cubies = [];
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const index2 = initial + i * d1 + j * d2;
const cubie = this.cubies[index2];
cubies.push(cubie);
}
}
return cubies;
}
/**
* @param {Cubie[]} cubies
* @param {V3} axis
*/
startRotation(cubies, axis) {
__privateSet(this, _rotationAxis, axis);
__privateSet(this, _rotationCenter, cubies[4].transform.position);
__privateSet(this, _rotatingCubies, cubies.map((cubie) => {
return {
cubie,
backupPosition: cubie.transform.position,
backupRotation: cubie.transform.rotation,
directionFromCenter: cubie.transform.position.sub(__privateGet(this, _rotationCenter))
};
}));
}
/** @param {number} angle */
rotateManual(angle) {
const rotation = Quaternion.fromAngle(__privateGet(this, _rotationAxis), -angle);
__privateSet(this, _currentAngle, angle);
__privateGet(this, _rotatingCubies).forEach(({ cubie, backupRotation, directionFromCenter }) => {
const rotatedDirectionFromCenter = rotation.rotate(directionFromCenter);
const newPosition = __privateGet(this, _rotationCenter).add(rotatedDirectionFromCenter);
cubie.transform.position = newPosition;
cubie.transform.rotation = backupRotation;
cubie.transform.rotate(__privateGet(this, _rotationAxis), angle);
});
}
/**
* @param {number} axis
* @param {number} index
* @param {number} angle
* @param {number} side
*/
finishRotation(axis, index, angle, side) {
__privateSet(this, _rotatingAutomatic, true);
__privateSet(this, _turnProgress, 0);
__privateSet(this, _targetAngle, angle);
__privateSet(this, _initialAngle, __privateGet(this, _currentAngle));
__privateSet(this, _rotationIndex, index);
__privateSet(this, _rotationAxisIndex, axis);
__privateSet(this, _side, side);
}
/** @param {number} delta */
update(delta) {
if (!__privateGet(this, _rotatingAutomatic)) {
return;
}
__privateSet(this, _turnProgress, __privateGet(this, _turnProgress) + delta * __privateGet(this, _turnSpeed));
if (__privateGet(this, _turnProgress) >= 1) {
__privateSet(this, _rotatingAutomatic, false);
__privateGet(this, _rotatingCubies).forEach(({ cubie, backupPosition, backupRotation }) => {
cubie.transform.position = backupPosition;
cubie.transform.rotation = backupRotation;
});
__privateMethod(this, _Rubiks_instances, turn_fn).call(this, __privateGet(this, _rotationAxisIndex), __privateGet(this, _rotationIndex), __privateGet(this, _targetAngle), __privateGet(this, _side), __privateGet(this, _rotatingCubies).map(({ cubie }) => cubie));
return;
}
const currentAngle = lerp(__privateGet(this, _initialAngle), __privateGet(this, _targetAngle) * 90, __privateGet(this, _turnProgress));
const rotation = Quaternion.fromAngle(__privateGet(this, _rotationAxis), -currentAngle);
__privateGet(this, _rotatingCubies).forEach(({ cubie, backupRotation, directionFromCenter }) => {
cubie.transform.rotation = backupRotation.mult(Quaternion.fromAngle(__privateGet(this, _rotationAxis), currentAngle));
const rotatedDirectionFromCenter = rotation.rotate(directionFromCenter);
const newPosition = __privateGet(this, _rotationCenter).add(rotatedDirectionFromCenter);
cubie.transform.position = newPosition;
});
}
get isTurning() {
return __privateGet(this, _rotatingAutomatic);
}
};
_turnCallback = new WeakMap();
_axisDeltasMap = new WeakMap();
_Rubiks_instances = new WeakSet();
/**
* @param {number} axis
* @param {number} index
* @param {number} angle
* @param {number} side
* @param {Cubie[]} plane
*/
turn_fn = function(axis, index, angle, side, plane) {
angle = mod(angle, 4);
if (angle === 0) {
return;
}
if (index === 1) {
__privateMethod(this, _Rubiks_instances, turn_fn).call(this, axis, 0, -angle, side, this.getPlane(axis, 0));
__privateMethod(this, _Rubiks_instances, turn_fn).call(this, axis, 2, -angle, side, this.getPlane(axis, 2));
this.transform.rotate(this.transform.rotationAxis[axis], angle * cubeRotationOnMiddle[axis][side]);
return;
}
if (shouldInvertAngle(axis, side)) {
angle = mod(-angle, 4);
}
__privateMethod(this, _Rubiks_instances, swapOuterFacelets_fn).call(this, plane, axis, angle);
__privateMethod(this, _Rubiks_instances, swapInnerFacelets_fn).call(this, plane, axis, index, angle);
__privateGet(this, _turnCallback).call(this, { axis, index, angle });
};
/**
* @param {Cubie[]} plane
* @param {number} axis
* @param {number} angle
*/
swapOuterFacelets_fn = function(plane, axis, angle) {
const [s0, s1, s2, s3] = sidesShiftMapper[axis];
const facelets = [
plane[0].getFaceletOfSide(s0),
plane[1].getFaceletOfSide(s0),
plane[2].getFaceletOfSide(s0),
plane[2].getFaceletOfSide(s1),
plane[5].getFaceletOfSide(s1),
plane[8].getFaceletOfSide(s1),
plane[8].getFaceletOfSide(s2),
plane[7].getFaceletOfSide(s2),
plane[6].getFaceletOfSide(s2),
plane[6].getFaceletOfSide(s3),
plane[3].getFaceletOfSide(s3),
plane[0].getFaceletOfSide(s3)
];
const shiftedUvs = [];
for (let index = 0; index < 12; index++) {
const shiftedIndex = mod(index + 3 * angle, 12);
const { uvs } = facelets[shiftedIndex];
const facelet = facelets[index];
const transformer = uvsTransformers[axis][facelet.side][angle];
shiftedUvs[index] = transformer(uvs);
}
for (let index = 0; index < 12; index++) {
facelets[index].uvs = shiftedUvs[index];
}
};
/**
* @param {Cubie[]} plane
* @param {number} axis
* @param {number} index
* @param {number} angle
*/
swapInnerFacelets_fn = function(plane, axis, index, angle) {
const side = axis * 2 + Math.sign(index);
const facelets = [
plane[0].getFaceletOfSide(side),
plane[1].getFaceletOfSide(side),
plane[2].getFaceletOfSide(side),
plane[5].getFaceletOfSide(side),
plane[8].getFaceletOfSide(side),
plane[7].getFaceletOfSide(side),
plane[6].getFaceletOfSide(side),
plane[3].getFaceletOfSide(side)
];
const shiftedUvs = [];
const transformer = uvsTransformers[axis][side][angle];
for (let index2 = 0; index2 < 8; index2++) {
const shiftedIndex = mod(index2 + 2 * angle, 8);
const { uvs } = facelets[shiftedIndex];
shiftedUvs[index2] = transformer(uvs);
}
for (let index2 = 0; index2 < 8; index2++) {
facelets[index2].uvs = shiftedUvs[index2];
}
const center = plane[4].getFaceletOfSide(side);
center.uvs = transformer(center.uvs);
};
_rotatingCubies = new WeakMap();
_rotationAxis = new WeakMap();
_rotationCenter = new WeakMap();
_currentAngle = new WeakMap();
_initialAngle = new WeakMap();
_rotatingAutomatic = new WeakMap();
_turnProgress = new WeakMap();
_turnSpeed = new WeakMap();
_targetAngle = new WeakMap();
_rotationIndex = new WeakMap();
_rotationAxisIndex = new WeakMap();
_side = new WeakMap();
/** @type {[number, number][]} */
__privateAdd(_Rubiks, _axisDeltasMap, [
[3, 9],
[1, 9],
[1, 3]
]);
var Rubiks = _Rubiks;
// node_modules/rubiks-js/src/ui/ray.js
var _origin, _direction, _Ray_instances, intersectCube_fn;
var Ray = class {
/**
* @param {import('./camera').Camera} camera
* @param {number} x
* @param {number} y
* @param {number} width
* @param {number} height
*/
constructor(camera, x, y, width, height) {
__privateAdd(this, _Ray_instances);
/** @type {V3} */
__privateAdd(this, _origin);
/** @type {V3} */
__privateAdd(this, _direction);
const u = (x + 0.5) / width * 2 - 1;
const v = (height - y + 0.5) / height * 2 - 1;
__privateSet(this, _origin, camera.cameraToWorldMatrix.mult(new V4(0, 0, 0, 1)).toV3());
const d1 = camera.projectionMatrixInverse.mult(new V4(u, v, 0, 1));
const d2 = camera.cameraToWorldMatrix.mult(new V4(d1.x, d1.y, d1.z, 0));
__privateSet(this, _direction, d2.toV3().normalized);
}
/** @param {import('./rubiks').Rubiks} rubiks */
intersectRubiks(rubiks) {
return rubiks.cubies.map((cubie) => __privateMethod(this, _Ray_instances, intersectCube_fn).call(this, cubie)).flat(1);
}
/**
* @param {import('./facelet').Facelet} facelet
* @returns {{
* inside: false
* } | {
* inside: true,
* facelet: import('./facelet').Facelet,
* d: number
* }}
*/
intersectFacelet(facelet) {
const { normal, top, left, topLeft, bottomRight } = facelet.transform;
const denom = __privateGet(this, _direction).dot(normal);
if (denom === 0) {
return { inside: false };
}
const d = topLeft.sub(__privateGet(this, _origin)).dot(normal) / denom;
const intersection = __privateGet(this, _origin).add(__privateGet(this, _direction).scale(d));
const fromTopLeft = intersection.sub(topLeft).normalized;
const fromBottomRight = intersection.sub(bottomRight).normalized;
const dot1 = fromTopLeft.dot(left);
const dot2 = fromTopLeft.dot(top);
const dot3 = fromBottomRight.dot(left.negate);
const dot4 = fromBottomRight.dot(top.negate);
const inside = dot1 <= 1 && dot1 >= 0 && dot2 <= 1 && dot2 >= 0 && dot3 <= 1 && dot3 >= 0 && dot4 <= 1 && dot4 >= 0;
if (!inside) {
return { inside: false };
}
return {
inside,
facelet,
d
};
}
};
_origin = new WeakMap();
_direction = new WeakMap();
_Ray_instances = new WeakSet();
/** @param {import('./cubie').Cubie} cubie */
intersectCube_fn = function(cubie) {
return cubie.facelets.reduce((acc, facelet) => {
const hit = this.intersectFacelet(facelet);
if (hit.inside) {
acc.push({ facelet: hit.facelet, d: hit.d });
}
return acc;
}, []);
};
// node_modules/rubiks-js/src/ui/inputHandler.js
var _a, _b, _c, _d, _e, _canvas, _rubiks, _camera, _maxZoom, _minZoom, _pointers, _action, _InputHandler_instances, setAction_fn, _pointerDown, _InputHandler_static, getPointerDown_fn, _pointerMove, getPointerMove_fn, _pointerUp, getPointerUp_fn, _pointerLeave, getPointerLeave_fn, _wheel, getWheel_fn, startActionRotatingSide_fn, actionRotatingSide_fn, startActionRotatingCube_fn, actionRotatingCube_fn, startActionGesture_fn, actionGesture_fn, actionHovering_fn, getTurnDirection_fn, rotateSide_fn, rotateCube_fn, zoomCube_fn, getZoom_fn;
var _InputHandler = class _InputHandler {
/**
* @param {HTMLCanvasElement} canvas
* @param {import('./rubiks').Rubiks} rubiks
* @param {import('./camera').Camera} camera
*/
constructor(canvas, rubiks, camera) {
__privateAdd(this, _InputHandler_instances);
/** @type {HTMLCanvasElement} */
__privateAdd(this, _canvas);
/** @type {import('./rubiks').Rubiks} */
__privateAdd(this, _rubiks);
/** @type {import('./camera').Camera} */
__privateAdd(this, _camera);
/** @readonly */
__privateAdd(this, _maxZoom, 40);
/** @readonly */
__privateAdd(this, _minZoom, 10);
/** @type {Map<number, PointerEvent>} */
__privateAdd(this, _pointers, /* @__PURE__ */ new Map());
/** @type {import('../types').Action} */
__privateAdd(this, _action, { type: "none" });
// event handlers
__privateAdd(this, _pointerDown, __privateMethod(_a = _InputHandler, _InputHandler_static, getPointerDown_fn).call(_a, this));
__privateAdd(this, _pointerMove, __privateMethod(_b = _InputHandler, _InputHandler_static, getPointerMove_fn).call(_b, this));
__privateAdd(this, _pointerUp, __privateMethod(_c = _InputHandler, _InputHandler_static, getPointerUp_fn).call(_c, this));
__privateAdd(this, _pointerLeave, __privateMethod(_d = _InputHandler, _InputHandler_static, getPointerLeave_fn).call(_d, this));
__privateAdd(this, _wheel, __privateMethod(_e = _InputHandler, _InputHandler_static, getWheel_fn).call(_e, this));
__privateSet(this, _canvas, canvas);
__privateSet(this, _rubiks, rubiks);
__privateSet(this, _camera, camera);
}
addEventListeners() {
__privateGet(this, _canvas).addEventListener("pointermove", __privateGet(this, _pointerMove));
__privateGet(this, _canvas).addEventListener("pointerdown", __privateGet(this, _pointerDown));
__privateGet(this, _canvas).addEventListener("pointerup", __privateGet(this, _pointerUp));
__privateGet(this, _canvas).addEventListener("pointerleave", __privateGet(this, _pointerLeave));
__privateGet(this, _canvas).addEventListener("wheel", __privateGet(this, _wheel));
}
removeEventListeners() {
__privateGet(this, _canvas).removeEventListener("pointermove", __privateGet(this, _pointerMove));
__privateGet(this, _canvas).removeEventListener("pointerdown", __privateGet(this, _pointerDown));
__privateGet(this, _canvas).removeEventListener("pointerup", __privateGet(this, _pointerUp));
__privateGet(this, _canvas).removeEventListener("pointerleave", __privateGet(this, _pointerLeave));
__privateGet(this, _canvas).removeEventListener("wheel", __privateGet(this, _wheel));
}
};
_canvas = new WeakMap();
_rubiks = new WeakMap();
_camera = new WeakMap();
_maxZoom = new WeakMap();
_minZoom = new WeakMap();
_pointers = new WeakMap();
_action = new WeakMap();
_InputHandler_instances = new WeakSet();
/** @param {import('../types').Action} action */
setAction_fn = function(action) {
if (__privateGet(this, _action).type === "hovering") {
__privateGet(this, _action).facelet.hovering = false;
}
if (action.type === "hovering") {
action.facelet.hovering = true;
}
if (__privateGet(this, _action).type === "rotatingSide" && __privateGet(this, _action).side) {
const info = __privateGet(this, _action)[__privateGet(this, _action).side];
const angle = Math.round(info.angle / 90);
__privateGet(this, _rubiks).finishRotation(info.axis, info.index, angle, __privateGet(this, _action).facelet.side);
}
__privateSet(this, _action, action);
};
_pointerDown = new WeakMap();
_InputHandler_static = new WeakSet();
getPointerDown_fn = function(inputHandler) {
return (event) => {
var _a3, _b2, _c2, _d2, _e2;
const { offsetX, offsetY, pointerId } = event;
if (event.button === 0) {
__privateGet(inputHandler, _pointers).set(pointerId, event);
} else if (event.button === 1) {
__privateGet(inputHandler, _pointers).set(pointerId, event);
__privateMethod(_a3 = inputHandler, _InputHandler_instances, setAction_fn).call(_a3, {
type: "rotatingCube",
mouse: new V2(offsetX, offsetY)
});
return;
}
if (__privateGet(inputHandler, _pointers).size === 1) {
if (__privateGet(inputHandler, _rubiks).isTurning) {
return;
}
if (__privateGet(inputHandler, _action).type === "none") {
__privateMethod(_b2 = inputHandler, _InputHandler_instances, actionHovering_fn).call(_b2, offsetX, offsetY);
}
if (__privateGet(inputHandler, _action).type === "hovering") {
__privateMethod(_c2 = inputHandler, _InputHandler_instances, startActionRotatingSide_fn).call(_c2, offsetX, offsetY, __privateGet(inputHandler, _action).facelet);
return;
}
__privateMethod(_d2 = inputHandler, _InputHandler_instances, startActionRotatingCube_fn).call(_d2, offsetX, offsetY);
} else if (__privateGet(inputHandler, _pointers).size === 2) {
__privateMethod(_e2 = inputHandler, _InputHandler_instances, startActionGesture_fn).call(_e2);
}
};
};
_pointerMove = new WeakMap();
getPointerMove_fn = function(inputHandler) {
return (event) => {
var _a3, _b2, _c2, _d2;
const { offsetX, offsetY } = event;
if (__privateGet(inputHandler, _pointers).size === 0) {
__privateMethod(_a3 = inputHandler, _InputHandler_instances, actionHovering_fn).call(_a3, offsetX, offsetY);
return;
}
__privateGet(inputHandler, _pointers).set(event.pointerId, event);
__privateMethod(_b2 = inputHandler, _InputHandler_instances, actionRotatingSide_fn).call(_b2, offsetX, offsetY);
__privateMethod(_c2 = inputHandler, _InputHandler_instances, actionRotatingCube_fn).call(_c2, offsetX, offsetY);
__privateMethod(_d2 = inputHandler, _InputHandler_instances, actionGesture_fn).call(_d2);
};
};
_pointerUp = new WeakMap();
getPointerUp_fn = function(inputHandler) {
return () => {
var _a3;
__privateGet(inputHandler, _pointers).clear();
__privateMethod(_a3 = inputHandler, _InputHandler_instances, setAction_fn).call(_a3, {
type: "none"
});
};
};
_pointerLeave = new WeakMap();
getPointerLeave_fn = function(inputHandler) {
return () => {
var _a3;
__privateGet(inputHandler, _pointers).clear();
__privateMethod(_a3 = inputHandler, _InputHandler_instances, setAction_fn).call(_a3, {
type: "none"
});
};
};
_wheel = new WeakMap();
getWheel_fn = function(inputHandler) {
return ({ deltaY, deltaMode }) => {
var _a3;
if (deltaMode !== WheelEvent.DOM_DELTA_PIXEL) {
return;
}
const d = clamp(deltaY / 102, -1, 1) * 0.1;
__privateMethod(_a3 = inputHandler, _InputHandler_instances, zoomCube_fn).call(_a3, d);
};
};
// actions
// rotating side
/**
* @param {number} offsetX
* @param {number} offsetY
* @param {import('./facelet').Facelet} hovering
*/
startActionRotatingSide_fn = function(offsetX, offsetY, hovering) {
const { left, top, topLeft } = hovering.transform;
const screenTopLeft = __privateGet(this, _camera).worldToScreen(topLeft);
const screenBottomLeft = __privateGet(this, _camera).worldToScreen(topLeft.add(left));
const screenTopRight = __privateGet(this, _camera).worldToScreen(topLeft.add(top));
const rightDir = screenTopRight.sub(screenTopLeft).normalized;
const downDir = screenBottomLeft.sub(screenTopLeft).normalized;
const rubiksRotation = __privateGet(this, _rubiks).transform;
const side = hovering.side;
const currentAxis = Math.floor(side / 2);
const cubie = hovering.transform.parent;
const [axis1, axis2] = [0, 1, 2].filter((axis) => axis !== currentAxis).map((axis) => {
const rotationAxis2 = V3.getRotationAxis(axis);
const rubiksRotationAxis = rubiksRotation.apply(rotationAxis2);
const index = Math.floor(cubie.index / Math.pow(3, axis)) % 3;
const info = {
default: rubiksRotationAxis,
inverted: rubiksRotationAxis.negate,
axis,
index
};
return info;
});
const sideInvertMap = [
false,
true,
true,
false,
false,
true
];
const invert = sideInvertMap[hovering.side];
const mouse = new V2(offsetX, __privateGet(this, _canvas).height - offsetY);
if (Math.abs(axis1.default.dot(top)) > 0.99) {
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "rotatingSide",
mouse,
down: __privateMethod(this, _InputHandler_instances, getTurnDirection_fn).call(this, axis1, top, downDir, true !== invert),
right: __privateMethod(this, _InputHandler_instances, getTurnDirection_fn).call(this, axis2, left, rightDir, false !== invert),
side: null,
facelet: hovering
});
} else {
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "rotatingSide",
mouse,
down: __privateMethod(this, _InputHandler_instances, getTurnDirection_fn).call(this, axis2, top, downDir, true !== invert),
right: __privateMethod(this, _InputHandler_instances, getTurnDirection_fn).call(this, axis1, left, rightDir, false !== invert),
side: null,
facelet: hovering
});
}
};
/**
* @param {number} offsetX
* @param {number} offsetY
*/
actionRotatingSide_fn = function(offsetX, offsetY) {
if (__privateGet(this, _action).type !== "rotatingSide") {
return;
}
const mouse = new V2(offsetX, __privateGet(this, _canvas).height - offsetY);
if (__privateGet(this, _action).mouse.sub(mouse).mag < 10) {
return;
}
const initialMouse = __privateGet(this, _action).mouse;
if (__privateGet(this, _action).side) {
__privateMethod(this, _InputHandler_instances, rotateSide_fn).call(this, mouse, __privateGet(this, _action)[__privateGet(this, _action).side], initialMouse);
return;
}
const { right, down } = __privateGet(this, _action);
const mouseDir = mouse.sub(initialMouse).normalized;
const rightDot = right.dir.dot(mouseDir);
const downDot = down.dir.dot(mouseDir);
if (Math.abs(rightDot) > Math.abs(downDot)) {
__privateGet(this, _action).side = "right";
__privateGet(this, _rubiks).startRotation(right.cubies, right.rotationAxis);
__privateMethod(this, _InputHandler_instances, rotateSide_fn).call(this, mouse, right, initialMouse);
} else {
__privateGet(this, _action).side = "down";
__privateGet(this, _rubiks).startRotation(down.cubies, down.rotationAxis);
__privateMethod(this, _InputHandler_instances, rotateSide_fn).call(this, mouse, down, initialMouse);
}
};
// rotating cube
/**
* @param {number} offsetX
* @param {number} offsetY
*/
startActionRotatingCube_fn = function(offsetX, offsetY) {
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "rotatingCube",
mouse: new V2(offsetX, offsetY)
});
};
/**
* @param {number} offsetX
* @param {number} offsetY
*/
actionRotatingCube_fn = function(offsetX, offsetY) {
if (__privateGet(this, _action).type !== "rotatingCube") {
return;
}
const mouse = new V2(offsetX, offsetY);
const delta = mouse.sub(__privateGet(this, _action).mouse);
__privateGet(this, _action).mouse = mouse;
__privateMethod(this, _InputHandler_instances, rotateCube_fn).call(this, delta);
};
// two pointer gesture
startActionGesture_fn = function() {
const [e1, e2] = __privateGet(this, _pointers).values();
const dx = e1.screenX - e2.screenX;
const dy = e1.screenY - e2.screenY;
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "gesture",
distance: dx * dx + dy * dy,
center: new V2(e1.screenX + e2.screenX, e1.screenY + e2.screenY).scale(0.5)
});
};
actionGesture_fn = function() {
if (__privateGet(this, _action).type !== "gesture") {
return;
}
const [e1, e2] = __privateGet(this, _pointers).values();
const dx = e1.screenX - e2.screenX;
const dy = e1.screenY - e2.screenY;
const distance = dx * dx + dy * dy;
const deltaDistance = distance - __privateGet(this, _action).distance;
__privateGet(this, _action).distance = distance;
const d = clamp(deltaDistance / 1e3, -1, 1) * -0.02;
__privateMethod(this, _InputHandler_instances, zoomCube_fn).call(this, d);
const center = new V2(e1.screenX + e2.screenX, e1.screenY + e2.screenY).scale(0.5);
const deltaCenter = center.sub(__privateGet(this, _action).center);
__privateGet(this, _action).center = center;
__privateMethod(this, _InputHandler_instances, rotateCube_fn).call(this, deltaCenter);
};
// hovering
/**
* @param {number} offsetX
* @param {number} offsetY
*/
actionHovering_fn = function(offsetX, offsetY) {
const ray = new Ray(__privateGet(this, _camera), offsetX, offsetY, window.innerWidth, window.innerHeight);
const facelets = ray.intersectRubiks(__privateGet(this, _rubiks));
if (facelets.length) {
facelets.sort((a, b) => a.d - b.d);
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "hovering",
facelet: facelets[0].facelet
});
} else {
__privateMethod(this, _InputHandler_instances, setAction_fn).call(this, {
type: "none"
});
}
};
// action helpers
// rotating side
/**
* @param {import('../types').AxisInfo} axisInfo
* @param {V3} vector
* @param {V2} dir
* @param {boolean} invert
* @returns {import('../types').SideInfo}
*/
getTurnDirection_fn = function(axisInfo, vector, dir, invert) {
if (axisInfo.default.dot(vector) > 0.99)
return {
dir,
angle: 0,
axis: axisInfo.axis,
rotationAxis: V3.getRotationAxis(axisInfo.axis).scale(invert ? -1 : 1),
index: axisInfo.index,
cubies: __privateGet(this, _rubiks).getPlane(axisInfo.axis, axisInfo.index)
};
return {
dir,
angle: 0,
axis: axisInfo.axis,
rotationAxis: V3.getRotationAxis(axisInfo.axis).scale(invert ? 1 : -1),
index: axisInfo.index,
cubies: __privateGet(this, _rubiks).getPlane(axisInfo.axis, axisInfo.index)
};
};
/**
* @param {V2} mouse
* @param {import('../types').SideInfo} info
* @param {V2} initialMouse
*/
rotateSide_fn = function(mouse, info, initialMouse) {
const length = info.dir.dot(initialMouse.sub(mouse));
const zoom = __privateMethod(this, _InputHandler_instances, getZoom_fn).call(this);
info.angle = length / (3 - zoom * 2);
__privateGet(this, _rubiks).rotateManual(info.angle);
};
// rotating cube
/** @param {V2} delta */
rotateCube_fn = function(delta) {
if (delta.x === 0 && delta.y === 0) {
return;
}
const n = __privateGet(this, _camera).up.scale(delta.y).add(__privateGet(this, _camera).right.scale(delta.x));
const axis = __privateGet(this, _camera).forward.cross(n);
const zoom = __privateMethod(this, _InputHandler_instances, getZoom_fn).call(this);
const angle = Math.sqrt(delta.x * delta.x + delta.y * delta.y) * 0.3 + 2 * zoom;
__privateGet(this, _rubiks).transform.rotate(axis, angle);
};
// zooming camera
/** @param {number} d */
zoomCube_fn = function(d) {
const { position } = __privateGet(this, _camera);
__privateGet(this, _camera).position = new V3(0, 0, clamp(position.z * (1 + d), -__privateGet(this, _maxZoom), -__privateGet(this, _minZoom)));
};
getZoom_fn = function() {
const zoom = -__privateGet(this, _camera).position.z;
const minZoom = __privateGet(this, _minZoom);
const maxZoom = __privateGet(this, _maxZoom);
return (zoom - minZoom) / (maxZoom - minZoom);
};
__privateAdd(_InputHandler, _InputHandler_static);
var InputHandler = _InputHandler;
// node_modules/rubiks-js/src/ui/debugger.js
var _ctx, _canvas2, _strokeColor, _fillColor, _Debugger_static, flipVector_fn;
var _Debugger = class _Debugger {
/**
* @param {Element?} canvas
*/
constructor(canvas) {
/** @type {CanvasRenderingContext2D?} */
__privateAdd(this, _ctx);
/** @type {HTMLCanvasElement?} */
__privateAdd(this, _canvas2);
__privateAdd(this, _strokeColor, "white");
__privateAdd(this, _fillColor, "white");
if (!canvas) {
return;
}
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error(`rubiks cube debugger is not a canvas, it is a <${canvas.tagName}>`);
}
__privateSet(this, _canvas2, canvas);
const ctx = canvas.getContext("2d");
if (!ctx)
throw new Error("cannot create 2d context for rubiks cube debugger");
__privateSet(this, _ctx, ctx);
}
clear() {
if (__privateGet(this, _ctx) && __privateGet(this, _canvas2)) {
__privateGet(this, _ctx).clearRect(0, 0, __privateGet(this, _canvas2).width, __privateGet(this, _canvas2).height);
}
}
/** @param {string} color */
stroke(color) {
__privateSet(this, _strokeColor, color);
}
/** @param {string} color */
fill(color) {
__privateSet(this, _fillColor, color);
}
/**
* @param {V2} from
* @param {V2} to
*/
line(from, to) {
var _a3, _b2;
if (__privateGet(this, _ctx) && __privateGet(this, _canvas2)) {
__privateGet(this, _ctx).strokeStyle = __privateGet(this, _strokeColor);
__privateGet(this, _ctx).lineWidth = 3;
const fromF = __privateMethod(_a3 = _Debugger, _Debugger_static, flipVector_fn).call(_a3, from, __privateGet(this, _canvas2));
const toF = __privateMethod(_b2 = _Debugger, _Debugger_static, flipVector_fn).call(_b2, to, __privateGet(this, _canvas2));
__privateGet(this, _ctx).beginPath();
__privateGet(this, _ctx).moveTo(fromF.x, fromF.y);
__privateGet(this, _ctx).lineTo(toF.x, toF.y);
__privateGet(this, _ctx).stroke();
}
}
/**
* @param {V2} origin
* @param {V2} direction
* @param {number} [length=1]
*/
vector(origin, direction, length = 1) {
this.line(origin, origin.add(direction.scale(length)));
}
/**
* @param {number} width
* @param {number} height
*/
setSize(width, height) {
if (__privateGet(this, _canvas2)) {
__privateGet(this, _canvas2).width = width;
__privateGet(this, _canvas2).height = height;
}
}
/**
* @param {V2} pos
* @param {string} text
*/
text(pos, text) {
if (__privateGet(this, _ctx)) {
__privateGet(this, _ctx).fillStyle = __privateGet(this, _fillColor);
__privateGet(this, _ctx).fillText(text, pos.x, pos.y);
}
}
};
_ctx = new WeakMap();
_canvas2 = new WeakMap();
_strokeColor = new WeakMap();
_fillColor = new WeakMap();
_Debugger_static = new WeakSet();
flipVector_fn = function({ x, y }, canvas) {
return new V2(x, canvas.height - y);
};
__privateAdd(_Debugger, _Debugger_static);
var Debugger = _Debugger;
var debugger_default = new Debugger(document.querySelector("[data-rubiks-cube-debug]"));
// node_modules/rubiks-js/src/shaders/facelet.glsl.js
var vertex = `#version 300 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aUV;
out vec2 uv;
out vec2 pos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
uv = aUV;
pos = aPos.yz;
}`;
var fragment = `#version 300 es
precision mediump float;
in vec2 uv;
in vec2 pos;
out vec4 FragColor;
uniform sampler2D tex;
uniform vec3 colorMult;
vec3 rime = vec3(0.07);
float outer = 0.45;
float inner = 0.44;
float map(float value, float min1, float max1, float min2, float max2)
{
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
void main()
{
float x = abs(pos.x);
float y = abs(pos.y);
if (x > outer || y > outer) {
FragColor = vec4(rime, 1.0);
return;
}
vec3 color = texture(tex, uv).rgb * colorMult;
if (x > inner || y > inner) {
float t = smoothstep(0.0, 1.0, map(max(x, y), outer, inner, 0.0, 1.0));
vec3 c = color * t + rime * (1.0 - t);
FragColor = vec4(c, 1.0);
return;
}
FragColor = vec4(color, 1.0);
}`;
// node_modules/rubiks-js/src/events.js
var ChangeEvent = class {
/**
* @param {number} axis
* @param {number} index
* @param {number} angle
* @param {import('./state/types').Turn} turn
* @param {import('./state').StateInfo} state
*/
constructor(axis, index, angle, turn, state) {
/**
* Axis that was turned around
*
* 0 => x-axis (from right to left)
*
* 1 => y-axis (from bottom to top)
*
* 2 => z-axis (from front to back)
* @type {0 | 1 | 2}
*/
__publicField(this, "axis");
/**
* The slice on the axis. Example using axis = 0:
*
* 0 => Left slice
*
* 2 => Right slice
*
* The middle layer is never turned. Instead both outer layers are turn
* in the opposite direction. This has the same effect.
* That way the centers always stay in the same position.
* @type {0 | 2}
*/
__publicField(this, "index");
/**
* Important: The angle is always clockwise around the axis and not
* clockwise around the turning side. This means that R and L' both
* have an angle of 1
* @type {1 | 2 | 3}
*/
__publicField(this, "angle");
/**
* @type {import('./state/types').Turn}
*/
__publicField(this, "turn");
/**
* @type {import('./state').StateInfo}
*/
__publicField(this, "state");
this.axis = /** @type {0 | 1 | 2} */
axis;
this.index = /** @type {0 | 2} */
index;
this.angle = /** @type {1 | 2 | 3} */
angle;
this.turn = turn;
this.state = state;
}
};
// node_modules/rubiks-js/src/rubiksCube.js
var _a2, _initialized, _gl, _canvas3, _program, _vao, _uvsVbo, _texture, _camera2, _rubiks2, _inputHandler, _state, _trackCenters, _frame, _resizeHandler, _canvasData, _image, _uvs, _hoveringColors, _RubiksCube_static, getResizeHandler_fn, _RubiksCube_instances, initialize_fn, _listeners, turnHandler_fn;
var _RubiksCube = class _RubiksCube {
/**
* @param {string} canvasData
* @param {ImageData | HTMLImageElement} image
* @param {number[][][]} uvs
* @param {number[][]} hoveringColors
* @param {boolean} trackCenters
*/
constructor(canvasData, image, uvs, hoveringColors, trackCenters) {
__privateAdd(this, _RubiksCube_instances);
__privateAdd(this, _initialized, false);
/** @type {WebGL2RenderingContext} */
__privateAdd(this, _gl);
/** @type {HTMLCanvasElement} */
__privateAdd(this, _canvas3);
/** @type {Program} */
__privateAdd(this, _program);
/** @type {WebGLVertexArrayObject} */
__privateAdd(this, _vao);
/** @type {WebGLBuffer} */
__privateAdd(this, _uvsVbo);
/** @type {WebGLTexture} */
__privateAdd(this, _texture);
/** @type {Camera} */
__privateAdd(this, _camera2);
/** @type {Rubiks} */
__privateAdd(this, _rubiks2);
/** @type {InputHandler} */
__privateAdd(this, _inputHandler);
/** @type {State} */
__privateAdd(this, _state);
/** @type {boolean} */
__privateAdd(this, _trackCenters);
__privateAdd(this, _frame, 0);
__privateAdd(this, _resizeHandler, __privateMethod(_a2 = _RubiksCube, _RubiksCube_static, getResizeHandler_fn).call(_a2, this));
/** @type {string} */
__privateAdd(this, _canvasData);
/** @type {ImageData | HTMLImageElement} */
__privateAdd(this, _image);
/** @type {number[][][]} */
__privateAdd(this, _uvs);
/** @type {number[][]} */
__privateAdd(this, _hoveringColors);
/** @type {Map<keyof Events, Set<(event: any) => void>>} */
__privateAdd(this, _listeners, /* @__PURE__ */ new Map());
__privateSet(this, _canvasData, canvasData);
__privateSet(this, _image, image);
__privateSet(this, _uvs, uvs);
__privateSet(this, _hoveringColors, hoveringColors);
__privateSet(this, _trackCenters, trackCenters);
}
/**
* Starts rendering the cube and listening for user inputs.
* Automaticly initializes webgl and pointer event listeners.
*/
start() {
if (!__privateGet(this, _initialized)) {
__privateMethod(this, _RubiksCube_instances, initialize_fn).call(this);
__privateSet(this, _initialized, true);
}
__privateGet(this, _inputHandler).addEventListeners();
window.addEventListener("resize", __privateGet(this, _resizeHandler));
__privateGet(this, _resizeHandler).call(this);
__privateGet(this, _program).use();
__privateGet(this, _gl).bindVertexArray(__privateGet(this, _vao));
__privateGet(this, _gl).activeTexture(__privateGet(this, _gl).TEXTURE0);
__privateGet(this, _gl).bindTexture(__privateGet(this, _gl).TEXTURE_2D, __privateGet(this, _texture));
__privateGet(this, _program).uniform("tex", {
setUniform: (gl, location) => gl.uniform1i(location, 0)
});
let lastTime = Date.now();
const loop = () => {
const currentTime = Date.now();
const deltaTime = (currentTime - lastTime) / 1e3;
lastTime = currentTime;
__privateGet(this, _gl).clear(__privateGet(this, _gl).COLOR_BUFFER_BIT | __privateGet(this, _gl).DEPTH_BUFFER_BIT);
__privateGet(this, _program).uniform("view", __privateGet(this, _camera2).worldToCameraMatrix);
__privateGet(this, _program).uniform("projection", __privateGet(this, _camera2).projectionMatrix);
__privateGet(this, _rubiks2).render(__privateGet(this, _program), __privateGet(this, _gl), __privateGet(this, _uvsVbo));
__privateGet(this, _rubiks2).update(deltaTime);
__privateSet(this, _frame, requestAnimationFrame(loop));
};
__privateSet(this, _frame, requestAnimationFrame(loop));
}
/**
* Stops rendering the cube and removes all listeners.
*/
stop() {
window.removeEventListener("resize", __privateGet(this, _resizeHandler));
cancelAnimationFrame(__privateGet(this, _frame));
__privateGet(this, _inputHandler).removeEventListeners();
}
/**
* Resets the internal state and applys it to the cube.
*/
reset() {
__privateGet(this, _state).reset();
__privateGet(this, _state).applyState(__privateGet(this, _uvs), __privateGet(this, _rubiks2));
}
/**
* @param {string} stateStr a base46 representation
* @returns {boolean} false if `stateStr` was invalid
*/
setState(stateStr) {
if (!__privateGet(this, _initialized)) {
__privateMethod(this, _RubiksCube_instances, initialize_fn).call(this);
__privateSet(this, _initialized, true);
}
if (!__privateGet(this, _state).decode(stateStr)) {
return false;
}
__privateGet(this, _state).applyState(__privateGet(this, _uvs), __privateGet(this, _rubiks2));
return true;
}
get transform() {
return __privateGet(this, _rubiks2).transform;
}
/**
* @template {keyof Events} Name
* @param {Name} name
* @param {(event: Events[Name]) => void} callback
*/
on(name, callback) {
const set = __privateGet(this, _listeners).get(name) ?? /* @__PURE__ */ new Set();
set.add(callback);
__privateGet(this, _listeners).set(name, set);
}
};
_initialized = new WeakMap();
_gl = new WeakMap();
_canvas3 = new WeakMap();
_program = new WeakMap();
_vao = new WeakMap();
_uvsVbo = new WeakMap();
_texture = new WeakMap();
_camera2 = new WeakMap();
_rubiks2 = new WeakMap();
_inputHandler = new WeakMap();
_state = new WeakMap();
_trackCenters = new WeakMap();
_frame = new WeakMap();
_resizeHandler = new WeakMap();
_canvasData = new WeakMap();
_image = new WeakMap();
_uvs = new WeakMap();
_hoveringColors = new WeakMap();
_RubiksCube_static = new WeakSet();
getResizeHandler_fn = function(rubiksCube) {
return () => {
const width = window.innerWidth;
const height = window.innerHeight;
debugger_default.setSize(width, height);
__privateGet(rubiksCube, _canvas3).width = width;
__privateGet(rubiksCube, _canvas3).height = height;
__privateGet(rubiksCube, _gl).viewport(0, 0, width, height);
__privateGet(rubiksCube, _camera2).screenSize(width, height);
};
};
_RubiksCube_instances = new WeakSet();
initialize_fn = function() {
const canvas = document.querySelector(`[${__privateGet(this, _canvasData)}]`);
if (!canvas) {
throw new Error(`<canvas ${__privateGet(this, _canvasData)}> does not exist`);
}
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error(`<canvas ${__privateGet(this, _canvasData)}> is not a canvas, it is a <${canvas.tagName}>`);
}
__privateSet(this, _canvas3, canvas);
const gl = canvas.getContext("webgl2");
if (!gl) {
throw new Error(`cannot create webgl2 context`);
}
__privateSet(this, _gl, gl);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LESS);
__privateSet(this, _program, new Program("rubiksCube/shaders/facelet.glsl", vertex, fragment, gl));
const vao = gl.createVertexArray();
if (!vao) {
throw new Error("could not create a webgl vertex array object");
}
__privateSet(this, _vao, vao);
gl.bindVertexArray(vao);
const vertices = [
0,
-0.5,
-0.5,
0,
-0.5,
0.5,
0,
0.5,
0.5,
0,
0.5,
-0.5
];
const verticesBuffer = new Float32Array(vertices);
const verticesVbo = gl.createBuffer();
const indices = [
0,
1,
3,
1,
3,
2
];
const indicesBuffer = new Int8Array(indices);
const ebo = gl.createBuffer();
const uvsVbo = gl.createBuffer();
if (!verticesVbo || !ebo || !uvsVbo) {
throw new Error("could not create a vertex buffer objects");
}
__privateSet(this, _uvsVbo, uvsVbo);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, verticesVbo);
gl.bufferData(gl.ARRAY_BUFFER, verticesBuffer, gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 12, 0);
gl.enableVertexAttribArray(0);
gl.enableVertexAttribArray(1);
gl.bindVertexArray(null);
const texture = gl.createTexture();
if (!texture) {
throw new Error("could not create a texture");
}
__privateSet(this, _texture, texture);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
__privateGet(this, _image)
);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
const hoveringColors = __privateGet(this, _hoveringColors).map(([r, g, b]) => new V3(r, g, b));
__privateSet(this, _camera2, new Camera(new V3(0, 0, -10), V3.zero, V3.up, 45, window.innerWidth, window.innerHeight, 0.1, 100));
__privateSet(this, _rubiks2, new Rubiks(Quaternion.identity, __privateGet(this, _uvs), hoveringColors, __privateMethod(this, _RubiksCube_instances, turnHandler_fn).bind(this)));
__privateSet(this, _inputHandler, new InputHandler(canvas, __privateGet(this, _rubiks2), __privateGet(this, _camera2)));
__privateSet(this, _state, new State(__privateGet(this, _trackCenters)));
};
_listeners = new WeakMap();
/**
* @param {import('./types').AIA} aia
*/
turnHandler_fn = function(aia) {
const turn = convertAiaToTurn(aia);
__privateGet(this, _state).applyTurn(turn);
const changeHandlers = __privateGet(this, _listeners).get("change");
if (changeHandlers) {
const event = new ChangeEvent(
aia.axis,
aia.index,
aia.angle,
turn,
__privateGet(this, _state).stateInfo
);
for (const callback of changeHandlers) {
callback(event);
}
}
};
__privateAdd(_RubiksCube, _RubiksCube_static);
var RubiksCube = _RubiksCube;
// node_modules/rubiks-js/src/index.js
var defaultTexture = new ImageData(new Uint8ClampedArray([
0,
0,
255,
255,
0,
255,
0,
255,
255,
255,
0,
255,
255,
255,
255,
255,
255,
0,
0,
255,
255,
127,
0,
255
]), 1, 6);
var defaultUVs = Array(6).fill(null).map((_, index) => {
return Array(9).fill([
0,
(index + 0) / 6,
1,
(index + 0) / 6,
1,
(index + 1) / 6,
0,
(index + 1) / 6
]);
});
var defaultHovorvingColors = Array(6).fill(Array(3).fill(0.7));
export {
RubiksCube,
defaultHovorvingColors,
defaultTexture,
defaultUVs
};
//# sourceMappingURL=rubiks-js.js.map