@rednaxela101/cubing 0.63.8 → 0.63.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +5 -5
  2. package/dist/bin/chunks/{chunk-EWR23OA4.js → chunk-3WUR6UXA.js} +2 -2
  3. package/dist/bin/order.js +1 -1
  4. package/dist/bin/puzzle-geometry-bin.js +1 -1
  5. package/dist/bin/scramble.js +1 -1
  6. package/dist/bin/svg.js +1 -1
  7. package/dist/lib/cubing/alg/index.d.ts +1 -1
  8. package/dist/lib/cubing/bluetooth/index.d.ts +2 -2
  9. package/dist/lib/cubing/chunks/{chunk-B2YKAP2I.js → chunk-IOHGEWB2.js} +2 -2
  10. package/dist/lib/cubing/chunks/{twisty-dynamic-3d-SLKSUJTE.js → twisty-dynamic-3d-3MGVD3TG.js} +928 -334
  11. package/dist/lib/cubing/chunks/twisty-dynamic-3d-3MGVD3TG.js.map +7 -0
  12. package/dist/lib/cubing/{index-ylnTp4i5.d.ts → index-0OM9yjf0.d.ts} +1 -1
  13. package/dist/lib/cubing/{index-FT5_Vsnm.d.ts → index-B_TS5TTk.d.ts} +13 -0
  14. package/dist/lib/cubing/kpuzzle/index.d.ts +1 -1
  15. package/dist/lib/cubing/notation/index.d.ts +1 -1
  16. package/dist/lib/cubing/{outside-D3tRtsxV.d.ts → outside-BUsE7O5Q.d.ts} +1 -1
  17. package/dist/lib/cubing/protocol/index.d.ts +1 -1
  18. package/dist/lib/cubing/puzzle-geometry/index.d.ts +1 -1
  19. package/dist/lib/cubing/puzzles/index.d.ts +1 -1
  20. package/dist/lib/cubing/scramble/index.d.ts +1 -1
  21. package/dist/lib/cubing/search/index.d.ts +1 -1
  22. package/dist/lib/cubing/stream/index.d.ts +1 -1
  23. package/dist/lib/cubing/twisty/index.d.ts +1 -1
  24. package/dist/lib/cubing/twisty/index.js +31 -2
  25. package/dist/lib/cubing/twisty/index.js.map +2 -2
  26. package/package.json +1 -1
  27. package/dist/lib/cubing/chunks/twisty-dynamic-3d-SLKSUJTE.js.map +0 -7
  28. /package/dist/bin/chunks/{chunk-EWR23OA4.js.map → chunk-3WUR6UXA.js.map} +0 -0
  29. /package/dist/lib/cubing/chunks/{chunk-B2YKAP2I.js.map → chunk-IOHGEWB2.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cubing/twisty/views/3D/puzzles/Cube3D.ts", "../../../../src/cubing/twisty/controllers/easing.ts", "../../../../src/cubing/twisty/views/3D/puzzles/BeveledCubieGeometry.ts", "../../../../src/cubing/twisty/views/3D/puzzles/CubieStyle.ts", "../../../../src/cubing/twisty/views/3D/puzzles/PuzzleLogo.ts", "../../../../src/cubing/twisty/views/3D/puzzles/CubePieces.ts", "../../../../src/cubing/twisty/views/3D/puzzles/StickerlessPlan.ts", "../../../../src/cubing/twisty/views/3D/puzzles/PG3D.ts", "../../../../src/cubing/twisty/views/3D/puzzles/SolidPieces.ts", "../../../../src/cubing/twisty/views/3D/puzzles/SolidPieceGeometry.ts", "../../../../src/cubing/twisty/views/3D/puzzles/Square1_3D.ts", "../../../../src/cubing/twisty/views/3D/puzzles/Stickerless3D.ts", "../../../../src/cubing/twisty/heavy-code-imports/dynamic-entries/twisty-dynamic-3d.ts", "../../../../src/cubing/twisty/views/3D/Twisty3DScene.ts"],
4
+ "sourcesContent": ["import { BackSide, DoubleSide, FrontSide } from \"three/src/constants.js\";\nimport { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Object3D } from \"three/src/core/Object3D.js\";\nimport { BoxGeometry } from \"three/src/geometries/BoxGeometry.js\";\nimport { TextureLoader } from \"three/src/loaders/TextureLoader.js\";\nimport type { Material } from \"three/src/materials/Material.js\";\nimport { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport { Color } from \"three/src/math/Color.js\";\nimport type { Euler } from \"three/src/math/Euler.js\";\nimport { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport { Quaternion } from \"three/src/math/Quaternion.js\";\nimport { Vector2 } from \"three/src/math/Vector2.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { Group } from \"three/src/objects/Group.js\";\nimport { Mesh } from \"three/src/objects/Mesh.js\";\nimport type { Texture } from \"three/src/textures/Texture.js\";\nimport type { KPuzzle } from \"../../../../kpuzzle\";\nimport type { ExperimentalStickeringMask } from \"../../../../puzzles/cubing-private\";\nimport type {\n FaceletMeshStickeringMask,\n StickeringMask,\n} from \"../../../../puzzles/stickerings/mask\";\nimport type {\n MillisecondTimestamp,\n PuzzlePosition,\n} from \"../../../controllers/AnimationTypes\";\nimport { smootherStep } from \"../../../controllers/easing\";\nimport type { FaceletScale } from \"../../../model/props/puzzle/display/FaceletScaleProp\";\nimport {\n type HintFaceletStyle,\n hintFaceletStyles,\n} from \"../../../model/props/puzzle/display/HintFaceletProp\";\nimport type { InitialHintFaceletsAnimation } from \"../../../model/props/puzzle/display/InitialHintFaceletsAnimationProp\";\nimport { TAU } from \"../TAU\";\nimport { haveStartedSharingRenderers } from \"../Twisty3DVantage\";\nimport { beveledCubieGeometry } from \"./BeveledCubieGeometry\";\nimport {\n bodyMaskColors,\n type CubeFaceStyle,\n cubeFaceStyles,\n cubieBodyDimensions,\n cubieBodyHalfExtent,\n hintMaskStyles,\n newBodyMaterial,\n} from \"./CubieStyle\";\nimport { newLogoMesh, rectangleLogoSurface, surfaceMatrix } from \"./PuzzleLogo\";\nimport type { Twisty3DPuzzle } from \"./Twisty3DPuzzle\";\n\nconst svgLoader = new TextureLoader();\n\nfunction newHintMaterial(style: {\n color: number;\n opacity: number;\n}): MeshBasicMaterial {\n return new MeshBasicMaterial({\n color: new Color(style.color).convertLinearToSRGB(),\n side: BackSide,\n transparent: true,\n opacity: style.opacity,\n });\n}\n\nconst ignoredMaterial = new MeshBasicMaterial({\n color: new Color(bodyMaskColors.ignored).convertLinearToSRGB(),\n});\n\nconst ignoredMaterialHint = newHintMaterial(hintMaskStyles.ignored);\n\nconst invisibleMaterial = new MeshBasicMaterial({\n visible: false,\n});\n\nconst orientedMaterial = new MeshBasicMaterial({\n color: bodyMaskColors.oriented,\n});\n\nconst orientedMaterialHint = newHintMaterial(hintMaskStyles.oriented);\n\nconst experimentalOriented2Material = new MeshBasicMaterial({\n color: bodyMaskColors.experimentalOriented2,\n});\n\nconst experimentalOriented2MaterialHint = newHintMaterial(\n hintMaskStyles.experimentalOriented2,\n);\n\nconst mysteryMaterial = new MeshBasicMaterial({\n color: bodyMaskColors.mystery,\n});\n\nconst mysterMaterialHint = newHintMaterial(hintMaskStyles.mystery);\n\nconst internalBodyMaterial = newBodyMaterial(bodyMaskColors.internal);\nconst ignoredBodyMaterial = newBodyMaterial(bodyMaskColors.ignored);\nconst orientedBodyMaterial = newBodyMaterial(bodyMaskColors.oriented);\nconst experimentalOriented2BodyMaterial = newBodyMaterial(\n bodyMaskColors.experimentalOriented2,\n);\nconst mysteryBodyMaterial = newBodyMaterial(bodyMaskColors.mystery);\n\ninterface MaterialMap<T extends Material = MeshBasicMaterial>\n extends Record<FaceletMeshStickeringMask, T> {\n regular: T;\n dim: T;\n ignored: T;\n invisible: T;\n}\n\nclass AxisInfo {\n public vector: Vector3;\n public fromZ: Euler;\n public stickerMaterial: MaterialMap;\n public hintStickerMaterial: MaterialMap;\n public bodyMaterial: MaterialMap;\n constructor(style: CubeFaceStyle) {\n const { color, dimColor, hintOpacityScale } = style;\n this.vector = style.vector;\n this.fromZ = style.fromZ;\n const colorLinearSRGB = new Color(color).convertLinearToSRGB();\n const dimColorLinearSRGB = new Color(dimColor).convertLinearToSRGB();\n // TODO: Make sticker material single-sided when cubie foundation is opaque?\n this.stickerMaterial = {\n regular: new MeshBasicMaterial({\n color: colorLinearSRGB,\n side: FrontSide, // TODO: set to `DoubleSide` when hint facelets are disabled.\n }),\n dim: new MeshBasicMaterial({\n color: dimColorLinearSRGB,\n side: FrontSide, // TODO: set to `DoubleSide` when hint facelets are disabled.\n }),\n oriented: orientedMaterial,\n experimentalOriented2: experimentalOriented2Material,\n ignored: ignoredMaterial,\n invisible: invisibleMaterial,\n mystery: mysteryMaterial,\n };\n this.hintStickerMaterial = {\n regular: newHintMaterial({\n color: style.hintColor,\n opacity: 0.5 * hintOpacityScale,\n }),\n dim: newHintMaterial({\n color: style.hintDimColor,\n opacity: 0.5 * hintOpacityScale,\n }),\n oriented: orientedMaterialHint,\n experimentalOriented2: experimentalOriented2MaterialHint,\n ignored: ignoredMaterialHint,\n invisible: invisibleMaterial,\n mystery: mysterMaterialHint,\n };\n this.bodyMaterial = {\n regular: newBodyMaterial(colorLinearSRGB),\n dim: newBodyMaterial(dimColorLinearSRGB),\n oriented: orientedBodyMaterial,\n experimentalOriented2: experimentalOriented2BodyMaterial,\n ignored: ignoredBodyMaterial,\n // A solid piece of plastic can't have a hole punched in it, so an\n // invisible facelet falls back to the internal plastic color.\n invisible: internalBodyMaterial,\n mystery: mysteryBodyMaterial,\n };\n }\n}\n\nconst axesInfo: AxisInfo[] = cubeFaceStyles.map((style) => new AxisInfo(style));\n\nconst face: { [s: string]: number } = {\n U: 0,\n L: 1,\n F: 2,\n R: 3,\n B: 4,\n D: 5,\n};\n\nconst familyToAxis: { [s: string]: number } = {\n U: face[\"U\"],\n u: face[\"U\"],\n Uw: face[\"U\"],\n Uv: face[\"U\"],\n y: face[\"U\"],\n L: face[\"L\"],\n l: face[\"L\"],\n Lw: face[\"L\"],\n Lv: face[\"L\"],\n M: face[\"L\"],\n F: face[\"F\"],\n f: face[\"F\"],\n Fw: face[\"F\"],\n Fv: face[\"F\"],\n S: face[\"F\"],\n z: face[\"F\"],\n R: face[\"R\"],\n r: face[\"R\"],\n Rw: face[\"R\"],\n Rv: face[\"R\"],\n x: face[\"R\"],\n B: face[\"B\"],\n b: face[\"B\"],\n Bw: face[\"B\"],\n Bv: face[\"B\"],\n D: face[\"D\"],\n d: face[\"D\"],\n Dw: face[\"D\"],\n Dv: face[\"D\"],\n E: face[\"D\"],\n};\n\nconst cubieDimensions = {\n // stickerWidth: 0.85, // Now `faceletScale` in options.\n stickerElevation: 0.503,\n foundationWidth: 1,\n defaultHintStickerElevation: 1.45,\n /**\n * How far back the eight corners of a `stickerless` cubie are shaved, from 0\n * (not at all) to 1 (all the way back to the edges). This is the only knob\n * that widens the notch where four pieces meet without also widening the\n * straight dividing lines.\n */\n bodyVertexCut: 0.45,\n};\n\n/**\n * The piece a logo is printed on: the white center, which is `CENTERS` piece 0\n * showing its only facelet.\n */\nconst LOGO_PIECE = { orbit: \"CENTERS\", ord: 0, faceletIdx: 0 };\n/** How far the logo floats off the face, in cubie widths. */\nconst LOGO_ELEVATION = 0.01;\n\nconst EXPERIMENTAL_PICTURE_CUBE_HINT_ELEVATION = 2;\n\n/**\n * - `stickers`: flat colored facelets floating above a black body.\n * - `stickerless`: solid beveled pieces of colored plastic, lit so that the\n * bevels read as volume. `showFoundation` and `faceletScale` do not apply,\n * since there is no separate foundation or sticker to size.\n */\nexport type ExperimentalCubieStyle = \"stickers\" | \"stickerless\";\n\nexport interface Cube3DOptions {\n showMainStickers?: boolean;\n experimentalCubieStyle?: ExperimentalCubieStyle;\n hintFacelets?: HintFaceletStyle;\n showFoundation?: boolean; // TODO: better name\n experimentalStickeringMask?: ExperimentalStickeringMask;\n foundationSprite?: Texture | null;\n hintSprite?: Texture | null;\n initialHintFaceletsAnimation?: InitialHintFaceletsAnimation;\n faceletScale?: \"auto\" | number;\n hintFaceletsElevation?: \"auto\" | number;\n}\n\nconst cube3DOptionsDefaults: Cube3DOptions = {\n showMainStickers: true,\n experimentalCubieStyle: \"stickerless\",\n hintFacelets: \"floating\",\n showFoundation: true,\n experimentalStickeringMask: undefined,\n foundationSprite: null,\n hintSprite: null,\n initialHintFaceletsAnimation: \"auto\",\n faceletScale: \"auto\",\n hintFaceletsElevation: \"auto\",\n};\n\nconst DEFAULT_STICKER_SCALE = 0.85;\nfunction getFaceletScale(options: Cube3DOptions): number {\n if (\n typeof options.faceletScale === \"undefined\" ||\n options.faceletScale === \"auto\"\n ) {\n return DEFAULT_STICKER_SCALE;\n }\n return options.faceletScale;\n}\n\n// TODO: Make internal foundation faces one-sided, facing to the outside of the cube.\nconst blackMesh = new MeshBasicMaterial({\n color: 0x000000,\n opacity: 1,\n transparent: true,\n});\n\nconst blackTranslucentMesh = new MeshBasicMaterial({\n color: 0x000000,\n opacity: 0.3,\n transparent: true,\n});\n\nclass CubieDef {\n public matrix: Matrix4;\n public stickerFaces: number[];\n // stickerFaceNames can be e.g. [\"U\", \"F\", \"R\"], \"UFR\" if every face is a single letter.\n constructor(\n public orbit: string,\n stickerFaceNames: string[] | string,\n q: Quaternion,\n ) {\n const individualStickerFaceNames =\n typeof stickerFaceNames === \"string\"\n ? stickerFaceNames.split(\"\")\n : stickerFaceNames;\n this.stickerFaces = individualStickerFaceNames.map((s) => face[s]);\n this.matrix = new Matrix4();\n this.matrix.setPosition(firstPiecePosition[orbit]);\n this.matrix.premultiply(new Matrix4().makeRotationFromQuaternion(q));\n }\n}\n\nfunction t(v: Vector3, t4: number): Quaternion {\n return new Quaternion().setFromAxisAngle(v, (TAU * t4) / 4);\n}\n\nconst r = {\n O: new Vector3(0, 0, 0),\n U: new Vector3(0, -1, 0),\n L: new Vector3(1, 0, 0),\n F: new Vector3(0, 0, -1),\n R: new Vector3(-1, 0, 0),\n B: new Vector3(0, 0, 1),\n D: new Vector3(0, 1, 0),\n};\n\ninterface OrbitIndexed<T> {\n [s: string]: T;\n}\ntype PieceIndexed<T> = OrbitIndexed<T[]>;\n\nconst firstPiecePosition: OrbitIndexed<Vector3> = {\n EDGES: new Vector3(0, 1, 1),\n CORNERS: new Vector3(1, 1, 1),\n CENTERS: new Vector3(0, 1, 0),\n};\nconst orientationRotation: OrbitIndexed<Matrix4[]> = {\n EDGES: [0, 1].map((i) =>\n new Matrix4().makeRotationAxis(\n firstPiecePosition[\"EDGES\"].clone().normalize(),\n (-i * TAU) / 2,\n ),\n ),\n CORNERS: [0, 1, 2].map((i) =>\n new Matrix4().makeRotationAxis(\n firstPiecePosition[\"CORNERS\"].clone().normalize(),\n (-i * TAU) / 3,\n ),\n ),\n CENTERS: [0, 1, 2, 3].map((i) =>\n new Matrix4().makeRotationAxis(\n firstPiecePosition[\"CENTERS\"].clone().normalize(),\n (-i * TAU) / 4,\n ),\n ),\n};\nconst cubieStickerOrder = [face[\"U\"], face[\"F\"], face[\"R\"]];\n\nconst pieceDefs: PieceIndexed<CubieDef> = {\n EDGES: [\n new CubieDef(\"EDGES\", \"UF\", t(r.O, 0)),\n new CubieDef(\"EDGES\", \"UR\", t(r.U, 3)),\n new CubieDef(\"EDGES\", \"UB\", t(r.U, 2)),\n new CubieDef(\"EDGES\", \"UL\", t(r.U, 1)),\n new CubieDef(\"EDGES\", \"DF\", t(r.F, 2)),\n new CubieDef(\"EDGES\", \"DR\", t(r.F, 2).premultiply(t(r.D, 1))),\n new CubieDef(\"EDGES\", \"DB\", t(r.F, 2).premultiply(t(r.D, 2))),\n new CubieDef(\"EDGES\", \"DL\", t(r.F, 2).premultiply(t(r.D, 3))),\n new CubieDef(\"EDGES\", \"FR\", t(r.U, 3).premultiply(t(r.R, 3))),\n new CubieDef(\"EDGES\", \"FL\", t(r.U, 1).premultiply(t(r.R, 3))),\n new CubieDef(\"EDGES\", \"BR\", t(r.U, 3).premultiply(t(r.R, 1))),\n new CubieDef(\"EDGES\", \"BL\", t(r.U, 1).premultiply(t(r.R, 1))),\n ],\n CORNERS: [\n new CubieDef(\"CORNERS\", \"UFR\", t(r.O, 0)),\n new CubieDef(\"CORNERS\", \"URB\", t(r.U, 3)),\n new CubieDef(\"CORNERS\", \"UBL\", t(r.U, 2)),\n new CubieDef(\"CORNERS\", \"ULF\", t(r.U, 1)),\n new CubieDef(\"CORNERS\", \"DRF\", t(r.F, 2).premultiply(t(r.D, 1))),\n new CubieDef(\"CORNERS\", \"DFL\", t(r.F, 2).premultiply(t(r.D, 0))),\n new CubieDef(\"CORNERS\", \"DLB\", t(r.F, 2).premultiply(t(r.D, 3))),\n new CubieDef(\"CORNERS\", \"DBR\", t(r.F, 2).premultiply(t(r.D, 2))),\n ],\n CENTERS: [\n new CubieDef(\"CENTERS\", \"U\", t(r.O, 0)),\n new CubieDef(\"CENTERS\", \"L\", t(r.R, 3).premultiply(t(r.U, 1))),\n new CubieDef(\"CENTERS\", \"F\", t(r.R, 3)),\n new CubieDef(\"CENTERS\", \"R\", t(r.R, 3).premultiply(t(r.D, 1))),\n new CubieDef(\"CENTERS\", \"B\", t(r.R, 3).premultiply(t(r.D, 2))),\n new CubieDef(\"CENTERS\", \"D\", t(r.R, 2)),\n ],\n};\n\nconst CUBE_SCALE = 1 / 3;\n\n// Oversized `stickerless` pieces push the puzzle past the \u00B11.5 half-extent that\n// `CUBE_SCALE` and the camera framing assume, so scale it back to the same outer\n// size. Reduces to `CUBE_SCALE` at a half-width of 0.5.\nfunction cubeScale(stickerless: boolean): number {\n return stickerless ? 0.5 / cubieBodyHalfExtent(3) : CUBE_SCALE;\n}\n\ninterface FaceletInfo {\n faceIdx: number;\n facelet: Mesh;\n hintFacelet?: Mesh;\n /**\n * Set in `stickerless` mode, where the facelet is one material group of the\n * shared cubie body instead of a mesh of its own.\n */\n bodyMaterialIndex?: number;\n}\n\n// TODO: Compatibility with Randelshofer or standard net layout? Offer a\n// conversion function?\nconst pictureStickerCoords: Record<string, number[][][]> = {\n EDGES: [\n [\n [0, 4, 6],\n [0, 4, 5],\n ],\n [\n [3, 5, 7],\n [0, 7, 5],\n ],\n [\n [2, 4, 8],\n [0, 10, 5],\n ],\n [\n [1, 3, 7],\n [0, 1, 5],\n ],\n [\n [2, 4, 2],\n [2, 4, 3],\n ],\n [\n [3, 5, 1],\n [2, 7, 3],\n ],\n [\n [0, 4, 0],\n [2, 10, 3],\n ],\n [\n [1, 3, 1],\n [2, 1, 3],\n ],\n [\n [3, 5, 4],\n [3, 6, 4],\n ],\n [\n [1, 3, 4],\n [1, 2, 4],\n ],\n [\n [1, 9, 4],\n [1, 8, 4],\n ],\n [\n [3, 11, 4],\n [3, 0, 4],\n ],\n ],\n CORNERS: [\n [\n [0, 5, 6],\n [0, 5, 5],\n [0, 6, 5],\n ],\n [\n [3, 5, 8],\n [0, 8, 5],\n [0, 9, 5],\n ],\n [\n [2, 3, 8],\n [0, 11, 5],\n [0, 0, 5],\n ],\n [\n [1, 3, 6],\n [0, 2, 5],\n [0, 3, 5],\n ],\n [\n [3, 5, 2],\n [2, 6, 3],\n [2, 5, 3],\n ],\n [\n [2, 3, 2],\n [2, 3, 3],\n [2, 2, 3],\n ],\n [\n [1, 3, 0],\n [2, 0, 3],\n [2, 11, 3],\n ],\n [\n [0, 5, 0],\n [2, 9, 3],\n [2, 8, 3],\n ],\n ],\n CENTERS: [\n [[0, 4, 7]],\n [[0, 1, 4]],\n [[0, 4, 4]],\n [[0, 7, 4]],\n [[0, 10, 4]],\n [[0, 4, 1]],\n ],\n};\n\nlet sharedCubieFoundationGeometryCache: BoxGeometry | null = null;\nfunction sharedCubieFoundationGeometry(): BoxGeometry {\n return (\n sharedCubieFoundationGeometryCache ??\n (sharedCubieFoundationGeometryCache = new BoxGeometry(\n cubieDimensions.foundationWidth,\n cubieDimensions.foundationWidth,\n cubieDimensions.foundationWidth,\n ))\n );\n}\n\nfunction newStickerGeometry(): BufferGeometry {\n const r = new BufferGeometry();\n const half = 0.5;\n r.setAttribute(\n \"position\",\n new BufferAttribute(\n new Float32Array([\n half,\n half,\n 0,\n -half,\n half,\n 0,\n half,\n -half,\n 0,\n -half,\n half,\n 0,\n -half,\n -half,\n 0,\n half,\n -half,\n 0,\n ]),\n 3,\n ),\n );\n r.setAttribute(\n \"uv\",\n new BufferAttribute(\n new Float32Array([\n 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1,\n ]),\n 2,\n ),\n );\n // r.setAttribute('normals', new BufferAttribute(new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]), 3));\n return r;\n}\n\n// Keyed by orbit: every cubie in an orbit has its outward faces along the same\n// local axes, so they all share one body.\nconst cubieBodyGeometryCache = new Map<string, BufferGeometry>();\nfunction cubieBodyGeometry(orbit: string, outerAxes: number[]): BufferGeometry {\n const cached = cubieBodyGeometryCache.get(orbit);\n if (cached) {\n return cached;\n }\n const scale = cubieBodyDimensions.pieceScale;\n // The material groups come out indexed like `axesInfo`, so a facelet's group\n // is the index of the local axis it sits on, and the outward faces are just\n // the axes this orbit's stickers sit on.\n const geometry = beveledCubieGeometry(\n axesInfo.map((axisInfo) => axisInfo.vector),\n outerAxes,\n cubieBodyDimensions.halfWidth * scale,\n cubieBodyDimensions.outerAxisRadius * scale,\n cubieBodyDimensions.innerEdgeRadius * scale,\n cubieBodyDimensions.innerCornerRadius * scale,\n cubieBodyDimensions.cornerSharpness,\n cubieBodyDimensions.roundingSegments,\n );\n cubieBodyGeometryCache.set(orbit, geometry);\n return geometry;\n}\n\nlet sharedStickerGeometryCache: BufferGeometry | undefined;\nfunction sharedStickerGeometry(): BufferGeometry {\n return (sharedStickerGeometryCache ??= newStickerGeometry());\n}\n\n// TODO: Split into \"scene model\" and \"view\".\nexport class Cube3D extends Object3D implements Twisty3DPuzzle {\n kpuzzleFaceletInfo: Record<string, FaceletInfo[][]>;\n private pieces: PieceIndexed<Object3D> = {};\n private options: Cube3DOptions;\n // TODO: Keep track of option-based meshes better.\n private experimentalHintStickerMeshes: Mesh[] = [];\n private experimentalFoundationMeshes: Mesh[] = [];\n\n #setSpriteURL: ((url: string) => void) | undefined;\n private sprite: Texture | Promise<Texture> = new Promise((resolve) => {\n this.#setSpriteURL = (url: string): void => {\n svgLoader.load(url, resolve);\n };\n });\n\n // TODO: Don't overwrite the static function.\n // TODO: This doesn't work dynamically yet.\n setSprite(texture: Texture): void {\n this.sprite = texture;\n }\n\n #setHintSpriteURL: ((url: string) => void) | undefined;\n private hintSprite: Texture | Promise<Texture> = new Promise((resolve) => {\n this.#setHintSpriteURL = (url: string): void => {\n svgLoader.load(url, resolve);\n };\n });\n\n // TODO: Don't overwrite the static function.\n // TODO: This doesn't work dynamically yet.\n setHintSprite(texture: Texture): void {\n this.hintSprite = texture;\n }\n\n constructor(\n private kpuzzle: KPuzzle,\n private scheduleRenderCallback?: () => void,\n options: Cube3DOptions = {},\n ) {\n super();\n\n this.options = { ...cube3DOptionsDefaults };\n Object.assign(this.options, options); // TODO: check if this works\n\n if (this.kpuzzle.name() !== \"3x3x3\") {\n throw new Error(\n `Invalid puzzle for this Cube3D implementation: ${this.kpuzzle.name()}`,\n );\n }\n\n if (options.foundationSprite) {\n this.setSprite(options.foundationSprite);\n }\n if (options.hintSprite) {\n this.setHintSprite(options.hintSprite);\n }\n\n this.kpuzzleFaceletInfo = {};\n for (const orbit in pieceDefs) {\n const orbitFaceletInfo: FaceletInfo[][] = [];\n this.kpuzzleFaceletInfo[orbit] = orbitFaceletInfo;\n this.pieces[orbit] = pieceDefs[orbit].map(\n this.createCubie.bind(this, orbit, orbitFaceletInfo),\n );\n }\n const scale = cubeScale(this.#stickerless());\n this.scale.set(scale, scale, scale);\n\n // TODO: Can we construct this directly instead of applying it later? Would that be more code-efficient?\n if (this.options.experimentalStickeringMask) {\n this.setStickeringMask(this.options.experimentalStickeringMask);\n }\n void this.#animateRaiseHintFacelets();\n\n if (this.options.faceletScale) {\n this.experimentalSetFaceletScale(this.options.faceletScale);\n }\n\n if (typeof this.options[\"hintFaceletsElevation\"] !== \"undefined\") {\n this.#elevationRequest = this.options.hintFaceletsElevation;\n }\n }\n\n #sharedHintStickerGeometryCache: BufferGeometry | undefined;\n #sharedHintStickerGeometry(): BufferGeometry {\n return (this.#sharedHintStickerGeometryCache ??= newStickerGeometry());\n }\n\n #elevationRequest: \"auto\" | number | undefined;\n setHintFaceletsElevation(elevation: \"auto\" | number) {\n if (elevation === this.#elevationRequest) {\n return;\n }\n this.#cancelAnimateRaiseHintSticker = true;\n this.#setHintFaceletsElevation(\n typeof elevation === \"number\"\n ? elevation\n : cubieDimensions.defaultHintStickerElevation,\n );\n this.#elevationRequest = elevation;\n }\n\n #lastHintStickerElevation = 0;\n #setHintFaceletsElevation(elevation: number) {\n this.#sharedHintStickerGeometry().translate(\n 0,\n 0,\n elevation - this.#lastHintStickerElevation,\n );\n this.#lastHintStickerElevation = elevation;\n }\n\n // TODO: support smooth physics\n #cancelAnimateRaiseHintSticker = false;\n // TODO: Generalize this into an animation mechanism.\n async #animateRaiseHintFacelets(): Promise<void> {\n if (\n this.options.initialHintFaceletsAnimation === \"none\" ||\n (this.options.initialHintFaceletsAnimation !== \"always\" &&\n haveStartedSharingRenderers())\n ) {\n return;\n }\n const targetElevation =\n typeof this.options.hintFaceletsElevation !== \"undefined\" &&\n this.options.hintFaceletsElevation !== \"auto\"\n ? this.options.hintFaceletsElevation\n : cubieDimensions.defaultHintStickerElevation;\n const translationRange = targetElevation - cubieDimensions.stickerElevation;\n this.#setHintFaceletsElevation(cubieDimensions.stickerElevation);\n\n // TODO: constant/config\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n const hintStartTime = performance.now();\n // TODO: constant/config\n const translationDuration = 1000 as MillisecondTimestamp;\n function ease(x: number) {\n return x * (2 - x);\n }\n const animateRaiseHintSticker = () => {\n if (this.#cancelAnimateRaiseHintSticker) {\n return;\n }\n const elapsed = performance.now() - hintStartTime;\n const fraction = Math.min(elapsed / translationDuration, 1);\n const newTranslation =\n ease(fraction) * translationRange + cubieDimensions.stickerElevation;\n this.#setHintFaceletsElevation(newTranslation);\n\n this.scheduleRenderCallback?.();\n if (elapsed < translationDuration) {\n requestAnimationFrame(animateRaiseHintSticker);\n }\n };\n animateRaiseHintSticker();\n }\n\n // Can only be called once.\n /** @deprecated */\n experimentalSetStickerSpriteURL(stickerSpriteURL: string): void {\n this.#setSpriteURL?.(stickerSpriteURL);\n }\n\n // Can only be called once.\n /** @deprecated */\n experimentalSetHintStickerSpriteURL(hintStickerSpriteURL: string): void {\n this.#setHintSpriteURL?.(hintStickerSpriteURL);\n }\n\n #stickerless(): boolean {\n return this.options.experimentalCubieStyle === \"stickerless\";\n }\n\n #setFaceletMaterial(\n faceletInfo: FaceletInfo,\n mask: FaceletMeshStickeringMask,\n ): void {\n const axisInfo = axesInfo[faceletInfo.faceIdx];\n const { bodyMaterialIndex } = faceletInfo;\n if (bodyMaterialIndex === undefined) {\n faceletInfo.facelet.material = axisInfo.stickerMaterial[mask];\n } else {\n // The facelet shares its mesh with the rest of the piece, so only its own\n // material group can change.\n (faceletInfo.facelet.material as Material[])[bodyMaterialIndex] =\n axisInfo.bodyMaterial[mask];\n }\n }\n\n setStickeringMask(stickeringMask: StickeringMask): void {\n if (stickeringMask.specialBehaviour === \"picture\") {\n // TODO: if the latest stickering mask was already \"picture\", don't redo work.\n for (const pieceInfos of Object.values(this.kpuzzleFaceletInfo)) {\n for (const faceletInfos of pieceInfos) {\n for (const faceletInfo of faceletInfos) {\n this.#setFaceletMaterial(faceletInfo, \"invisible\");\n const { hintFacelet } = faceletInfo;\n if (hintFacelet) {\n hintFacelet.material = invisibleMaterial;\n }\n }\n }\n }\n return;\n }\n this.options.experimentalStickeringMask = stickeringMask;\n for (const [orbitName, orbitStickeringMask] of Object.entries(\n stickeringMask.orbits,\n )) {\n for (\n let pieceIdx = 0;\n pieceIdx < orbitStickeringMask.pieces.length;\n pieceIdx++\n ) {\n const pieceStickeringMask = orbitStickeringMask.pieces[pieceIdx];\n if (pieceStickeringMask) {\n const pieceInfo = this.kpuzzleFaceletInfo[orbitName][pieceIdx];\n for (\n let faceletIdx = 0;\n faceletIdx < pieceInfo.length;\n faceletIdx++\n ) {\n const faceletStickeringMask =\n pieceStickeringMask.facelets[faceletIdx];\n if (faceletStickeringMask) {\n const faceletInfo = pieceInfo[faceletIdx];\n\n const stickeringMask =\n typeof faceletStickeringMask === \"string\"\n ? faceletStickeringMask\n : faceletStickeringMask?.mask;\n\n this.#setFaceletMaterial(faceletInfo, stickeringMask);\n // TODO\n const hintStickeringMask =\n typeof faceletStickeringMask === \"string\"\n ? stickeringMask\n : (faceletStickeringMask.hintMask ?? stickeringMask);\n if (faceletInfo.hintFacelet) {\n faceletInfo.hintFacelet.material =\n axesInfo[faceletInfo.faceIdx].hintStickerMaterial[\n hintStickeringMask\n ];\n }\n }\n }\n }\n }\n }\n if (this.scheduleRenderCallback) {\n this.scheduleRenderCallback();\n }\n }\n\n /** @deprecated */\n public experimentalUpdateOptions(options: Cube3DOptions): void {\n if (\"showMainStickers\" in options) {\n throw new Error(\"Unimplemented\");\n }\n\n const showFoundation = options.showFoundation;\n if (\n typeof showFoundation !== \"undefined\" &&\n this.options.showFoundation !== showFoundation\n ) {\n this.options.showFoundation = showFoundation;\n for (const foundation of this.experimentalFoundationMeshes) {\n foundation.visible = showFoundation;\n }\n }\n\n const hintFacelets = options.hintFacelets;\n if (\n typeof hintFacelets !== \"undefined\" &&\n this.options.hintFacelets !== hintFacelets &&\n hintFaceletStyles[hintFacelets] // TODO: test this\n ) {\n this.options.hintFacelets = hintFacelets;\n for (const hintSticker of this.experimentalHintStickerMeshes) {\n hintSticker.visible = hintFacelets === \"floating\";\n }\n this.scheduleRenderCallback!(); // TODO\n }\n\n const { experimentalStickeringMask } = options;\n if (typeof experimentalStickeringMask !== \"undefined\") {\n this.options.experimentalStickeringMask = experimentalStickeringMask;\n this.setStickeringMask(experimentalStickeringMask);\n this.scheduleRenderCallback!(); // TODO\n }\n\n const { faceletScale } = options;\n if (typeof faceletScale !== \"undefined\") {\n this.experimentalSetFaceletScale(faceletScale);\n }\n\n const { hintFaceletsElevation } = options;\n if (typeof hintFaceletsElevation !== \"undefined\") {\n this.setHintFaceletsElevation(hintFaceletsElevation);\n }\n }\n\n #lastPosition: PuzzlePosition | null = null;\n public onPositionChange(p: PuzzlePosition): void {\n this.#lastPosition = p;\n const reid333 = p.pattern;\n for (const orbit in pieceDefs) {\n const pieces = pieceDefs[orbit];\n for (let i = 0; i < pieces.length; i++) {\n const j = reid333.patternData[orbit].pieces[i];\n this.pieces[orbit][j].matrix.copy(pieceDefs[orbit][i].matrix);\n this.pieces[orbit][j].matrix.multiply(\n orientationRotation[orbit][reid333.patternData[orbit].orientation[i]],\n );\n }\n for (const moveProgress of p.movesInProgress) {\n const move = moveProgress.move;\n const turnNormal = axesInfo[familyToAxis[move.family]].vector;\n const moveMatrix = new Matrix4().makeRotationAxis(\n turnNormal,\n (-this.ease(moveProgress.fraction) *\n moveProgress.direction *\n move.amount *\n TAU) /\n 4,\n );\n // Loop-invariant: this depends only on `move`, so computing it inside\n // the piece loop rebuilt a `Move` and a `KTransformation` per piece per\n // frame.\n const orbitTransformationData = this.kpuzzle.moveToTransformation(\n move.modified({ amount: 1 }),\n ).transformationData[orbit];\n const { permutation, orientationDelta } = orbitTransformationData;\n for (let i = 0; i < pieces.length; i++) {\n if (i !== permutation[i] || orientationDelta[i] !== 0) {\n const j = reid333.patternData[orbit].pieces[i];\n this.pieces[orbit][j].matrix.premultiply(moveMatrix);\n }\n }\n }\n }\n // After the pieces, since the logo rides on one of them.\n this.#placeLogo(p);\n this.scheduleRenderCallback!();\n }\n\n // TODO: Always create (but sometimes hide parts) so we can show them later,\n // or (better) support creating puzzle parts on demand.\n private createCubie(\n orbit: string,\n orbitFacelets: FaceletInfo[][],\n piece: CubieDef,\n orbitPieceIdx: number,\n ): Object3D {\n const cubieFaceletInfo: FaceletInfo[] = [];\n orbitFacelets.push(cubieFaceletInfo);\n const cubie = new Group();\n // In `stickerless` mode the whole piece is one solid mesh, and each of its\n // six material groups is either an outward facelet color or the internal\n // plastic that shows through the grooves.\n const body = this.#stickerless()\n ? new Mesh(\n cubieBodyGeometry(\n orbit,\n cubieStickerOrder.slice(0, piece.stickerFaces.length),\n ),\n axesInfo.map(() => internalBodyMaterial as Material),\n )\n : null;\n if (body) {\n cubie.add(body);\n } else if (this.options.showFoundation) {\n const foundation = this.createCubieFoundation();\n cubie.add(foundation);\n this.experimentalFoundationMeshes.push(foundation);\n }\n for (let i = 0; i < piece.stickerFaces.length; i++) {\n const faceIdx = piece.stickerFaces[i];\n const faceletInfo: FaceletInfo = body\n ? { faceIdx, facelet: body, bodyMaterialIndex: cubieStickerOrder[i] }\n : {\n faceIdx,\n facelet: this.createSticker(\n axesInfo[cubieStickerOrder[i]],\n axesInfo[faceIdx],\n false,\n ),\n };\n if (body) {\n (body.material as Material[])[cubieStickerOrder[i]] =\n axesInfo[faceIdx].bodyMaterial.regular;\n } else {\n cubie.add(faceletInfo.facelet);\n }\n if (this.options.hintFacelets === \"floating\") {\n const hintSticker = this.createSticker(\n axesInfo[cubieStickerOrder[i]],\n axesInfo[faceIdx],\n true,\n );\n cubie.add(hintSticker);\n faceletInfo.hintFacelet = hintSticker;\n this.experimentalHintStickerMeshes.push(hintSticker);\n }\n\n if (\n this.options.experimentalStickeringMask?.specialBehaviour ===\n \"picture\" &&\n pictureStickerCoords[orbit] &&\n pictureStickerCoords[orbit][orbitPieceIdx] &&\n pictureStickerCoords[orbit][orbitPieceIdx][i]\n ) {\n const [rotate, offsetX, offsetY] =\n pictureStickerCoords[orbit][orbitPieceIdx][i];\n void (async () => {\n const addImageSticker = async (hint: boolean) => {\n const texture: Texture = await (hint\n ? this.hintSprite\n : this.sprite);\n\n const mesh = this.createSticker(\n axesInfo[cubieStickerOrder[i]],\n axesInfo[piece.stickerFaces[i]],\n hint,\n );\n mesh.material = new MeshBasicMaterial({\n map: texture,\n side: hint ? BackSide : DoubleSide,\n transparent: true,\n });\n\n const x1 = offsetX / 12;\n const x2 = (offsetX + 1) / 12;\n const y1 = offsetY / 9;\n const y2 = (offsetY + 1) / 9;\n\n let v1 = new Vector2(x1, y1);\n let v2 = new Vector2(x1, y2);\n let v3 = new Vector2(x2, y2);\n let v4 = new Vector2(x2, y1);\n\n switch (rotate) {\n case 1: {\n [v1, v2, v3, v4] = [v2, v3, v4, v1];\n break;\n }\n case 2: {\n [v1, v2, v3, v4] = [v3, v4, v1, v2];\n break;\n }\n case 3: {\n [v1, v2, v3, v4] = [v4, v1, v2, v3];\n break;\n }\n }\n mesh.geometry.setAttribute(\n \"uv\",\n new BufferAttribute(\n new Float32Array([\n v3.x,\n v3.y,\n v2.x,\n v2.y,\n v4.x,\n v4.y,\n v2.x,\n v2.y,\n v1.x,\n v1.y,\n v4.x,\n v4.y,\n ]),\n 2,\n ),\n );\n cubie.add(mesh);\n };\n // const delay: number = ({\n // CENTERS: 1000,\n // EDGES: 2000,\n // CORNERS: 3500,\n // } as Record<string, number>)[orbit];\n // if (orbit === \"CENTERS\" && orbitPieceIdx === 5) {\n void addImageSticker(true);\n void addImageSticker(false);\n // } else {\n // await this.sprite;\n // await this.hintSprite;\n // setTimeout(\n // () => addImageSticker(true),\n // delay + orbitPieceIdx * 100,\n // );\n // setTimeout(\n // () => addImageSticker(false),\n // delay + orbitPieceIdx * 100,\n // );\n // }\n })();\n }\n\n cubieFaceletInfo.push(faceletInfo);\n }\n cubie.matrix.copy(piece.matrix);\n cubie.matrixAutoUpdate = false;\n this.add(cubie);\n return cubie;\n }\n\n // TODO: Support creating only the outward-facing parts?\n private createCubieFoundation(): Mesh {\n const box = sharedCubieFoundationGeometry();\n return new Mesh(\n box,\n this.options.experimentalStickeringMask?.specialBehaviour === \"picture\"\n ? blackMesh\n : blackTranslucentMesh,\n );\n }\n\n private createSticker(\n posAxisInfo: AxisInfo,\n materialAxisInfo: AxisInfo,\n isHint: boolean,\n ): Mesh {\n const geo =\n this.options.experimentalStickeringMask?.specialBehaviour === \"picture\"\n ? newStickerGeometry()\n : isHint\n ? this.#sharedHintStickerGeometry()\n : sharedStickerGeometry();\n const stickerMesh = new Mesh(\n geo,\n isHint\n ? materialAxisInfo.hintStickerMaterial.regular\n : materialAxisInfo.stickerMaterial.regular,\n );\n stickerMesh.setRotationFromEuler(posAxisInfo.fromZ);\n stickerMesh.position.copy(posAxisInfo.vector);\n\n const elevation = (() => {\n if (!isHint) {\n return cubieDimensions.stickerElevation;\n }\n if (typeof this.options.hintFaceletsElevation === \"number\") {\n return this.options.hintFaceletsElevation;\n }\n if (\n this.options.experimentalStickeringMask?.specialBehaviour === \"picture\"\n ) {\n return EXPERIMENTAL_PICTURE_CUBE_HINT_ELEVATION;\n }\n return cubieDimensions.defaultHintStickerElevation;\n })();\n if (isHint) {\n this.#lastHintStickerElevation = elevation;\n }\n const scale = getFaceletScale(this.options);\n stickerMesh.scale.setX(scale);\n stickerMesh.scale.setY(scale);\n stickerMesh.translateZ(elevation - 1);\n return stickerMesh;\n }\n\n #logoMesh: Mesh | null = null;\n /** The logo's placement on its facelet, in the piece's own frame. */\n #logoSurface: Matrix4 | null = null;\n #logoPieceMatrix = new Matrix4();\n /**\n * Prints a logo on the white center, or takes it off again when passed\n * `null`.\n *\n * The image is stretched onto a square sized to the piece, so its own\n * proportions don't matter. It rides the piece, so a rotation of the whole\n * cube carries it to whichever face the white center ends up on.\n */\n experimentalSetLogo(texture: Texture | null): void {\n if (this.#logoMesh) {\n this.#logoMesh.removeFromParent();\n (this.#logoMesh.material as MeshBasicMaterial).dispose();\n this.#logoMesh = null;\n this.#logoSurface = null;\n }\n if (texture) {\n // The facelet's own axis in cubie-local coordinates, which for the first\n // facelet of a piece is the first of `cubieStickerOrder`.\n const normal = axesInfo[cubieStickerOrder[LOGO_PIECE.faceletIdx]].vector;\n const u = new Vector3(normal.y, normal.z, normal.x);\n const v = new Vector3().crossVectors(normal, u);\n const surface = rectangleLogoSurface(\n normal.clone().multiplyScalar(this.#faceletDistance() + LOGO_ELEVATION),\n // Half-axes of the facelet, which is one cubie wide.\n u.multiplyScalar(0.5),\n v.multiplyScalar(0.5),\n );\n this.#logoMesh = newLogoMesh(texture);\n this.#logoSurface = surfaceMatrix(surface, new Matrix4());\n this.add(this.#logoMesh);\n if (this.#lastPosition) {\n this.#placeLogo(this.#lastPosition);\n }\n }\n this.scheduleRenderCallback?.();\n }\n\n /**\n * Puts the logo where its piece is.\n *\n * Almost all of this is the piece's own matrix, but not quite: the 3\u00D73\u00D73's\n * `KPuzzle` does not track how a center is turned (`orientationMod` is 1),\n * so a `U` ends in the state it started in as far as the white center is\n * concerned. Riding that animation would spin the logo through the turn and\n * snap it back at the end, so a move that leaves the piece in its own slot\n * leaves the logo alone. A move that carries the piece elsewhere \u2014 a cube\n * rotation \u2014 still takes the logo with it.\n */\n #placeLogo(p: PuzzlePosition): void {\n const mesh = this.#logoMesh;\n if (!mesh || !this.#logoSurface) {\n return;\n }\n const { orbit, ord } = LOGO_PIECE;\n const orbitPattern = p.pattern.patternData[orbit];\n const slot = orbitPattern.pieces.indexOf(ord);\n if (slot === -1) {\n mesh.visible = false;\n return;\n }\n mesh.visible = true;\n const untracked = orbitPattern.orientationMod?.[slot] === 1;\n const staysPut =\n untracked &&\n p.movesInProgress.every(\n (moveProgress) =>\n this.kpuzzle.moveToTransformation(\n moveProgress.move.modified({ amount: 1 }),\n ).transformationData[orbit].permutation[slot] === slot,\n );\n const pieceMatrix = staysPut\n ? this.#logoPieceMatrix\n .copy(pieceDefs[orbit][slot].matrix)\n .multiply(orientationRotation[orbit][orbitPattern.orientation[slot]])\n : this.pieces[orbit][ord].matrix;\n mesh.matrix.multiplyMatrices(pieceMatrix, this.#logoSurface);\n mesh.matrixWorldNeedsUpdate = true;\n }\n\n /** How far a facelet's surface sits from the center of its cubie. */\n #faceletDistance(): number {\n return this.#stickerless()\n ? cubieBodyDimensions.halfWidth * cubieBodyDimensions.pieceScale\n : cubieDimensions.stickerElevation;\n }\n\n /** @deprecated */\n experimentalSetFoundationOpacity(opacity: number): void {\n // `stickerless` pieces are solid, so there are no foundation meshes.\n if (this.experimentalFoundationMeshes.length === 0) {\n return;\n }\n (\n this.experimentalFoundationMeshes[0].material as MeshBasicMaterial\n ).opacity = opacity;\n }\n\n /** @deprecated */\n experimentalSetFaceletScale(faceletScale: FaceletScale): void {\n this.options.faceletScale = faceletScale;\n for (const orbitInfo of Object.values(this.kpuzzleFaceletInfo)) {\n for (const pieceInfo of orbitInfo) {\n for (const faceletInfo of pieceInfo) {\n const scale = getFaceletScale(this.options);\n // A `stickerless` facelet is part of the piece itself; scaling it\n // would resize the whole cubie.\n if (faceletInfo.bodyMaterialIndex === undefined) {\n faceletInfo.facelet.scale.setX(scale);\n faceletInfo.facelet.scale.setY(scale);\n }\n faceletInfo.hintFacelet?.scale.setX(scale);\n faceletInfo.hintFacelet?.scale.setY(scale);\n // faceletInfo.facelet.setRotationFromAxisAngle(new Vector3(0, 1, 0), 0);\n // faceletInfo.facelet.rotateOnAxis(new Vector3(1, 0, 1), TAU / 6);\n }\n }\n }\n }\n\n // /** @deprecated */\n // experimentalSetCenterStickerWidth(width: number): void {\n // for (const orbitInfo of [this.kpuzzleFaceletInfo[\"CENTERS\"]]) {\n // for (const pieceInfo of orbitInfo) {\n // for (const faceletInfo of pieceInfo) {\n // faceletInfo.facelet.scale.setScalar(\n // width / getStickerScale(this.options),\n // );\n // // faceletInfo.facelet.setRotationFromAxisAngle(new Vector3(0, 1, 0), 0);\n // // faceletInfo.facelet.rotateOnAxis(new Vector3(1, 0, 1), TAU / 6);\n // }\n // }\n // }\n // }\n\n private ease(fraction: number): number {\n return smootherStep(fraction);\n }\n}\n", "export function smootherStep(x: number): number {\n return x * x * x * (10 - x * (15 - 6 * x));\n}\n", "import { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\n\nfunction clamp(value: number, bound: number): number {\n return Math.min(Math.max(value, -bound), bound);\n}\n\nfunction component(vector: Vector3, axis: number): number {\n return axis === 0 ? vector.x : axis === 1 ? vector.y : vector.z;\n}\n\nfunction setComponent(vector: Vector3, axis: number, value: number): void {\n if (axis === 0) {\n vector.x = value;\n } else if (axis === 1) {\n vector.y = value;\n } else {\n vector.z = value;\n }\n}\n\n/**\n * Builds a rounded cubie centered at the origin, with one material group per\n * face.\n *\n * The surface of a box of half-size `halfSize` is sampled as six grids, and\n * every sample is pushed onto the Minkowski sum of a smaller box and an\n * ellipsoid. A sample in the middle of a face lands back where it started, so\n * the face stays flat; one near an edge or a corner rolls over.\n *\n * Three properties make this worth doing over a hand-built rounded box:\n *\n * - Each grid covers exactly one face of the underlying box, so the boundary\n * between two grids maps onto the midline of the rounding between them \u2014\n * exactly where two colors of plastic meet on a stickerless cube. Each face\n * can be its own material group and its color wraps over its own half of the\n * rounding for free.\n * - The rounding is a field over the cubie rather than a constant. Because it\n * is a pure function of the sample's position on the box \u2014 which is shared by\n * the two grids meeting along any edge \u2014 neighboring faces still agree\n * exactly and the surface stays closed.\n * - The field is a radius per axis, not one radius. A sphere of radius r rounds\n * a corner by r *and* domes it by r, and the two cannot be separated. An\n * ellipsoid can be wide across a face and shallow along its normal, which is\n * what a real speedcube facelet is: a flat plate with a rounded outline\n * rather than a cushion.\n *\n * Each axis takes its radius from whether the face on that side of the cubie is\n * listed in `outerFaceIndices`:\n *\n * - Pointing out of the puzzle: `outerAxisRadius` everywhere. This is the roll\n * at the rim of a facelet, so keeping it small is what keeps the piece flat.\n * - Pointing at a neighboring piece: `innerEdgeRadius` along the middle of an\n * edge, widening to `innerCornerRadius` at a corner over `cornerSharpness`.\n * The first sets how wide the line between two pieces reads, the second\n * rounds a facelet's corners within its own plane \u2014 but only at corners\n * where a single face points out of the puzzle, so that the ones sitting on\n * the puzzle's rim stay square.\n *\n * Those two rules alone give a face its three piece shapes. A center has no\n * outward-facing axis in its own plane, so its outline rounds off on all four\n * sides and it reads as a disc. A corner piece has two, so it stays square\n * apart from the single corner pointing at the middle of the face. An edge\n * piece has one, so it is straight along the puzzle's rim and round on its\n * other three sides.\n *\n * Group `i` corresponds to `faceNormals[i]`.\n */\nexport function beveledCubieGeometry(\n faceNormals: Vector3[],\n outerFaceIndices: number[],\n halfSize: number,\n outerAxisRadius: number,\n innerEdgeRadius: number,\n innerCornerRadius: number,\n cornerSharpness: number,\n segments: number,\n): BufferGeometry {\n const allRadii = [outerAxisRadius, innerEdgeRadius, innerCornerRadius];\n const maxRadius = Math.max(...allRadii);\n if (!(Math.min(...allRadii) > 0 && maxRadius < halfSize)) {\n throw new Error(\n \"Every radius must be positive and smaller than the half-size.\",\n );\n }\n if (cornerSharpness <= 0 || segments < 1) {\n throw new Error(\n \"The corner sharpness must be positive, with at least one segment.\",\n );\n }\n\n // Whether the face on each side of each axis points out of the puzzle.\n const outward: number[][] = [\n [0, 0],\n [0, 0],\n [0, 0],\n ];\n for (let faceIdx = 0; faceIdx < faceNormals.length; faceIdx++) {\n const normal = faceNormals[faceIdx];\n const axis =\n Math.abs(normal.x) > 0.5 ? 0 : Math.abs(normal.y) > 0.5 ? 1 : 2;\n outward[axis][component(normal, axis) > 0 ? 1 : 0] =\n outerFaceIndices.includes(faceIdx) ? 1 : 0;\n }\n\n // Laid out for the widest rounding anything asks for. Somewhere with a\n // smaller radius just stays flat further into the band, which costs a few\n // vertices but keeps the grid \u2014 and so the seams between faces \u2014 identical.\n const inner = halfSize - maxRadius;\n\n const samples: number[] = [];\n for (let i = 0; i <= segments; i++) {\n samples.push(-halfSize + (maxRadius * i) / segments);\n }\n for (let i = 0; i <= segments; i++) {\n samples.push(inner + (maxRadius * i) / segments);\n }\n const gridSize = samples.length;\n\n const positions: number[] = [];\n const indices: number[] = [];\n\n const geometry = new BufferGeometry();\n\n const point = new Vector3();\n const core = new Vector3();\n const offset = new Vector3();\n const u = new Vector3();\n const v = new Vector3();\n const radii = new Vector3();\n const outerness = [0, 0, 0];\n\n const radiiAt = (p: Vector3, out: Vector3): void => {\n // 1 at a corner, and 0 wherever any coordinate passes through the middle of\n // the cubie \u2014 which is also everywhere the sides below swap over, so the\n // corner term has faded out before it could jump.\n const towardCorner =\n ((Math.abs(p.x) * Math.abs(p.y) * Math.abs(p.z)) /\n (halfSize * halfSize * halfSize)) **\n cornerSharpness;\n let outwardFaceCount = 0;\n for (let axis = 0; axis < 3; axis++) {\n // Which side of this axis the point is on, as a ramp rather than a step,\n // so that the radius stays continuous through the middle of the cubie.\n const towardPositive = (component(p, axis) / halfSize + 1) / 2;\n outerness[axis] =\n towardPositive * outward[axis][1] +\n (1 - towardPositive) * outward[axis][0];\n outwardFaceCount += outerness[axis];\n }\n // Round a corner within its plane only where it is an interior point of a\n // single face \u2014 the place four pieces meet. As soon as a second face there\n // also points out of the puzzle the corner is on the puzzle's rim, where\n // the pieces have to meet the outline at a square 90\u00B0 instead of flaring\n // into it.\n const interiorCorner = Math.min(Math.max(2 - outwardFaceCount, 0), 1);\n for (let axis = 0; axis < 3; axis++) {\n const alongEdge =\n innerEdgeRadius + (outerAxisRadius - innerEdgeRadius) * outerness[axis];\n const atCorner =\n innerCornerRadius +\n (outerAxisRadius - innerCornerRadius) * outerness[axis];\n setComponent(\n out,\n axis,\n alongEdge + (atCorner - alongEdge) * towardCorner * interiorCorner,\n );\n }\n };\n\n for (let faceIdx = 0; faceIdx < faceNormals.length; faceIdx++) {\n const normal = faceNormals[faceIdx];\n // Any perpendicular pair will do, as long as `u \u00D7 v === normal` so that the\n // triangles below wind counter-clockwise as seen from outside. Rotating the\n // components is enough to get a vector that is never parallel to an\n // axis-aligned `normal`.\n u.set(normal.y, normal.z, normal.x);\n v.crossVectors(normal, u);\n\n const vertexStart = positions.length / 3;\n for (let i = 0; i < gridSize; i++) {\n for (let j = 0; j < gridSize; j++) {\n point\n .copy(u)\n .multiplyScalar(samples[i])\n .addScaledVector(v, samples[j])\n .addScaledVector(normal, halfSize);\n radiiAt(point, radii);\n core.set(\n clamp(point.x, halfSize - radii.x),\n clamp(point.y, halfSize - radii.y),\n clamp(point.z, halfSize - radii.z),\n );\n // Project onto the ellipsoid in the space where it is a unit sphere,\n // then scale back out.\n offset\n .set(\n (point.x - core.x) / radii.x,\n (point.y - core.y) / radii.y,\n (point.z - core.z) / radii.z,\n )\n .normalize();\n positions.push(\n core.x + offset.x * radii.x,\n core.y + offset.y * radii.y,\n core.z + offset.z * radii.z,\n );\n }\n }\n\n const indexStart = indices.length;\n for (let i = 0; i < gridSize - 1; i++) {\n for (let j = 0; j < gridSize - 1; j++) {\n const a = vertexStart + i * gridSize + j;\n const b = a + gridSize;\n indices.push(a, b, b + 1, a, b + 1, a + 1);\n }\n }\n geometry.addGroup(indexStart, indices.length - indexStart, faceIdx);\n }\n\n geometry.setAttribute(\n \"position\",\n new BufferAttribute(new Float32Array(positions), 3),\n );\n geometry.setIndex(indices);\n return geometry;\n}\n", "import { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport { Color } from \"three/src/math/Color.js\";\nimport { Euler } from \"three/src/math/Euler.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { TAU } from \"../TAU\";\n\n/**\n * What a cube is made of, kept in one place so that every cube renderer molds\n * its pieces out of the same plastic. A 3\u00D73\u00D73 (`Cube3D`) and a 7\u00D77\u00D77\n * (`CubeNxN3D`) sitting side by side should look like two puzzles from the same\n * shelf, not two puzzles from two apps.\n */\n\n/** Everything the color of one facelet depends on. */\nexport interface FaceletStyle {\n color: number;\n dimColor: number;\n hintColor: number;\n hintDimColor: number;\n // TODO: make this work better across bright *and* dark backgrounds. Maybe tweak sticker compositing settings?\n hintOpacityScale: number;\n}\n\nexport interface CubeFaceStyle extends FaceletStyle {\n /** Outward direction of the face, in cubie-local coordinates. */\n vector: Vector3;\n /** Rotation taking a facelet lying in the `z` plane onto this face. */\n fromZ: Euler;\n}\n\n/** Indexed `U`, `L`, `F`, `R`, `B`, `D`. */\nexport const cubeFaceStyles: CubeFaceStyle[] = [\n {\n vector: new Vector3(0, 1, 0),\n fromZ: new Euler(-TAU / 4, 0, 0),\n color: 0xffffff,\n dimColor: 0xdddddd,\n hintColor: 0xffffff,\n hintDimColor: 0xdddddd,\n hintOpacityScale: 1.25,\n },\n {\n vector: new Vector3(-1, 0, 0),\n fromZ: new Euler(0, -TAU / 4, 0),\n color: 0xff9900,\n dimColor: 0x885500,\n hintColor: 0xff9900,\n hintDimColor: 0x884400,\n hintOpacityScale: 1,\n },\n {\n vector: new Vector3(0, 0, 1),\n fromZ: new Euler(0, 0, 0),\n color: 0x00ff00,\n dimColor: 0x008800,\n hintColor: 0x00ff00,\n hintDimColor: 0x009900,\n hintOpacityScale: 1,\n },\n {\n vector: new Vector3(1, 0, 0),\n fromZ: new Euler(0, TAU / 4, 0),\n color: 0xff0000,\n dimColor: 0x660000,\n hintColor: 0xff0000,\n hintDimColor: 0x660000,\n hintOpacityScale: 1,\n },\n {\n vector: new Vector3(0, 0, -1),\n fromZ: new Euler(0, TAU / 2, 0),\n color: 0x2266ff,\n dimColor: 0x113388,\n hintColor: 0x2266ff,\n hintDimColor: 0x001866,\n hintOpacityScale: 0.75,\n },\n {\n vector: new Vector3(0, -1, 0),\n fromZ: new Euler(TAU / 4, 0, 0),\n color: 0xffff00,\n dimColor: 0x888800,\n hintColor: 0xffff00,\n hintDimColor: 0xdddd00,\n hintOpacityScale: 1.25,\n },\n];\n\n/**\n * The shape of a `stickerless` cubie, in units where a cubie's slot is exactly\n * 1 wide. A renderer for an N\u00D7N\u00D7N cube scales all of these by the width of one\n * of its slots, so that pieces of any cube are the same shape.\n */\nexport const cubieBodyDimensions = {\n /**\n * Half-width of a `stickerless` cubie body. Deliberately more than the 0.5\n * that would make pieces exactly fill their slot: oversized pieces press into\n * each other, which buries most of each rounded edge inside its neighbor and\n * keeps the dividing lines thin.\n */\n halfWidth: 0.54,\n /**\n * Roll at the rim of a facelet, along the axis the facelet faces \u2014 so also\n * the rounding of the puzzle's own outer edges and corners. Effectively zero,\n * which leaves those edges sharp and the plates dead flat.\n *\n * Not exactly zero: the construction lifts each face off the core box along\n * this axis, so a true zero leaves nothing to normalize in the middle of a\n * face. A few thousandths is below a pixel at any sane size.\n */\n outerAxisRadius: 0.004,\n /**\n * Rounding along an axis pointing at a neighboring piece, in the middle of an\n * edge. Sets how wide the dividing line between two pieces reads.\n */\n innerEdgeRadius: 0.07,\n /**\n * The same axis at a corner. This one rounds a facelet's corners within its\n * own plane, so it is what turns a center into a disc, and it costs no\n * thickness because the roll stays `outerAxisRadius` deep.\n */\n innerCornerRadius: 0.34,\n /** How tightly the corner rounding is pulled in toward the corners. */\n cornerSharpness: 1.3,\n /**\n * Everything above, shrunk about each piece's own center. Scaling rather than\n * trimming the half-width leaves every proportion of the piece untouched and\n * only opens a gap against its neighbors, so the pieces read as separate with\n * a thin line of the puzzle's interior showing between them.\n */\n pieceScale: 0.95,\n roundingSegments: 3,\n};\n\n/**\n * The outer half-extent a puzzle built from {@link cubieBodyDimensions} reaches,\n * in slots, for a cube `layers` slots wide. More than `layers / 2` because the\n * pieces are oversized; a renderer scales by the ratio of the two to hold the\n * puzzle to the size the camera framing expects.\n */\nexport function cubieBodyHalfExtent(layers: number): number {\n return (\n layers / 2 -\n 0.5 +\n cubieBodyDimensions.halfWidth * cubieBodyDimensions.pieceScale\n );\n}\n\n// Unlit, so that a facelet is its color and nothing else. A light would have to\n// be fixed either to the puzzle or to the camera, and both give themselves away:\n// fixed to the puzzle it reads as a lamp taped to one face, which turns with the\n// cube on a smart-cube feed; fixed to the camera it makes the same facelet\n// change shade as the cube is turned. What separates the pieces is the dark\n// plastic in the grooves between them, which needs no light to read.\n//\n// `Color` converts sRGB to linear on assignment, and the renderer writes linear\n// values straight out (see `RendererPool`), so every color here has to make the\n// same `convertLinearToSRGB` round trip the sticker materials make.\nexport function newBodyMaterial(color: Color | number): MeshBasicMaterial {\n return new MeshBasicMaterial({\n color:\n typeof color === \"number\"\n ? new Color(color).convertLinearToSRGB()\n : color,\n });\n}\n\n/**\n * The same material, but taking its color from the mesh's own vertices \u2014 for\n * renderers that put many pieces into one mesh instead of giving each facelet\n * its own material.\n */\nexport function newVertexColorBodyMaterial(): MeshBasicMaterial {\n const material = newBodyMaterial(0xffffff);\n material.vertexColors = true;\n return material;\n}\n\n/** Colors a stickering mask puts on a piece in place of a facelet's own. */\nexport const bodyMaskColors = {\n /** The plastic that shows through the grooves between pieces. */\n internal: 0x0e0e0e,\n ignored: 0x666666,\n oriented: 0x44ddcc,\n experimentalOriented2: 0xfffdaa,\n mystery: 0xf2cbcb,\n};\n\n/** The same, for hint facelets, which are lighter and partly transparent. */\nexport const hintMaskStyles = {\n ignored: { color: 0xcccccc, opacity: 0.75 },\n oriented: { color: 0x44ddcc, opacity: 0.5 },\n experimentalOriented2: { color: 0xfff979, opacity: 0.5 },\n mystery: { color: 0xf2cbcb, opacity: 0.5 },\n};\n", "import { FrontSide } from \"three/src/constants.js\";\nimport { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport type { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { Mesh } from \"three/src/objects/Mesh.js\";\nimport type { Texture } from \"three/src/textures/Texture.js\";\nimport type { StickerDat } from \"../../../../puzzle-geometry\";\n\n/**\n * A logo printed on one piece of the puzzle, the way a brand prints one on the\n * white center of a 3\u00D73\u00D73.\n *\n * The image is placed by the puzzle's own geometry rather than by anything the\n * caller passes in: whatever picture arrives is stretched onto the largest\n * square that fits the facelet it belongs on, so a tall logo, a wide one, and\n * one of an odd size all come out the same size on the piece.\n *\n * Which piece that is, is a question about the puzzle and not about the\n * renderer, so it is answered once here (see {@link logoFaceletAddress}) and\n * every 3D renderer places the same square the same way.\n */\n\n/** How much of the facelet the logo takes up, across its middle. */\nconst LOGO_FIT = 0.8;\n\nconst EPSILON = 1e-9;\n\n/** One facelet of one piece, in the numbering a `KPuzzle` orbit uses. */\nexport interface FaceletAddress {\n orbit: string;\n /** The piece the logo is printed on, by its solved position. */\n ord: number;\n /** Which facelet of that piece. */\n ori: number;\n}\n\n/**\n * The square a logo is drawn on: `center \u00B1 u \u00B1 v` are its corners, so `u` and\n * `v` are half-axes and their cross product points out of the puzzle.\n */\nexport interface FaceletSurface {\n center: Vector3;\n u: Vector3;\n v: Vector3;\n}\n\n/**\n * The largest square centered on a facelet that stays inside it, shrunk to\n * {@link LOGO_FIT} and lifted clear of the plastic by `elevation`.\n *\n * The square is aligned with the facelet's first edge, which puts it square to\n * a cube's facelets and leaves it centered on anything else. Its size comes\n * from the polygon itself rather than from a bounding box, so that a triangle\n * (the middle of a pyraminx face) and a pentagon (a megaminx center) each get a\n * logo that fits them instead of one that hangs over their slanted edges.\n */\nexport function logoSurface(\n polygon: Vector3[],\n normal: Vector3,\n elevation: number,\n): FaceletSurface | null {\n if (polygon.length < 3) {\n return null;\n }\n const center = new Vector3();\n for (const vertex of polygon) {\n center.addScaledVector(vertex, 1 / polygon.length);\n }\n const u = new Vector3()\n .subVectors(polygon[1], polygon[0])\n .addScaledVector(\n normal,\n -new Vector3().subVectors(polygon[1], polygon[0]).dot(normal),\n );\n if (u.lengthSq() < EPSILON) {\n return null;\n }\n u.normalize();\n const v = new Vector3().crossVectors(normal, u).normalize();\n\n // A square of half-size `h` clears an edge when the edge's distance from the\n // center covers the square's reach in that direction, which is `h` times the\n // edge normal's own spread over the two in-plane axes.\n let half = Number.POSITIVE_INFINITY;\n for (let i = 0; i < polygon.length; i++) {\n const edge = new Vector3().subVectors(\n polygon[(i + 1) % polygon.length],\n polygon[i],\n );\n const outward = new Vector3().crossVectors(edge, normal);\n if (outward.lengthSq() < EPSILON) {\n continue;\n }\n outward.normalize();\n const distance = Math.abs(\n new Vector3().subVectors(polygon[i], center).dot(outward),\n );\n const reach = Math.abs(outward.dot(u)) + Math.abs(outward.dot(v));\n if (reach > EPSILON) {\n half = Math.min(half, distance / reach);\n }\n }\n if (!Number.isFinite(half) || half <= 0) {\n return null;\n }\n half *= LOGO_FIT;\n return {\n center: center.addScaledVector(normal, elevation),\n u: u.multiplyScalar(half),\n v: v.multiplyScalar(half),\n };\n}\n\n/** The same, for a facelet that is already known to be a rectangle. */\nexport function rectangleLogoSurface(\n center: Vector3,\n u: Vector3,\n v: Vector3,\n): FaceletSurface {\n const half = LOGO_FIT * Math.min(u.length(), v.length());\n return {\n center,\n u: u.clone().setLength(half),\n v: v.clone().setLength(half),\n };\n}\n\n/** Places the unit quad from {@link logoGeometry} onto a facelet. */\nexport function surfaceMatrix(surface: FaceletSurface, into: Matrix4): Matrix4 {\n return into\n .makeBasis(\n surface.u,\n surface.v,\n new Vector3().crossVectors(surface.u, surface.v).normalize(),\n )\n .setPosition(surface.center);\n}\n\nlet cachedLogoGeometry: BufferGeometry | undefined;\n/** A quad from (-1, -1) to (1, 1) in the `z` plane, carrying the whole image. */\nexport function logoGeometry(): BufferGeometry {\n if (cachedLogoGeometry) {\n return cachedLogoGeometry;\n }\n const geometry = new BufferGeometry();\n geometry.setAttribute(\n \"position\",\n new BufferAttribute(\n // biome-ignore format: one vertex per line is less readable than one triangle per line.\n new Float32Array([\n -1, -1, 0, 1, -1, 0, 1, 1, 0,\n -1, -1, 0, 1, 1, 0, -1, 1, 0,\n ]),\n 3,\n ),\n );\n geometry.setAttribute(\n \"uv\",\n // biome-ignore format: see above.\n new BufferAttribute(new Float32Array([\n 0, 0, 1, 0, 1, 1,\n 0, 0, 1, 1, 0, 1,\n ]), 2),\n );\n cachedLogoGeometry = geometry;\n return geometry;\n}\n\n/**\n * A mesh ready to be parented to whatever the renderer moves around. Its matrix\n * is set by hand from a {@link FaceletSurface}, so it does not track a position\n * or rotation of its own.\n */\nexport function newLogoMesh(texture: Texture): Mesh {\n const mesh = new Mesh(\n logoGeometry(),\n new MeshBasicMaterial({\n map: texture,\n side: FrontSide,\n transparent: true,\n // The logo floats just above the plastic, so it never has to compete with\n // it for depth, and writing depth would let its transparent corners\n // punch a hole in anything drawn after it.\n depthWrite: false,\n }),\n );\n mesh.matrixAutoUpdate = false;\n // Drawn after the piece it sits on, whatever order the pieces come out in.\n mesh.renderOrder = 1;\n return mesh;\n}\n\n/** Where the logo goes on a puzzle, in terms the puzzle's geometry can answer. */\ninterface LogoSpot {\n /** The face it is printed on, by `PuzzleGeometry`'s name for it. */\n face: string;\n /**\n * Set for a logo on a corner of that face, which is the piece it goes on for\n * a cube big enough to have somewhere else to put it. Otherwise the facelet\n * closest to the middle of the face wins.\n */\n corner?: boolean;\n /**\n * Which of the equally good candidates to take: the one whose facelet lies\n * furthest this way. Points at the corner the default camera is looking at.\n */\n toward?: [number, number, number];\n}\n\n/**\n * The white face of every puzzle that has one, the yellow face of the pyraminx\n * (which does not), and the piece within it a logo belongs on.\n *\n * `PuzzleGeometry` colors a face by its name, so naming the face here picks the\n * color out of the default scheme without depending on the numbering, which\n * differs between puzzles.\n */\nconst logoSpots: Record<string, LogoSpot> = {\n // Every piece of a 2\u00D72\u00D72 is a corner, so this is just \"a piece of the white\n // face\".\n \"2x2x2\": { face: \"U\", corner: true, toward: [1, 1, 1] },\n // `Cube3D` draws the 3\u00D73\u00D73 by default and places its own logo; this is for\n // `visualization=\"PG3D\"`.\n \"3x3x3\": { face: \"U\" },\n \"4x4x4\": { face: \"U\", corner: true, toward: [1, 1, 1] },\n \"5x5x5\": { face: \"U\", corner: true, toward: [1, 1, 1] },\n \"6x6x6\": { face: \"U\", corner: true, toward: [1, 1, 1] },\n \"7x7x7\": { face: \"U\", corner: true, toward: [1, 1, 1] },\n megaminx: { face: \"U\" },\n // A pyraminx has no center piece: the middle of a face is an edge's facelet.\n pyraminx: { face: \"D\" },\n skewb: { face: \"U\" },\n // No logo on the FTO or the clock.\n};\n\nfunction centroid(coords: number[]): Vector3 {\n const center = new Vector3();\n const vertices = coords.length / 3;\n for (let i = 0; i < coords.length; i += 3) {\n center.x += coords[i] / vertices;\n center.y += coords[i + 1] / vertices;\n center.z += coords[i + 2] / vertices;\n }\n return center;\n}\n\n/**\n * Which facelet of which piece carries the logo on this puzzle, or `null` for a\n * puzzle that doesn't take one.\n */\nexport function logoFaceletAddress(\n puzzleID: string,\n stickerDat: StickerDat,\n): FaceletAddress | null {\n const spot = logoSpots[puzzleID];\n if (!spot) {\n return null;\n }\n const faceIdx = stickerDat.faces.findIndex((face) => face.name === spot.face);\n if (faceIdx === -1) {\n return null;\n }\n const faceCenter = centroid(stickerDat.faces[faceIdx].coords);\n\n // How many faces of the puzzle each piece reaches, which is what tells a\n // corner from a center without knowing an orbit's name.\n const faceletCounts = new Map<string, number>();\n for (const sticker of stickerDat.stickers) {\n if (sticker.isDup) {\n continue;\n }\n const key = `${sticker.orbit}/${sticker.ord}`;\n faceletCounts.set(key, (faceletCounts.get(key) ?? 0) + 1);\n }\n\n const toward = spot.toward ? new Vector3(...spot.toward) : null;\n let best: FaceletAddress | null = null;\n let bestScore = Number.NEGATIVE_INFINITY;\n for (const sticker of stickerDat.stickers) {\n if (sticker.isDup || sticker.face !== faceIdx) {\n continue;\n }\n if (\n spot.corner &&\n faceletCounts.get(`${sticker.orbit}/${sticker.ord}`) !== 3\n ) {\n continue;\n }\n const center = centroid(sticker.coords);\n const score = toward ? center.dot(toward) : -center.distanceTo(faceCenter);\n if (score > bestScore) {\n bestScore = score;\n best = { orbit: sticker.orbit, ord: sticker.ord, ori: sticker.ori };\n }\n }\n return best;\n}\n", "import { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport type { StickerDat } from \"../../../../puzzle-geometry\";\nimport { beveledCubieGeometry } from \"./BeveledCubieGeometry\";\nimport {\n cubeFaceStyles,\n cubieBodyDimensions,\n cubieBodyHalfExtent,\n} from \"./CubieStyle\";\nimport { type FaceletSurface, rectangleLogoSurface } from \"./PuzzleLogo\";\nimport type { VertexRange } from \"./SolidPieceGeometry\";\nimport {\n type FaceletPlan,\n HINT_FACELET_ELEVATION,\n HINT_FACELET_SCALE,\n type PieceMesh,\n type PiecePlan,\n type PuzzlePlan,\n paintInternal,\n} from \"./StickerlessPlan\";\n\n/**\n * The pieces of an N\u00D7N\u00D7N cube, cut the way `Cube3D` cuts the 3\u00D73\u00D73's.\n *\n * `Cube3D` knows the 3\u00D73\u00D73 by heart: it has a hand-written table of the 26\n * pieces and where their stickers go. There is no such table for the 4\u00D74\u00D74 and\n * up, so this reads the puzzle back out of the `StickerDat` that\n * `PuzzleGeometry` already produces for `PG3D` \u2014 which is a plain grid of\n * squares once the puzzle is a cube \u2014 and rebuilds the pieces from it.\n */\n\nconst PG_SCALE = 0.5; // Matches `PG3D`, so that the camera framing carries over.\n\nconst FACE_COUNT = 6;\n\n/** How far a logo floats off the face it is printed on, in slot widths. */\nconst LOGO_ELEVATION = 0.01;\n\n/** One cell of the puzzle: which faces of it point out, and where it sits. */\ninterface CubieLayout {\n orbit: string;\n ord: number;\n center: Vector3;\n /** Indices into `cubeFaceStyles`, ascending. */\n outwardFaces: number[];\n stickers: { faceIdx: number; ori: number; isDup: boolean }[];\n}\n\ninterface CubeLayout {\n layers: number;\n /** Half-width of the puzzle, in the `StickerDat`'s coordinates. */\n halfExtent: number;\n cubies: CubieLayout[];\n}\n\nfunction faceIdxForNormal(x: number, y: number, z: number): number {\n for (let faceIdx = 0; faceIdx < FACE_COUNT; faceIdx++) {\n const { vector } = cubeFaceStyles[faceIdx];\n if (vector.x * x + vector.y * y + vector.z * z > 0.5) {\n return faceIdx;\n }\n }\n return -1;\n}\n\n/**\n * Reads an N\u00D7N\u00D7N cube back out of a `StickerDat`, or returns `null` for any\n * puzzle that is not one.\n *\n * The test is deliberately strict \u2014 every sticker has to be a square of exactly\n * one cell, flat against an axis-aligned face, sitting on the grid \u2014 because\n * passing something else through would produce a plausible-looking but wrong\n * puzzle rather than an error.\n */\nexport function cubeLayout(stickerDat: StickerDat): CubeLayout | null {\n const { stickers } = stickerDat;\n if (stickerDat.faces.length !== FACE_COUNT || stickers.length === 0) {\n return null;\n }\n // A piece whose orientation the puzzle tracks but whose facelets are all one\n // square \u2014 a face center of an odd cube \u2014 comes with one sticker per\n // orientation, stacked in the same place and all but one marked as a\n // duplicate. Only the real ones tile the puzzle.\n let faceletCount = 0;\n let halfExtent = 0;\n for (const sticker of stickers) {\n if (sticker.coords.length !== 12) {\n return null;\n }\n if (!sticker.isDup) {\n faceletCount++;\n }\n for (const coord of sticker.coords) {\n halfExtent = Math.max(halfExtent, Math.abs(coord));\n }\n }\n const layers = Math.round(Math.sqrt(faceletCount / FACE_COUNT));\n if (FACE_COUNT * layers * layers !== faceletCount || layers < 2) {\n return null;\n }\n const slotWidth = (2 * halfExtent) / layers;\n const epsilon = slotWidth / 1000;\n\n // A facelet takes its color from the face it started on rather than from the\n // `StickerDat`, so that every cube in the app is painted from the one scheme\n // in `CubieStyle`. That substitution is only honest for a puzzle whose faces\n // are each a single solid color, so check that before claiming this one.\n const faceColors: (string | undefined)[] = new Array(FACE_COUNT);\n\n const cubiesByPiece = new Map<string, CubieLayout>();\n const cubies: CubieLayout[] = [];\n const centroid = [0, 0, 0];\n for (const sticker of stickers) {\n const { coords } = sticker;\n for (let axis = 0; axis < 3; axis++) {\n centroid[axis] =\n (coords[axis] +\n coords[axis + 3] +\n coords[axis + 6] +\n coords[axis + 9]) /\n 4;\n }\n // The axis the sticker faces is the only one that can reach the outside of\n // the puzzle; the other two stay within the outermost slot's center.\n let normalAxis = 0;\n for (let axis = 1; axis < 3; axis++) {\n if (Math.abs(centroid[axis]) > Math.abs(centroid[normalAxis])) {\n normalAxis = axis;\n }\n }\n const outward = Math.sign(centroid[normalAxis]);\n const center = new Vector3();\n for (let axis = 0; axis < 3; axis++) {\n let expected: number;\n if (axis === normalAxis) {\n expected = outward * halfExtent;\n center.setComponent(axis, outward * (halfExtent - slotWidth / 2));\n } else {\n // Snap to the nearest slot center, then check we were already there.\n const slot = Math.round(\n (centroid[axis] + halfExtent) / slotWidth - 0.5,\n );\n if (slot < 0 || slot >= layers) {\n return null;\n }\n expected = -halfExtent + (slot + 0.5) * slotWidth;\n center.setComponent(axis, expected);\n }\n if (Math.abs(centroid[axis] - expected) > epsilon) {\n return null;\n }\n // A square of exactly one slot: two corners on either side of the center\n // along each in-plane axis, and all four flat against the face.\n const halfSpan = axis === normalAxis ? 0 : slotWidth / 2;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = Math.abs(coords[3 * vertex + axis] - expected);\n if (Math.abs(offset - halfSpan) > epsilon) {\n return null;\n }\n }\n }\n const faceIdx = faceIdxForNormal(\n normalAxis === 0 ? outward : 0,\n normalAxis === 1 ? outward : 0,\n normalAxis === 2 ? outward : 0,\n );\n if (faceIdx === -1) {\n return null;\n }\n faceColors[faceIdx] ??= sticker.color;\n if (faceColors[faceIdx] !== sticker.color) {\n return null;\n }\n\n const pieceKey = `${sticker.orbit}/${sticker.ord}`;\n let cubie = cubiesByPiece.get(pieceKey);\n if (!cubie) {\n cubie = {\n orbit: sticker.orbit,\n ord: sticker.ord,\n center,\n outwardFaces: [],\n stickers: [],\n };\n cubiesByPiece.set(pieceKey, cubie);\n cubies.push(cubie);\n } else if (cubie.center.distanceTo(center) > epsilon) {\n // Two stickers of one piece that don't sit on the same cell: not a cube\n // whose pieces are single cells.\n return null;\n }\n if (!cubie.outwardFaces.includes(faceIdx)) {\n cubie.outwardFaces.push(faceIdx);\n cubie.outwardFaces.sort((a, b) => a - b);\n }\n cubie.stickers.push({ faceIdx, ori: sticker.ori, isDup: !!sticker.isDup });\n }\n if (new Set(faceColors).size !== FACE_COUNT) {\n return null;\n }\n return { layers, halfExtent, cubies };\n}\n\n/**\n * The geometry of one shape of piece: a beveled body with a color per face,\n * plus a hint facelet floating off each face that points out of the puzzle.\n *\n * Every piece with the same faces pointing out is the same shape, so a whole\n * puzzle only ever needs the 26 of these that a cube has room for, and they can\n * share their vertices \u2014 each cubie's mesh carries nothing of its own but the\n * colors.\n */\ninterface CubieShape {\n bodyPosition: BufferAttribute;\n bodyIndex: BufferAttribute;\n bodyVertexCount: number;\n hintPosition: BufferAttribute;\n hintIndex: BufferAttribute;\n hintVertexCount: number;\n /** Vertex range of each face of the body, indexed like `cubeFaceStyles`. */\n faceVertexRanges: VertexRange[];\n /** Vertex range of the hint facelet of each outward face. */\n hintVertexRanges: Map<number, VertexRange>;\n /** Where a logo would sit on each outward face, in the cubie's own frame. */\n logoSurfaces: Map<number, FaceletSurface>;\n}\n\nfunction newCubieShape(outwardFaces: number[], slotWidth: number): CubieShape {\n const scale = cubieBodyDimensions.pieceScale * slotWidth;\n const body = beveledCubieGeometry(\n cubeFaceStyles.map((style) => style.vector),\n outwardFaces,\n cubieBodyDimensions.halfWidth * scale,\n cubieBodyDimensions.outerAxisRadius * scale,\n cubieBodyDimensions.innerEdgeRadius * scale,\n cubieBodyDimensions.innerCornerRadius * scale,\n cubieBodyDimensions.cornerSharpness,\n cubieBodyDimensions.roundingSegments,\n );\n const bodyPositions = body.getAttribute(\"position\").array as Float32Array;\n const bodyIndices = Array.from(body.getIndex()!.array);\n\n const faceVertexRanges: VertexRange[] = [];\n for (const group of body.groups) {\n let start = Number.POSITIVE_INFINITY;\n let end = 0;\n for (let i = group.start; i < group.start + group.count; i++) {\n start = Math.min(start, bodyIndices[i]);\n end = Math.max(end, bodyIndices[i] + 1);\n }\n faceVertexRanges[group.materialIndex!] = { start, count: end - start };\n }\n\n // The hint facelets are a mesh of their own: they are drawn with a different\n // material, so they belong in a different batch.\n const hintPositions: number[] = [];\n const hintIndices: number[] = [];\n const hintVertexRanges = new Map<number, VertexRange>();\n\n const hintHalfWidth = (HINT_FACELET_SCALE * slotWidth) / 2;\n const hintDistance = slotWidth / 2 + HINT_FACELET_ELEVATION;\n // A facelet is the whole outward face of the cubie, so a logo on it is a\n // square of the piece's own width, resting on the plastic.\n const logoSurfaces = new Map<number, FaceletSurface>();\n const faceDistance =\n cubieBodyDimensions.halfWidth * cubieBodyDimensions.pieceScale * slotWidth;\n const u = new Vector3();\n const v = new Vector3();\n const corner = new Vector3();\n for (const faceIdx of outwardFaces) {\n const normal = cubeFaceStyles[faceIdx].vector;\n // The same perpendicular pair `beveledCubieGeometry` picks, so that the\n // quad below winds counter-clockwise as seen from outside the puzzle.\n u.set(normal.y, normal.z, normal.x);\n v.crossVectors(normal, u);\n logoSurfaces.set(\n faceIdx,\n rectangleLogoSurface(\n normal\n .clone()\n .multiplyScalar(faceDistance + LOGO_ELEVATION * slotWidth),\n u.clone().multiplyScalar(slotWidth / 2),\n v.clone().multiplyScalar(slotWidth / 2),\n ),\n );\n const start = hintPositions.length / 3;\n for (const [su, sv] of [\n [-1, -1],\n [1, -1],\n [1, 1],\n [-1, 1],\n ]) {\n corner\n .copy(normal)\n .multiplyScalar(hintDistance)\n .addScaledVector(u, su * hintHalfWidth)\n .addScaledVector(v, sv * hintHalfWidth);\n hintPositions.push(corner.x, corner.y, corner.z);\n }\n hintIndices.push(start, start + 1, start + 2, start, start + 2, start + 3);\n hintVertexRanges.set(faceIdx, { start, count: 4 });\n }\n\n body.dispose();\n return {\n bodyPosition: new BufferAttribute(bodyPositions.slice(), 3),\n bodyIndex: new BufferAttribute(new Uint16Array(bodyIndices), 1),\n bodyVertexCount: bodyPositions.length / 3,\n hintPosition: new BufferAttribute(new Float32Array(hintPositions), 3),\n hintIndex: new BufferAttribute(new Uint16Array(hintIndices), 1),\n hintVertexCount: hintPositions.length / 3,\n faceVertexRanges,\n hintVertexRanges,\n logoSurfaces,\n };\n}\n\nfunction newPieceMesh(\n position: BufferAttribute,\n index: BufferAttribute,\n vertexCount: number,\n): PieceMesh {\n const geometry = new BufferGeometry();\n geometry.setAttribute(\"position\", position);\n geometry.setIndex(index);\n const colors = new BufferAttribute(new Uint8Array(4 * vertexCount), 4, true);\n geometry.setAttribute(\"color\", colors);\n return { geometry, colors };\n}\n\nfunction newCubiePiece(cubie: CubieLayout, shape: CubieShape): PiecePlan {\n const body = newPieceMesh(\n shape.bodyPosition,\n shape.bodyIndex,\n shape.bodyVertexCount,\n );\n const hint =\n shape.hintVertexCount > 0\n ? newPieceMesh(shape.hintPosition, shape.hintIndex, shape.hintVertexCount)\n : null;\n // Every face starts out as the plastic inside the puzzle; the ones that point\n // out of it are painted over by the first `onPositionChange`.\n paintInternal(body.colors, shape.faceVertexRanges);\n\n const facelets: FaceletPlan[] = cubie.stickers.map((sticker) => ({\n ori: sticker.ori,\n faceStyle: sticker.faceIdx,\n // A duplicate shares its square with the real facelet, which is the one\n // that gets painted.\n body: sticker.isDup ? [] : [shape.faceVertexRanges[sticker.faceIdx]],\n hint: sticker.isDup\n ? []\n : [shape.hintVertexRanges.get(sticker.faceIdx)!].filter(Boolean),\n // Set for a duplicate too: it is the same square, seen through another of\n // the piece's facelets.\n logo: shape.logoSurfaces.get(sticker.faceIdx) ?? null,\n }));\n return {\n orbit: cubie.orbit,\n ord: cubie.ord,\n home: new Matrix4().setPosition(cubie.center),\n body,\n hint,\n facelets,\n };\n}\n\n/** The plan for an N\u00D7N\u00D7N cube, or `null` for any puzzle that is not one. */\nexport function cubePuzzlePlan(stickerDat: StickerDat): PuzzlePlan | null {\n const layout = cubeLayout(stickerDat);\n if (!layout) {\n return null;\n }\n const slotWidth = (2 * layout.halfExtent) / layout.layers;\n const shapes = new Map<string, CubieShape>();\n const pieces = layout.cubies.map((cubie) => {\n const shapeKey = cubie.outwardFaces.join(\",\");\n let shape = shapes.get(shapeKey);\n if (!shape) {\n shape = newCubieShape(cubie.outwardFaces, slotWidth);\n shapes.set(shapeKey, shape);\n }\n return newCubiePiece(cubie, shape);\n });\n return {\n faceStyles: cubeFaceStyles,\n pieces,\n // Oversized pieces push the puzzle past the half-extent the camera framing\n // assumes, so scale it back to the size `PG3D` would have drawn.\n scale:\n (PG_SCALE * layout.halfExtent) /\n (cubieBodyHalfExtent(layout.layers) * slotWidth),\n };\n}\n", "import type { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport type { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport type { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport type { FaceletMeshStickeringMask } from \"../../../../puzzles/stickerings/mask\";\nimport {\n bodyMaskColors,\n type FaceletStyle,\n hintMaskStyles,\n} from \"./CubieStyle\";\nimport type { FaceletSurface } from \"./PuzzleLogo\";\nimport type { VertexRange } from \"./SolidPieceGeometry\";\n\n/**\n * A puzzle's pieces, cut and colored and ready to be handed to `Stickerless3D`.\n *\n * Splitting this out is what lets one renderer drive both an N\u00D7N\u00D7N cube, whose\n * pieces are rounded cubies that can share their vertices, and puzzles whose\n * pieces are each their own shape. Everything after the geometry \u2014 which piece\n * a move sweeps, which color a slot shows, hint facelets, stickering masks \u2014 is\n * the same work either way.\n */\n\nexport interface FaceletPlan {\n /** Which facelet of its piece this is, in the `KPuzzle`'s numbering. */\n ori: number;\n /** Index into the plan's `faceStyles`. */\n faceStyle: number;\n /**\n * Vertices showing this facelet's own color. Empty for a facelet that shares\n * its square with another one, where only one of them is drawn.\n */\n body: VertexRange[];\n /** Vertices of its hint facelet. */\n hint: VertexRange[];\n /**\n * Where a logo would sit on this facelet, in the piece's own frame, or `null`\n * for a facelet with no flat square to print on. Set even for a facelet that\n * shares its square with another one, since a piece that turns in place shows\n * the same square through a different facelet.\n */\n logo: FaceletSurface | null;\n}\n\n/**\n * One drawable part of a piece: `position`, `color`, and an index where the\n * geometry has one. Body and hint facelets are kept apart so that each can go\n * into a batch of its own, since they are drawn with different materials.\n */\nexport interface PieceMesh {\n geometry: BufferGeometry;\n /** The geometry's color attribute, seeding the batch's own. */\n colors: BufferAttribute;\n}\n\nexport interface PiecePlan {\n orbit: string;\n ord: number;\n /** Where the piece sits when nothing is turning. */\n home: Matrix4;\n /** With the plastic inside already painted. */\n body: PieceMesh;\n /** `null` for a piece with no facelet to float a hint off. */\n hint: PieceMesh | null;\n facelets: FaceletPlan[];\n}\n\nexport interface PuzzlePlan {\n faceStyles: FaceletStyle[];\n pieces: PiecePlan[];\n /** Uniform scale bringing the puzzle to the size the camera expects. */\n scale: number;\n}\n\n/** How far a hint facelet floats beyond the surface. Matches `PG3D`. */\nexport const HINT_FACELET_ELEVATION = 0.5;\n/** Width of a hint facelet, as a fraction of a facelet. Matches `Cube3D`. */\nexport const HINT_FACELET_SCALE = 0.85;\n\nexport const faceletMeshStickeringMasks: FaceletMeshStickeringMask[] = [\n \"regular\",\n \"dim\",\n \"oriented\",\n \"experimentalOriented2\",\n \"ignored\",\n \"invisible\",\n \"mystery\",\n];\n\n/** The color a facelet's body shows for a given face and stickering mask. */\nfunction bodyColor(\n style: FaceletStyle,\n mask: FaceletMeshStickeringMask,\n): number {\n switch (mask) {\n case \"regular\":\n return style.color;\n case \"dim\":\n return style.dimColor;\n // A solid piece of plastic can't have a hole punched in it, so an invisible\n // facelet falls back to the internal plastic color.\n case \"invisible\":\n return bodyMaskColors.internal;\n default:\n return bodyMaskColors[mask];\n }\n}\n\n/** The same for its hint facelet, which also carries an opacity. */\nfunction hintColor(\n style: FaceletStyle,\n mask: FaceletMeshStickeringMask,\n): { color: number; opacity: number } {\n switch (mask) {\n case \"regular\":\n return { color: style.hintColor, opacity: 0.5 * style.hintOpacityScale };\n case \"dim\":\n return {\n color: style.hintDimColor,\n opacity: 0.5 * style.hintOpacityScale,\n };\n case \"invisible\":\n return { color: 0, opacity: 0 };\n default:\n return hintMaskStyles[mask];\n }\n}\n\n/**\n * How a facelet looks: four bytes of body color and four of hint color, ready\n * to be copied into a piece's vertex colors.\n *\n * Keyed by face and mask rather than by facelet, so that the common case of\n * many facelets sharing a look also shares one lookup \u2014 and so that a slot can\n * tell whether it is already showing the right thing by comparing keys.\n */\nexport function faceletAppearanceKey(\n faceStyle: number,\n mask: FaceletMeshStickeringMask,\n hintMask: FaceletMeshStickeringMask,\n): number {\n return (\n (faceStyle * faceletMeshStickeringMasks.length +\n faceletMeshStickeringMasks.indexOf(mask)) *\n faceletMeshStickeringMasks.length +\n faceletMeshStickeringMasks.indexOf(hintMask)\n );\n}\n\nexport function faceletAppearance(\n cache: Map<number, Uint8Array>,\n styles: FaceletStyle[],\n faceStyle: number,\n mask: FaceletMeshStickeringMask,\n hintMask: FaceletMeshStickeringMask,\n): Uint8Array {\n const key = faceletAppearanceKey(faceStyle, mask, hintMask);\n const cached = cache.get(key);\n if (cached) {\n return cached;\n }\n const style = styles[faceStyle];\n const body = bodyColor(style, mask);\n const hint = hintColor(style, hintMask);\n // Colors go in as their raw sRGB bytes: the renderer writes linear values\n // straight out (see `RendererPool`), which is the round trip the materials in\n // `CubieStyle` make with `convertLinearToSRGB`.\n const appearance = new Uint8Array([\n (body >> 16) & 0xff,\n (body >> 8) & 0xff,\n body & 0xff,\n 0xff,\n (hint.color >> 16) & 0xff,\n (hint.color >> 8) & 0xff,\n hint.color & 0xff,\n Math.round(hint.opacity * 0xff),\n ]);\n cache.set(key, appearance);\n return appearance;\n}\n\n/** Paints vertex ranges with one half of an appearance. */\nexport function writeColor(\n colors: BufferAttribute,\n ranges: VertexRange[],\n appearance: Uint8Array,\n offset: number = 0,\n): void {\n const array = colors.array as Uint8Array;\n const red = appearance[offset];\n const green = appearance[offset + 1];\n const blue = appearance[offset + 2];\n const alpha = appearance[offset + 3];\n for (const range of ranges) {\n for (\n let vertex = range.start;\n vertex < range.start + range.count;\n vertex++\n ) {\n array[4 * vertex] = red;\n array[4 * vertex + 1] = green;\n array[4 * vertex + 2] = blue;\n array[4 * vertex + 3] = alpha;\n }\n }\n}\n\n/** The plastic inside the puzzle, which never changes color. */\nexport function paintInternal(\n colors: BufferAttribute,\n ranges: VertexRange[],\n): void {\n const internal = bodyMaskColors.internal;\n writeColor(\n colors,\n ranges,\n new Uint8Array([\n (internal >> 16) & 0xff,\n (internal >> 8) & 0xff,\n internal & 0xff,\n 0xff,\n ]),\n );\n}\n", "import { DoubleSide, FrontSide } from \"three/src/constants.js\";\nimport { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Object3D } from \"three/src/core/Object3D.js\";\nimport type { Material } from \"three/src/materials/Material.js\";\nimport { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport { Color } from \"three/src/math/Color.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { Group } from \"three/src/objects/Group.js\";\nimport { Mesh } from \"three/src/objects/Mesh.js\";\nimport type { Texture } from \"three/src/textures/Texture.js\";\nimport { Move } from \"../../../../alg\";\nimport type {\n KPuzzle,\n KTransformation,\n KTransformationData,\n} from \"../../../../kpuzzle\";\nimport type {\n StickerDat,\n StickerDatAxis,\n StickerDatSticker,\n} from \"../../../../puzzle-geometry\";\nimport type { TextureMapper } from \"../../../../puzzle-geometry/PuzzleGeometry\";\nimport {\n type ExperimentalFaceletMeshStickeringMask,\n type ExperimentalStickeringMask,\n experimentalGetFaceletStickeringMask,\n} from \"../../../../puzzles/cubing-private\";\nimport type { PuzzlePosition } from \"../../../controllers/AnimationTypes\";\nimport { smootherStep } from \"../../../controllers/easing\";\nimport type { HintFaceletStyle } from \"../../../model/props/puzzle/display/HintFaceletProp\";\nimport { TAU } from \"../TAU\";\nimport type { Twisty3DPuzzle } from \"./Twisty3DPuzzle\";\n\nconst foundationMaterial = new MeshBasicMaterial({\n side: DoubleSide,\n color: 0x000000,\n});\nconst invisMaterial = new MeshBasicMaterial({\n visible: false,\n});\nconst basicStickerMaterial = new MeshBasicMaterial({\n vertexColors: true,\n});\n\nfunction dist(coords: number[], a: number, b: number): number {\n return Math.hypot(\n coords[3 * a] - coords[3 * b],\n coords[3 * a + 1] - coords[3 * b + 1],\n coords[3 * a + 2] - coords[3 * b + 2],\n );\n}\n\nfunction triarea(coords: number[], a: number, b: number, c: number): number {\n const ab = dist(coords, a, b);\n const bc = dist(coords, b, c);\n const ac = dist(coords, a, c);\n const p = (ab + bc + ac) / 2;\n return Math.sqrt(p * (p - ab) * (p - bc) * (p - ac));\n}\n\nfunction polyarea(coords: number[]): number {\n let sum = 0;\n for (let i = 2; 3 * i < coords.length; i++) {\n sum += triarea(coords, 0, 1, i);\n }\n return sum;\n}\n\nfunction normalize(r: number[]): number[] {\n const m = Math.hypot(r[0], r[1], r[2]);\n r[0] /= m;\n r[1] /= m;\n r[2] /= m;\n return r;\n}\n\nfunction cross(a: number[], b: number[]): number[] {\n const r = new Array<number>(3);\n r[0] = a[1] * b[2] - a[2] * b[1];\n r[1] = a[2] * b[0] - a[0] * b[2];\n r[2] = a[0] * b[1] - a[1] * b[0];\n return r;\n}\n\nfunction normal(c: number[]): number[] {\n const a: number[] = [c[3] - c[0], c[4] - c[1], c[5] - c[2]];\n const b: number[] = [c[6] - c[3], c[7] - c[4], c[8] - c[5]];\n const r = cross(a, b);\n return normalize(r);\n}\n\nfunction trimEdges(face: number[], tr: number): number[] {\n const r: number[] = [];\n const A: number[] = new Array(3);\n const B: number[] = new Array(3);\n for (let iter = 1; iter < 10; iter++) {\n for (let i = 0; i < face.length; i += 3) {\n const pi = (i + face.length - 3) % face.length;\n const ni = (i + 3) % face.length;\n for (let k = 0; k < 3; k++) {\n A[k] = face[pi + k] - face[i + k];\n B[k] = face[ni + k] - face[i + k];\n }\n const alen = Math.hypot(A[0], A[1], A[2]);\n const blen = Math.hypot(B[0], B[1], B[2]);\n for (let k = 0; k < 3; k++) {\n A[k] /= alen;\n B[k] /= blen;\n }\n const d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2];\n const m = tr / Math.sqrt(1 - d * d);\n for (let k = 0; k < 3; k++) {\n r[i + k] = face[i + k] + (A[k] + B[k]) * m;\n }\n }\n let good = true;\n for (let i = 0; good && i < r.length; i += 3) {\n const ni = (i + 3) % face.length;\n let t = 0;\n for (let k = 0; k < 3; k++) {\n const a = face[ni + k] - face[i + k];\n const b = r[ni + k] - r[i + k];\n t += a * b;\n }\n if (t <= 0) {\n good = false;\n }\n }\n if (good) {\n return r;\n }\n tr /= 2;\n }\n return face;\n}\n\nclass Filler {\n pos: number;\n ipos: number;\n vertices: Float32Array;\n colors: Uint8Array;\n uvs?: Float32Array;\n ind: Uint8Array;\n constructor(\n public sz: number,\n public tm: TextureMapper,\n ) {\n this.vertices = new Float32Array(9 * sz);\n this.uvs = undefined;\n this.colors = new Uint8Array(18 * sz);\n this.ind = new Uint8Array(sz);\n this.pos = 0;\n this.ipos = 0;\n }\n\n add(pt: number[], i: number, c: number) {\n this.vertices[this.pos] = pt[3 * i + 0];\n this.vertices[this.pos + 1] = pt[3 * i + 1];\n this.vertices[this.pos + 2] = pt[3 * i + 2];\n this.colors[this.pos] = c >> 16;\n this.colors[this.pos + 1] = (c >> 8) & 255;\n this.colors[this.pos + 2] = c & 255;\n this.pos += 3;\n }\n\n addUncolored(pt: number[], i: number) {\n this.vertices[this.pos] = pt[3 * i + 0];\n this.vertices[this.pos + 1] = pt[3 * i + 1];\n this.vertices[this.pos + 2] = pt[3 * i + 2];\n this.pos += 3;\n }\n\n setind(i: number) {\n this.ind[this.ipos++] = i;\n }\n\n makePoly(coords: number[], color: number, ind: number): void {\n const ncoords: number[] = coords;\n for (let g = 1; 3 * (g + 1) < ncoords.length; g++) {\n this.add(ncoords, 0, color);\n this.add(ncoords, g, color);\n this.add(ncoords, g + 1, color);\n this.setind(ind);\n }\n }\n\n setAttributes(geo: BufferGeometry) {\n geo.setAttribute(\"position\", new BufferAttribute(this.vertices, 3));\n // the geometry only needs the first half of the array\n const sa2 = this.colors.subarray(0, 9 * this.sz);\n geo.setAttribute(\"color\", new BufferAttribute(sa2, 3, true));\n }\n\n makeGroups(geo: BufferGeometry) {\n geo.clearGroups();\n for (let i = 0; i < this.ipos; ) {\n const si = i++;\n const iv = this.ind[si];\n while (this.ind[i] === iv) {\n i++;\n }\n geo.addGroup(3 * si, 3 * (i - si), iv);\n }\n }\n\n saveOriginalColors() {\n this.colors.copyWithin(this.pos, 0, this.pos);\n }\n}\n\nclass StickerDef {\n private origColor: number;\n private origColorStickeringMask: number;\n private faceColor: number;\n private texturePtr?: StickerDef = undefined;\n public twistVal: number = -1;\n public stickerStart: number;\n public stickerEnd: number;\n public hintStart?: number;\n public hintEnd?: number;\n public foundationStart?: number;\n public foundationEnd?: number;\n private isDup: boolean;\n private faceNum: number;\n constructor(\n filler: Filler,\n stickerDat: StickerDatSticker,\n trim: number,\n options?: {\n stickeringMask?: ExperimentalFaceletMeshStickeringMask;\n },\n ) {\n this.isDup = !!stickerDat.isDup;\n this.faceNum = stickerDat.face;\n this.stickerStart = filler.ipos;\n const sdColor = new Color(stickerDat.color).getHex();\n this.origColor = sdColor;\n this.origColorStickeringMask = sdColor;\n if (options?.stickeringMask) {\n this.setStickeringMask(filler, options.stickeringMask);\n }\n this.faceColor = sdColor;\n const coords = this.stickerCoords(stickerDat.coords, trim);\n filler.makePoly(coords, this.faceColor, this.isDup ? 4 : 0);\n this.stickerEnd = filler.ipos;\n }\n\n private stickerCoords(coords: number[], trim: number): number[] {\n return trimEdges(coords.slice(), trim);\n }\n\n private hintCoords(\n coords: number[],\n hintStickerHeightScale: number,\n trim: number,\n normal: number[],\n ): number[] {\n coords = this.stickerCoords(coords, trim); // pick up trim from stickers\n normal = normal.slice();\n for (let i = 0; i < 3; i++) {\n normal[i] *= 0.5 * hintStickerHeightScale;\n }\n const hCoords = new Array<number>(coords.length);\n for (let i = 0; 3 * i < coords.length; i++) {\n const j = coords.length / 3 - 1 - i;\n hCoords[3 * i] = coords[3 * j] + normal[0];\n hCoords[3 * i + 1] = coords[3 * j + 1] + normal[1];\n hCoords[3 * i + 2] = coords[3 * j + 2] + normal[2];\n }\n return hCoords;\n }\n\n private foundationCoords(coords: number[]): number[] {\n const ncoords = coords.slice();\n for (let i = 0; i < coords.length; i++) {\n ncoords[i] = coords[i] * 0.999;\n }\n return ncoords;\n }\n\n addHint(\n filler: Filler,\n stickerDat: StickerDatSticker,\n hintStickers: boolean,\n hintStickerHeightScale: number,\n trim: number,\n normal: number[],\n ): void {\n this.hintStart = filler.ipos;\n const coords = this.hintCoords(\n stickerDat.coords,\n hintStickerHeightScale,\n trim,\n normal,\n );\n filler.makePoly(\n coords,\n this.faceColor,\n hintStickers && !this.isDup ? 2 : 4,\n );\n this.hintEnd = filler.ipos;\n }\n\n public addFoundation(\n filler: Filler,\n stickerDat: StickerDatSticker,\n black: number,\n ) {\n this.foundationStart = filler.ipos;\n const coords = this.foundationCoords(stickerDat.coords);\n filler.makePoly(coords, black, this.isDup ? 4 : 6);\n this.foundationEnd = filler.ipos;\n }\n\n private setHintStickers(filler: Filler, hintStickers: boolean): void {\n const indv = this.isDup || !hintStickers ? 4 : 2;\n // TODO: refactor to avoid non-null-assertions\n for (let i = this.hintStart!; i < this.hintEnd!; i++) {\n filler.ind[i] = indv | (filler.ind[i] & 1);\n }\n }\n\n setStickeringMask(\n filler: Filler,\n faceletMeshStickeringMask: ExperimentalFaceletMeshStickeringMask,\n ): void {\n let c = 0;\n switch (faceletMeshStickeringMask) {\n case \"regular\": {\n c = this.origColor;\n break;\n }\n case \"dim\": {\n if (this.origColor === 0xffffff) {\n c = 0xdddddd;\n } else {\n c = new Color(this.origColor).multiplyScalar(0.5).getHex();\n }\n break;\n }\n case \"oriented\": {\n c = 0x44ddcc;\n break;\n }\n case \"experimentalOriented2\": {\n c = 0xfffdaa;\n break;\n }\n case \"ignored\": {\n c = 0x444444;\n break;\n }\n case \"mystery\": {\n c = 0xf2cbcb;\n break;\n }\n case \"invisible\":\n c = this.origColor;\n }\n this.origColorStickeringMask = c;\n for (let i = 9 * this.stickerStart; i < 9 * this.stickerEnd; i += 3) {\n filler.colors[filler.pos + i] = c >> 16;\n filler.colors[filler.pos + i + 1] = (c >> 8) & 255;\n filler.colors[filler.pos + i + 2] = c & 255;\n }\n // TODO: refactor to avoid non-null-assertions\n for (let i = 9 * this.hintStart!; i < 9 * this.hintEnd!; i += 3) {\n filler.colors[filler.pos + i] = c >> 16;\n filler.colors[filler.pos + i + 1] = (c >> 8) & 255;\n filler.colors[filler.pos + i + 2] = c & 255;\n }\n this.setHintStickers(\n filler,\n faceletMeshStickeringMask !== \"invisible\" && !this.isDup,\n );\n }\n\n public addUVs(filler: Filler): void {\n const uvs = filler.uvs!;\n const vert = filler.vertices;\n const coords = new Array(3);\n for (let i = 3 * this.stickerStart; i < 3 * this.stickerEnd; i++) {\n coords[0] = vert[3 * i];\n coords[1] = vert[3 * i + 1];\n coords[2] = vert[3 * i + 2];\n const uv = filler.tm.getuv(this.faceNum, coords);\n uvs[2 * i] = uv[0];\n uvs[2 * i + 1] = uv[1];\n }\n // TODO: refactor to avoid non-null-assertions\n for (let i = 3 * this.hintStart!; i < 3 * this.hintEnd!; i++) {\n coords[0] = vert[3 * i];\n coords[1] = vert[3 * i + 1];\n coords[2] = vert[3 * i + 2];\n const uv = filler.tm.getuv(this.faceNum, coords);\n uvs[2 * i] = uv[0];\n uvs[2 * i + 1] = uv[1];\n }\n }\n\n public setTexture(filler: Filler, sd: StickerDef): number {\n if (this.texturePtr === sd) {\n return 0;\n }\n this.texturePtr = sd;\n const sz = 6 * filler.sz;\n filler.uvs!.copyWithin(\n 6 * this.stickerStart,\n 6 * sd.stickerStart + sz,\n 6 * sd.stickerEnd + sz,\n );\n filler.uvs!.copyWithin(\n 6 * this.hintStart!, // TODO: refactor to avoid non-null-assertion\n 6 * sd.hintStart! + sz, // TODO: refactor to avoid non-null-assertion\n 6 * sd.hintEnd! + sz, // TODO: refactor to avoid non-null-assertion\n );\n return 1;\n }\n\n public setColor(filler: Filler, sd: StickerDef): number {\n const c = sd.origColorStickeringMask;\n if (this.faceColor !== c) {\n this.faceColor = c;\n const sz = filler.pos;\n filler.colors.copyWithin(\n 9 * this.stickerStart,\n 9 * sd.stickerStart + sz,\n 9 * sd.stickerEnd + sz,\n );\n filler.colors.copyWithin(\n 9 * this.hintStart!, // TODO: refactor to avoid non-null-assertion\n 9 * sd.hintStart! + sz, // TODO: refactor to avoid non-null-assertion\n 9 * sd.hintEnd! + sz, // TODO: refactor to avoid non-null-assertion\n );\n return 1;\n } else {\n return 0;\n }\n }\n}\n\nclass HitPlaneDef {\n public cubie: Group;\n private geo: BufferGeometry;\n constructor(hitface: any, tm: TextureMapper, stickerDat: StickerDat) {\n this.cubie = new Group();\n const coords = hitface.coords as number[];\n const filler = new Filler(coords.length / 3 - 2, tm);\n for (let g = 1; 3 * g + 3 < coords.length; g++) {\n filler.addUncolored(coords, 0);\n filler.addUncolored(coords, g);\n filler.addUncolored(coords, g + 1);\n }\n this.geo = new BufferGeometry();\n filler.setAttributes(this.geo);\n const obj = new Mesh(this.geo, invisMaterial);\n obj.userData[\"quantumMove\"] = stickerDat.notationMapper.notationToExternal(\n new Move(hitface.name),\n );\n this.cubie.scale.setScalar(0.99);\n this.cubie.add(obj);\n }\n}\n\nclass AxisInfo {\n public axis: Vector3;\n public order: number;\n constructor(axisDat: StickerDatAxis) {\n const vec = axisDat.coordinates;\n this.axis = new Vector3(vec[0], vec[1], vec[2]);\n this.order = axisDat.order;\n }\n}\n\nexport interface PG3DOptions {\n stickeringMask?: ExperimentalStickeringMask;\n}\n\nconst DEFAULT_COLOR_FRACTION = 0.71;\nconst PG_SCALE = 0.5;\n\n// TODO: Split into \"scene model\" and \"view\".\n/*\n * PG3D uses a single geometry for the puzzle, with all the faces for\n * each sticker (including the foundation stickers) in a single\n * geometry. We use the materialIndex in the face to point to a\n * specific entry, which is either a colored sticker, invisible, or\n * black (foundation).\n *\n * To support general twisting of a subset of the puzzle, we then\n * instantiate this same geometry in two different meshes with two\n * distinct material arrays. One, the fixed mesh, has the material\n * array set up like: [colored, invisible, black, invisible].\n * The twisting mesh has the material array set up as\n * [invisible, colored, invislble, black]. When not twisted, the\n * two meshes are directly coincident, and the (shared) materialIndex\n * in each face points to a non-invisible material in exactly one of\n * the two meshes. When we decide to twist some cubies, we make\n * the cubies that move point to visible materials in the moving\n * mesh (which makes them point to invisible materials in the static\n * mesh). This way, we only need to rotate the moving mesh as a\n * single object---this should be very fast, and occur entirely in\n * the GPU. Unfortunately this doesn't quite work as fast as we'd\n * like because three.js makes a draw call every time we have a change\n * in the material index. By moving the foundation triangles separate\n * from the sticker triangles, we enhance the probability that many\n * triangles can be rendered in one call speeding up the render.\n * We also get some assistance from puzzleGeometry to try to keep\n * nearby stickers close to each other.\n */\nexport class PG3D extends Object3D implements Twisty3DPuzzle {\n private stickers: { [key: string]: StickerDef[][] };\n private axesInfo: { [key: string]: AxisInfo };\n\n private stickerTargets: Object3D[] = [];\n private controlTargets: Object3D[] = [];\n\n private movingObj: Object3D;\n private filler: Filler;\n private foundationBound: number; // before this: colored; after: black\n private fixedGeo: BufferGeometry;\n private lastPos?: PuzzlePosition;\n private lastMoveTransformationData?: KTransformationData;\n private hintMaterial: Material;\n private stickerMaterial: Material;\n private materialArray1: Material[];\n private materialArray2: Material[];\n private textured: boolean = false;\n private showHintStickers: boolean = false;\n private showFoundations: boolean = false;\n private hintMaterialDisposable: boolean;\n private stickerMaterialDisposable: boolean;\n\n #pendingStickeringUpdate: boolean = false;\n\n constructor(\n private scheduleRenderCallback: () => void,\n private kpuzzle: KPuzzle,\n private stickerDat: StickerDat,\n enableFoundationOpt: boolean = false,\n enableHintStickersOpt: boolean = false,\n hintStickerHeightScale: number = 1,\n private faceletScale: \"auto\" | number = 1,\n private params: PG3DOptions = {},\n ) {\n super();\n if (stickerDat.stickers.length === 0) {\n throw Error(\"Reuse of stickerdat from pg; please don't do that.\");\n }\n this.hintMaterial = new MeshBasicMaterial({\n vertexColors: true,\n transparent: true,\n opacity: 0.5,\n });\n this.hintMaterialDisposable = true;\n this.stickerMaterial = basicStickerMaterial;\n this.stickerMaterialDisposable = false;\n this.axesInfo = {};\n const axesDef = this.stickerDat.axis;\n for (const axis of axesDef) {\n this.axesInfo[axis.quantumMove.family] = new AxisInfo(axis);\n }\n const stickers = this.stickerDat.stickers as any[];\n this.stickers = {};\n this.materialArray1 = new Array(8);\n this.materialArray2 = new Array(8);\n // TODO: the argument enableFoundationOpt really means, do we ever want to display\n // foundations. But it is presently *used* to mean, show foundations initially\n // (and maybe setStickeringMask changes this). So for now we set up the\n // show flag from the enable flag, and turn on the enable flag so later when it's\n // used we will get the foundations. What this means is the geometry always \"pays\"\n // for foundations, even if they aren't displayed.\n this.showFoundation(enableFoundationOpt);\n enableFoundationOpt = true;\n let triangleCount = 0;\n const multiplier = 3;\n for (const sticker of stickers) {\n const sides = sticker.coords.length / 3;\n triangleCount += multiplier * (sides - 2);\n }\n const filler = new Filler(triangleCount, stickerDat.textureMapper);\n const black = 0;\n const normals: number[][] = [];\n let totArea = 0;\n for (const f of stickerDat.faces) {\n normals.push(normal(f.coords));\n totArea += polyarea(f.coords);\n }\n const colorfrac =\n faceletScale !== \"auto\"\n ? faceletScale * faceletScale\n : DEFAULT_COLOR_FRACTION;\n let nonDupStickers = 0;\n for (const sticker of stickers) {\n if (!sticker.isDup) {\n nonDupStickers++;\n }\n }\n const trim =\n (Math.sqrt(totArea / nonDupStickers) * (1 - Math.sqrt(colorfrac))) / 2;\n for (const sticker of stickers) {\n const orbit = sticker.orbit;\n const ord = sticker.ord;\n const ori = sticker.ori;\n if (!this.stickers[orbit]) {\n this.stickers[orbit] = [];\n }\n if (!this.stickers[orbit][ori]) {\n this.stickers[orbit][ori] = [];\n }\n const options: {\n stickeringMask?: ExperimentalFaceletMeshStickeringMask;\n } = {};\n if (params.stickeringMask) {\n options.stickeringMask = experimentalGetFaceletStickeringMask(\n params.stickeringMask,\n orbit,\n ord,\n ori,\n false,\n );\n }\n const stickerdef = new StickerDef(filler, sticker, trim, options);\n this.stickers[orbit][ori][ord] = stickerdef;\n }\n // TODO: the argument enableHintStickersOpt really means, do we ever want to display\n // hint stickers. But it is presently *used* to mean, show hint stickers initially\n // (and maybe setStickeringMask changes this). So for now we set up the\n // show flag from the enable flag, and turn on the enable flag so later when it's\n // used we will get the hint stickers. What this means is the geometry always \"pays\"\n // for hint stickers, even if they aren't displayed.\n this.showHintStickers = enableHintStickersOpt;\n enableHintStickersOpt = true;\n for (const sticker of stickers) {\n const orbit = sticker.orbit;\n const ord = sticker.ord;\n const ori = sticker.ori;\n this.stickers[orbit][ori][ord].addHint(\n filler,\n sticker,\n enableHintStickersOpt,\n hintStickerHeightScale,\n trim,\n normals[sticker.face],\n );\n }\n this.foundationBound = filler.ipos;\n for (const sticker of stickers) {\n const orbit = sticker.orbit;\n const ord = sticker.ord;\n const ori = sticker.ori;\n if (enableFoundationOpt) {\n this.stickers[orbit][ori][ord].addFoundation(filler, sticker, black);\n }\n }\n const fixedGeo = new BufferGeometry();\n filler.setAttributes(fixedGeo);\n filler.makeGroups(fixedGeo);\n const obj = new Mesh(fixedGeo, this.materialArray1);\n obj.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);\n this.add(obj);\n const obj2 = new Mesh(fixedGeo, this.materialArray2);\n obj2.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);\n this.add(obj2);\n const hitfaces = this.stickerDat.faces as any[];\n this.movingObj = obj2;\n this.fixedGeo = fixedGeo;\n this.filler = filler;\n for (const hitface of hitfaces) {\n const facedef = new HitPlaneDef(\n hitface,\n stickerDat.textureMapper,\n this.stickerDat,\n );\n facedef.cubie.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);\n this.add(facedef.cubie);\n this.controlTargets.push(facedef.cubie.children[0]);\n }\n filler.saveOriginalColors();\n stickerDat.stickers = []; // don't need these anymore\n this.updateMaterialArrays();\n /*\n this.experimentalUpdateTexture(\n true,\n new TextureLoader().load(\n \"/experiments.cubing.net/cubing.js/twisty/mkbhd-sprite-red.png\",\n ),\n new TextureLoader().load(\n \"/experiments.cubing.net/cubing.js/twisty/mkbhd-sprite-red-hint.png\",\n ),\n );\n */\n }\n\n public dispose(): void {\n if (this.fixedGeo) {\n this.fixedGeo.dispose();\n }\n if (this.stickerMaterialDisposable) {\n this.stickerMaterial.dispose();\n this.stickerMaterial = basicStickerMaterial;\n this.stickerMaterialDisposable = false;\n }\n if (this.hintMaterialDisposable) {\n this.hintMaterial.dispose();\n this.hintMaterial = basicStickerMaterial;\n this.hintMaterialDisposable = false;\n }\n }\n\n public experimentalGetStickerTargets(): Object3D[] {\n return this.stickerTargets;\n }\n\n public experimentalGetControlTargets(): Object3D[] {\n return this.controlTargets;\n }\n\n #isValidMove(move: Move): boolean {\n try {\n this.kpuzzle.moveToTransformation(move);\n return true;\n } catch (_) {\n return false;\n }\n }\n\n getClosestMoveToAxis(\n point: Vector3,\n transformations: {\n invert: boolean;\n depth?: \"secondSlice\" | \"rotation\" | \"none\";\n },\n ): { move: Move; order: number } | null {\n let closestMove: Move | null = null;\n let closestMoveDotProduct: number = 0;\n\n let modify: (move: Move) => Move = (m) => m;\n switch (transformations.depth) {\n case \"secondSlice\": {\n modify = (m: Move) => m.modified({ innerLayer: 2 });\n break;\n }\n case \"rotation\": {\n modify = (m: Move) => m.modified({ family: `${m.family}v` });\n break;\n }\n }\n\n for (const axis of this.stickerDat.axis) {\n const product = point.dot(new Vector3(...axis.coordinates));\n if (product > closestMoveDotProduct) {\n const modified = this.stickerDat.notationMapper.notationToExternal(\n modify(axis.quantumMove),\n );\n if (!modified) {\n continue;\n }\n // Special case: for the FTO, there is a rotation that is defined\n // as T. This is a rotation (without the v), and it does not have\n // a v on the end nor does it correspond to a geometry. So, if\n // depth is \"none\", we'll pick up \"T\" as a normal move; we\n // shouldn't.\n console.log(modified.family);\n if (modified.family === \"T\" && transformations.depth === \"none\") {\n continue;\n }\n if (this.#isValidMove(modified)) {\n closestMoveDotProduct = product;\n closestMove = modified;\n }\n }\n }\n\n if (!closestMove) {\n return null;\n }\n\n if (transformations.invert) {\n closestMove = closestMove.invert();\n }\n const order = this.kpuzzle\n .moveToTransformation(closestMove)\n .repetitionOrder();\n return { move: closestMove, order }; // TODO: push this down\n }\n\n setStickeringMask(stickeringMask: ExperimentalStickeringMask): void {\n this.params.stickeringMask = stickeringMask;\n if (stickeringMask.specialBehaviour !== \"picture\") {\n for (const orbitDefinition of this.kpuzzle.definition.orbits) {\n // This isn't strictly necessary, but it keeps the following lines more\n // readable by fitting each `for` loop onto a single line when running\n // `make format`.\n const { numPieces, numOrientations } = orbitDefinition;\n for (let pieceIdx = 0; pieceIdx < numPieces; pieceIdx++) {\n for (let faceletIdx = 0; faceletIdx < numOrientations; faceletIdx++) {\n const faceletStickeringMask = experimentalGetFaceletStickeringMask(\n stickeringMask,\n orbitDefinition.orbitName,\n pieceIdx,\n faceletIdx,\n false,\n );\n const stickerDef =\n this.stickers[orbitDefinition.orbitName][faceletIdx][pieceIdx];\n if (\n this.textured &&\n this.hintMaterialDisposable &&\n faceletStickeringMask === \"invisible\"\n ) {\n // ignore \"invisible\" if textured hints\n } else {\n stickerDef.setStickeringMask(this.filler, faceletStickeringMask);\n }\n }\n }\n }\n }\n this.#pendingStickeringUpdate = true;\n if (this.lastPos) {\n this.onPositionChange(this.lastPos);\n }\n }\n\n public onPositionChange(p: PuzzlePosition): void {\n const { pattern } = p;\n this.movingObj.rotation.set(0, 0, 0);\n let colormods = 0;\n const filler = this.filler;\n const ind = filler.ind;\n if (\n !this.lastPos ||\n this.#pendingStickeringUpdate ||\n !this.lastPos.pattern.isIdentical(pattern)\n ) {\n for (const orbit in this.stickers) {\n const pieces = this.stickers[orbit];\n const pos2 = pattern.patternData[orbit];\n const orin = pieces.length;\n if (orin === 1) {\n const pieces2 = pieces[0];\n for (let i = 0; i < pieces2.length; i++) {\n const ni = pos2.pieces[i];\n if (this.textured) {\n colormods += pieces2[i].setTexture(filler, pieces2[ni]);\n } else {\n colormods += pieces2[i].setColor(filler, pieces2[ni]);\n }\n }\n } else {\n for (let ori = 0; ori < orin; ori++) {\n const pieces2 = pieces[ori];\n for (let i = 0; i < pieces2.length; i++) {\n const nori = (ori + orin - pos2.orientation[i]) % orin;\n const ni = pos2.pieces[i];\n if (this.textured) {\n colormods += pieces2[i].setTexture(filler, pieces[nori][ni]);\n } else {\n colormods += pieces2[i].setColor(filler, pieces[nori][ni]);\n }\n }\n }\n }\n }\n this.lastPos = p;\n }\n let vismods = 0;\n for (const moveProgress of p.movesInProgress) {\n const externalMove = moveProgress.move;\n // TODO: unswizzle goes external to internal, and so does the call after that\n // and so does the stateForBlockMove call\n const unswizzled = this.stickerDat.unswizzle(externalMove);\n if (!unswizzled) {\n // bad times, but let's not throw.\n return;\n }\n\n const move = externalMove;\n let quantumTransformation: KTransformation | undefined;\n try {\n quantumTransformation = this.kpuzzle.moveToTransformation(\n move.modified({ amount: 1 }),\n );\n } catch (e) {\n // couldn't get it from a quantum of the external move. Let's try\n // getting it from a quantum of the internal move, translated back\n // to external so we can get the transformation. This happens for\n // instance when working with \"x2\" on megaminx.\n const move1 = this.stickerDat.notationMapper.notationToInternal(move);\n if (move1) {\n const move2 = this.stickerDat.notationMapper.notationToExternal(\n move1.modified({ amount: 1 }),\n );\n if (move2) {\n quantumTransformation = this.kpuzzle.moveToTransformation(move2);\n }\n }\n if (!quantumTransformation) {\n console.log(e);\n throw e;\n }\n }\n const ax = this.axesInfo[unswizzled.family];\n const turnNormal = ax.axis;\n const angle =\n (-this.ease(moveProgress.fraction) *\n moveProgress.direction *\n unswizzled.amount *\n TAU) /\n ax.order;\n this.movingObj.rotateOnAxis(turnNormal, angle);\n const quantumTransformationData =\n quantumTransformation.transformationData;\n if (this.lastMoveTransformationData !== quantumTransformationData) {\n for (const orbit in this.stickers) {\n const pieces = this.stickers[orbit];\n const orin = pieces.length;\n const bmv = quantumTransformationData[orbit];\n for (let ori = 0; ori < orin; ori++) {\n const pieces2 = pieces[ori];\n for (let i = 0; i < pieces2.length; i++) {\n const p2 = pieces2[i];\n const ni = bmv.permutation[i];\n let tv = 0;\n if (ni !== i || bmv.orientationDelta[i] !== 0) {\n tv = 1;\n }\n if (tv !== p2.twistVal) {\n if (tv) {\n for (let j = p2.stickerStart; j < p2.stickerEnd; j++) {\n ind[j] |= 1;\n }\n // TODO: refactor to avoid non-null-assertion\n for (let j = p2.hintStart!; j < p2.hintEnd!; j++) {\n ind[j] |= 1;\n }\n // TODO: refactor to avoid non-null-assertion\n for (\n let j = p2.foundationStart!;\n j < p2.foundationEnd!;\n j++\n ) {\n ind[j] |= 1;\n }\n } else {\n for (let j = p2.stickerStart!; j < p2.stickerEnd; j++) {\n ind[j] &= ~1;\n }\n // TODO: refactor to avoid non-null-assertion\n for (let j = p2.hintStart!; j < p2.hintEnd!; j++) {\n ind[j] &= ~1;\n }\n // TODO: refactor to avoid non-null-assertion\n for (\n let j = p2.foundationStart!;\n j < p2.foundationEnd!;\n j++\n ) {\n ind[j] &= ~1;\n }\n }\n p2.twistVal = tv;\n vismods++;\n }\n }\n }\n }\n this.lastMoveTransformationData = quantumTransformationData;\n }\n }\n if (this.#pendingStickeringUpdate || vismods) {\n this.filler.makeGroups(this.fixedGeo);\n }\n if (this.#pendingStickeringUpdate || colormods) {\n if (this.textured) {\n (this.fixedGeo.getAttribute(\"uv\") as BufferAttribute).addUpdateRange(\n 0,\n 6 * this.foundationBound,\n );\n (this.fixedGeo.getAttribute(\"uv\") as BufferAttribute).needsUpdate =\n true;\n }\n if (this.#pendingStickeringUpdate || !this.textured) {\n (this.fixedGeo.getAttribute(\"color\") as BufferAttribute).addUpdateRange(\n 0,\n 9 * this.foundationBound,\n );\n (this.fixedGeo.getAttribute(\"color\") as BufferAttribute).needsUpdate =\n true;\n }\n }\n this.scheduleRenderCallback();\n this.#pendingStickeringUpdate = false;\n }\n\n private ease(fraction: number): number {\n return smootherStep(fraction);\n }\n\n private showHintFacelets(v: boolean) {\n this.showHintStickers = v;\n }\n\n private updateMaterialArrays() {\n for (let i = 0; i < 8; i++) {\n this.materialArray1[i] = invisMaterial;\n this.materialArray2[i] = invisMaterial;\n }\n this.materialArray1[0] = this.stickerMaterial;\n this.materialArray2[1] = this.stickerMaterial;\n if (this.showHintStickers) {\n this.materialArray1[2] = this.hintMaterial;\n this.materialArray2[3] = this.hintMaterial;\n } else {\n this.materialArray1[2] = invisMaterial;\n this.materialArray2[3] = invisMaterial;\n }\n if (this.showFoundations) {\n this.materialArray1[6] = foundationMaterial;\n this.materialArray2[7] = foundationMaterial;\n } else {\n this.materialArray1[6] = invisMaterial;\n this.materialArray2[7] = invisMaterial;\n }\n }\n\n private showFoundation(v: boolean) {\n this.showFoundations = v;\n }\n\n private setHintStickerOpacity(v: number): void {\n if (this.hintMaterialDisposable) {\n this.hintMaterial.dispose();\n this.hintMaterialDisposable = false;\n }\n if (v === 0) {\n this.hintMaterial = invisMaterial;\n } else if (v === 1) {\n this.hintMaterial = this.stickerMaterial;\n } else {\n this.hintMaterial = new MeshBasicMaterial({\n vertexColors: true,\n transparent: true,\n opacity: v,\n });\n this.hintMaterialDisposable = true;\n }\n }\n\n public experimentalUpdateOptions(options: {\n showMainStickers?: boolean;\n hintFacelets?: HintFaceletStyle;\n showFoundation?: boolean; // TODO: better name\n hintStickerOpacity?: number;\n faceletScale?: \"auto\" | number;\n }): void {\n if (options.hintFacelets !== undefined) {\n this.showHintFacelets(options.hintFacelets !== \"none\");\n }\n if (options.showFoundation !== undefined) {\n this.showFoundation(options.showFoundation);\n }\n if (options.hintStickerOpacity !== undefined) {\n this.setHintStickerOpacity(options.hintStickerOpacity);\n }\n this.#pendingStickeringUpdate = true;\n if (this.lastPos) {\n this.onPositionChange(this.lastPos);\n }\n if (\n typeof options.faceletScale !== \"undefined\" &&\n options.faceletScale !== this.faceletScale\n ) {\n console.warn(\n \"Dynamic facelet scale is not yet supported for PG3D. For now, re-create the TwistyPlayer to change the facelet scale.\",\n );\n }\n this.updateMaterialArrays();\n this.scheduleRenderCallback();\n }\n\n private adduvs() {\n const filler = this.filler;\n if (filler.uvs) {\n return;\n }\n this.filler.uvs = new Float32Array(12 * filler.sz);\n for (const orbit in this.stickers) {\n const pieces = this.stickers[orbit];\n const orin = pieces.length;\n for (let ori = 0; ori < orin; ori++) {\n const pieces2 = pieces[ori];\n for (const piece2 of pieces2) {\n piece2.addUVs(this.filler);\n }\n }\n }\n filler.uvs!.copyWithin(6 * filler.sz, 0, 6 * filler.sz);\n const sa1 = filler.uvs!.subarray(0, 6 * filler.sz);\n this.fixedGeo.setAttribute(\"uv\", new BufferAttribute(sa1, 2, true));\n }\n\n public experimentalUpdateTexture(\n enabled: boolean,\n stickerTexture?: Texture | null,\n hintTexture?: Texture | null,\n ) {\n if (!stickerTexture) {\n enabled = false;\n }\n if (enabled && !this.filler.uvs) {\n this.adduvs();\n }\n this.textured = enabled;\n if (this.stickerMaterialDisposable) {\n this.stickerMaterial.dispose();\n this.stickerMaterialDisposable = false;\n }\n if (enabled) {\n this.stickerMaterial = new MeshBasicMaterial({\n map: stickerTexture,\n side: FrontSide,\n transparent: false,\n });\n this.stickerMaterialDisposable = true;\n } else {\n this.stickerMaterial = basicStickerMaterial;\n }\n if (this.hintMaterialDisposable) {\n this.hintMaterial.dispose();\n this.hintMaterialDisposable = false;\n }\n if (enabled) {\n this.hintMaterial = new MeshBasicMaterial({\n map: hintTexture,\n side: FrontSide,\n transparent: true,\n });\n this.hintMaterialDisposable = true;\n } else {\n this.hintMaterial = basicStickerMaterial;\n }\n if (enabled) {\n this.showHintFacelets(hintTexture !== null);\n }\n this.updateMaterialArrays();\n this.#pendingStickeringUpdate = true;\n if (this.lastPos) {\n this.onPositionChange(this.lastPos);\n }\n this.scheduleRenderCallback();\n }\n}\n", "import { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Color } from \"three/src/math/Color.js\";\nimport { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport type {\n StickerDat,\n StickerDatSticker,\n} from \"../../../../puzzle-geometry\";\nimport { cubeFaceStyles, type FaceletStyle } from \"./CubieStyle\";\nimport { type FaceletSurface, logoSurface } from \"./PuzzleLogo\";\nimport {\n type PiecePlane,\n SOLID_PIECE_CHAMFER,\n SOLID_PIECE_GROOVE,\n solidPieceGeometry,\n type VertexRange,\n} from \"./SolidPieceGeometry\";\nimport {\n type FaceletPlan,\n HINT_FACELET_ELEVATION,\n HINT_FACELET_SCALE,\n type PieceMesh,\n type PiecePlan,\n type PuzzlePlan,\n paintInternal,\n} from \"./StickerlessPlan\";\n\n/**\n * The pieces of a puzzle, read off the stickers `PuzzleGeometry` produces.\n *\n * A piece is bounded by the faces of the puzzle its stickers sit on, and by the\n * cuts separating it from its neighbors. Both are recoverable from the surface:\n * the faces are the sticker planes, and every cut shows up as an edge between\n * two stickers of different pieces, lying square to an axis the puzzle turns\n * about. Recovering the cuts is most of the work, since an edge fits several\n * axes and only one of them is the cut it lies on.\n *\n * `CubePieces` gets first refusal on the N\u00D7N\u00D7N cubes, whose pieces are all the\n * same shape and worth rounding properly.\n */\n\nconst PG_SCALE = 0.5; // Matches `PG3D`, so that the camera framing carries over.\n\nconst EPSILON = 1e-6;\n\n/** How far a logo floats off the face it is printed on, in feature widths. */\nconst LOGO_ELEVATION = 0.01;\n\nfunction vertexAt(sticker: StickerDatSticker, index: number): Vector3 {\n return new Vector3(\n sticker.coords[3 * index],\n sticker.coords[3 * index + 1],\n sticker.coords[3 * index + 2],\n );\n}\n\nfunction polygonOf(sticker: StickerDatSticker): Vector3[] {\n const vertices: Vector3[] = [];\n for (let i = 0; i < sticker.coords.length / 3; i++) {\n vertices.push(vertexAt(sticker, i));\n }\n return vertices;\n}\n\n/** The outward unit normal of a sticker on a puzzle centered at the origin. */\nfunction outwardNormal(polygon: Vector3[]): Vector3 | null {\n const normal = new Vector3().crossVectors(\n new Vector3().subVectors(polygon[1], polygon[0]),\n new Vector3().subVectors(polygon[2], polygon[0]),\n );\n if (normal.length() < EPSILON) {\n return null;\n }\n normal.normalize();\n return normal.dot(polygon[0]) < 0 ? normal.negate() : normal;\n}\n\nfunction keyOf(vertex: Vector3, quantum: number): string {\n return `${Math.round(vertex.x / quantum)},${Math.round(vertex.y / quantum)},${Math.round(vertex.z / quantum)}`;\n}\n\ninterface PieceStickers {\n orbit: string;\n ord: number;\n stickers: { sticker: StickerDatSticker; polygon: Vector3[] }[];\n duplicates: StickerDatSticker[];\n}\n\n/**\n * How each face of the puzzle is colored.\n *\n * A puzzle shaped like a cube borrows the scheme every other cube in the app is\n * painted from, so that a skewb and a 3\u00D73\u00D73 side by side are the same plastic.\n * Anything else keeps the colors `PuzzleGeometry` gave it, dimmed the way\n * `PG3D` dims them.\n */\nfunction faceStyles(\n faceNormals: (Vector3 | null)[],\n faceColors: (string | undefined)[],\n): FaceletStyle[] | null {\n const styles: FaceletStyle[] = [];\n const cubeFaces: number[] = [];\n for (let face = 0; face < faceNormals.length; face++) {\n const normal = faceNormals[face];\n const color = faceColors[face];\n if (!normal || color === undefined) {\n return null;\n }\n cubeFaces.push(\n cubeFaceStyles.findIndex((style) => style.vector.dot(normal) > 0.999),\n );\n }\n const isCube =\n faceNormals.length === cubeFaceStyles.length &&\n new Set(cubeFaces).size === cubeFaceStyles.length &&\n !cubeFaces.includes(-1) &&\n new Set(faceColors).size === faceColors.length;\n for (let face = 0; face < faceNormals.length; face++) {\n if (isCube) {\n styles.push(cubeFaceStyles[cubeFaces[face]]);\n continue;\n }\n const color = new Color(faceColors[face]).getHex();\n const dimColor = new Color(color).multiplyScalar(0.5).getHex();\n styles.push({\n color,\n dimColor,\n hintColor: color,\n hintDimColor: dimColor,\n hintOpacityScale: 1,\n });\n }\n return styles;\n}\n\n/** The hint facelet of one sticker: its own outline, floating beyond it. */\nfunction hintPolygon(polygon: Vector3[], normal: Vector3): Vector3[] {\n const centroid = new Vector3();\n for (const vertex of polygon) {\n centroid.addScaledVector(vertex, 1 / polygon.length);\n }\n return polygon.map((vertex) =>\n centroid\n .clone()\n .addScaledVector(\n new Vector3().subVectors(vertex, centroid),\n HINT_FACELET_SCALE,\n )\n .addScaledVector(normal, HINT_FACELET_ELEVATION),\n );\n}\n\n/**\n * The plan for a puzzle whose pieces can be cut out of its stickers this way,\n * or `null` for one where they can't \u2014 which falls back to `PG3D`.\n */\nexport function solidPuzzlePlan(stickerDat: StickerDat): PuzzlePlan | null {\n const { stickers } = stickerDat;\n if (stickers.length === 0 || stickerDat.faces.length === 0) {\n return null;\n }\n\n let radius = 0;\n let faceletArea = 0;\n let faceletCount = 0;\n for (const sticker of stickers) {\n if (sticker.coords.length < 9 || sticker.coords.length % 3 !== 0) {\n return null;\n }\n for (let i = 0; i < sticker.coords.length; i += 3) {\n radius = Math.max(\n radius,\n Math.hypot(\n sticker.coords[i],\n sticker.coords[i + 1],\n sticker.coords[i + 2],\n ),\n );\n }\n }\n const quantum = radius * 1e-5;\n\n const faceNormals: (Vector3 | null)[] = new Array(stickerDat.faces.length);\n const faceColors: (string | undefined)[] = new Array(stickerDat.faces.length);\n const pieces = new Map<string, PieceStickers>();\n const order: PieceStickers[] = [];\n // Which pieces meet along each edge of the surface.\n const edges = new Map<string, Set<string>>();\n let faceDistance = 0;\n\n for (const sticker of stickers) {\n const pieceKey = `${sticker.orbit}/${sticker.ord}`;\n let piece = pieces.get(pieceKey);\n if (!piece) {\n piece = {\n orbit: sticker.orbit,\n ord: sticker.ord,\n stickers: [],\n duplicates: [],\n };\n pieces.set(pieceKey, piece);\n order.push(piece);\n }\n // A duplicate is stacked on top of a real sticker; only the real one is\n // part of the surface.\n if (sticker.isDup) {\n piece.duplicates.push(sticker);\n continue;\n }\n const polygon = polygonOf(sticker);\n const normal = outwardNormal(polygon);\n if (!normal) {\n return null;\n }\n for (const vertex of polygon) {\n if (Math.abs(vertex.dot(normal) - polygon[0].dot(normal)) > quantum) {\n return null; // Not flat.\n }\n }\n const distance = polygon[0].dot(normal);\n faceDistance = faceDistance || distance;\n if (faceNormals[sticker.face]) {\n if (faceNormals[sticker.face]!.dot(normal) < 0.999) {\n return null; // One face, two planes.\n }\n } else {\n faceNormals[sticker.face] = normal;\n }\n faceColors[sticker.face] ??= sticker.color;\n if (faceColors[sticker.face] !== sticker.color) {\n return null;\n }\n faceletCount++;\n for (let i = 1; i < polygon.length - 1; i++) {\n faceletArea +=\n new Vector3()\n .subVectors(polygon[i], polygon[0])\n .cross(new Vector3().subVectors(polygon[i + 1], polygon[0]))\n .length() / 2;\n }\n piece.stickers.push({ sticker, polygon });\n\n for (let i = 0; i < polygon.length; i++) {\n const edgeKey = [\n keyOf(polygon[i], quantum),\n keyOf(polygon[(i + 1) % polygon.length], quantum),\n ]\n .sort()\n .join(\"|\");\n const sharing = edges.get(edgeKey);\n if (sharing) {\n sharing.add(pieceKey);\n } else {\n edges.set(edgeKey, new Set([pieceKey]));\n }\n }\n }\n\n const styles = faceStyles(faceNormals, faceColors);\n if (!styles) {\n return null;\n }\n // A groove is a gap in the plastic, so it goes by the size of the puzzle. On\n // a puzzle whose facelets are small that would swamp them, so it goes by the\n // size of a facelet too, whichever comes out narrower. The two agree on a\n // 3\u00D73\u00D73, whose half-width is one and a half facelets.\n const featureScale = Math.min(\n faceDistance,\n 1.5 * Math.sqrt(faceletArea / faceletCount),\n );\n\n const cuts = cutPlanes(\n order,\n edges,\n stickerDat.axis.map((axis) => new Vector3(...axis.coordinates).normalize()),\n quantum,\n );\n if (!cuts) {\n return null;\n }\n const plans: PiecePlan[] = [];\n for (const piece of order) {\n const plan = newSolidPiece(\n piece,\n { planes: cuts, edges },\n {\n quantum,\n radius,\n featureScale,\n },\n );\n if (!plan) {\n return null;\n }\n plans.push(plan);\n }\n return { faceStyles: styles, pieces: plans, scale: PG_SCALE };\n}\n\n/**\n * Every cut of the puzzle, recovered from the surface.\n *\n * A cut shows up as an edge between two stickers of different pieces, and it\n * faces along an axis the puzzle turns about, so each such edge nominates the\n * axes it lies square to. Several axes fit any one edge, and the way to tell\n * the real cut from the rest is that a cut never crosses a piece: it is a plane\n * the whole puzzle is cut along, not just a plane that happens to slip between\n * these two pieces. Anything some piece straddles is dropped.\n *\n * Returns `null` when an edge is left with no cut to lie on, which means this\n * isn't a puzzle whose pieces can be recovered this way.\n */\ninterface Cut {\n normal: Vector3;\n offset: number;\n /** How many edges of the surface lie in it. */\n uses: number;\n}\n\nfunction cutPlanes(\n pieces: PieceStickers[],\n edges: Map<string, Set<string>>,\n axes: Vector3[],\n quantum: number,\n): Cut[] | null {\n const candidates = new Map<string, Cut>();\n const boundaryEdges: [Vector3, Vector3][] = [];\n for (const piece of pieces) {\n const pieceKey = `${piece.orbit}/${piece.ord}`;\n for (const { polygon } of piece.stickers) {\n for (let i = 0; i < polygon.length; i++) {\n const a = polygon[i];\n const b = polygon[(i + 1) % polygon.length];\n const sharing = edges.get(\n [keyOf(a, quantum), keyOf(b, quantum)].sort().join(\"|\"),\n );\n // An edge the piece keeps to itself is a fold in one piece of plastic,\n // not a cut.\n if (!sharing || ![...sharing].some((key) => key !== pieceKey)) {\n continue;\n }\n boundaryEdges.push([a, b]);\n for (const axis of axes) {\n if (Math.abs(a.dot(axis) - b.dot(axis)) > quantum) {\n continue;\n }\n // One entry per plane, however many edges nominate it.\n const offset = a.dot(axis);\n const key = `${keyOf(axis, 1e-4)}|${Math.round(offset / quantum)}`;\n const candidate = candidates.get(key);\n if (candidate) {\n candidate.uses++;\n } else {\n candidates.set(key, { normal: axis, offset, uses: 1 });\n }\n }\n }\n }\n }\n\n // A cut of the puzzle runs the whole way across it, so it holds many of the\n // edges it could hold. A plane that merely grazes a corner holds a handful,\n // and picking by this is what tells the two apart where geometry cannot.\n const cuts = [...candidates.values()].sort((a, b) => b.uses - a.uses);\n const kept = cuts.filter(({ normal, offset }) => {\n for (const piece of pieces) {\n let above = false;\n let below = false;\n for (const { polygon } of piece.stickers) {\n let onIt = true;\n for (const vertex of polygon) {\n above ||= vertex.dot(normal) > offset + quantum;\n below ||= vertex.dot(normal) < offset - quantum;\n onIt &&= Math.abs(vertex.dot(normal) - offset) <= quantum;\n }\n // A plane holding a whole sticker is the puzzle's own surface, not a\n // cut. Letting it through would cut every piece back from its face.\n if (onIt) {\n return false;\n }\n }\n if (above && below) {\n return false;\n }\n }\n return true;\n });\n\n for (const [a, b] of boundaryEdges) {\n const covered = kept.some(\n ({ normal, offset }) =>\n Math.abs(a.dot(normal) - offset) < quantum &&\n Math.abs(b.dot(normal) - offset) < quantum,\n );\n if (!covered) {\n return null;\n }\n }\n return kept;\n}\n\nfunction newSolidPiece(\n piece: PieceStickers,\n cuts: { planes: Cut[]; edges: Map<string, Set<string>> },\n sizes: { quantum: number; radius: number; featureScale: number },\n): PiecePlan | null {\n if (piece.stickers.length === 0) {\n return null;\n }\n const planes: PiecePlane[] = [];\n // Which plane each sticker's face became, so its facelet can be painted.\n const planeOfSticker = new Map<StickerDatSticker, number>();\n\n // Strictly inside the piece, since a cut runs along an edge of a sticker and\n // the rest of the piece stays on one side of it. Pulling it toward the\n // puzzle's center instead would leave a shallow piece behind.\n const interior = new Vector3();\n for (const { polygon } of piece.stickers) {\n for (const vertex of polygon) {\n interior.addScaledVector(\n vertex,\n 1 / polygon.length / piece.stickers.length,\n );\n }\n }\n\n for (const { sticker, polygon } of piece.stickers) {\n const normal = outwardNormal(polygon)!;\n planeOfSticker.set(sticker, planes.length);\n planes.push({\n normal,\n offset: polygon[0].dot(normal),\n color: sticker.face,\n });\n }\n\n // One cut per edge the piece shares with another piece, which is what bounds\n // it. Taking every cut the piece happens to sit on one side of instead would\n // let a plane that only grazes the surface here slice into the body.\n const pieceKey = `${piece.orbit}/${piece.ord}`;\n for (const { polygon } of piece.stickers) {\n for (let i = 0; i < polygon.length; i++) {\n const a = polygon[i];\n const b = polygon[(i + 1) % polygon.length];\n const sharing = cuts.edges.get(\n [keyOf(a, sizes.quantum), keyOf(b, sizes.quantum)].sort().join(\"|\"),\n );\n // An edge the piece keeps to itself is a fold in one piece of plastic,\n // not a cut: it stays sharp, and no plane belongs to it.\n if (!sharing || ![...sharing].some((key) => key !== pieceKey)) {\n continue;\n }\n // `cuts.planes` is in order of how much of the puzzle each cut explains,\n // so the first one holding this edge is the one both pieces settle on.\n const cut = cuts.planes.find(\n ({ normal, offset }) =>\n Math.abs(a.dot(normal) - offset) < sizes.quantum &&\n Math.abs(b.dot(normal) - offset) < sizes.quantum,\n );\n if (!cut) {\n return null;\n }\n const outward = interior.dot(cut.normal) < cut.offset;\n const normal = outward ? cut.normal.clone() : cut.normal.clone().negate();\n const offset = outward ? cut.offset : -cut.offset;\n if (\n planes.some(\n (plane) =>\n plane.color === null &&\n plane.normal.dot(normal) > 0.9999 &&\n Math.abs(plane.offset - offset) < sizes.quantum,\n )\n ) {\n continue;\n }\n planes.push({ normal, offset, color: null });\n }\n }\n\n // A cut can also bound the piece from behind, where it never reaches the\n // surface and so no edge nominates it \u2014 the back of a cube's center, say.\n // Those are the cuts the piece stays clear of entirely; a cut it touches is\n // one an edge already spoke for, and adding it here would let a plane that\n // only grazes the surface slice into the body.\n for (const cut of cuts.planes) {\n let touches = false;\n let above = false;\n let below = false;\n for (const { polygon } of piece.stickers) {\n for (const vertex of polygon) {\n const side = vertex.dot(cut.normal) - cut.offset;\n if (Math.abs(side) <= sizes.quantum) {\n touches = true;\n } else if (side > 0) {\n above = true;\n } else {\n below = true;\n }\n }\n }\n if (touches || above === below) {\n continue;\n }\n planes.push(\n above\n ? {\n normal: cut.normal.clone().negate(),\n offset: -cut.offset,\n color: null,\n }\n : { normal: cut.normal.clone(), offset: cut.offset, color: null },\n );\n }\n\n const solid = solidPieceGeometry(planes, {\n groove: SOLID_PIECE_GROOVE * sizes.featureScale,\n chamfer: SOLID_PIECE_CHAMFER * sizes.featureScale,\n radius: sizes.radius,\n });\n if (!solid) {\n return null;\n }\n\n // The hint facelets are a mesh of their own: they are drawn with a different\n // material, so they belong in a different batch.\n const hintPositions: number[] = [];\n const hintRanges = new Map<StickerDatSticker, VertexRange>();\n for (const { sticker, polygon } of piece.stickers) {\n const normal = outwardNormal(polygon)!;\n const hint = hintPolygon(polygon, normal);\n const start = hintPositions.length / 3;\n for (let i = 1; i < hint.length - 1; i++) {\n for (const vertex of [hint[0], hint[i], hint[i + 1]]) {\n hintPositions.push(vertex.x, vertex.y, vertex.z);\n }\n }\n hintRanges.set(sticker, {\n start,\n count: hintPositions.length / 3 - start,\n });\n }\n\n const body = newPieceMesh(solid.positions);\n const hint =\n hintPositions.length > 0\n ? newPieceMesh(new Float32Array(hintPositions))\n : null;\n paintInternal(body.colors, solid.internalRanges);\n\n // A logo sits just clear of the plastic, on the largest square that fits the\n // facelet. Kept per face rather than per sticker, so that the duplicates\n // stacked on a center's square get the square they share.\n const logoByFace = new Map<number, FaceletSurface | null>();\n for (const { sticker, polygon } of piece.stickers) {\n logoByFace.set(\n sticker.face,\n logoSurface(\n polygon,\n outwardNormal(polygon)!,\n LOGO_ELEVATION * sizes.featureScale,\n ),\n );\n }\n\n const facelets: FaceletPlan[] = piece.stickers.map(({ sticker }) => ({\n ori: sticker.ori,\n faceStyle: sticker.face,\n body: solid.ranges[planeOfSticker.get(sticker)!],\n hint: [hintRanges.get(sticker)!],\n logo: logoByFace.get(sticker.face) ?? null,\n }));\n for (const sticker of piece.duplicates) {\n facelets.push({\n ori: sticker.ori,\n faceStyle: sticker.face,\n body: [],\n hint: [],\n logo: logoByFace.get(sticker.face) ?? null,\n });\n }\n\n return {\n orbit: piece.orbit,\n ord: piece.ord,\n // The geometry is already where the piece belongs.\n home: new Matrix4(),\n body,\n hint,\n facelets,\n };\n}\n\nfunction newPieceMesh(positions: Float32Array): PieceMesh {\n const geometry = new BufferGeometry();\n geometry.setAttribute(\"position\", new BufferAttribute(positions, 3));\n const colors = new BufferAttribute(\n new Uint8Array((4 * positions.length) / 3),\n 4,\n true,\n );\n geometry.setAttribute(\"color\", colors);\n return { geometry, colors };\n}\n", "import { Vector3 } from \"three/src/math/Vector3.js\";\n\n/**\n * One flat side of a piece.\n *\n * A piece of a twisty puzzle is what is left when every cut of the puzzle has\n * been made, so it is exactly an intersection of half-spaces \u2014 which is a far\n * easier thing to hand a renderer than a mesh. Give this module the planes and\n * it hands back a solid.\n */\nexport interface PiecePlane {\n /** Unit vector pointing out of the piece. */\n normal: Vector3;\n /** The plane is where `position \u00B7 normal === offset`. */\n offset: number;\n /**\n * `null` for a side that meets another piece rather than the outside world:\n * it is cut back to open a groove, and shows the plastic inside.\n */\n color: number | null;\n}\n\nexport interface VertexRange {\n start: number;\n count: number;\n}\n\nexport interface SolidPiece {\n positions: Float32Array;\n vertexCount: number;\n /**\n * Vertices to paint with each plane's color, indexed like the planes passed\n * in. A colored plane owns its own face plus the bevels running around it, so\n * that changing a facelet's color changes all of it.\n */\n ranges: VertexRange[][];\n /** Everything else: the plastic inside the puzzle. */\n internalRanges: VertexRange[];\n}\n\n/**\n * Default groove and bevel, as a fraction of how far the puzzle's faces sit\n * from its center. The groove is sized to read about as wide as the one between\n * two cubies of the 3\u00D73\u00D73; the bevel is deliberately a hairline, just enough to\n * catch the light along a rim, since a facelet is a flat plate and a wide bevel\n * would make every piece look raised.\n */\nexport const SOLID_PIECE_GROOVE = 0.018;\nexport const SOLID_PIECE_CHAMFER = 0.005;\n\nexport interface SolidPieceOptions {\n /**\n * How far a side that meets another piece is cut back. Half the width of the\n * groove between two pieces, since both sides give up the same.\n */\n groove: number;\n /**\n * Width of the bevel where a colored face runs into a groove. Only there:\n * where two colored faces meet, the piece is one unbroken piece of plastic\n * and its edge stays sharp, the way a cube's own edges do.\n */\n chamfer: number;\n /** Roughly how far the puzzle reaches from its center. Sets the tolerances. */\n radius: number;\n}\n\ninterface WorkingPlane {\n normal: Vector3;\n offset: number;\n /**\n * Which of the planes passed in colors this one: itself for a real side, the\n * face it runs alongside for a bevel, and -1 for the box we start from.\n */\n source: number;\n}\n\ninterface Facet {\n plane: number;\n vertices: Vector3[];\n}\n\nconst BOX_PLANE = -1;\n\n/** The polygon of the starting box's side along `normal`. */\nfunction boxFacet(planeIdx: number, normal: Vector3, size: number): Facet {\n const reference =\n Math.abs(normal.y) > 0.5 ? new Vector3(0, 0, 1) : new Vector3(0, 1, 0);\n const u = new Vector3().crossVectors(reference, normal).normalize();\n const v = new Vector3().crossVectors(normal, u);\n const center = normal.clone().multiplyScalar(size);\n return {\n plane: planeIdx,\n vertices: (\n [\n [-1, -1],\n [1, -1],\n [1, 1],\n [-1, 1],\n ] as const\n ).map(([su, sv]) =>\n center\n .clone()\n .addScaledVector(u, su * size)\n .addScaledVector(v, sv * size),\n ),\n };\n}\n\nconst BOX_NORMALS = [\n new Vector3(1, 0, 0),\n new Vector3(-1, 0, 0),\n new Vector3(0, 1, 0),\n new Vector3(0, -1, 0),\n new Vector3(0, 0, 1),\n new Vector3(0, 0, -1),\n];\n\n/** Sorts points lying in one plane into a loop, counter-clockwise from outside. */\nfunction orderInPlane(points: Vector3[], normal: Vector3): Vector3[] {\n const centroid = new Vector3();\n for (const point of points) {\n centroid.addScaledVector(point, 1 / points.length);\n }\n const reference = new Vector3().subVectors(points[0], centroid).normalize();\n const other = new Vector3().crossVectors(normal, reference);\n const offset = new Vector3();\n return points\n .map((point) => {\n offset.subVectors(point, centroid);\n return {\n point,\n angle: Math.atan2(offset.dot(other), offset.dot(reference)),\n };\n })\n .sort((a, b) => a.angle - b.angle)\n .map(({ point }) => point);\n}\n\nfunction vertexKey(vertex: Vector3, quantum: number): string {\n return `${Math.round(vertex.x / quantum)},${Math.round(vertex.y / quantum)},${Math.round(vertex.z / quantum)}`;\n}\n\nfunction clipByPlane(\n facets: Facet[],\n plane: WorkingPlane,\n planeIdx: number,\n epsilon: number,\n): Facet[] {\n const clipped: Facet[] = [];\n const capPoints: Vector3[] = [];\n const capKeys = new Set<string>();\n const quantum = epsilon * 10;\n\n for (const facet of facets) {\n const kept: Vector3[] = [];\n const count = facet.vertices.length;\n for (let i = 0; i < count; i++) {\n const current = facet.vertices[i];\n const next = facet.vertices[(i + 1) % count];\n const currentSide = current.dot(plane.normal) - plane.offset;\n const nextSide = next.dot(plane.normal) - plane.offset;\n if (currentSide <= epsilon) {\n kept.push(current);\n }\n if (\n (currentSide > epsilon && nextSide < -epsilon) ||\n (currentSide < -epsilon && nextSide > epsilon)\n ) {\n kept.push(\n current.clone().lerp(next, currentSide / (currentSide - nextSide)),\n );\n }\n }\n if (kept.length < 3) {\n continue;\n }\n clipped.push({ plane: facet.plane, vertices: kept });\n for (const vertex of kept) {\n if (Math.abs(vertex.dot(plane.normal) - plane.offset) > epsilon) {\n continue;\n }\n // The same corner reaches the cap once per facet that meets there.\n const key = vertexKey(vertex, quantum);\n if (!capKeys.has(key)) {\n capKeys.add(key);\n capPoints.push(vertex);\n }\n }\n }\n\n if (capPoints.length >= 3) {\n clipped.push({\n plane: planeIdx,\n vertices: orderInPlane(capPoints, plane.normal),\n });\n }\n return clipped;\n}\n\nfunction buildFacets(\n planes: WorkingPlane[],\n radius: number,\n epsilon: number,\n): Facet[] | null {\n let facets = BOX_NORMALS.map((normal) =>\n boxFacet(BOX_PLANE, normal, radius * 4),\n );\n for (let planeIdx = 0; planeIdx < planes.length; planeIdx++) {\n facets = clipByPlane(facets, planes[planeIdx], planeIdx, epsilon);\n }\n // A surviving side of the starting box means the planes didn't close a solid.\n if (facets.some((facet) => facet.plane === BOX_PLANE) || facets.length < 4) {\n return null;\n }\n return facets;\n}\n\n/**\n * The bevel planes: one for each edge where a colored face meets a groove.\n *\n * Adding them as more half-spaces rather than building the bevel geometry by\n * hand keeps the result a convex solid built the one way, and makes the bevels\n * meet each other correctly at the piece's corners for free.\n */\nfunction chamferPlanes(\n facets: Facet[],\n planes: WorkingPlane[],\n chamfer: number,\n epsilon: number,\n): WorkingPlane[] {\n const quantum = epsilon * 10;\n // Which facets meet along each edge.\n const edges = new Map<string, number[]>();\n for (const facet of facets) {\n const { vertices } = facet;\n for (let i = 0; i < vertices.length; i++) {\n const edgeKey = [\n vertexKey(vertices[i], quantum),\n vertexKey(vertices[(i + 1) % vertices.length], quantum),\n ]\n .sort()\n .join(\"|\");\n const sharing = edges.get(edgeKey);\n if (sharing) {\n sharing.push(facet.plane);\n } else {\n edges.set(edgeKey, [facet.plane]);\n }\n }\n }\n\n const added: WorkingPlane[] = [];\n const seen = new Set<string>();\n for (const sharing of edges.values()) {\n if (sharing.length !== 2) {\n continue;\n }\n const [a, b] = sharing;\n const colored = planes[a].source !== -1 ? a : b;\n const internal = planes[a].source !== -1 ? b : a;\n // Only the rim between plastic that shows and plastic that doesn't.\n if (planes[colored].source === -1 || planes[internal].source !== -1) {\n continue;\n }\n const pairKey = `${colored}|${internal}`;\n if (seen.has(pairKey)) {\n continue;\n }\n seen.add(pairKey);\n const sum = new Vector3().addVectors(\n planes[colored].normal,\n planes[internal].normal,\n );\n if (sum.length() < 1e-6) {\n continue;\n }\n added.push({\n normal: sum.clone().normalize(),\n // Where the two faces meet, measured along the bevel's own direction.\n offset:\n (planes[colored].offset + planes[internal].offset) / sum.length() -\n chamfer,\n source: planes[colored].source,\n });\n }\n return added;\n}\n\n/**\n * Builds a piece as the intersection of its planes: the sides that meet other\n * pieces cut back to open a thin groove, and a small bevel run around every\n * colored face that borders one.\n *\n * Returns `null` if the planes don't bound a solid, so that a caller handed\n * something unexpected can fall back rather than draw nonsense.\n */\nexport function solidPieceGeometry(\n planes: PiecePlane[],\n options: SolidPieceOptions,\n): SolidPiece | null {\n const epsilon = options.radius * 1e-6;\n // An internal plane keeps `source: -1`, which is also what marks it as the\n // plastic inside: only a colored plane names a facelet to paint.\n const working: WorkingPlane[] = planes.map((plane, index) => ({\n normal: plane.normal,\n offset: plane.offset - (plane.color === null ? options.groove : 0),\n source: plane.color === null ? -1 : index,\n }));\n\n const plain = buildFacets(working, options.radius, epsilon);\n if (!plain) {\n return null;\n }\n const withChamfers =\n options.chamfer > 0\n ? working.concat(chamferPlanes(plain, working, options.chamfer, epsilon))\n : working;\n const facets =\n (options.chamfer > 0\n ? buildFacets(withChamfers, options.radius, epsilon)\n : plain) ?? plain;\n\n const positions: number[] = [];\n const ranges: VertexRange[][] = planes.map(() => []);\n const internalRanges: VertexRange[] = [];\n for (const facet of facets) {\n const start = positions.length / 3;\n for (let i = 1; i < facet.vertices.length - 1; i++) {\n for (const vertex of [\n facet.vertices[0],\n facet.vertices[i],\n facet.vertices[i + 1],\n ]) {\n positions.push(vertex.x, vertex.y, vertex.z);\n }\n }\n const range = { start, count: positions.length / 3 - start };\n if (range.count === 0) {\n continue;\n }\n if (withChamfers[facet.plane].source === -1) {\n internalRanges.push(range);\n } else {\n ranges[withChamfers[facet.plane].source].push(range);\n }\n }\n\n return {\n positions: new Float32Array(positions),\n vertexCount: positions.length / 3,\n ranges,\n internalRanges,\n };\n}\n", "import { DoubleSide } from \"three/src/constants.js\";\nimport { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Object3D } from \"three/src/core/Object3D.js\";\nimport { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport { Color } from \"three/src/math/Color.js\";\nimport { Quaternion } from \"three/src/math/Quaternion.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { Group } from \"three/src/objects/Group.js\";\nimport { Mesh } from \"three/src/objects/Mesh.js\";\nimport type { Texture } from \"three/src/textures/Texture.js\";\nimport type { KPuzzle } from \"../../../../kpuzzle\";\nimport type { ExperimentalStickeringMask } from \"../../../../puzzles/cubing-private\";\nimport type { PuzzlePosition } from \"../../../controllers/AnimationTypes\";\nimport { smootherStep } from \"../../../controllers/easing\";\nimport { TAU } from \"../TAU\";\nimport { bodyMaskColors, newVertexColorBodyMaterial } from \"./CubieStyle\";\nimport {\n type FaceletSurface,\n newLogoMesh,\n rectangleLogoSurface,\n surfaceMatrix,\n} from \"./PuzzleLogo\";\nimport {\n type PiecePlane,\n solidPieceGeometry,\n type VertexRange,\n} from \"./SolidPieceGeometry\";\nimport type { Twisty3DPuzzle } from \"./Twisty3DPuzzle\";\n\nconst DEGREE = TAU / 360;\n\nconst SLOT_ANGLE_DEGREES = 30;\nconst WEDGES_PER_LAYER = 12;\n\nconst CUBE_HALF_EDGE = 1;\nconst EQUATOR_HALF_HEIGHT = 0.25;\nconst PUZZLE_SCALE = 0.5;\n\nconst DEFAULT_FACELET_SCALE = 0.85;\nconst STICKER_ELEVATION = 0.004;\n\nconst COLOR_UP = 0xffff00;\nconst COLOR_DOWN = 0xffffff;\nconst RING_COLORS = [0x2266ff, 0xff9900, 0x00ff00, 0xff0000];\n\nconst FRAME_OFFSET_DEGREES = 180;\n\nconst BODY_COLOR = 0x111111;\n\nconst MIRROR = -1;\n\nconst Y_AXIS = new Vector3(0, 1, 0);\nconst SLICE_AXIS = new Vector3(\n MIRROR * Math.sin(15 * DEGREE),\n 0,\n Math.cos(15 * DEGREE),\n).normalize();\n\nconst SLICE_QUATERNION = new Quaternion().setFromAxisAngle(SLICE_AXIS, TAU / 2);\nconst HALF_TURN_Y = new Quaternion().setFromAxisAngle(Y_AXIS, TAU / 2);\n\ntype Point2 = [x: number, z: number];\n\nfunction slotAzimuthDegrees(slot: number): number {\n return (\n FRAME_OFFSET_DEGREES +\n (slot < WEDGES_PER_LAYER\n ? SLOT_ANGLE_DEGREES * slot + 120\n : 90 - SLOT_ANGLE_DEGREES * (slot - WEDGES_PER_LAYER))\n );\n}\n\nfunction slotQuaternion(slot: number): Quaternion {\n const quaternion = new Quaternion().setFromAxisAngle(\n Y_AXIS,\n MIRROR * slotAzimuthDegrees(slot) * DEGREE,\n );\n if (slot >= WEDGES_PER_LAYER) {\n quaternion.multiply(\n new Quaternion().setFromAxisAngle(new Vector3(0, 0, 1), TAU / 2),\n );\n }\n return quaternion;\n}\n\nconst SLOT_QUATERNIONS: Quaternion[] = new Array(2 * WEDGES_PER_LAYER)\n .fill(null)\n .map((_, slot) => slotQuaternion(slot));\n\ntype WedgeShape = \"cornerHigh\" | \"cornerLow\" | \"edge\";\n\nfunction wedgeShape(homeSlot: number): WedgeShape {\n const phase =\n homeSlot < WEDGES_PER_LAYER\n ? homeSlot % 3\n : (homeSlot - WEDGES_PER_LAYER + 2) % 3;\n return phase === 0 ? \"cornerHigh\" : phase === 1 ? \"cornerLow\" : \"edge\";\n}\n\nfunction outerFaceOffsetDegrees(shape: WedgeShape): number {\n switch (shape) {\n case \"cornerHigh\":\n return -30;\n case \"cornerLow\":\n return 30;\n case \"edge\":\n return 0;\n }\n}\n\nfunction squarePoint(phiDegrees: number): Point2 {\n return polarPoint(phiDegrees, Math.round(phiDegrees / 90) * 90);\n}\n\nfunction polarPoint(phiDegrees: number, faceCenterDegrees: number): Point2 {\n const radius =\n CUBE_HALF_EDGE / Math.cos((phiDegrees - faceCenterDegrees) * DEGREE);\n const phi = phiDegrees * DEGREE;\n return [MIRROR * radius * Math.sin(phi), radius * Math.cos(phi)];\n}\n\nfunction wedgeCrossSection(shape: WedgeShape): Point2[] {\n const faceCenterDegrees = outerFaceOffsetDegrees(shape);\n return [\n [0, 0],\n polarPoint(-SLOT_ANGLE_DEGREES / 2, faceCenterDegrees),\n polarPoint(SLOT_ANGLE_DEGREES / 2, faceCenterDegrees),\n ];\n}\n\nfunction cornerCrossSection(): Point2[] {\n return [\n [0, 0],\n polarPoint(-SLOT_ANGLE_DEGREES / 2, -30),\n polarPoint(SLOT_ANGLE_DEGREES / 2, -30), // the cube corner, shared by both halves\n polarPoint(SLOT_ANGLE_DEGREES + SLOT_ANGLE_DEGREES / 2, 60),\n ];\n}\n\nconst CORNER_PAIRS: [high: number, low: number][] = [];\nfor (let slot = 0; slot < 2 * WEDGES_PER_LAYER; slot++) {\n if (wedgeShape(slot) === \"cornerHigh\") {\n CORNER_PAIRS.push([slot, nextSlotInLayer(slot)]);\n }\n}\n\nfunction nextSlotInLayer(slot: number): number {\n return slot < WEDGES_PER_LAYER\n ? (slot + 1) % WEDGES_PER_LAYER\n : WEDGES_PER_LAYER + ((slot - WEDGES_PER_LAYER + 1) % WEDGES_PER_LAYER);\n}\n\nfunction wedgeSideColor(homeSlot: number): number {\n return ringColorAt(slotAzimuthDegrees(homeSlot));\n}\n\ninterface PrismSpec {\n polygon: Point2[];\n yBottom: number;\n yTop: number;\n topColor: number | null;\n bottomColor: number | null;\n sideColors: (number | null)[];\n}\n\ninterface StickerSpec {\n corners: Vector3[];\n normal: Vector3;\n color: number;\n}\n\nfunction prismBodyPositions(spec: PrismSpec): Float32Array {\n const { polygon, yBottom, yTop } = spec;\n const out: number[] = [];\n const n = polygon.length;\n for (const y of [yTop, yBottom]) {\n for (let i = 1; i < n - 1; i++) {\n out.push(\n polygon[0][0],\n y,\n polygon[0][1],\n polygon[i][0],\n y,\n polygon[i][1],\n polygon[i + 1][0],\n y,\n polygon[i + 1][1],\n );\n }\n }\n for (let i = 0; i < n; i++) {\n const [x0, z0] = polygon[i];\n const [x1, z1] = polygon[(i + 1) % n];\n out.push(x0, yBottom, z0, x1, yBottom, z1, x1, yTop, z1);\n out.push(x0, yBottom, z0, x1, yTop, z1, x0, yTop, z0);\n }\n return new Float32Array(out);\n}\n\nfunction prismStickerSpecs(spec: PrismSpec): StickerSpec[] {\n const { polygon, yBottom, yTop, topColor, bottomColor, sideColors } = spec;\n const specs: StickerSpec[] = [];\n if (topColor !== null) {\n specs.push({\n corners: polygon.map(([x, z]) => new Vector3(x, yTop, z)),\n normal: new Vector3(0, 1, 0),\n color: topColor,\n });\n }\n if (bottomColor !== null) {\n specs.push({\n corners: polygon.map(([x, z]) => new Vector3(x, yBottom, z)),\n normal: new Vector3(0, -1, 0),\n color: bottomColor,\n });\n }\n\n let centroidX = 0;\n let centroidZ = 0;\n for (const [x, z] of polygon) {\n centroidX += x / polygon.length;\n centroidZ += z / polygon.length;\n }\n\n for (let i = 0; i < polygon.length; i++) {\n const color = sideColors[i];\n if (color === null || color === undefined) {\n continue;\n }\n const [x0, z0] = polygon[i];\n const [x1, z1] = polygon[(i + 1) % polygon.length];\n const normal = new Vector3(z1 - z0, 0, -(x1 - x0)).normalize();\n const outward =\n normal.x * ((x0 + x1) / 2 - centroidX) +\n normal.z * ((z0 + z1) / 2 - centroidZ);\n if (outward < 0) {\n normal.negate();\n }\n specs.push({\n corners: [\n new Vector3(x0, yBottom, z0),\n new Vector3(x1, yBottom, z1),\n new Vector3(x1, yTop, z1),\n new Vector3(x0, yTop, z0),\n ],\n normal,\n color,\n });\n }\n return specs;\n}\n\nfunction stickerPositions(\n spec: StickerSpec,\n faceletScale: number,\n): Float32Array {\n const center = new Vector3();\n for (const corner of spec.corners) {\n center.addScaledVector(corner, 1 / spec.corners.length);\n }\n const placed = spec.corners.map((corner) =>\n center\n .clone()\n .addScaledVector(corner.clone().sub(center), faceletScale)\n .addScaledVector(spec.normal, STICKER_ELEVATION),\n );\n const out: number[] = [];\n for (let i = 1; i < placed.length - 1; i++) {\n out.push(\n placed[0].x,\n placed[0].y,\n placed[0].z,\n placed[i].x,\n placed[i].y,\n placed[i].z,\n placed[i + 1].x,\n placed[i + 1].y,\n placed[i + 1].z,\n );\n }\n return new Float32Array(out);\n}\n\n/**\n * How far a side that meets another piece is cut back, and how wide the bevel\n * around a colored face is. Sized so that the groove between two pieces reads\n * about as wide as the one between two cubies of the 3\u00D73\u00D73.\n */\nconst PIECE_GROOVE_HALF_WIDTH = 0.018;\nconst PIECE_CHAMFER = 0.005;\n/** How far the puzzle reaches from its center, for the geometry's tolerances. */\nconst PUZZLE_RADIUS = CUBE_HALF_EDGE * Math.SQRT2;\n\n/**\n * The planes bounding one piece: the top and bottom of the prism, plus one per\n * side of its cross-section. A side with no color is a cut, where this piece\n * meets the next one.\n */\nfunction prismPlanes(spec: PrismSpec): PiecePlane[] {\n const { polygon, sideColors } = spec;\n const planes: PiecePlane[] = [\n { normal: new Vector3(0, 1, 0), offset: spec.yTop, color: spec.topColor },\n {\n normal: new Vector3(0, -1, 0),\n offset: -spec.yBottom,\n color: spec.bottomColor,\n },\n ];\n let centroidX = 0;\n let centroidZ = 0;\n for (const [x, z] of polygon) {\n centroidX += x / polygon.length;\n centroidZ += z / polygon.length;\n }\n for (let i = 0; i < polygon.length; i++) {\n const [x0, z0] = polygon[i];\n const [x1, z1] = polygon[(i + 1) % polygon.length];\n const normal = new Vector3(z1 - z0, 0, -(x1 - x0)).normalize();\n if (normal.x * (x0 - centroidX) + normal.z * (z0 - centroidZ) < 0) {\n normal.negate();\n }\n planes.push({\n normal,\n offset: normal.x * x0 + normal.z * z0,\n color: sideColors[i] ?? null,\n });\n }\n return planes;\n}\n\n/**\n * The whole piece as one solid of colored plastic: every face the puzzle shows\n * takes its own color, every side that meets another piece is cut back to the\n * plastic inside. There is no sticker and no separate foundation.\n */\nfunction stickerlessPieceGeometry(spec: PrismSpec): BufferGeometry {\n const planes = prismPlanes(spec);\n const piece = solidPieceGeometry(planes, {\n groove: PIECE_GROOVE_HALF_WIDTH,\n chamfer: PIECE_CHAMFER,\n radius: PUZZLE_RADIUS,\n });\n if (!piece) {\n throw new Error(\"Could not build a Square-1 piece out of its planes.\");\n }\n const colors = new Uint8Array(4 * piece.vertexCount);\n const paint = (ranges: VertexRange[], color: number) => {\n for (const range of ranges) {\n for (let i = range.start; i < range.start + range.count; i++) {\n colors[4 * i] = (color >> 16) & 0xff;\n colors[4 * i + 1] = (color >> 8) & 0xff;\n colors[4 * i + 2] = color & 0xff;\n colors[4 * i + 3] = 0xff;\n }\n }\n };\n paint(piece.internalRanges, bodyMaskColors.internal);\n for (let i = 0; i < planes.length; i++) {\n const color = planes[i].color;\n if (color !== null) {\n paint(piece.ranges[i], color);\n }\n }\n\n const geometry = new BufferGeometry();\n geometry.setAttribute(\"position\", new BufferAttribute(piece.positions, 3));\n geometry.setAttribute(\"color\", new BufferAttribute(colors, 4, true));\n return geometry;\n}\n\nconst bodyMaterial = new MeshBasicMaterial({\n color: new Color(BODY_COLOR).convertLinearToSRGB(),\n side: DoubleSide,\n});\n\nlet stickerlessMaterialCache: MeshBasicMaterial | undefined;\nfunction stickerlessMaterial(): MeshBasicMaterial {\n return (stickerlessMaterialCache ??= newVertexColorBodyMaterial());\n}\n\nconst stickerMaterialCache = new Map<number, MeshBasicMaterial>();\nfunction stickerMaterial(color: number): MeshBasicMaterial {\n let material = stickerMaterialCache.get(color);\n if (!material) {\n material = new MeshBasicMaterial({\n color: new Color(color).convertLinearToSRGB(),\n side: DoubleSide,\n });\n stickerMaterialCache.set(color, material);\n }\n return material;\n}\n\nclass Square1Piece extends Group {\n readonly body: Mesh;\n readonly #stickerSpecs: StickerSpec[] = [];\n readonly #stickerMeshes: Mesh[] = [];\n\n constructor(spec: PrismSpec, faceletScale: number, stickerless: boolean) {\n super();\n\n if (stickerless) {\n this.body = new Mesh(\n stickerlessPieceGeometry(spec),\n stickerlessMaterial(),\n );\n this.add(this.body);\n return;\n }\n\n const bodyGeometry = new BufferGeometry();\n bodyGeometry.setAttribute(\n \"position\",\n new BufferAttribute(prismBodyPositions(spec), 3),\n );\n this.body = new Mesh(bodyGeometry, bodyMaterial);\n this.add(this.body);\n\n this.#stickerSpecs = prismStickerSpecs(spec);\n for (const stickerSpec of this.#stickerSpecs) {\n const geometry = new BufferGeometry();\n geometry.setAttribute(\n \"position\",\n new BufferAttribute(stickerPositions(stickerSpec, faceletScale), 3),\n );\n const mesh = new Mesh(geometry, stickerMaterial(stickerSpec.color));\n this.#stickerMeshes.push(mesh);\n this.add(mesh);\n }\n }\n\n setFaceletScale(faceletScale: number): void {\n for (let i = 0; i < this.#stickerMeshes.length; i++) {\n const geometry = this.#stickerMeshes[i].geometry;\n geometry.setAttribute(\n \"position\",\n new BufferAttribute(\n stickerPositions(this.#stickerSpecs[i], faceletScale),\n 3,\n ),\n );\n }\n }\n\n setFoundationVisible(visible: boolean): void {\n // A stickerless piece is nothing but its body.\n if (this.#stickerMeshes.length > 0) {\n this.body.visible = visible;\n }\n }\n}\n\nfunction wedgePrismSpec(homeSlot: number): PrismSpec {\n const shape = wedgeShape(homeSlot);\n return {\n polygon: wedgeCrossSection(shape),\n yBottom: EQUATOR_HALF_HEIGHT,\n yTop: CUBE_HALF_EDGE,\n topColor: homeSlot < WEDGES_PER_LAYER ? COLOR_UP : COLOR_DOWN,\n bottomColor: null,\n sideColors: [null, wedgeSideColor(homeSlot), null],\n };\n}\n\nfunction cornerPrismSpec([high, low]: [number, number]): PrismSpec {\n return {\n polygon: cornerCrossSection(),\n yBottom: EQUATOR_HALF_HEIGHT,\n yTop: CUBE_HALF_EDGE,\n topColor: high < WEDGES_PER_LAYER ? COLOR_UP : COLOR_DOWN,\n bottomColor: null,\n sideColors: [null, wedgeSideColor(high), wedgeSideColor(low), null],\n };\n}\n\nfunction equatorPrismSpec(homePiece: number): PrismSpec {\n const startDegrees = FRAME_OFFSET_DEGREES + (homePiece === 0 ? 105 : 285);\n const boundaries = [startDegrees];\n for (\n let corner = Math.ceil((startDegrees - 45) / 90) * 90 + 45;\n corner < startDegrees + 180;\n corner += 90\n ) {\n boundaries.push(corner);\n }\n boundaries.push(startDegrees + 180);\n return {\n polygon: boundaries.map((phiDegrees) => squarePoint(phiDegrees)),\n yBottom: -EQUATOR_HALF_HEIGHT,\n yTop: EQUATOR_HALF_HEIGHT,\n topColor: null,\n bottomColor: null,\n sideColors: [\n ...boundaries\n .slice(0, -1)\n .map((phiDegrees, i) =>\n ringColorAt((phiDegrees + boundaries[i + 1]) / 2),\n ),\n null,\n ],\n };\n}\n\n/**\n * Where a logo goes on a Square-1: the equator, which is the one piece of the\n * puzzle that is a block rather than a wedge, on the side of it that is a whole\n * face of the cube. The two slivers to either side of that face are too narrow\n * to print on.\n */\nconst LOGO_EQUATOR_PIECE = 0;\n/** How far the logo floats off the face, clear of a sticker at the same spot. */\nconst LOGO_ELEVATION = 2 * STICKER_ELEVATION;\n\nfunction equatorLogoSurface(spec: PrismSpec): FaceletSurface | null {\n const { polygon, yBottom, yTop, sideColors } = spec;\n let best: FaceletSurface | null = null;\n let bestWidth = 0;\n for (let i = 0; i < polygon.length; i++) {\n if (sideColors[i] === null || sideColors[i] === undefined) {\n continue;\n }\n const [x0, z0] = polygon[i];\n const [x1, z1] = polygon[(i + 1) % polygon.length];\n const width = Math.hypot(x1 - x0, z1 - z0);\n if (width <= bestWidth) {\n continue;\n }\n const normal = new Vector3(z1 - z0, 0, -(x1 - x0)).normalize();\n const u = new Vector3(x1 - x0, 0, z1 - z0).multiplyScalar(0.5);\n const v = new Vector3(0, (yTop - yBottom) / 2, 0);\n // `v` points up, so `u` is whichever way around the face leaves the logo\n // facing out of the puzzle rather than into it.\n if (new Vector3().crossVectors(u, v).dot(normal) < 0) {\n u.negate();\n }\n const center = new Vector3(\n (x0 + x1) / 2,\n (yBottom + yTop) / 2,\n (z0 + z1) / 2,\n ).addScaledVector(normal, LOGO_ELEVATION);\n bestWidth = width;\n best = rectangleLogoSurface(center, u, v);\n }\n return best;\n}\n\nfunction ringColorAt(phiDegrees: number): number {\n const faceIndex = Math.round(phiDegrees / 90);\n return RING_COLORS[((faceIndex % 4) + 4) % 4];\n}\n\n/**\n * - `stickers`: flat colored facelets floating above a black body.\n * - `stickerless`: solid pieces of colored plastic, lit so that the faces read\n * as separate planes. `showFoundation` and `faceletScale` do not apply, since\n * there is no separate foundation or sticker to size.\n */\nexport type ExperimentalWedgeStyle = \"stickers\" | \"stickerless\";\n\nexport interface Square1_3DOptions {\n experimentalWedgeStyle?: ExperimentalWedgeStyle;\n showFoundation?: boolean;\n faceletScale?: \"auto\" | number;\n hintFacelets?: unknown;\n hintFaceletsElevation?: unknown;\n}\n\nexport class Square1_3D extends Object3D implements Twisty3DPuzzle {\n #wedgePieces: Square1Piece[] = [];\n #cornerPieces: Square1Piece[] = [];\n #equatorPieces: Square1Piece[] = [];\n #faceletScale: number = DEFAULT_FACELET_SCALE;\n #showFoundation = true;\n #stickerless = true;\n\n #slotOfPiece = new Int8Array(2 * WEDGES_PER_LAYER);\n #slotMoveMask = new Uint8Array(2 * WEDGES_PER_LAYER);\n #slotRotation: (Quaternion | null)[] = new Array(2 * WEDGES_PER_LAYER).fill(\n null,\n );\n\n constructor(\n kpuzzle: KPuzzle,\n private scheduleRenderCallback?: () => void,\n options: Square1_3DOptions = {},\n ) {\n super();\n\n if (kpuzzle.name() !== \"Square-1\") {\n throw new Error(\n `Invalid puzzle for this Square1_3D implementation: ${kpuzzle.name()}`,\n );\n }\n\n if (typeof options.faceletScale === \"number\") {\n this.#faceletScale = options.faceletScale;\n }\n if (typeof options.showFoundation === \"boolean\") {\n this.#showFoundation = options.showFoundation;\n }\n if (options.experimentalWedgeStyle) {\n this.#stickerless = options.experimentalWedgeStyle === \"stickerless\";\n }\n\n for (let piece = 0; piece < 2 * WEDGES_PER_LAYER; piece++) {\n const wedge = new Square1Piece(\n wedgePrismSpec(piece),\n this.#faceletScale,\n this.#stickerless,\n );\n wedge.setFoundationVisible(this.#showFoundation);\n wedge.quaternion.copy(SLOT_QUATERNIONS[piece]);\n this.#wedgePieces.push(wedge);\n this.add(wedge);\n }\n for (const pair of CORNER_PAIRS) {\n const corner = new Square1Piece(\n cornerPrismSpec(pair),\n this.#faceletScale,\n this.#stickerless,\n );\n corner.setFoundationVisible(this.#showFoundation);\n corner.visible = false; // Until `onPositionChange` decides.\n this.#cornerPieces.push(corner);\n this.add(corner);\n }\n for (let piece = 0; piece < 2; piece++) {\n const equator = new Square1Piece(\n equatorPrismSpec(piece),\n this.#faceletScale,\n this.#stickerless,\n );\n equator.setFoundationVisible(this.#showFoundation);\n this.#equatorPieces.push(equator);\n this.add(equator);\n }\n\n this.scale.set(PUZZLE_SCALE, PUZZLE_SCALE, PUZZLE_SCALE);\n }\n\n onPositionChange(position: PuzzlePosition): void {\n const wedges = position.pattern.patternData[\"WEDGES\"];\n const equator = position.pattern.patternData[\"EQUATOR\"];\n\n for (let slot = 0; slot < 2 * WEDGES_PER_LAYER; slot++) {\n this.#slotOfPiece[wedges.pieces[slot]] = slot;\n this.#slotMoveMask[slot] = 0;\n this.#slotRotation[slot] = null;\n }\n\n let equatorRotation: Quaternion | null = null;\n let moveBit = 1;\n for (const moveInProgress of position.movesInProgress) {\n const { family, amount } = moveInProgress.move;\n const turns =\n smootherStep(moveInProgress.fraction) *\n moveInProgress.direction *\n amount;\n\n let slotStart: number;\n let slotEnd: number;\n const quaternion = new Quaternion();\n switch (family) {\n case \"U_SQ_\":\n quaternion.setFromAxisAngle(\n Y_AXIS,\n MIRROR * turns * SLOT_ANGLE_DEGREES * DEGREE,\n );\n slotStart = 0;\n slotEnd = WEDGES_PER_LAYER;\n break;\n case \"D_SQ_\":\n quaternion.setFromAxisAngle(\n Y_AXIS,\n -MIRROR * turns * SLOT_ANGLE_DEGREES * DEGREE,\n );\n slotStart = WEDGES_PER_LAYER;\n slotEnd = 2 * WEDGES_PER_LAYER;\n break;\n case \"_SLASH_\":\n quaternion.setFromAxisAngle(SLICE_AXIS, (turns * TAU) / 2);\n slotStart = WEDGES_PER_LAYER / 2;\n slotEnd = WEDGES_PER_LAYER + WEDGES_PER_LAYER / 2;\n equatorRotation = quaternion;\n break;\n default:\n continue;\n }\n\n for (let slot = slotStart; slot < slotEnd; slot++) {\n const existing = this.#slotRotation[slot];\n this.#slotRotation[slot] = existing\n ? existing.clone().premultiply(quaternion)\n : quaternion;\n this.#slotMoveMask[slot] |= moveBit;\n }\n moveBit = (moveBit << 1) & 0xff;\n }\n\n for (let piece = 0; piece < 2 * WEDGES_PER_LAYER; piece++) {\n this.#placeWedge(this.#wedgePieces[piece], this.#slotOfPiece[piece]);\n }\n\n for (let i = 0; i < CORNER_PAIRS.length; i++) {\n const [high, low] = CORNER_PAIRS[i];\n const highSlot = this.#slotOfPiece[high];\n const lowSlot = this.#slotOfPiece[low];\n const joined =\n nextSlotInLayer(highSlot) === lowSlot &&\n this.#slotMoveMask[highSlot] === this.#slotMoveMask[lowSlot];\n this.#cornerPieces[i].visible = joined;\n this.#wedgePieces[high].visible = !joined;\n this.#wedgePieces[low].visible = !joined;\n if (joined) {\n this.#placeWedge(this.#cornerPieces[i], highSlot);\n }\n }\n\n for (let slot = 0; slot < 2; slot++) {\n const piece = equator.pieces[slot];\n const quaternion = this.#equatorPieces[piece].quaternion;\n quaternion.identity();\n if (piece !== slot) {\n quaternion.multiply(HALF_TURN_Y);\n }\n if (((equator.orientation[slot] % 6) + 6) % 6 >= 3) {\n quaternion.premultiply(SLICE_QUATERNION);\n }\n if (slot === 1 && equatorRotation) {\n quaternion.premultiply(equatorRotation);\n }\n }\n }\n\n #placeWedge(piece: Square1Piece, slot: number): void {\n const quaternion = piece.quaternion.copy(SLOT_QUATERNIONS[slot]);\n const rotation = this.#slotRotation[slot];\n if (rotation) {\n quaternion.premultiply(rotation);\n }\n }\n\n setStickeringMask(_stickeringMask: ExperimentalStickeringMask): void {}\n\n #logoMesh: Mesh | null = null;\n /**\n * Prints a logo on the equator block, or takes it off again when passed\n * `null`.\n *\n * The image is stretched onto a square sized to the face, so its own\n * proportions don't matter. It is a child of the piece, so it turns and flips\n * with the equator.\n */\n experimentalSetLogo(texture: Texture | null): void {\n if (this.#logoMesh) {\n this.#logoMesh.removeFromParent();\n (this.#logoMesh.material as MeshBasicMaterial).dispose();\n this.#logoMesh = null;\n }\n if (texture) {\n const surface = equatorLogoSurface(equatorPrismSpec(LOGO_EQUATOR_PIECE));\n if (surface) {\n this.#logoMesh = newLogoMesh(texture);\n surfaceMatrix(surface, this.#logoMesh.matrix);\n this.#equatorPieces[LOGO_EQUATOR_PIECE].add(this.#logoMesh);\n }\n }\n this.scheduleRenderCallback?.();\n }\n\n experimentalUpdateOptions(options: Square1_3DOptions): void {\n let changed = false;\n\n if (typeof options.showFoundation === \"boolean\") {\n if (options.showFoundation !== this.#showFoundation) {\n this.#showFoundation = options.showFoundation;\n for (const piece of this.#allPieces()) {\n piece.setFoundationVisible(this.#showFoundation);\n }\n changed = true;\n }\n }\n\n if (typeof options.faceletScale !== \"undefined\") {\n const faceletScale =\n options.faceletScale === \"auto\"\n ? DEFAULT_FACELET_SCALE\n : options.faceletScale;\n if (faceletScale !== this.#faceletScale) {\n this.#faceletScale = faceletScale;\n for (const piece of this.#allPieces()) {\n piece.setFaceletScale(faceletScale);\n }\n changed = true;\n }\n }\n\n if (changed) {\n this.scheduleRenderCallback?.();\n }\n }\n\n *#allPieces(): Generator<Square1Piece> {\n yield* this.#wedgePieces;\n yield* this.#cornerPieces;\n yield* this.#equatorPieces;\n }\n}\n", "import { BackSide } from \"three/src/constants.js\";\nimport { BufferAttribute } from \"three/src/core/BufferAttribute.js\";\nimport { BufferGeometry } from \"three/src/core/BufferGeometry.js\";\nimport { Object3D } from \"three/src/core/Object3D.js\";\nimport type { Material } from \"three/src/materials/Material.js\";\nimport { MeshBasicMaterial } from \"three/src/materials/MeshBasicMaterial.js\";\nimport { Matrix4 } from \"three/src/math/Matrix4.js\";\nimport { Vector3 } from \"three/src/math/Vector3.js\";\nimport { BatchedMesh } from \"three/src/objects/BatchedMesh.js\";\nimport { Mesh } from \"three/src/objects/Mesh.js\";\nimport type { Texture } from \"three/src/textures/Texture.js\";\nimport { Move } from \"../../../../alg\";\nimport type { KPuzzle, KTransformation } from \"../../../../kpuzzle\";\nimport type { StickerDat, StickerDatFace } from \"../../../../puzzle-geometry\";\nimport {\n type ExperimentalStickeringMask,\n experimentalGetFaceletStickeringMask,\n} from \"../../../../puzzles/cubing-private\";\nimport type { FaceletMeshStickeringMask } from \"../../../../puzzles/stickerings/mask\";\nimport type { PuzzlePosition } from \"../../../controllers/AnimationTypes\";\nimport { smootherStep } from \"../../../controllers/easing\";\nimport type { HintFaceletStyle } from \"../../../model/props/puzzle/display/HintFaceletProp\";\nimport { TAU } from \"../TAU\";\nimport { newVertexColorBodyMaterial } from \"./CubieStyle\";\nimport {\n type FaceletAddress,\n type FaceletSurface,\n newLogoMesh,\n surfaceMatrix,\n} from \"./PuzzleLogo\";\nimport type { VertexRange } from \"./SolidPieceGeometry\";\nimport {\n faceletAppearance,\n faceletAppearanceKey,\n type PieceMesh,\n type PiecePlan,\n type PuzzlePlan,\n writeColor,\n} from \"./StickerlessPlan\";\nimport type { Twisty3DPuzzle } from \"./Twisty3DPuzzle\";\n\n/**\n * Draws a puzzle as solid pieces of colored plastic, the way `Cube3D` draws the\n * 3\u00D73\u00D73, for any puzzle whose pieces a planner in {@link PuzzlePlan} can cut.\n *\n * The difference from `Cube3D` that shapes everything here: a piece is drawn at\n * a *slot* rather than followed around the puzzle. Each mesh stays where it is\n * and takes on the colors of whichever piece is currently there, which is how\n * `PG3D` works too, and it means this renderer never has to know an orbit's\n * orientation convention \u2014 only which slots a move sweeps.\n */\n\nconst invisibleMaterial = new MeshBasicMaterial({ visible: false });\n\nfunction newBatch(meshes: PieceMesh[], material: Material): BatchedMesh {\n let vertices = 0;\n let indices = 0;\n for (const { geometry } of meshes) {\n vertices += geometry.getAttribute(\"position\").count;\n indices += geometry.getIndex()?.count ?? 0;\n }\n return new BatchedMesh(meshes.length, vertices, indices, material);\n}\n\n/** Copies one piece's geometry in, and returns where the batch put it. */\nfunction addToBatch(\n batch: BatchedMesh,\n mesh: PieceMesh,\n home: Matrix4,\n): { instance: number; vertexStart: number } {\n const geometryId = batch.addGeometry(mesh.geometry);\n const instance = batch.addInstance(geometryId);\n batch.setMatrixAt(instance, home);\n mesh.geometry.dispose();\n // `getGeometryRangeAt` reports more than the types admit to.\n const range = batch.getGeometryRangeAt(geometryId) as unknown as {\n vertexStart: number;\n };\n return { instance, vertexStart: range.vertexStart };\n}\n\ninterface Piece {\n /** Where this piece sits in each batch. -1 when it has no hint facelet. */\n bodyInstance: number;\n hintInstance: number;\n home: Matrix4;\n /** Where it is right now, which is `home` unless a move is sweeping it. */\n matrix: Matrix4;\n turning: boolean;\n}\n\n/** Where one facelet of the puzzle lives, and what it is currently showing. */\ninterface FaceletSlot {\n piece: Piece;\n faceStyle: number;\n /** Vertices in the batch's own color attribute, not the piece's. */\n body: VertexRange[];\n hint: VertexRange[];\n /** Which face and masks the colors currently written here came from. */\n appearanceKey: number;\n /** The masks this facelet contributes when another slot displays it. */\n mask: FaceletMeshStickeringMask;\n hintMask: FaceletMeshStickeringMask;\n /** Where a logo shown in this slot sits, in the piece's own frame. */\n logo: FaceletSurface | null;\n}\n\ninterface AxisInfo {\n axis: Vector3;\n order: number;\n}\n\nexport interface Stickerless3DOptions {\n hintFacelets?: HintFaceletStyle;\n stickeringMask?: ExperimentalStickeringMask;\n /** The facelet {@link Stickerless3D.experimentalSetLogo} prints on. */\n logoFacelet?: FaceletAddress | null;\n}\n\nexport class Stickerless3D extends Object3D implements Twisty3DPuzzle {\n #pieces: Piece[] = [];\n /**\n * One draw call for every piece of the puzzle, and one for every hint\n * facelet. A batch keeps a matrix per instance, so a move still moves the\n * pieces it sweeps and nothing else.\n */\n #bodyBatch: BatchedMesh;\n #hintBatch: BatchedMesh | null = null;\n #bodyColors: BufferAttribute;\n #hintColors: BufferAttribute | null = null;\n /** Indexed `[orbit][ori][ord]`, like the orbits of the `KPuzzle`. */\n #facelets: Record<string, FaceletSlot[][]> = {};\n #axesInfo: Record<string, AxisInfo> = {};\n #controlTargets: Object3D[] = [];\n #bodyMaterial: Material;\n #hintMaterial: Material;\n #appearances = new Map<number, Uint8Array>();\n /** Pieces rotated away from their home position by the last frame. */\n #turningPieces: Piece[] = [];\n /** Which pieces each quantum move sweeps, by the move's notation. */\n #turnedPieces = new Map<string, Piece[]>();\n /** The span of each color attribute that changed, so only it is uploaded. */\n #dirtyColors = new Map<BufferAttribute, { first: number; last: number }>();\n #lastPosition: PuzzlePosition | null = null;\n #pendingStickeringUpdate = false;\n /** The facelet a logo is printed on, and where it currently shows. */\n #logoFacelet: FaceletAddress | null = null;\n #logoMesh: Mesh | null = null;\n #logoSlot: FaceletSlot | null = null;\n #logoSurfaceMatrix = new Matrix4();\n\n constructor(\n private scheduleRenderCallback: () => void,\n private kpuzzle: KPuzzle,\n private stickerDat: StickerDat,\n private plan: PuzzlePlan,\n options: Stickerless3DOptions = {},\n ) {\n super();\n this.#logoFacelet = options.logoFacelet ?? null;\n this.#hintMaterial = new MeshBasicMaterial({\n vertexColors: true,\n transparent: true,\n // Hint facelets show the faces turned away from the camera, so they are\n // drawn from the inside out.\n side: BackSide,\n });\n this.#bodyMaterial = newVertexColorBodyMaterial();\n\n for (const axis of stickerDat.axis) {\n this.#axesInfo[axis.quantumMove.family] = {\n axis: new Vector3(...axis.coordinates),\n order: axis.order,\n };\n }\n\n this.#bodyBatch = newBatch(\n plan.pieces.map((piecePlan) => piecePlan.body),\n this.#bodyMaterial,\n );\n // Opaque and always on screen, so neither sorting nor culling per piece\n // buys anything, and skipping both lets the batch sit still between moves.\n this.#bodyBatch.sortObjects = false;\n this.#bodyBatch.perObjectFrustumCulled = false;\n this.add(this.#bodyBatch);\n\n const hints = plan.pieces\n .map((piecePlan) => piecePlan.hint)\n .filter((hint) => hint !== null);\n if (hints.length > 0) {\n this.#hintBatch = newBatch(hints, this.#hintMaterial);\n this.#hintBatch.perObjectFrustumCulled = false;\n this.add(this.#hintBatch);\n }\n for (const piecePlan of plan.pieces) {\n this.#addPiece(piecePlan);\n }\n // A batch has no buffers of its own until the first geometry goes in.\n this.#bodyColors = this.#bodyBatch.geometry.getAttribute(\n \"color\",\n ) as BufferAttribute;\n this.#hintColors =\n (this.#hintBatch?.geometry.getAttribute(\"color\") as BufferAttribute) ??\n null;\n this.experimentalUpdateOptions({\n hintFacelets: options.hintFacelets ?? \"floating\",\n });\n\n for (const face of stickerDat.faces) {\n this.#addControlTarget(face);\n }\n this.scale.setScalar(plan.scale);\n\n if (options.stickeringMask) {\n this.setStickeringMask(options.stickeringMask);\n }\n }\n\n #addPiece(plan: PiecePlan): void {\n const bodyInstance = addToBatch(this.#bodyBatch, plan.body, plan.home);\n const hintInstance =\n plan.hint && this.#hintBatch\n ? addToBatch(this.#hintBatch, plan.hint, plan.home)\n : -1;\n const piece: Piece = {\n bodyInstance: bodyInstance.instance,\n hintInstance: hintInstance === -1 ? -1 : hintInstance.instance,\n home: plan.home,\n matrix: plan.home.clone(),\n turning: false,\n };\n this.#pieces.push(piece);\n\n // A facelet's vertices sit wherever the batch put the piece's geometry.\n const shift = (ranges: VertexRange[], offset: number) =>\n ranges.map((range) => ({\n start: range.start + offset,\n count: range.count,\n }));\n const orbitFacelets = (this.#facelets[plan.orbit] ??= []);\n for (const facelet of plan.facelets) {\n (orbitFacelets[facelet.ori] ??= [])[plan.ord] = {\n piece,\n faceStyle: facelet.faceStyle,\n body: shift(facelet.body, bodyInstance.vertexStart),\n hint:\n hintInstance === -1\n ? []\n : shift(facelet.hint, hintInstance.vertexStart),\n appearanceKey: -1,\n mask: \"regular\",\n hintMask: \"regular\",\n logo: facelet.logo,\n };\n }\n }\n\n #setMatrix(piece: Piece): void {\n this.#bodyBatch.setMatrixAt(piece.bodyInstance, piece.matrix);\n if (piece.hintInstance !== -1) {\n this.#hintBatch!.setMatrixAt(piece.hintInstance, piece.matrix);\n }\n }\n\n #addControlTarget(face: StickerDatFace): void {\n const { coords } = face;\n const triangles = coords.length / 3 - 2;\n const positions = new Float32Array(9 * triangles);\n for (let triangle = 0; triangle < triangles; triangle++) {\n for (const [vertex, source] of [\n 0,\n triangle + 1,\n triangle + 2,\n ].entries()) {\n for (let axis = 0; axis < 3; axis++) {\n positions[9 * triangle + 3 * vertex + axis] =\n coords[3 * source + axis];\n }\n }\n }\n const geometry = new BufferGeometry();\n geometry.setAttribute(\"position\", new BufferAttribute(positions, 3));\n const mesh = new Mesh(geometry, invisibleMaterial);\n mesh.userData[\"quantumMove\"] =\n this.stickerDat.notationMapper.notationToExternal(new Move(face.name));\n mesh.scale.setScalar(0.99);\n this.add(mesh);\n this.#controlTargets.push(mesh);\n }\n\n /**\n * Prints a logo on the piece this puzzle keeps one on, or takes it off again\n * when passed `null`.\n *\n * The image is stretched onto the square {@link PuzzlePlan} sized for that\n * facelet, so its own proportions don't matter. It follows the piece: the\n * logo is drawn wherever the piece currently is, including part-way through a\n * move. The one thing it does not follow is a piece turning in place \u2014 a\n * megaminx or skewb center whose facelets are all one square \u2014 which leaves\n * the logo upright rather than rotating it with the plastic.\n */\n experimentalSetLogo(texture: Texture | null): void {\n if (!texture || !this.#logoFacelet) {\n this.#disposeLogo();\n this.scheduleRenderCallback();\n return;\n }\n if (this.#logoMesh) {\n const material = this.#logoMesh.material as MeshBasicMaterial;\n material.map = texture;\n material.needsUpdate = true;\n } else {\n this.#logoMesh = newLogoMesh(texture);\n this.add(this.#logoMesh);\n }\n this.#updateLogoSlot();\n this.#placeLogo();\n this.scheduleRenderCallback();\n }\n\n #disposeLogo(): void {\n if (!this.#logoMesh) {\n return;\n }\n this.remove(this.#logoMesh);\n (this.#logoMesh.material as MeshBasicMaterial).dispose();\n this.#logoMesh = null;\n this.#logoSlot = null;\n }\n\n /** Which slot is showing the logo's facelet, as of the last position. */\n #updateLogoSlot(): void {\n this.#logoSlot = null;\n const address = this.#logoFacelet;\n const pattern = this.#lastPosition?.pattern;\n if (!address || !pattern) {\n return;\n }\n const orbitFacelets = this.#facelets[address.orbit];\n const orbitPattern = pattern.patternData[address.orbit];\n if (!orbitFacelets || !orbitPattern) {\n return;\n }\n const numOrientations = orbitFacelets.length;\n for (let ord = 0; ord < orbitPattern.pieces.length; ord++) {\n if (orbitPattern.pieces[ord] !== address.ord) {\n continue;\n }\n // The mirror of the lookup in `#updateColors`: a piece's own facelet\n // comes around to the slot facelet its orientation has carried it to.\n const ori =\n numOrientations === 1\n ? 0\n : (address.ori + orbitPattern.orientation[ord]) % numOrientations;\n this.#logoSlot = orbitFacelets[ori]?.[ord] ?? null;\n return;\n }\n }\n\n #placeLogo(): void {\n const mesh = this.#logoMesh;\n if (!mesh) {\n return;\n }\n const slot = this.#logoSlot;\n if (!slot?.logo) {\n mesh.visible = false;\n return;\n }\n mesh.visible = true;\n mesh.matrix.multiplyMatrices(\n slot.piece.matrix,\n surfaceMatrix(slot.logo, this.#logoSurfaceMatrix),\n );\n mesh.matrixWorldNeedsUpdate = true;\n }\n\n dispose(): void {\n this.#disposeLogo();\n this.#bodyBatch.dispose();\n this.#bodyBatch.geometry.dispose();\n this.#hintBatch?.dispose();\n this.#hintBatch?.geometry.dispose();\n this.#bodyMaterial.dispose();\n this.#hintMaterial.dispose();\n }\n\n experimentalGetStickerTargets(): Object3D[] {\n return [];\n }\n\n experimentalGetControlTargets(): Object3D[] {\n return this.#controlTargets;\n }\n\n #isValidMove(move: Move): boolean {\n try {\n this.kpuzzle.moveToTransformation(move);\n return true;\n } catch {\n return false;\n }\n }\n\n getClosestMoveToAxis(\n point: Vector3,\n transformations: {\n invert: boolean;\n depth?: \"secondSlice\" | \"rotation\" | \"none\";\n },\n ): { move: Move; order: number } | null {\n let closestMove: Move | null = null;\n let closestMoveDotProduct = 0;\n\n let modify: (move: Move) => Move = (m) => m;\n switch (transformations.depth) {\n case \"secondSlice\": {\n modify = (m: Move) => m.modified({ innerLayer: 2 });\n break;\n }\n case \"rotation\": {\n modify = (m: Move) => m.modified({ family: `${m.family}v` });\n break;\n }\n }\n\n for (const axis of this.stickerDat.axis) {\n const product = point.dot(new Vector3(...axis.coordinates));\n if (product > closestMoveDotProduct) {\n const modified = this.stickerDat.notationMapper.notationToExternal(\n modify(axis.quantumMove),\n );\n if (!modified || !this.#isValidMove(modified)) {\n continue;\n }\n closestMoveDotProduct = product;\n closestMove = modified;\n }\n }\n\n if (!closestMove) {\n return null;\n }\n if (transformations.invert) {\n closestMove = closestMove.invert();\n }\n const order = this.kpuzzle\n .moveToTransformation(closestMove)\n .repetitionOrder();\n return { move: closestMove, order };\n }\n\n setStickeringMask(stickeringMask: ExperimentalStickeringMask): void {\n // A picture cube needs a sticker to print on, which a solid piece of\n // plastic doesn't have. Leave the plastic in its own colors.\n for (const orbitDefinition of stickeringMask.specialBehaviour === \"picture\"\n ? []\n : this.kpuzzle.definition.orbits) {\n const { orbitName, numPieces, numOrientations } = orbitDefinition;\n const orbitFacelets = this.#facelets[orbitName];\n if (!orbitFacelets) {\n continue;\n }\n for (let ori = 0; ori < numOrientations; ori++) {\n for (let ord = 0; ord < numPieces; ord++) {\n const facelet = orbitFacelets[ori]?.[ord];\n if (!facelet) {\n continue;\n }\n facelet.mask = experimentalGetFaceletStickeringMask(\n stickeringMask,\n orbitName,\n ord,\n ori,\n false,\n );\n facelet.hintMask = experimentalGetFaceletStickeringMask(\n stickeringMask,\n orbitName,\n ord,\n ori,\n true,\n );\n }\n }\n }\n this.#pendingStickeringUpdate = true;\n if (this.#lastPosition) {\n this.onPositionChange(this.#lastPosition);\n }\n }\n\n /** @deprecated */\n experimentalUpdateOptions(options: {\n showMainStickers?: boolean;\n hintFacelets?: HintFaceletStyle;\n showFoundation?: boolean; // A stickerless piece is solid; there is nothing to show through it.\n hintStickerOpacity?: number;\n faceletScale?: \"auto\" | number;\n }): void {\n if (options.hintFacelets !== undefined && this.#hintBatch) {\n this.#hintBatch.visible = options.hintFacelets !== \"none\";\n this.scheduleRenderCallback();\n }\n }\n\n /** @deprecated */\n experimentalUpdateTexture(\n enabled: boolean,\n stickerTexture?: Texture | null,\n _hintTexture?: Texture | null,\n ): void {\n // Picture cubes need a sticker to print on, which a solid piece of plastic\n // doesn't have. A sprite that was set before the puzzle was built sends it\n // to `PG3D` instead (see `pg3dShim`); one set afterwards is too late.\n if (enabled && stickerTexture) {\n console.warn(\n \"Sprites are not supported for stickerless pieces. For now, set the sprite before creating the TwistyPlayer.\",\n );\n }\n }\n\n onPositionChange(position: PuzzlePosition): void {\n const { pattern } = position;\n if (\n this.#pendingStickeringUpdate ||\n !this.#lastPosition ||\n !this.#lastPosition.pattern.isIdentical(pattern)\n ) {\n this.#updateColors(position);\n this.#lastPosition = position;\n this.#pendingStickeringUpdate = false;\n this.#updateLogoSlot();\n }\n\n const wereTurning = this.#turningPieces;\n for (const piece of wereTurning) {\n piece.turning = false;\n }\n this.#turningPieces = [];\n\n const turnMatrix = new Matrix4();\n for (const moveProgress of position.movesInProgress) {\n const move = moveProgress.move;\n const unswizzled = this.stickerDat.unswizzle(move);\n if (!unswizzled) {\n continue;\n }\n const axisInfo = this.#axesInfo[unswizzled.family];\n if (!axisInfo) {\n continue;\n }\n turnMatrix.makeRotationAxis(\n axisInfo.axis,\n (-smootherStep(moveProgress.fraction) *\n moveProgress.direction *\n unswizzled.amount *\n TAU) /\n axisInfo.order,\n );\n for (const piece of this.#piecesTurnedBy(move)) {\n if (!piece.turning) {\n piece.turning = true;\n piece.matrix.copy(piece.home);\n this.#turningPieces.push(piece);\n }\n piece.matrix.premultiply(turnMatrix);\n }\n }\n\n for (const piece of wereTurning) {\n if (!piece.turning) {\n piece.matrix.copy(piece.home);\n this.#setMatrix(piece);\n }\n }\n for (const piece of this.#turningPieces) {\n this.#setMatrix(piece);\n }\n // After the matrices, since the logo rides on whichever piece is under it.\n this.#placeLogo();\n\n this.scheduleRenderCallback();\n }\n\n /**\n * The pieces a single quantum of `move` sweeps: the ones whose slot does not\n * map to itself.\n */\n #piecesTurnedBy(move: Move): Piece[] {\n const quantum = move.modified({ amount: 1 });\n const key = quantum.toString();\n const cached = this.#turnedPieces.get(key);\n if (cached) {\n return cached;\n }\n const pieces: Piece[] = [];\n const { transformationData } = this.#quantumTransformation(quantum);\n for (const orbitName in this.#facelets) {\n const orbitTransformation = transformationData[orbitName];\n if (!orbitTransformation) {\n continue;\n }\n const { permutation, orientationDelta } = orbitTransformation;\n // Every facelet of a piece moves with it, so the first orientation is\n // enough to reach each piece exactly once.\n const slots = this.#facelets[orbitName][0];\n for (let ord = 0; ord < permutation.length; ord++) {\n if (permutation[ord] !== ord || orientationDelta[ord] !== 0) {\n const slot = slots[ord];\n if (slot) {\n pieces.push(slot.piece);\n }\n }\n }\n }\n this.#turnedPieces.set(key, pieces);\n return pieces;\n }\n\n #quantumTransformation(quantum: Move): KTransformation {\n try {\n return this.kpuzzle.moveToTransformation(quantum);\n } catch (e) {\n // The external notation didn't have a quantum of its own. Try going\n // through the internal notation and back, which is what makes e.g. \"x2\"\n // work on puzzles whose rotations are only defined in one direction.\n const internal =\n this.stickerDat.notationMapper.notationToInternal(quantum);\n const external =\n internal &&\n this.stickerDat.notationMapper.notationToExternal(\n internal.modified({ amount: 1 }),\n );\n if (!external) {\n throw e;\n }\n return this.kpuzzle.moveToTransformation(external);\n }\n }\n\n /** Repaints every slot with the colors of whatever piece is now in it. */\n #updateColors(position: PuzzlePosition): void {\n for (const orbitName in this.#facelets) {\n const orbitFacelets = this.#facelets[orbitName];\n const orbitPattern = position.pattern.patternData[orbitName];\n const numOrientations = orbitFacelets.length;\n for (let ori = 0; ori < numOrientations; ori++) {\n const slots = orbitFacelets[ori];\n for (let ord = 0; ord < slots.length; ord++) {\n const slot = slots[ord];\n if (!slot) {\n continue;\n }\n // The piece in this slot shows the facelet that its own orientation\n // has brought around to this side.\n const sourceOri =\n numOrientations === 1\n ? 0\n : (ori + numOrientations - orbitPattern.orientation[ord]) %\n numOrientations;\n const source = orbitFacelets[sourceOri][orbitPattern.pieces[ord]];\n const key = faceletAppearanceKey(\n source.faceStyle,\n source.mask,\n source.hintMask,\n );\n if (key === slot.appearanceKey) {\n continue;\n }\n slot.appearanceKey = key;\n if (slot.body.length === 0 && slot.hint.length === 0) {\n continue;\n }\n const appearance = faceletAppearance(\n this.#appearances,\n this.plan.faceStyles,\n source.faceStyle,\n source.mask,\n source.hintMask,\n );\n this.#paint(this.#bodyColors, slot.body, appearance, 0);\n if (this.#hintColors) {\n this.#paint(this.#hintColors, slot.hint, appearance, 4);\n }\n }\n }\n }\n for (const [colors, span] of this.#dirtyColors) {\n // In elements, not vertices, which is what `WebGLAttributes` slices by.\n colors.addUpdateRange(4 * span.first, 4 * (span.last - span.first + 1));\n colors.needsUpdate = true;\n }\n this.#dirtyColors.clear();\n }\n\n #paint(\n colors: BufferAttribute,\n ranges: VertexRange[],\n appearance: Uint8Array,\n offset: number,\n ): void {\n if (ranges.length === 0) {\n return;\n }\n writeColor(colors, ranges, appearance, offset);\n let span = this.#dirtyColors.get(colors);\n if (!span) {\n span = { first: Number.POSITIVE_INFINITY, last: 0 };\n this.#dirtyColors.set(colors, span);\n }\n for (const range of ranges) {\n span.first = Math.min(span.first, range.start);\n span.last = Math.max(span.last, range.start + range.count - 1);\n }\n }\n}\n", "import { cube3x3x3, type PuzzleLoader } from \"../../../puzzles\";\nimport type { FaceletScale } from \"../../model/props/puzzle/display/FaceletScaleProp\";\nimport type { HintFaceletStyle } from \"../../model/props/puzzle/display/HintFaceletProp\";\nimport { Cube3D, type Cube3DOptions } from \"../../views/3D/puzzles/Cube3D\";\nimport { cubePuzzlePlan } from \"../../views/3D/puzzles/CubePieces\";\nimport { PG3D } from \"../../views/3D/puzzles/PG3D\";\nimport { logoFaceletAddress } from \"../../views/3D/puzzles/PuzzleLogo\";\nimport { solidPuzzlePlan } from \"../../views/3D/puzzles/SolidPieces\";\nimport { Square1_3D } from \"../../views/3D/puzzles/Square1_3D\";\nimport { Stickerless3D } from \"../../views/3D/puzzles/Stickerless3D\";\n\n// TODO: figure out how to load these dynamically without a bottleneck.\nexport { PerspectiveCamera as ThreePerspectiveCamera } from \"three/src/cameras/PerspectiveCamera.js\";\nexport { Raycaster as ThreeRaycaster } from \"three/src/core/Raycaster.js\";\nexport { TextureLoader as ThreeTextureLoader } from \"three/src/loaders/TextureLoader.js\";\nexport { Spherical as ThreeSpherical } from \"three/src/math/Spherical.js\";\nexport { Vector2 as ThreeVector2 } from \"three/src/math/Vector2.js\";\nexport { Vector3 as ThreeVector3 } from \"three/src/math/Vector3.js\";\nexport { WebGLRenderer as ThreeWebGLRenderer } from \"three/src/renderers/WebGLRenderer.js\";\nexport { Scene as ThreeScene } from \"three/src/scenes/Scene.js\";\n\nexport { Cube3D } from \"../../views/3D/puzzles/Cube3D\";\nexport { PG3D } from \"../../views/3D/puzzles/PG3D\";\nexport { Square1_3D } from \"../../views/3D/puzzles/Square1_3D\";\nexport { Stickerless3D } from \"../../views/3D/puzzles/Stickerless3D\";\nexport { Twisty3DScene } from \"../../views/3D/Twisty3DScene\";\n\nexport async function cube3DShim(\n renderCallback: () => void,\n options?: Cube3DOptions,\n): Promise<Cube3D> {\n return new Cube3D(await cube3x3x3.kpuzzle(), renderCallback, options);\n}\n\nexport async function square1_3DShim(\n renderCallback: () => void,\n puzzleLoader: PuzzleLoader,\n faceletScale: FaceletScale,\n): Promise<Square1_3D> {\n return new Square1_3D(await puzzleLoader.kpuzzle(), renderCallback, {\n faceletScale,\n });\n}\n\n// TODO: take loader?\nexport async function pg3dShim(\n renderCallback: () => void,\n puzzleLoader: PuzzleLoader,\n hintFacelets: HintFaceletStyle,\n faceletScale: FaceletScale,\n darkIgnoredOrbits: boolean,\n // A picture cube needs a sticker to print on, and a stickerless piece has\n // none, so leave those to `PG3D` as well.\n pictureCube: boolean = false,\n): Promise<PG3D | Stickerless3D> {\n const kpuzzle = await puzzleLoader.kpuzzle();\n const stickerDat = (await puzzleLoader.pg!()).get3d({ darkIgnoredOrbits });\n // Every puzzle whose pieces we can cut gets the same solid plastic the 3\u00D73\u00D73\n // gets from `Cube3D`. `PG3D` still draws the rest.\n const plan =\n darkIgnoredOrbits || pictureCube\n ? null\n : (cubePuzzlePlan(stickerDat) ?? solidPuzzlePlan(stickerDat));\n if (plan) {\n return new Stickerless3D(renderCallback, kpuzzle, stickerDat, plan, {\n hintFacelets,\n logoFacelet: logoFaceletAddress(puzzleLoader.id, stickerDat),\n });\n }\n return new PG3D(\n renderCallback,\n kpuzzle,\n stickerDat,\n true,\n hintFacelets === \"floating\",\n undefined,\n faceletScale,\n );\n}\n", "import type { Scene as ThreeScene } from \"three/src/Three.js\";\nimport { bulk3DCode } from \"../../heavy-code-imports/3d\";\nimport type { Twisty3DPuzzle } from \"./puzzles/Twisty3DPuzzle\";\nimport type { Twisty3DRenderTarget } from \"./Twisty3DRenderTarget\";\n\nexport class Twisty3DScene implements Twisty3DRenderTarget {\n private renderTargets: Set<Twisty3DRenderTarget> = new Set();\n public twisty3Ds: Set<Twisty3DPuzzle> = new Set();\n\n threeJSScene: Promise<ThreeScene> = (async () =>\n new (await bulk3DCode).ThreeScene())();\n\n addRenderTarget(renderTarget: Twisty3DRenderTarget): void {\n this.renderTargets.add(renderTarget);\n }\n\n scheduleRender(): void {\n for (const renderTarget of this.renderTargets) {\n renderTarget.scheduleRender();\n }\n }\n\n async addTwisty3DPuzzle(twisty3DPuzzle: Twisty3DPuzzle): Promise<void> {\n this.twisty3Ds.add(twisty3DPuzzle);\n (await this.threeJSScene).add(twisty3DPuzzle);\n // TODO: scheduleRender?\n }\n\n async removeTwisty3DPuzzle(twisty3DPuzzle: Twisty3DPuzzle): Promise<void> {\n this.twisty3Ds.delete(twisty3DPuzzle);\n (await this.threeJSScene).remove(twisty3DPuzzle);\n // TODO: scheduleRender?\n }\n\n async clearPuzzles(): Promise<void> {\n for (const puz of this.twisty3Ds) {\n (await this.threeJSScene).remove(puz);\n }\n this.twisty3Ds.clear();\n // TODO: scheduleRender?\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["FrontSide", "BufferAttribute", "BufferGeometry", "MeshBasicMaterial", "Color", "Vector3", "Mesh", "normal", "Vector3", "Vector3", "BufferAttribute", "BufferGeometry", "MeshBasicMaterial", "Vector3", "normal", "face", "MeshBasicMaterial", "Color", "FrontSide", "Vector3", "r", "BufferGeometry", "BufferAttribute", "stickeringMask", "Mesh", "normal", "BufferAttribute", "BufferGeometry", "Matrix4", "Vector3", "LOGO_ELEVATION", "centroid", "Vector3", "normal", "BufferAttribute", "BufferGeometry", "Matrix4", "DoubleSide", "FrontSide", "BufferAttribute", "BufferGeometry", "Object3D", "MeshBasicMaterial", "Color", "Vector3", "Group", "Mesh", "MeshBasicMaterial", "DoubleSide", "r", "face", "t", "BufferAttribute", "Color", "normal", "Group", "BufferGeometry", "Mesh", "AxisInfo", "Vector3", "PG_SCALE", "Object3D", "FrontSide", "BufferAttribute", "BufferGeometry", "Color", "Matrix4", "Vector3", "Vector3", "normal", "centroid", "PG_SCALE", "EPSILON", "LOGO_ELEVATION", "Vector3", "normal", "face", "Color", "centroid", "offset", "hint", "newPieceMesh", "Matrix4", "BufferGeometry", "BufferAttribute", "DoubleSide", "BufferAttribute", "BufferGeometry", "Object3D", "MeshBasicMaterial", "Color", "Quaternion", "Vector3", "Group", "Mesh", "Vector3", "Quaternion", "normal", "BufferGeometry", "BufferAttribute", "MeshBasicMaterial", "Color", "DoubleSide", "Group", "Mesh", "LOGO_ELEVATION", "Object3D", "BackSide", "BufferAttribute", "BufferGeometry", "Object3D", "MeshBasicMaterial", "Matrix4", "Vector3", "Mesh", "invisibleMaterial", "MeshBasicMaterial", "Object3D", "BackSide", "Vector3", "face", "Matrix4", "BufferGeometry", "BufferAttribute", "Mesh", "TextureLoader", "Vector2", "Vector3"]
7
+ }