cubing 0.63.2 → 0.63.3
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.
- package/dist/bin/chunks/{chunk-52ODPET6.js → chunk-OI3YIXMQ.js} +2 -2
- package/dist/bin/order.js +1 -1
- package/dist/bin/puzzle-geometry-bin.js +1 -1
- package/dist/bin/scramble.js +1 -1
- package/dist/lib/cubing/{PuzzleLoader-R-puDLmC.d.ts → PuzzleLoader-Bp8zngUn.d.ts} +10 -0
- package/dist/lib/cubing/alg/index.d.ts +2 -2
- package/dist/lib/cubing/bluetooth/index.d.ts +2 -2
- package/dist/lib/cubing/chunks/chunk-44CFF24P.js +239 -0
- package/dist/lib/cubing/chunks/chunk-44CFF24P.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-DQGYYYHZ.js +1180 -0
- package/dist/lib/cubing/chunks/chunk-DQGYYYHZ.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-FTE3QI5X.js +1074 -0
- package/dist/lib/cubing/chunks/chunk-FTE3QI5X.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-FZBKZ5ZB.js +265 -0
- package/dist/lib/cubing/chunks/chunk-FZBKZ5ZB.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-OUM32GEA.js +239 -0
- package/dist/lib/cubing/chunks/chunk-OUM32GEA.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-SGJ5WPE4.js +1074 -0
- package/dist/lib/cubing/chunks/chunk-SGJ5WPE4.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-TAVR35KU.js +265 -0
- package/dist/lib/cubing/chunks/chunk-TAVR35KU.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-VRTKWZPL.js +10084 -0
- package/dist/lib/cubing/chunks/chunk-VRTKWZPL.js.map +7 -0
- package/dist/lib/cubing/chunks/chunk-VSMFYTG6.js +10086 -0
- package/dist/lib/cubing/chunks/chunk-VSMFYTG6.js.map +7 -0
- package/dist/lib/cubing/chunks/inside-IHWQVDVU.js +564 -0
- package/dist/lib/cubing/chunks/inside-IHWQVDVU.js.map +7 -0
- package/dist/lib/cubing/chunks/inside-L2JI2BEY.js +564 -0
- package/dist/lib/cubing/chunks/inside-L2JI2BEY.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-MXHP7O4R.js +1890 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-MXHP7O4R.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-XFECDWOF.js +1890 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-side-events-XFECDWOF.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-CM33KT7L.js +1267 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-CM33KT7L.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-Q4LLHL2O.js +1267 -0
- package/dist/lib/cubing/chunks/search-dynamic-sgs-unofficial-Q4LLHL2O.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-COSEVJBV.js +2922 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-COSEVJBV.js.map +7 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NANDMURR.js +2922 -0
- package/dist/lib/cubing/chunks/search-dynamic-solve-4x4x4-NANDMURR.js.map +7 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-5NZRNZ7C.js +1881 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-5NZRNZ7C.js.map +7 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-VGZIQ64W.js +1927 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-VGZIQ64W.js.map +7 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-XLUOPCLN.js +1881 -0
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-XLUOPCLN.js.map +7 -0
- package/dist/lib/cubing/{events-IfSwQLYm.d.ts → events-CewDA1aS.d.ts} +1 -1
- package/dist/lib/cubing/{index-btIxbuNp.d.ts → index-DabjED-w.d.ts} +1 -1
- package/dist/lib/cubing/kpuzzle/index.d.ts +1 -1
- package/dist/lib/cubing/notation/index.d.ts +1 -1
- package/dist/lib/cubing/protocol/index.d.ts +1 -1
- package/dist/lib/cubing/puzzle-geometry/index.d.ts +2 -2
- package/dist/lib/cubing/puzzles/index.d.ts +1 -1
- package/dist/lib/cubing/scramble/index.d.ts +2 -2
- package/dist/lib/cubing/search/index.d.ts +3 -3
- package/dist/lib/cubing/stream/index.d.ts +3 -3
- package/dist/lib/cubing/twisty/index.d.ts +2 -2
- package/dist/lib/cubing/twisty/index.js +37 -4
- package/dist/lib/cubing/twisty/index.js.map +3 -3
- package/package.json +1 -1
- /package/dist/bin/chunks/{chunk-52ODPET6.js.map → chunk-OI3YIXMQ.js.map} +0 -0
|
@@ -0,0 +1,1927 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TAU,
|
|
3
|
+
bulk3DCode,
|
|
4
|
+
haveStartedSharingRenderers,
|
|
5
|
+
hintFaceletStyles
|
|
6
|
+
} from "./chunk-DQGYYYHZ.js";
|
|
7
|
+
import "./chunk-FLK6AZKB.js";
|
|
8
|
+
import {
|
|
9
|
+
cube3x3x3,
|
|
10
|
+
getFaceletStickeringMask
|
|
11
|
+
} from "./chunk-FUHYAW74.js";
|
|
12
|
+
import "./chunk-RINY3U6G.js";
|
|
13
|
+
import {
|
|
14
|
+
Move
|
|
15
|
+
} from "./chunk-O6HEZXGY.js";
|
|
16
|
+
|
|
17
|
+
// src/cubing/twisty/views/3D/puzzles/Cube3D.ts
|
|
18
|
+
import { BackSide, DoubleSide, FrontSide } from "three/src/constants.js";
|
|
19
|
+
import { BufferAttribute } from "three/src/core/BufferAttribute.js";
|
|
20
|
+
import { BufferGeometry } from "three/src/core/BufferGeometry.js";
|
|
21
|
+
import { Object3D } from "three/src/core/Object3D.js";
|
|
22
|
+
import { BoxGeometry } from "three/src/geometries/BoxGeometry.js";
|
|
23
|
+
import { TextureLoader } from "three/src/loaders/TextureLoader.js";
|
|
24
|
+
import { MeshBasicMaterial } from "three/src/materials/MeshBasicMaterial.js";
|
|
25
|
+
import { Color } from "three/src/math/Color.js";
|
|
26
|
+
import { Euler } from "three/src/math/Euler.js";
|
|
27
|
+
import { Matrix4 } from "three/src/math/Matrix4.js";
|
|
28
|
+
import { Quaternion } from "three/src/math/Quaternion.js";
|
|
29
|
+
import { Vector2 } from "three/src/math/Vector2.js";
|
|
30
|
+
import { Vector3 } from "three/src/math/Vector3.js";
|
|
31
|
+
import { Group } from "three/src/objects/Group.js";
|
|
32
|
+
import { Mesh } from "three/src/objects/Mesh.js";
|
|
33
|
+
|
|
34
|
+
// src/cubing/twisty/controllers/easing.ts
|
|
35
|
+
function smootherStep(x) {
|
|
36
|
+
return x * x * x * (10 - x * (15 - 6 * x));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/cubing/twisty/views/3D/puzzles/Cube3D.ts
|
|
40
|
+
var svgLoader = new TextureLoader();
|
|
41
|
+
var ignoredMaterial = new MeshBasicMaterial({
|
|
42
|
+
color: new Color(6710886).convertLinearToSRGB()
|
|
43
|
+
});
|
|
44
|
+
var ignoredMaterialHint = new MeshBasicMaterial({
|
|
45
|
+
color: new Color(13421772).convertLinearToSRGB(),
|
|
46
|
+
side: BackSide,
|
|
47
|
+
transparent: true,
|
|
48
|
+
opacity: 0.75
|
|
49
|
+
});
|
|
50
|
+
var invisibleMaterial = new MeshBasicMaterial({
|
|
51
|
+
visible: false
|
|
52
|
+
});
|
|
53
|
+
var orientedMaterial = new MeshBasicMaterial({
|
|
54
|
+
color: 4513228
|
|
55
|
+
});
|
|
56
|
+
var orientedMaterialHint = new MeshBasicMaterial({
|
|
57
|
+
color: 4513228,
|
|
58
|
+
side: BackSide,
|
|
59
|
+
transparent: true,
|
|
60
|
+
opacity: 0.5
|
|
61
|
+
});
|
|
62
|
+
var experimentalOriented2Material = new MeshBasicMaterial({
|
|
63
|
+
color: 16776618
|
|
64
|
+
});
|
|
65
|
+
var experimentalOriented2MaterialHint = new MeshBasicMaterial({
|
|
66
|
+
color: 16775545,
|
|
67
|
+
side: BackSide,
|
|
68
|
+
transparent: true,
|
|
69
|
+
opacity: 0.5
|
|
70
|
+
});
|
|
71
|
+
var mysteryMaterial = new MeshBasicMaterial({
|
|
72
|
+
color: 15911883
|
|
73
|
+
});
|
|
74
|
+
var mysterMaterialHint = new MeshBasicMaterial({
|
|
75
|
+
color: 15911883,
|
|
76
|
+
side: BackSide,
|
|
77
|
+
transparent: true,
|
|
78
|
+
opacity: 0.5
|
|
79
|
+
});
|
|
80
|
+
var AxisInfo = class {
|
|
81
|
+
constructor(vector, fromZ, color, dimColor, hintOpacityScale, options) {
|
|
82
|
+
this.vector = vector;
|
|
83
|
+
this.fromZ = fromZ;
|
|
84
|
+
this.color = color;
|
|
85
|
+
this.dimColor = dimColor;
|
|
86
|
+
this.hintOpacityScale = hintOpacityScale;
|
|
87
|
+
const colorLinearSRGB = new Color(color).convertLinearToSRGB();
|
|
88
|
+
const dimColorLinearSRGB = new Color(dimColor).convertLinearToSRGB();
|
|
89
|
+
this.stickerMaterial = {
|
|
90
|
+
regular: new MeshBasicMaterial({
|
|
91
|
+
color: colorLinearSRGB,
|
|
92
|
+
side: FrontSide
|
|
93
|
+
// TODO: set to `DoubleSide` when hint facelets are disabled.
|
|
94
|
+
}),
|
|
95
|
+
dim: new MeshBasicMaterial({
|
|
96
|
+
color: dimColorLinearSRGB,
|
|
97
|
+
side: FrontSide
|
|
98
|
+
// TODO: set to `DoubleSide` when hint facelets are disabled.
|
|
99
|
+
}),
|
|
100
|
+
oriented: orientedMaterial,
|
|
101
|
+
experimentalOriented2: experimentalOriented2Material,
|
|
102
|
+
ignored: ignoredMaterial,
|
|
103
|
+
invisible: invisibleMaterial,
|
|
104
|
+
mystery: mysteryMaterial
|
|
105
|
+
};
|
|
106
|
+
this.hintStickerMaterial = {
|
|
107
|
+
regular: new MeshBasicMaterial({
|
|
108
|
+
color: new Color(options?.hintColor ?? color).convertLinearToSRGB(),
|
|
109
|
+
side: BackSide,
|
|
110
|
+
transparent: true,
|
|
111
|
+
opacity: 0.5 * hintOpacityScale
|
|
112
|
+
}),
|
|
113
|
+
dim: new MeshBasicMaterial({
|
|
114
|
+
color: new Color(
|
|
115
|
+
options?.hintDimColor ?? dimColor
|
|
116
|
+
).convertLinearToSRGB(),
|
|
117
|
+
side: BackSide,
|
|
118
|
+
transparent: true,
|
|
119
|
+
opacity: 0.5 * hintOpacityScale
|
|
120
|
+
}),
|
|
121
|
+
oriented: orientedMaterialHint,
|
|
122
|
+
experimentalOriented2: experimentalOriented2MaterialHint,
|
|
123
|
+
ignored: ignoredMaterialHint,
|
|
124
|
+
invisible: invisibleMaterial,
|
|
125
|
+
mystery: mysterMaterialHint
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
stickerMaterial;
|
|
129
|
+
hintStickerMaterial;
|
|
130
|
+
};
|
|
131
|
+
var axesInfo = [
|
|
132
|
+
new AxisInfo(
|
|
133
|
+
new Vector3(0, 1, 0),
|
|
134
|
+
new Euler(-TAU / 4, 0, 0),
|
|
135
|
+
16777215,
|
|
136
|
+
14540253,
|
|
137
|
+
1.25
|
|
138
|
+
),
|
|
139
|
+
new AxisInfo(
|
|
140
|
+
new Vector3(-1, 0, 0),
|
|
141
|
+
new Euler(0, -TAU / 4, 0),
|
|
142
|
+
16750848,
|
|
143
|
+
8934656,
|
|
144
|
+
1,
|
|
145
|
+
{ hintDimColor: 8930304 }
|
|
146
|
+
),
|
|
147
|
+
new AxisInfo(
|
|
148
|
+
new Vector3(0, 0, 1),
|
|
149
|
+
new Euler(0, 0, 0),
|
|
150
|
+
65280,
|
|
151
|
+
34816,
|
|
152
|
+
1,
|
|
153
|
+
{ hintDimColor: 39168 }
|
|
154
|
+
),
|
|
155
|
+
new AxisInfo(
|
|
156
|
+
new Vector3(1, 0, 0),
|
|
157
|
+
new Euler(0, TAU / 4, 0),
|
|
158
|
+
16711680,
|
|
159
|
+
6684672,
|
|
160
|
+
1,
|
|
161
|
+
{ hintDimColor: 6684672 }
|
|
162
|
+
),
|
|
163
|
+
new AxisInfo(
|
|
164
|
+
new Vector3(0, 0, -1),
|
|
165
|
+
new Euler(0, TAU / 2, 0),
|
|
166
|
+
2254591,
|
|
167
|
+
1127304,
|
|
168
|
+
0.75,
|
|
169
|
+
{ hintDimColor: 6246 }
|
|
170
|
+
),
|
|
171
|
+
new AxisInfo(
|
|
172
|
+
new Vector3(0, -1, 0),
|
|
173
|
+
new Euler(TAU / 4, 0, 0),
|
|
174
|
+
16776960,
|
|
175
|
+
8947712,
|
|
176
|
+
1.25,
|
|
177
|
+
{ hintDimColor: 14540032 }
|
|
178
|
+
)
|
|
179
|
+
];
|
|
180
|
+
var face = {
|
|
181
|
+
U: 0,
|
|
182
|
+
L: 1,
|
|
183
|
+
F: 2,
|
|
184
|
+
R: 3,
|
|
185
|
+
B: 4,
|
|
186
|
+
D: 5
|
|
187
|
+
};
|
|
188
|
+
var familyToAxis = {
|
|
189
|
+
U: face["U"],
|
|
190
|
+
u: face["U"],
|
|
191
|
+
Uw: face["U"],
|
|
192
|
+
Uv: face["U"],
|
|
193
|
+
y: face["U"],
|
|
194
|
+
L: face["L"],
|
|
195
|
+
l: face["L"],
|
|
196
|
+
Lw: face["L"],
|
|
197
|
+
Lv: face["L"],
|
|
198
|
+
M: face["L"],
|
|
199
|
+
F: face["F"],
|
|
200
|
+
f: face["F"],
|
|
201
|
+
Fw: face["F"],
|
|
202
|
+
Fv: face["F"],
|
|
203
|
+
S: face["F"],
|
|
204
|
+
z: face["F"],
|
|
205
|
+
R: face["R"],
|
|
206
|
+
r: face["R"],
|
|
207
|
+
Rw: face["R"],
|
|
208
|
+
Rv: face["R"],
|
|
209
|
+
x: face["R"],
|
|
210
|
+
B: face["B"],
|
|
211
|
+
b: face["B"],
|
|
212
|
+
Bw: face["B"],
|
|
213
|
+
Bv: face["B"],
|
|
214
|
+
D: face["D"],
|
|
215
|
+
d: face["D"],
|
|
216
|
+
Dw: face["D"],
|
|
217
|
+
Dv: face["D"],
|
|
218
|
+
E: face["D"]
|
|
219
|
+
};
|
|
220
|
+
var cubieDimensions = {
|
|
221
|
+
// stickerWidth: 0.85, // Now `faceletScale` in options.
|
|
222
|
+
stickerElevation: 0.503,
|
|
223
|
+
foundationWidth: 1,
|
|
224
|
+
defaultHintStickerElevation: 1.45
|
|
225
|
+
};
|
|
226
|
+
var EXPERIMENTAL_PICTURE_CUBE_HINT_ELEVATION = 2;
|
|
227
|
+
var cube3DOptionsDefaults = {
|
|
228
|
+
showMainStickers: true,
|
|
229
|
+
hintFacelets: "floating",
|
|
230
|
+
showFoundation: true,
|
|
231
|
+
experimentalStickeringMask: void 0,
|
|
232
|
+
foundationSprite: null,
|
|
233
|
+
hintSprite: null,
|
|
234
|
+
initialHintFaceletsAnimation: "auto",
|
|
235
|
+
faceletScale: "auto",
|
|
236
|
+
hintFaceletsElevation: "auto"
|
|
237
|
+
};
|
|
238
|
+
var DEFAULT_STICKER_SCALE = 0.85;
|
|
239
|
+
function getFaceletScale(options) {
|
|
240
|
+
if (typeof options.faceletScale === "undefined" || options.faceletScale === "auto") {
|
|
241
|
+
return DEFAULT_STICKER_SCALE;
|
|
242
|
+
}
|
|
243
|
+
return options.faceletScale;
|
|
244
|
+
}
|
|
245
|
+
var blackMesh = new MeshBasicMaterial({
|
|
246
|
+
color: 0,
|
|
247
|
+
opacity: 1,
|
|
248
|
+
transparent: true
|
|
249
|
+
});
|
|
250
|
+
var blackTranslucentMesh = new MeshBasicMaterial({
|
|
251
|
+
color: 0,
|
|
252
|
+
opacity: 0.3,
|
|
253
|
+
transparent: true
|
|
254
|
+
});
|
|
255
|
+
var CubieDef = class {
|
|
256
|
+
// stickerFaceNames can be e.g. ["U", "F", "R"], "UFR" if every face is a single letter.
|
|
257
|
+
constructor(orbit, stickerFaceNames, q) {
|
|
258
|
+
this.orbit = orbit;
|
|
259
|
+
const individualStickerFaceNames = typeof stickerFaceNames === "string" ? stickerFaceNames.split("") : stickerFaceNames;
|
|
260
|
+
this.stickerFaces = individualStickerFaceNames.map((s) => face[s]);
|
|
261
|
+
this.matrix = new Matrix4();
|
|
262
|
+
this.matrix.setPosition(firstPiecePosition[orbit]);
|
|
263
|
+
this.matrix.premultiply(new Matrix4().makeRotationFromQuaternion(q));
|
|
264
|
+
}
|
|
265
|
+
matrix;
|
|
266
|
+
stickerFaces;
|
|
267
|
+
};
|
|
268
|
+
function t(v, t4) {
|
|
269
|
+
return new Quaternion().setFromAxisAngle(v, TAU * t4 / 4);
|
|
270
|
+
}
|
|
271
|
+
var r = {
|
|
272
|
+
O: new Vector3(0, 0, 0),
|
|
273
|
+
U: new Vector3(0, -1, 0),
|
|
274
|
+
L: new Vector3(1, 0, 0),
|
|
275
|
+
F: new Vector3(0, 0, -1),
|
|
276
|
+
R: new Vector3(-1, 0, 0),
|
|
277
|
+
B: new Vector3(0, 0, 1),
|
|
278
|
+
D: new Vector3(0, 1, 0)
|
|
279
|
+
};
|
|
280
|
+
var firstPiecePosition = {
|
|
281
|
+
EDGES: new Vector3(0, 1, 1),
|
|
282
|
+
CORNERS: new Vector3(1, 1, 1),
|
|
283
|
+
CENTERS: new Vector3(0, 1, 0)
|
|
284
|
+
};
|
|
285
|
+
var orientationRotation = {
|
|
286
|
+
EDGES: [0, 1].map(
|
|
287
|
+
(i) => new Matrix4().makeRotationAxis(
|
|
288
|
+
firstPiecePosition["EDGES"].clone().normalize(),
|
|
289
|
+
-i * TAU / 2
|
|
290
|
+
)
|
|
291
|
+
),
|
|
292
|
+
CORNERS: [0, 1, 2].map(
|
|
293
|
+
(i) => new Matrix4().makeRotationAxis(
|
|
294
|
+
firstPiecePosition["CORNERS"].clone().normalize(),
|
|
295
|
+
-i * TAU / 3
|
|
296
|
+
)
|
|
297
|
+
),
|
|
298
|
+
CENTERS: [0, 1, 2, 3].map(
|
|
299
|
+
(i) => new Matrix4().makeRotationAxis(
|
|
300
|
+
firstPiecePosition["CENTERS"].clone().normalize(),
|
|
301
|
+
-i * TAU / 4
|
|
302
|
+
)
|
|
303
|
+
)
|
|
304
|
+
};
|
|
305
|
+
var cubieStickerOrder = [face["U"], face["F"], face["R"]];
|
|
306
|
+
var pieceDefs = {
|
|
307
|
+
EDGES: [
|
|
308
|
+
new CubieDef("EDGES", "UF", t(r.O, 0)),
|
|
309
|
+
new CubieDef("EDGES", "UR", t(r.U, 3)),
|
|
310
|
+
new CubieDef("EDGES", "UB", t(r.U, 2)),
|
|
311
|
+
new CubieDef("EDGES", "UL", t(r.U, 1)),
|
|
312
|
+
new CubieDef("EDGES", "DF", t(r.F, 2)),
|
|
313
|
+
new CubieDef("EDGES", "DR", t(r.F, 2).premultiply(t(r.D, 1))),
|
|
314
|
+
new CubieDef("EDGES", "DB", t(r.F, 2).premultiply(t(r.D, 2))),
|
|
315
|
+
new CubieDef("EDGES", "DL", t(r.F, 2).premultiply(t(r.D, 3))),
|
|
316
|
+
new CubieDef("EDGES", "FR", t(r.U, 3).premultiply(t(r.R, 3))),
|
|
317
|
+
new CubieDef("EDGES", "FL", t(r.U, 1).premultiply(t(r.R, 3))),
|
|
318
|
+
new CubieDef("EDGES", "BR", t(r.U, 3).premultiply(t(r.R, 1))),
|
|
319
|
+
new CubieDef("EDGES", "BL", t(r.U, 1).premultiply(t(r.R, 1)))
|
|
320
|
+
],
|
|
321
|
+
CORNERS: [
|
|
322
|
+
new CubieDef("CORNERS", "UFR", t(r.O, 0)),
|
|
323
|
+
new CubieDef("CORNERS", "URB", t(r.U, 3)),
|
|
324
|
+
new CubieDef("CORNERS", "UBL", t(r.U, 2)),
|
|
325
|
+
new CubieDef("CORNERS", "ULF", t(r.U, 1)),
|
|
326
|
+
new CubieDef("CORNERS", "DRF", t(r.F, 2).premultiply(t(r.D, 1))),
|
|
327
|
+
new CubieDef("CORNERS", "DFL", t(r.F, 2).premultiply(t(r.D, 0))),
|
|
328
|
+
new CubieDef("CORNERS", "DLB", t(r.F, 2).premultiply(t(r.D, 3))),
|
|
329
|
+
new CubieDef("CORNERS", "DBR", t(r.F, 2).premultiply(t(r.D, 2)))
|
|
330
|
+
],
|
|
331
|
+
CENTERS: [
|
|
332
|
+
new CubieDef("CENTERS", "U", t(r.O, 0)),
|
|
333
|
+
new CubieDef("CENTERS", "L", t(r.R, 3).premultiply(t(r.U, 1))),
|
|
334
|
+
new CubieDef("CENTERS", "F", t(r.R, 3)),
|
|
335
|
+
new CubieDef("CENTERS", "R", t(r.R, 3).premultiply(t(r.D, 1))),
|
|
336
|
+
new CubieDef("CENTERS", "B", t(r.R, 3).premultiply(t(r.D, 2))),
|
|
337
|
+
new CubieDef("CENTERS", "D", t(r.R, 2))
|
|
338
|
+
]
|
|
339
|
+
};
|
|
340
|
+
var CUBE_SCALE = 1 / 3;
|
|
341
|
+
var pictureStickerCoords = {
|
|
342
|
+
EDGES: [
|
|
343
|
+
[
|
|
344
|
+
[0, 4, 6],
|
|
345
|
+
[0, 4, 5]
|
|
346
|
+
],
|
|
347
|
+
[
|
|
348
|
+
[3, 5, 7],
|
|
349
|
+
[0, 7, 5]
|
|
350
|
+
],
|
|
351
|
+
[
|
|
352
|
+
[2, 4, 8],
|
|
353
|
+
[0, 10, 5]
|
|
354
|
+
],
|
|
355
|
+
[
|
|
356
|
+
[1, 3, 7],
|
|
357
|
+
[0, 1, 5]
|
|
358
|
+
],
|
|
359
|
+
[
|
|
360
|
+
[2, 4, 2],
|
|
361
|
+
[2, 4, 3]
|
|
362
|
+
],
|
|
363
|
+
[
|
|
364
|
+
[3, 5, 1],
|
|
365
|
+
[2, 7, 3]
|
|
366
|
+
],
|
|
367
|
+
[
|
|
368
|
+
[0, 4, 0],
|
|
369
|
+
[2, 10, 3]
|
|
370
|
+
],
|
|
371
|
+
[
|
|
372
|
+
[1, 3, 1],
|
|
373
|
+
[2, 1, 3]
|
|
374
|
+
],
|
|
375
|
+
[
|
|
376
|
+
[3, 5, 4],
|
|
377
|
+
[3, 6, 4]
|
|
378
|
+
],
|
|
379
|
+
[
|
|
380
|
+
[1, 3, 4],
|
|
381
|
+
[1, 2, 4]
|
|
382
|
+
],
|
|
383
|
+
[
|
|
384
|
+
[1, 9, 4],
|
|
385
|
+
[1, 8, 4]
|
|
386
|
+
],
|
|
387
|
+
[
|
|
388
|
+
[3, 11, 4],
|
|
389
|
+
[3, 0, 4]
|
|
390
|
+
]
|
|
391
|
+
],
|
|
392
|
+
CORNERS: [
|
|
393
|
+
[
|
|
394
|
+
[0, 5, 6],
|
|
395
|
+
[0, 5, 5],
|
|
396
|
+
[0, 6, 5]
|
|
397
|
+
],
|
|
398
|
+
[
|
|
399
|
+
[3, 5, 8],
|
|
400
|
+
[0, 8, 5],
|
|
401
|
+
[0, 9, 5]
|
|
402
|
+
],
|
|
403
|
+
[
|
|
404
|
+
[2, 3, 8],
|
|
405
|
+
[0, 11, 5],
|
|
406
|
+
[0, 0, 5]
|
|
407
|
+
],
|
|
408
|
+
[
|
|
409
|
+
[1, 3, 6],
|
|
410
|
+
[0, 2, 5],
|
|
411
|
+
[0, 3, 5]
|
|
412
|
+
],
|
|
413
|
+
[
|
|
414
|
+
[3, 5, 2],
|
|
415
|
+
[2, 6, 3],
|
|
416
|
+
[2, 5, 3]
|
|
417
|
+
],
|
|
418
|
+
[
|
|
419
|
+
[2, 3, 2],
|
|
420
|
+
[2, 3, 3],
|
|
421
|
+
[2, 2, 3]
|
|
422
|
+
],
|
|
423
|
+
[
|
|
424
|
+
[1, 3, 0],
|
|
425
|
+
[2, 0, 3],
|
|
426
|
+
[2, 11, 3]
|
|
427
|
+
],
|
|
428
|
+
[
|
|
429
|
+
[0, 5, 0],
|
|
430
|
+
[2, 9, 3],
|
|
431
|
+
[2, 8, 3]
|
|
432
|
+
]
|
|
433
|
+
],
|
|
434
|
+
CENTERS: [
|
|
435
|
+
[[0, 4, 7]],
|
|
436
|
+
[[0, 1, 4]],
|
|
437
|
+
[[0, 4, 4]],
|
|
438
|
+
[[0, 7, 4]],
|
|
439
|
+
[[0, 10, 4]],
|
|
440
|
+
[[0, 4, 1]]
|
|
441
|
+
]
|
|
442
|
+
};
|
|
443
|
+
var sharedCubieFoundationGeometryCache = null;
|
|
444
|
+
function sharedCubieFoundationGeometry() {
|
|
445
|
+
return sharedCubieFoundationGeometryCache ?? (sharedCubieFoundationGeometryCache = new BoxGeometry(
|
|
446
|
+
cubieDimensions.foundationWidth,
|
|
447
|
+
cubieDimensions.foundationWidth,
|
|
448
|
+
cubieDimensions.foundationWidth
|
|
449
|
+
));
|
|
450
|
+
}
|
|
451
|
+
function newStickerGeometry() {
|
|
452
|
+
const r2 = new BufferGeometry();
|
|
453
|
+
const half = 0.5;
|
|
454
|
+
r2.setAttribute(
|
|
455
|
+
"position",
|
|
456
|
+
new BufferAttribute(
|
|
457
|
+
new Float32Array([
|
|
458
|
+
half,
|
|
459
|
+
half,
|
|
460
|
+
0,
|
|
461
|
+
-half,
|
|
462
|
+
half,
|
|
463
|
+
0,
|
|
464
|
+
half,
|
|
465
|
+
-half,
|
|
466
|
+
0,
|
|
467
|
+
-half,
|
|
468
|
+
half,
|
|
469
|
+
0,
|
|
470
|
+
-half,
|
|
471
|
+
-half,
|
|
472
|
+
0,
|
|
473
|
+
half,
|
|
474
|
+
-half,
|
|
475
|
+
0
|
|
476
|
+
]),
|
|
477
|
+
3
|
|
478
|
+
)
|
|
479
|
+
);
|
|
480
|
+
r2.setAttribute(
|
|
481
|
+
"uv",
|
|
482
|
+
new BufferAttribute(
|
|
483
|
+
new Float32Array([
|
|
484
|
+
1,
|
|
485
|
+
1,
|
|
486
|
+
0,
|
|
487
|
+
1,
|
|
488
|
+
1,
|
|
489
|
+
0,
|
|
490
|
+
0,
|
|
491
|
+
1,
|
|
492
|
+
0,
|
|
493
|
+
0,
|
|
494
|
+
1,
|
|
495
|
+
0,
|
|
496
|
+
0,
|
|
497
|
+
1,
|
|
498
|
+
0,
|
|
499
|
+
0,
|
|
500
|
+
1,
|
|
501
|
+
1,
|
|
502
|
+
0,
|
|
503
|
+
0,
|
|
504
|
+
1,
|
|
505
|
+
0,
|
|
506
|
+
1,
|
|
507
|
+
1
|
|
508
|
+
]),
|
|
509
|
+
2
|
|
510
|
+
)
|
|
511
|
+
);
|
|
512
|
+
return r2;
|
|
513
|
+
}
|
|
514
|
+
var sharedStickerGeometryCache;
|
|
515
|
+
function sharedStickerGeometry() {
|
|
516
|
+
return sharedStickerGeometryCache ??= newStickerGeometry();
|
|
517
|
+
}
|
|
518
|
+
var Cube3D = class extends Object3D {
|
|
519
|
+
constructor(kpuzzle, scheduleRenderCallback, options = {}) {
|
|
520
|
+
super();
|
|
521
|
+
this.kpuzzle = kpuzzle;
|
|
522
|
+
this.scheduleRenderCallback = scheduleRenderCallback;
|
|
523
|
+
this.options = { ...cube3DOptionsDefaults };
|
|
524
|
+
Object.assign(this.options, options);
|
|
525
|
+
if (this.kpuzzle.name() !== "3x3x3") {
|
|
526
|
+
throw new Error(
|
|
527
|
+
`Invalid puzzle for this Cube3D implementation: ${this.kpuzzle.name()}`
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
if (options.foundationSprite) {
|
|
531
|
+
this.setSprite(options.foundationSprite);
|
|
532
|
+
}
|
|
533
|
+
if (options.hintSprite) {
|
|
534
|
+
this.setHintSprite(options.hintSprite);
|
|
535
|
+
}
|
|
536
|
+
this.kpuzzleFaceletInfo = {};
|
|
537
|
+
for (const orbit in pieceDefs) {
|
|
538
|
+
const orbitFaceletInfo = [];
|
|
539
|
+
this.kpuzzleFaceletInfo[orbit] = orbitFaceletInfo;
|
|
540
|
+
this.pieces[orbit] = pieceDefs[orbit].map(
|
|
541
|
+
this.createCubie.bind(this, orbit, orbitFaceletInfo)
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
this.scale.set(CUBE_SCALE, CUBE_SCALE, CUBE_SCALE);
|
|
545
|
+
if (this.options.experimentalStickeringMask) {
|
|
546
|
+
this.setStickeringMask(this.options.experimentalStickeringMask);
|
|
547
|
+
}
|
|
548
|
+
void this.#animateRaiseHintFacelets();
|
|
549
|
+
if (this.options.faceletScale) {
|
|
550
|
+
this.experimentalSetFaceletScale(this.options.faceletScale);
|
|
551
|
+
}
|
|
552
|
+
if (typeof this.options["hintFaceletsElevation"] !== "undefined") {
|
|
553
|
+
this.#elevationRequest = this.options.hintFaceletsElevation;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
kpuzzleFaceletInfo;
|
|
557
|
+
pieces = {};
|
|
558
|
+
options;
|
|
559
|
+
// TODO: Keep track of option-based meshes better.
|
|
560
|
+
experimentalHintStickerMeshes = [];
|
|
561
|
+
experimentalFoundationMeshes = [];
|
|
562
|
+
#setSpriteURL;
|
|
563
|
+
sprite = new Promise((resolve) => {
|
|
564
|
+
this.#setSpriteURL = (url) => {
|
|
565
|
+
svgLoader.load(url, resolve);
|
|
566
|
+
};
|
|
567
|
+
});
|
|
568
|
+
// TODO: Don't overwrite the static function.
|
|
569
|
+
// TODO: This doesn't work dynamically yet.
|
|
570
|
+
setSprite(texture) {
|
|
571
|
+
this.sprite = texture;
|
|
572
|
+
}
|
|
573
|
+
#setHintSpriteURL;
|
|
574
|
+
hintSprite = new Promise((resolve) => {
|
|
575
|
+
this.#setHintSpriteURL = (url) => {
|
|
576
|
+
svgLoader.load(url, resolve);
|
|
577
|
+
};
|
|
578
|
+
});
|
|
579
|
+
// TODO: Don't overwrite the static function.
|
|
580
|
+
// TODO: This doesn't work dynamically yet.
|
|
581
|
+
setHintSprite(texture) {
|
|
582
|
+
this.hintSprite = texture;
|
|
583
|
+
}
|
|
584
|
+
#sharedHintStickerGeometryCache;
|
|
585
|
+
#sharedHintStickerGeometry() {
|
|
586
|
+
return this.#sharedHintStickerGeometryCache ??= newStickerGeometry();
|
|
587
|
+
}
|
|
588
|
+
#elevationRequest;
|
|
589
|
+
setHintFaceletsElevation(elevation) {
|
|
590
|
+
if (elevation === this.#elevationRequest) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
this.#cancelAnimateRaiseHintSticker = true;
|
|
594
|
+
this.#setHintFaceletsElevation(
|
|
595
|
+
typeof elevation === "number" ? elevation : cubieDimensions.defaultHintStickerElevation
|
|
596
|
+
);
|
|
597
|
+
this.#elevationRequest = elevation;
|
|
598
|
+
}
|
|
599
|
+
#lastHintStickerElevation = 0;
|
|
600
|
+
#setHintFaceletsElevation(elevation) {
|
|
601
|
+
this.#sharedHintStickerGeometry().translate(
|
|
602
|
+
0,
|
|
603
|
+
0,
|
|
604
|
+
elevation - this.#lastHintStickerElevation
|
|
605
|
+
);
|
|
606
|
+
this.#lastHintStickerElevation = elevation;
|
|
607
|
+
}
|
|
608
|
+
// TODO: support smooth physics
|
|
609
|
+
#cancelAnimateRaiseHintSticker = false;
|
|
610
|
+
// TODO: Generalize this into an animation mechanism.
|
|
611
|
+
async #animateRaiseHintFacelets() {
|
|
612
|
+
if (this.options.initialHintFaceletsAnimation === "none" || this.options.initialHintFaceletsAnimation !== "always" && haveStartedSharingRenderers()) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const targetElevation = typeof this.options.hintFaceletsElevation !== "undefined" && this.options.hintFaceletsElevation !== "auto" ? this.options.hintFaceletsElevation : cubieDimensions.defaultHintStickerElevation;
|
|
616
|
+
const translationRange = targetElevation - cubieDimensions.stickerElevation;
|
|
617
|
+
this.#setHintFaceletsElevation(cubieDimensions.stickerElevation);
|
|
618
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
619
|
+
const hintStartTime = performance.now();
|
|
620
|
+
const translationDuration = 1e3;
|
|
621
|
+
function ease(x) {
|
|
622
|
+
return x * (2 - x);
|
|
623
|
+
}
|
|
624
|
+
const animateRaiseHintSticker = () => {
|
|
625
|
+
if (this.#cancelAnimateRaiseHintSticker) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
const elapsed = performance.now() - hintStartTime;
|
|
629
|
+
const fraction = Math.min(elapsed / translationDuration, 1);
|
|
630
|
+
const newTranslation = ease(fraction) * translationRange + cubieDimensions.stickerElevation;
|
|
631
|
+
this.#setHintFaceletsElevation(newTranslation);
|
|
632
|
+
this.scheduleRenderCallback?.();
|
|
633
|
+
if (elapsed < translationDuration) {
|
|
634
|
+
requestAnimationFrame(animateRaiseHintSticker);
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
animateRaiseHintSticker();
|
|
638
|
+
}
|
|
639
|
+
// Can only be called once.
|
|
640
|
+
/** @deprecated */
|
|
641
|
+
experimentalSetStickerSpriteURL(stickerSpriteURL) {
|
|
642
|
+
this.#setSpriteURL?.(stickerSpriteURL);
|
|
643
|
+
}
|
|
644
|
+
// Can only be called once.
|
|
645
|
+
/** @deprecated */
|
|
646
|
+
experimentalSetHintStickerSpriteURL(hintStickerSpriteURL) {
|
|
647
|
+
this.#setHintSpriteURL?.(hintStickerSpriteURL);
|
|
648
|
+
}
|
|
649
|
+
setStickeringMask(stickeringMask) {
|
|
650
|
+
if (stickeringMask.specialBehaviour === "picture") {
|
|
651
|
+
for (const pieceInfos of Object.values(this.kpuzzleFaceletInfo)) {
|
|
652
|
+
for (const faceletInfos of pieceInfos) {
|
|
653
|
+
for (const faceletInfo of faceletInfos) {
|
|
654
|
+
faceletInfo.facelet.material = invisibleMaterial;
|
|
655
|
+
const { hintFacelet } = faceletInfo;
|
|
656
|
+
if (hintFacelet) {
|
|
657
|
+
hintFacelet.material = invisibleMaterial;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
this.options.experimentalStickeringMask = stickeringMask;
|
|
665
|
+
for (const [orbitName, orbitStickeringMask] of Object.entries(
|
|
666
|
+
stickeringMask.orbits
|
|
667
|
+
)) {
|
|
668
|
+
for (let pieceIdx = 0; pieceIdx < orbitStickeringMask.pieces.length; pieceIdx++) {
|
|
669
|
+
const pieceStickeringMask = orbitStickeringMask.pieces[pieceIdx];
|
|
670
|
+
if (pieceStickeringMask) {
|
|
671
|
+
const pieceInfo = this.kpuzzleFaceletInfo[orbitName][pieceIdx];
|
|
672
|
+
for (let faceletIdx = 0; faceletIdx < pieceInfo.length; faceletIdx++) {
|
|
673
|
+
const faceletStickeringMask = pieceStickeringMask.facelets[faceletIdx];
|
|
674
|
+
if (faceletStickeringMask) {
|
|
675
|
+
const faceletInfo = pieceInfo[faceletIdx];
|
|
676
|
+
const stickeringMask2 = typeof faceletStickeringMask === "string" ? faceletStickeringMask : faceletStickeringMask?.mask;
|
|
677
|
+
faceletInfo.facelet.material = axesInfo[faceletInfo.faceIdx].stickerMaterial[stickeringMask2];
|
|
678
|
+
const hintStickeringMask = typeof faceletStickeringMask === "string" ? stickeringMask2 : faceletStickeringMask.hintMask ?? stickeringMask2;
|
|
679
|
+
if (faceletInfo.hintFacelet) {
|
|
680
|
+
faceletInfo.hintFacelet.material = axesInfo[faceletInfo.faceIdx].hintStickerMaterial[hintStickeringMask];
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (this.scheduleRenderCallback) {
|
|
688
|
+
this.scheduleRenderCallback();
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/** @deprecated */
|
|
692
|
+
experimentalUpdateOptions(options) {
|
|
693
|
+
if ("showMainStickers" in options) {
|
|
694
|
+
throw new Error("Unimplemented");
|
|
695
|
+
}
|
|
696
|
+
const showFoundation = options.showFoundation;
|
|
697
|
+
if (typeof showFoundation !== "undefined" && this.options.showFoundation !== showFoundation) {
|
|
698
|
+
this.options.showFoundation = showFoundation;
|
|
699
|
+
for (const foundation of this.experimentalFoundationMeshes) {
|
|
700
|
+
foundation.visible = showFoundation;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
const hintFacelets = options.hintFacelets;
|
|
704
|
+
if (typeof hintFacelets !== "undefined" && this.options.hintFacelets !== hintFacelets && hintFaceletStyles[hintFacelets]) {
|
|
705
|
+
this.options.hintFacelets = hintFacelets;
|
|
706
|
+
for (const hintSticker of this.experimentalHintStickerMeshes) {
|
|
707
|
+
hintSticker.visible = hintFacelets === "floating";
|
|
708
|
+
}
|
|
709
|
+
this.scheduleRenderCallback();
|
|
710
|
+
}
|
|
711
|
+
const { experimentalStickeringMask } = options;
|
|
712
|
+
if (typeof experimentalStickeringMask !== "undefined") {
|
|
713
|
+
this.options.experimentalStickeringMask = experimentalStickeringMask;
|
|
714
|
+
this.setStickeringMask(experimentalStickeringMask);
|
|
715
|
+
this.scheduleRenderCallback();
|
|
716
|
+
}
|
|
717
|
+
const { faceletScale } = options;
|
|
718
|
+
if (typeof faceletScale !== "undefined") {
|
|
719
|
+
this.experimentalSetFaceletScale(faceletScale);
|
|
720
|
+
}
|
|
721
|
+
const { hintFaceletsElevation } = options;
|
|
722
|
+
if (typeof hintFaceletsElevation !== "undefined") {
|
|
723
|
+
this.setHintFaceletsElevation(hintFaceletsElevation);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
onPositionChange(p) {
|
|
727
|
+
const reid333 = p.pattern;
|
|
728
|
+
for (const orbit in pieceDefs) {
|
|
729
|
+
const pieces = pieceDefs[orbit];
|
|
730
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
731
|
+
const j = reid333.patternData[orbit].pieces[i];
|
|
732
|
+
this.pieces[orbit][j].matrix.copy(pieceDefs[orbit][i].matrix);
|
|
733
|
+
this.pieces[orbit][j].matrix.multiply(
|
|
734
|
+
orientationRotation[orbit][reid333.patternData[orbit].orientation[i]]
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
for (const moveProgress of p.movesInProgress) {
|
|
738
|
+
const move = moveProgress.move;
|
|
739
|
+
const turnNormal = axesInfo[familyToAxis[move.family]].vector;
|
|
740
|
+
const moveMatrix = new Matrix4().makeRotationAxis(
|
|
741
|
+
turnNormal,
|
|
742
|
+
-this.ease(moveProgress.fraction) * moveProgress.direction * move.amount * TAU / 4
|
|
743
|
+
);
|
|
744
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
745
|
+
const quantumTransformation = this.kpuzzle.moveToTransformation(
|
|
746
|
+
move.modified({ amount: 1 })
|
|
747
|
+
);
|
|
748
|
+
const k = quantumTransformation.transformationData[orbit].permutation[i];
|
|
749
|
+
if (i !== k || quantumTransformation.transformationData[orbit].orientationDelta[i] !== 0) {
|
|
750
|
+
const j = reid333.patternData[orbit].pieces[i];
|
|
751
|
+
this.pieces[orbit][j].matrix.premultiply(moveMatrix);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
this.scheduleRenderCallback();
|
|
757
|
+
}
|
|
758
|
+
// TODO: Always create (but sometimes hide parts) so we can show them later,
|
|
759
|
+
// or (better) support creating puzzle parts on demand.
|
|
760
|
+
createCubie(orbit, orbitFacelets, piece, orbitPieceIdx) {
|
|
761
|
+
const cubieFaceletInfo = [];
|
|
762
|
+
orbitFacelets.push(cubieFaceletInfo);
|
|
763
|
+
const cubie = new Group();
|
|
764
|
+
if (this.options.showFoundation) {
|
|
765
|
+
const foundation = this.createCubieFoundation();
|
|
766
|
+
cubie.add(foundation);
|
|
767
|
+
this.experimentalFoundationMeshes.push(foundation);
|
|
768
|
+
}
|
|
769
|
+
for (let i = 0; i < piece.stickerFaces.length; i++) {
|
|
770
|
+
const sticker = this.createSticker(
|
|
771
|
+
axesInfo[cubieStickerOrder[i]],
|
|
772
|
+
axesInfo[piece.stickerFaces[i]],
|
|
773
|
+
false
|
|
774
|
+
);
|
|
775
|
+
const faceletInfo = {
|
|
776
|
+
faceIdx: piece.stickerFaces[i],
|
|
777
|
+
facelet: sticker
|
|
778
|
+
};
|
|
779
|
+
cubie.add(sticker);
|
|
780
|
+
if (this.options.hintFacelets === "floating") {
|
|
781
|
+
const hintSticker = this.createSticker(
|
|
782
|
+
axesInfo[cubieStickerOrder[i]],
|
|
783
|
+
axesInfo[piece.stickerFaces[i]],
|
|
784
|
+
true
|
|
785
|
+
);
|
|
786
|
+
cubie.add(hintSticker);
|
|
787
|
+
faceletInfo.hintFacelet = hintSticker;
|
|
788
|
+
this.experimentalHintStickerMeshes.push(hintSticker);
|
|
789
|
+
}
|
|
790
|
+
if (this.options.experimentalStickeringMask?.specialBehaviour === "picture" && pictureStickerCoords[orbit] && pictureStickerCoords[orbit][orbitPieceIdx] && pictureStickerCoords[orbit][orbitPieceIdx][i]) {
|
|
791
|
+
const [rotate, offsetX, offsetY] = pictureStickerCoords[orbit][orbitPieceIdx][i];
|
|
792
|
+
void (async () => {
|
|
793
|
+
const addImageSticker = async (hint) => {
|
|
794
|
+
const texture = await (hint ? this.hintSprite : this.sprite);
|
|
795
|
+
const mesh = this.createSticker(
|
|
796
|
+
axesInfo[cubieStickerOrder[i]],
|
|
797
|
+
axesInfo[piece.stickerFaces[i]],
|
|
798
|
+
hint
|
|
799
|
+
);
|
|
800
|
+
mesh.material = new MeshBasicMaterial({
|
|
801
|
+
map: texture,
|
|
802
|
+
side: hint ? BackSide : DoubleSide,
|
|
803
|
+
transparent: true
|
|
804
|
+
});
|
|
805
|
+
const x1 = offsetX / 12;
|
|
806
|
+
const x2 = (offsetX + 1) / 12;
|
|
807
|
+
const y1 = offsetY / 9;
|
|
808
|
+
const y2 = (offsetY + 1) / 9;
|
|
809
|
+
let v1 = new Vector2(x1, y1);
|
|
810
|
+
let v2 = new Vector2(x1, y2);
|
|
811
|
+
let v3 = new Vector2(x2, y2);
|
|
812
|
+
let v4 = new Vector2(x2, y1);
|
|
813
|
+
switch (rotate) {
|
|
814
|
+
case 1: {
|
|
815
|
+
[v1, v2, v3, v4] = [v2, v3, v4, v1];
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
case 2: {
|
|
819
|
+
[v1, v2, v3, v4] = [v3, v4, v1, v2];
|
|
820
|
+
break;
|
|
821
|
+
}
|
|
822
|
+
case 3: {
|
|
823
|
+
[v1, v2, v3, v4] = [v4, v1, v2, v3];
|
|
824
|
+
break;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
mesh.geometry.setAttribute(
|
|
828
|
+
"uv",
|
|
829
|
+
new BufferAttribute(
|
|
830
|
+
new Float32Array([
|
|
831
|
+
v3.x,
|
|
832
|
+
v3.y,
|
|
833
|
+
v2.x,
|
|
834
|
+
v2.y,
|
|
835
|
+
v4.x,
|
|
836
|
+
v4.y,
|
|
837
|
+
v2.x,
|
|
838
|
+
v2.y,
|
|
839
|
+
v1.x,
|
|
840
|
+
v1.y,
|
|
841
|
+
v4.x,
|
|
842
|
+
v4.y
|
|
843
|
+
]),
|
|
844
|
+
2
|
|
845
|
+
)
|
|
846
|
+
);
|
|
847
|
+
cubie.add(mesh);
|
|
848
|
+
};
|
|
849
|
+
void addImageSticker(true);
|
|
850
|
+
void addImageSticker(false);
|
|
851
|
+
})();
|
|
852
|
+
}
|
|
853
|
+
cubieFaceletInfo.push(faceletInfo);
|
|
854
|
+
}
|
|
855
|
+
cubie.matrix.copy(piece.matrix);
|
|
856
|
+
cubie.matrixAutoUpdate = false;
|
|
857
|
+
this.add(cubie);
|
|
858
|
+
return cubie;
|
|
859
|
+
}
|
|
860
|
+
// TODO: Support creating only the outward-facing parts?
|
|
861
|
+
createCubieFoundation() {
|
|
862
|
+
const box = sharedCubieFoundationGeometry();
|
|
863
|
+
return new Mesh(
|
|
864
|
+
box,
|
|
865
|
+
this.options.experimentalStickeringMask?.specialBehaviour === "picture" ? blackMesh : blackTranslucentMesh
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
createSticker(posAxisInfo, materialAxisInfo, isHint) {
|
|
869
|
+
const geo = this.options.experimentalStickeringMask?.specialBehaviour === "picture" ? newStickerGeometry() : isHint ? this.#sharedHintStickerGeometry() : sharedStickerGeometry();
|
|
870
|
+
const stickerMesh = new Mesh(
|
|
871
|
+
geo,
|
|
872
|
+
isHint ? materialAxisInfo.hintStickerMaterial.regular : materialAxisInfo.stickerMaterial.regular
|
|
873
|
+
);
|
|
874
|
+
stickerMesh.setRotationFromEuler(posAxisInfo.fromZ);
|
|
875
|
+
stickerMesh.position.copy(posAxisInfo.vector);
|
|
876
|
+
const elevation = (() => {
|
|
877
|
+
if (!isHint) {
|
|
878
|
+
return cubieDimensions.stickerElevation;
|
|
879
|
+
}
|
|
880
|
+
if (typeof this.options.hintFaceletsElevation === "number") {
|
|
881
|
+
return this.options.hintFaceletsElevation;
|
|
882
|
+
}
|
|
883
|
+
if (this.options.experimentalStickeringMask?.specialBehaviour === "picture") {
|
|
884
|
+
return EXPERIMENTAL_PICTURE_CUBE_HINT_ELEVATION;
|
|
885
|
+
}
|
|
886
|
+
return cubieDimensions.defaultHintStickerElevation;
|
|
887
|
+
})();
|
|
888
|
+
if (isHint) {
|
|
889
|
+
this.#lastHintStickerElevation = elevation;
|
|
890
|
+
}
|
|
891
|
+
const scale = getFaceletScale(this.options);
|
|
892
|
+
stickerMesh.scale.setX(scale);
|
|
893
|
+
stickerMesh.scale.setY(scale);
|
|
894
|
+
stickerMesh.translateZ(elevation - 1);
|
|
895
|
+
return stickerMesh;
|
|
896
|
+
}
|
|
897
|
+
/** @deprecated */
|
|
898
|
+
experimentalSetFoundationOpacity(opacity) {
|
|
899
|
+
this.experimentalFoundationMeshes[0].material.opacity = opacity;
|
|
900
|
+
}
|
|
901
|
+
/** @deprecated */
|
|
902
|
+
experimentalSetFaceletScale(faceletScale) {
|
|
903
|
+
this.options.faceletScale = faceletScale;
|
|
904
|
+
for (const orbitInfo of Object.values(this.kpuzzleFaceletInfo)) {
|
|
905
|
+
for (const pieceInfo of orbitInfo) {
|
|
906
|
+
for (const faceletInfo of pieceInfo) {
|
|
907
|
+
const scale = getFaceletScale(this.options);
|
|
908
|
+
faceletInfo.facelet.scale.setX(scale);
|
|
909
|
+
faceletInfo.facelet.scale.setY(scale);
|
|
910
|
+
faceletInfo.hintFacelet?.scale.setX(scale);
|
|
911
|
+
faceletInfo.hintFacelet?.scale.setY(scale);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
// /** @deprecated */
|
|
917
|
+
// experimentalSetCenterStickerWidth(width: number): void {
|
|
918
|
+
// for (const orbitInfo of [this.kpuzzleFaceletInfo["CENTERS"]]) {
|
|
919
|
+
// for (const pieceInfo of orbitInfo) {
|
|
920
|
+
// for (const faceletInfo of pieceInfo) {
|
|
921
|
+
// faceletInfo.facelet.scale.setScalar(
|
|
922
|
+
// width / getStickerScale(this.options),
|
|
923
|
+
// );
|
|
924
|
+
// // faceletInfo.facelet.setRotationFromAxisAngle(new Vector3(0, 1, 0), 0);
|
|
925
|
+
// // faceletInfo.facelet.rotateOnAxis(new Vector3(1, 0, 1), TAU / 6);
|
|
926
|
+
// }
|
|
927
|
+
// }
|
|
928
|
+
// }
|
|
929
|
+
// }
|
|
930
|
+
ease(fraction) {
|
|
931
|
+
return smootherStep(fraction);
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
// src/cubing/twisty/views/3D/puzzles/PG3D.ts
|
|
936
|
+
import { DoubleSide as DoubleSide2, FrontSide as FrontSide2 } from "three/src/constants.js";
|
|
937
|
+
import { BufferAttribute as BufferAttribute2 } from "three/src/core/BufferAttribute.js";
|
|
938
|
+
import { BufferGeometry as BufferGeometry2 } from "three/src/core/BufferGeometry.js";
|
|
939
|
+
import { Object3D as Object3D2 } from "three/src/core/Object3D.js";
|
|
940
|
+
import { MeshBasicMaterial as MeshBasicMaterial2 } from "three/src/materials/MeshBasicMaterial.js";
|
|
941
|
+
import { Color as Color2 } from "three/src/math/Color.js";
|
|
942
|
+
import { Euler as Euler2 } from "three/src/math/Euler.js";
|
|
943
|
+
import { Vector3 as Vector32 } from "three/src/math/Vector3.js";
|
|
944
|
+
import { Group as Group2 } from "three/src/objects/Group.js";
|
|
945
|
+
import { Mesh as Mesh2 } from "three/src/objects/Mesh.js";
|
|
946
|
+
var foundationMaterial = new MeshBasicMaterial2({
|
|
947
|
+
side: DoubleSide2,
|
|
948
|
+
color: 0
|
|
949
|
+
});
|
|
950
|
+
var invisMaterial = new MeshBasicMaterial2({
|
|
951
|
+
visible: false
|
|
952
|
+
});
|
|
953
|
+
var basicStickerMaterial = new MeshBasicMaterial2({
|
|
954
|
+
vertexColors: true
|
|
955
|
+
});
|
|
956
|
+
function dist(coords, a, b) {
|
|
957
|
+
return Math.hypot(
|
|
958
|
+
coords[3 * a] - coords[3 * b],
|
|
959
|
+
coords[3 * a + 1] - coords[3 * b + 1],
|
|
960
|
+
coords[3 * a + 2] - coords[3 * b + 2]
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
function triarea(coords, a, b, c) {
|
|
964
|
+
const ab = dist(coords, a, b);
|
|
965
|
+
const bc = dist(coords, b, c);
|
|
966
|
+
const ac = dist(coords, a, c);
|
|
967
|
+
const p = (ab + bc + ac) / 2;
|
|
968
|
+
return Math.sqrt(p * (p - ab) * (p - bc) * (p - ac));
|
|
969
|
+
}
|
|
970
|
+
function polyarea(coords) {
|
|
971
|
+
let sum = 0;
|
|
972
|
+
for (let i = 2; 3 * i < coords.length; i++) {
|
|
973
|
+
sum += triarea(coords, 0, 1, i);
|
|
974
|
+
}
|
|
975
|
+
return sum;
|
|
976
|
+
}
|
|
977
|
+
function normalize(r2) {
|
|
978
|
+
const m = Math.hypot(r2[0], r2[1], r2[2]);
|
|
979
|
+
r2[0] /= m;
|
|
980
|
+
r2[1] /= m;
|
|
981
|
+
r2[2] /= m;
|
|
982
|
+
return r2;
|
|
983
|
+
}
|
|
984
|
+
function cross(a, b) {
|
|
985
|
+
const r2 = new Array(3);
|
|
986
|
+
r2[0] = a[1] * b[2] - a[2] * b[1];
|
|
987
|
+
r2[1] = a[2] * b[0] - a[0] * b[2];
|
|
988
|
+
r2[2] = a[0] * b[1] - a[1] * b[0];
|
|
989
|
+
return r2;
|
|
990
|
+
}
|
|
991
|
+
function normal(c) {
|
|
992
|
+
const a = [c[3] - c[0], c[4] - c[1], c[5] - c[2]];
|
|
993
|
+
const b = [c[6] - c[3], c[7] - c[4], c[8] - c[5]];
|
|
994
|
+
const r2 = cross(a, b);
|
|
995
|
+
return normalize(r2);
|
|
996
|
+
}
|
|
997
|
+
function trimEdges(face2, tr) {
|
|
998
|
+
const r2 = [];
|
|
999
|
+
const A = new Array(3);
|
|
1000
|
+
const B = new Array(3);
|
|
1001
|
+
for (let iter = 1; iter < 10; iter++) {
|
|
1002
|
+
for (let i = 0; i < face2.length; i += 3) {
|
|
1003
|
+
const pi = (i + face2.length - 3) % face2.length;
|
|
1004
|
+
const ni = (i + 3) % face2.length;
|
|
1005
|
+
for (let k = 0; k < 3; k++) {
|
|
1006
|
+
A[k] = face2[pi + k] - face2[i + k];
|
|
1007
|
+
B[k] = face2[ni + k] - face2[i + k];
|
|
1008
|
+
}
|
|
1009
|
+
const alen = Math.hypot(A[0], A[1], A[2]);
|
|
1010
|
+
const blen = Math.hypot(B[0], B[1], B[2]);
|
|
1011
|
+
for (let k = 0; k < 3; k++) {
|
|
1012
|
+
A[k] /= alen;
|
|
1013
|
+
B[k] /= blen;
|
|
1014
|
+
}
|
|
1015
|
+
const d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2];
|
|
1016
|
+
const m = tr / Math.sqrt(1 - d * d);
|
|
1017
|
+
for (let k = 0; k < 3; k++) {
|
|
1018
|
+
r2[i + k] = face2[i + k] + (A[k] + B[k]) * m;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
let good = true;
|
|
1022
|
+
for (let i = 0; good && i < r2.length; i += 3) {
|
|
1023
|
+
const ni = (i + 3) % face2.length;
|
|
1024
|
+
let t2 = 0;
|
|
1025
|
+
for (let k = 0; k < 3; k++) {
|
|
1026
|
+
const a = face2[ni + k] - face2[i + k];
|
|
1027
|
+
const b = r2[ni + k] - r2[i + k];
|
|
1028
|
+
t2 += a * b;
|
|
1029
|
+
}
|
|
1030
|
+
if (t2 <= 0) {
|
|
1031
|
+
good = false;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
if (good) {
|
|
1035
|
+
return r2;
|
|
1036
|
+
}
|
|
1037
|
+
tr /= 2;
|
|
1038
|
+
}
|
|
1039
|
+
return face2;
|
|
1040
|
+
}
|
|
1041
|
+
var Filler = class {
|
|
1042
|
+
constructor(sz, tm) {
|
|
1043
|
+
this.sz = sz;
|
|
1044
|
+
this.tm = tm;
|
|
1045
|
+
this.vertices = new Float32Array(9 * sz);
|
|
1046
|
+
this.uvs = void 0;
|
|
1047
|
+
this.colors = new Uint8Array(18 * sz);
|
|
1048
|
+
this.ind = new Uint8Array(sz);
|
|
1049
|
+
this.pos = 0;
|
|
1050
|
+
this.ipos = 0;
|
|
1051
|
+
}
|
|
1052
|
+
pos;
|
|
1053
|
+
ipos;
|
|
1054
|
+
vertices;
|
|
1055
|
+
colors;
|
|
1056
|
+
uvs;
|
|
1057
|
+
ind;
|
|
1058
|
+
add(pt, i, c) {
|
|
1059
|
+
this.vertices[this.pos] = pt[3 * i + 0];
|
|
1060
|
+
this.vertices[this.pos + 1] = pt[3 * i + 1];
|
|
1061
|
+
this.vertices[this.pos + 2] = pt[3 * i + 2];
|
|
1062
|
+
this.colors[this.pos] = c >> 16;
|
|
1063
|
+
this.colors[this.pos + 1] = c >> 8 & 255;
|
|
1064
|
+
this.colors[this.pos + 2] = c & 255;
|
|
1065
|
+
this.pos += 3;
|
|
1066
|
+
}
|
|
1067
|
+
addUncolored(pt, i) {
|
|
1068
|
+
this.vertices[this.pos] = pt[3 * i + 0];
|
|
1069
|
+
this.vertices[this.pos + 1] = pt[3 * i + 1];
|
|
1070
|
+
this.vertices[this.pos + 2] = pt[3 * i + 2];
|
|
1071
|
+
this.pos += 3;
|
|
1072
|
+
}
|
|
1073
|
+
setind(i) {
|
|
1074
|
+
this.ind[this.ipos++] = i;
|
|
1075
|
+
}
|
|
1076
|
+
makePoly(coords, color, ind) {
|
|
1077
|
+
const ncoords = coords;
|
|
1078
|
+
for (let g = 1; 3 * (g + 1) < ncoords.length; g++) {
|
|
1079
|
+
this.add(ncoords, 0, color);
|
|
1080
|
+
this.add(ncoords, g, color);
|
|
1081
|
+
this.add(ncoords, g + 1, color);
|
|
1082
|
+
this.setind(ind);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
setAttributes(geo) {
|
|
1086
|
+
geo.setAttribute("position", new BufferAttribute2(this.vertices, 3));
|
|
1087
|
+
const sa2 = this.colors.subarray(0, 9 * this.sz);
|
|
1088
|
+
geo.setAttribute("color", new BufferAttribute2(sa2, 3, true));
|
|
1089
|
+
}
|
|
1090
|
+
makeGroups(geo) {
|
|
1091
|
+
geo.clearGroups();
|
|
1092
|
+
for (let i = 0; i < this.ipos; ) {
|
|
1093
|
+
const si = i++;
|
|
1094
|
+
const iv = this.ind[si];
|
|
1095
|
+
while (this.ind[i] === iv) {
|
|
1096
|
+
i++;
|
|
1097
|
+
}
|
|
1098
|
+
geo.addGroup(3 * si, 3 * (i - si), iv);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
saveOriginalColors() {
|
|
1102
|
+
this.colors.copyWithin(this.pos, 0, this.pos);
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
var StickerDef = class {
|
|
1106
|
+
origColor;
|
|
1107
|
+
origColorStickeringMask;
|
|
1108
|
+
faceColor;
|
|
1109
|
+
texturePtr = void 0;
|
|
1110
|
+
twistVal = -1;
|
|
1111
|
+
stickerStart;
|
|
1112
|
+
stickerEnd;
|
|
1113
|
+
hintStart;
|
|
1114
|
+
hintEnd;
|
|
1115
|
+
foundationStart;
|
|
1116
|
+
foundationEnd;
|
|
1117
|
+
isDup;
|
|
1118
|
+
faceNum;
|
|
1119
|
+
constructor(filler, stickerDat, trim, options) {
|
|
1120
|
+
this.isDup = !!stickerDat.isDup;
|
|
1121
|
+
this.faceNum = stickerDat.face;
|
|
1122
|
+
this.stickerStart = filler.ipos;
|
|
1123
|
+
const sdColor = new Color2(stickerDat.color).getHex();
|
|
1124
|
+
this.origColor = sdColor;
|
|
1125
|
+
this.origColorStickeringMask = sdColor;
|
|
1126
|
+
if (options?.stickeringMask) {
|
|
1127
|
+
this.setStickeringMask(filler, options.stickeringMask);
|
|
1128
|
+
}
|
|
1129
|
+
this.faceColor = sdColor;
|
|
1130
|
+
const coords = this.stickerCoords(stickerDat.coords, trim);
|
|
1131
|
+
filler.makePoly(coords, this.faceColor, this.isDup ? 4 : 0);
|
|
1132
|
+
this.stickerEnd = filler.ipos;
|
|
1133
|
+
}
|
|
1134
|
+
stickerCoords(coords, trim) {
|
|
1135
|
+
return trimEdges(coords.slice(), trim);
|
|
1136
|
+
}
|
|
1137
|
+
hintCoords(coords, hintStickerHeightScale, trim, normal2) {
|
|
1138
|
+
coords = this.stickerCoords(coords, trim);
|
|
1139
|
+
normal2 = normal2.slice();
|
|
1140
|
+
for (let i = 0; i < 3; i++) {
|
|
1141
|
+
normal2[i] *= 0.5 * hintStickerHeightScale;
|
|
1142
|
+
}
|
|
1143
|
+
const hCoords = new Array(coords.length);
|
|
1144
|
+
for (let i = 0; 3 * i < coords.length; i++) {
|
|
1145
|
+
const j = coords.length / 3 - 1 - i;
|
|
1146
|
+
hCoords[3 * i] = coords[3 * j] + normal2[0];
|
|
1147
|
+
hCoords[3 * i + 1] = coords[3 * j + 1] + normal2[1];
|
|
1148
|
+
hCoords[3 * i + 2] = coords[3 * j + 2] + normal2[2];
|
|
1149
|
+
}
|
|
1150
|
+
return hCoords;
|
|
1151
|
+
}
|
|
1152
|
+
foundationCoords(coords) {
|
|
1153
|
+
const ncoords = coords.slice();
|
|
1154
|
+
for (let i = 0; i < coords.length; i++) {
|
|
1155
|
+
ncoords[i] = coords[i] * 0.999;
|
|
1156
|
+
}
|
|
1157
|
+
return ncoords;
|
|
1158
|
+
}
|
|
1159
|
+
addHint(filler, stickerDat, hintStickers, hintStickerHeightScale, trim, normal2) {
|
|
1160
|
+
this.hintStart = filler.ipos;
|
|
1161
|
+
const coords = this.hintCoords(
|
|
1162
|
+
stickerDat.coords,
|
|
1163
|
+
hintStickerHeightScale,
|
|
1164
|
+
trim,
|
|
1165
|
+
normal2
|
|
1166
|
+
);
|
|
1167
|
+
filler.makePoly(
|
|
1168
|
+
coords,
|
|
1169
|
+
this.faceColor,
|
|
1170
|
+
hintStickers && !this.isDup ? 2 : 4
|
|
1171
|
+
);
|
|
1172
|
+
this.hintEnd = filler.ipos;
|
|
1173
|
+
}
|
|
1174
|
+
addFoundation(filler, stickerDat, black) {
|
|
1175
|
+
this.foundationStart = filler.ipos;
|
|
1176
|
+
const coords = this.foundationCoords(stickerDat.coords);
|
|
1177
|
+
filler.makePoly(coords, black, this.isDup ? 4 : 6);
|
|
1178
|
+
this.foundationEnd = filler.ipos;
|
|
1179
|
+
}
|
|
1180
|
+
setHintStickers(filler, hintStickers) {
|
|
1181
|
+
const indv = this.isDup || !hintStickers ? 4 : 2;
|
|
1182
|
+
for (let i = this.hintStart; i < this.hintEnd; i++) {
|
|
1183
|
+
filler.ind[i] = indv | filler.ind[i] & 1;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
setStickeringMask(filler, faceletMeshStickeringMask) {
|
|
1187
|
+
let c = 0;
|
|
1188
|
+
switch (faceletMeshStickeringMask) {
|
|
1189
|
+
case "regular": {
|
|
1190
|
+
c = this.origColor;
|
|
1191
|
+
break;
|
|
1192
|
+
}
|
|
1193
|
+
case "dim": {
|
|
1194
|
+
if (this.origColor === 16777215) {
|
|
1195
|
+
c = 14540253;
|
|
1196
|
+
} else {
|
|
1197
|
+
c = new Color2(this.origColor).multiplyScalar(0.5).getHex();
|
|
1198
|
+
}
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1201
|
+
case "oriented": {
|
|
1202
|
+
c = 4513228;
|
|
1203
|
+
break;
|
|
1204
|
+
}
|
|
1205
|
+
case "experimentalOriented2": {
|
|
1206
|
+
c = 16776618;
|
|
1207
|
+
break;
|
|
1208
|
+
}
|
|
1209
|
+
case "ignored": {
|
|
1210
|
+
c = 4473924;
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
case "mystery": {
|
|
1214
|
+
c = 15911883;
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
case "invisible":
|
|
1218
|
+
c = this.origColor;
|
|
1219
|
+
}
|
|
1220
|
+
this.origColorStickeringMask = c;
|
|
1221
|
+
for (let i = 9 * this.stickerStart; i < 9 * this.stickerEnd; i += 3) {
|
|
1222
|
+
filler.colors[filler.pos + i] = c >> 16;
|
|
1223
|
+
filler.colors[filler.pos + i + 1] = c >> 8 & 255;
|
|
1224
|
+
filler.colors[filler.pos + i + 2] = c & 255;
|
|
1225
|
+
}
|
|
1226
|
+
for (let i = 9 * this.hintStart; i < 9 * this.hintEnd; i += 3) {
|
|
1227
|
+
filler.colors[filler.pos + i] = c >> 16;
|
|
1228
|
+
filler.colors[filler.pos + i + 1] = c >> 8 & 255;
|
|
1229
|
+
filler.colors[filler.pos + i + 2] = c & 255;
|
|
1230
|
+
}
|
|
1231
|
+
this.setHintStickers(
|
|
1232
|
+
filler,
|
|
1233
|
+
faceletMeshStickeringMask !== "invisible" && !this.isDup
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
addUVs(filler) {
|
|
1237
|
+
const uvs = filler.uvs;
|
|
1238
|
+
const vert = filler.vertices;
|
|
1239
|
+
const coords = new Array(3);
|
|
1240
|
+
for (let i = 3 * this.stickerStart; i < 3 * this.stickerEnd; i++) {
|
|
1241
|
+
coords[0] = vert[3 * i];
|
|
1242
|
+
coords[1] = vert[3 * i + 1];
|
|
1243
|
+
coords[2] = vert[3 * i + 2];
|
|
1244
|
+
const uv = filler.tm.getuv(this.faceNum, coords);
|
|
1245
|
+
uvs[2 * i] = uv[0];
|
|
1246
|
+
uvs[2 * i + 1] = uv[1];
|
|
1247
|
+
}
|
|
1248
|
+
for (let i = 3 * this.hintStart; i < 3 * this.hintEnd; i++) {
|
|
1249
|
+
coords[0] = vert[3 * i];
|
|
1250
|
+
coords[1] = vert[3 * i + 1];
|
|
1251
|
+
coords[2] = vert[3 * i + 2];
|
|
1252
|
+
const uv = filler.tm.getuv(this.faceNum, coords);
|
|
1253
|
+
uvs[2 * i] = uv[0];
|
|
1254
|
+
uvs[2 * i + 1] = uv[1];
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
setTexture(filler, sd) {
|
|
1258
|
+
if (this.texturePtr === sd) {
|
|
1259
|
+
return 0;
|
|
1260
|
+
}
|
|
1261
|
+
this.texturePtr = sd;
|
|
1262
|
+
const sz = 6 * filler.sz;
|
|
1263
|
+
filler.uvs.copyWithin(
|
|
1264
|
+
6 * this.stickerStart,
|
|
1265
|
+
6 * sd.stickerStart + sz,
|
|
1266
|
+
6 * sd.stickerEnd + sz
|
|
1267
|
+
);
|
|
1268
|
+
filler.uvs.copyWithin(
|
|
1269
|
+
6 * this.hintStart,
|
|
1270
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1271
|
+
6 * sd.hintStart + sz,
|
|
1272
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1273
|
+
6 * sd.hintEnd + sz
|
|
1274
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1275
|
+
);
|
|
1276
|
+
return 1;
|
|
1277
|
+
}
|
|
1278
|
+
setColor(filler, sd) {
|
|
1279
|
+
const c = sd.origColorStickeringMask;
|
|
1280
|
+
if (this.faceColor !== c) {
|
|
1281
|
+
this.faceColor = c;
|
|
1282
|
+
const sz = filler.pos;
|
|
1283
|
+
filler.colors.copyWithin(
|
|
1284
|
+
9 * this.stickerStart,
|
|
1285
|
+
9 * sd.stickerStart + sz,
|
|
1286
|
+
9 * sd.stickerEnd + sz
|
|
1287
|
+
);
|
|
1288
|
+
filler.colors.copyWithin(
|
|
1289
|
+
9 * this.hintStart,
|
|
1290
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1291
|
+
9 * sd.hintStart + sz,
|
|
1292
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1293
|
+
9 * sd.hintEnd + sz
|
|
1294
|
+
// TODO: refactor to avoid non-null-assertion
|
|
1295
|
+
);
|
|
1296
|
+
return 1;
|
|
1297
|
+
} else {
|
|
1298
|
+
return 0;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
var HitPlaneDef = class {
|
|
1303
|
+
cubie;
|
|
1304
|
+
geo;
|
|
1305
|
+
constructor(hitface, tm, stickerDat) {
|
|
1306
|
+
this.cubie = new Group2();
|
|
1307
|
+
const coords = hitface.coords;
|
|
1308
|
+
const filler = new Filler(coords.length / 3 - 2, tm);
|
|
1309
|
+
for (let g = 1; 3 * g + 3 < coords.length; g++) {
|
|
1310
|
+
filler.addUncolored(coords, 0);
|
|
1311
|
+
filler.addUncolored(coords, g);
|
|
1312
|
+
filler.addUncolored(coords, g + 1);
|
|
1313
|
+
}
|
|
1314
|
+
this.geo = new BufferGeometry2();
|
|
1315
|
+
filler.setAttributes(this.geo);
|
|
1316
|
+
const obj = new Mesh2(this.geo, invisMaterial);
|
|
1317
|
+
obj.userData["quantumMove"] = stickerDat.notationMapper.notationToExternal(
|
|
1318
|
+
new Move(hitface.name)
|
|
1319
|
+
);
|
|
1320
|
+
this.cubie.scale.setScalar(0.99);
|
|
1321
|
+
this.cubie.add(obj);
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
var AxisInfo2 = class {
|
|
1325
|
+
axis;
|
|
1326
|
+
order;
|
|
1327
|
+
constructor(axisDat) {
|
|
1328
|
+
const vec = axisDat.coordinates;
|
|
1329
|
+
this.axis = new Vector32(vec[0], vec[1], vec[2]);
|
|
1330
|
+
this.order = axisDat.order;
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
var DEFAULT_COLOR_FRACTION = 0.71;
|
|
1334
|
+
var PG_SCALE = 0.5;
|
|
1335
|
+
var PG3D = class extends Object3D2 {
|
|
1336
|
+
constructor(scheduleRenderCallback, kpuzzle, stickerDat, enableFoundationOpt = false, enableHintStickersOpt = false, hintStickerHeightScale = 1, faceletScale = 1, params = {}) {
|
|
1337
|
+
super();
|
|
1338
|
+
this.scheduleRenderCallback = scheduleRenderCallback;
|
|
1339
|
+
this.kpuzzle = kpuzzle;
|
|
1340
|
+
this.stickerDat = stickerDat;
|
|
1341
|
+
this.faceletScale = faceletScale;
|
|
1342
|
+
this.params = params;
|
|
1343
|
+
if (stickerDat.stickers.length === 0) {
|
|
1344
|
+
throw Error("Reuse of stickerdat from pg; please don't do that.");
|
|
1345
|
+
}
|
|
1346
|
+
this.hintMaterial = new MeshBasicMaterial2({
|
|
1347
|
+
vertexColors: true,
|
|
1348
|
+
transparent: true,
|
|
1349
|
+
opacity: 0.5
|
|
1350
|
+
});
|
|
1351
|
+
this.hintMaterialDisposable = true;
|
|
1352
|
+
this.stickerMaterial = basicStickerMaterial;
|
|
1353
|
+
this.stickerMaterialDisposable = false;
|
|
1354
|
+
this.axesInfo = {};
|
|
1355
|
+
const axesDef = this.stickerDat.axis;
|
|
1356
|
+
for (const axis of axesDef) {
|
|
1357
|
+
this.axesInfo[axis.quantumMove.family] = new AxisInfo2(axis);
|
|
1358
|
+
}
|
|
1359
|
+
const stickers = this.stickerDat.stickers;
|
|
1360
|
+
this.stickers = {};
|
|
1361
|
+
this.materialArray1 = new Array(8);
|
|
1362
|
+
this.materialArray2 = new Array(8);
|
|
1363
|
+
this.showFoundation(enableFoundationOpt);
|
|
1364
|
+
enableFoundationOpt = true;
|
|
1365
|
+
let triangleCount = 0;
|
|
1366
|
+
const multiplier = 3;
|
|
1367
|
+
for (const sticker of stickers) {
|
|
1368
|
+
const sides = sticker.coords.length / 3;
|
|
1369
|
+
triangleCount += multiplier * (sides - 2);
|
|
1370
|
+
}
|
|
1371
|
+
const filler = new Filler(triangleCount, stickerDat.textureMapper);
|
|
1372
|
+
const black = 0;
|
|
1373
|
+
const normals = [];
|
|
1374
|
+
let totArea = 0;
|
|
1375
|
+
for (const f of stickerDat.faces) {
|
|
1376
|
+
normals.push(normal(f.coords));
|
|
1377
|
+
totArea += polyarea(f.coords);
|
|
1378
|
+
}
|
|
1379
|
+
const colorfrac = faceletScale !== "auto" ? faceletScale * faceletScale : DEFAULT_COLOR_FRACTION;
|
|
1380
|
+
let nonDupStickers = 0;
|
|
1381
|
+
for (const sticker of stickers) {
|
|
1382
|
+
if (!sticker.isDup) {
|
|
1383
|
+
nonDupStickers++;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
const trim = Math.sqrt(totArea / nonDupStickers) * (1 - Math.sqrt(colorfrac)) / 2;
|
|
1387
|
+
for (const sticker of stickers) {
|
|
1388
|
+
const orbit = sticker.orbit;
|
|
1389
|
+
const ord = sticker.ord;
|
|
1390
|
+
const ori = sticker.ori;
|
|
1391
|
+
if (!this.stickers[orbit]) {
|
|
1392
|
+
this.stickers[orbit] = [];
|
|
1393
|
+
}
|
|
1394
|
+
if (!this.stickers[orbit][ori]) {
|
|
1395
|
+
this.stickers[orbit][ori] = [];
|
|
1396
|
+
}
|
|
1397
|
+
const options = {};
|
|
1398
|
+
if (params.stickeringMask) {
|
|
1399
|
+
options.stickeringMask = getFaceletStickeringMask(
|
|
1400
|
+
params.stickeringMask,
|
|
1401
|
+
orbit,
|
|
1402
|
+
ord,
|
|
1403
|
+
ori,
|
|
1404
|
+
false
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
const stickerdef = new StickerDef(filler, sticker, trim, options);
|
|
1408
|
+
this.stickers[orbit][ori][ord] = stickerdef;
|
|
1409
|
+
}
|
|
1410
|
+
this.showHintStickers = enableHintStickersOpt;
|
|
1411
|
+
enableHintStickersOpt = true;
|
|
1412
|
+
for (const sticker of stickers) {
|
|
1413
|
+
const orbit = sticker.orbit;
|
|
1414
|
+
const ord = sticker.ord;
|
|
1415
|
+
const ori = sticker.ori;
|
|
1416
|
+
this.stickers[orbit][ori][ord].addHint(
|
|
1417
|
+
filler,
|
|
1418
|
+
sticker,
|
|
1419
|
+
enableHintStickersOpt,
|
|
1420
|
+
hintStickerHeightScale,
|
|
1421
|
+
trim,
|
|
1422
|
+
normals[sticker.face]
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
this.foundationBound = filler.ipos;
|
|
1426
|
+
for (const sticker of stickers) {
|
|
1427
|
+
const orbit = sticker.orbit;
|
|
1428
|
+
const ord = sticker.ord;
|
|
1429
|
+
const ori = sticker.ori;
|
|
1430
|
+
if (enableFoundationOpt) {
|
|
1431
|
+
this.stickers[orbit][ori][ord].addFoundation(filler, sticker, black);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
const fixedGeo = new BufferGeometry2();
|
|
1435
|
+
filler.setAttributes(fixedGeo);
|
|
1436
|
+
filler.makeGroups(fixedGeo);
|
|
1437
|
+
const obj = new Mesh2(fixedGeo, this.materialArray1);
|
|
1438
|
+
obj.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);
|
|
1439
|
+
this.add(obj);
|
|
1440
|
+
const obj2 = new Mesh2(fixedGeo, this.materialArray2);
|
|
1441
|
+
obj2.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);
|
|
1442
|
+
this.add(obj2);
|
|
1443
|
+
const hitfaces = this.stickerDat.faces;
|
|
1444
|
+
this.movingObj = obj2;
|
|
1445
|
+
this.fixedGeo = fixedGeo;
|
|
1446
|
+
this.filler = filler;
|
|
1447
|
+
for (const hitface of hitfaces) {
|
|
1448
|
+
const facedef = new HitPlaneDef(
|
|
1449
|
+
hitface,
|
|
1450
|
+
stickerDat.textureMapper,
|
|
1451
|
+
this.stickerDat
|
|
1452
|
+
);
|
|
1453
|
+
facedef.cubie.scale.set(PG_SCALE, PG_SCALE, PG_SCALE);
|
|
1454
|
+
this.add(facedef.cubie);
|
|
1455
|
+
this.controlTargets.push(facedef.cubie.children[0]);
|
|
1456
|
+
}
|
|
1457
|
+
filler.saveOriginalColors();
|
|
1458
|
+
stickerDat.stickers = [];
|
|
1459
|
+
this.updateMaterialArrays();
|
|
1460
|
+
}
|
|
1461
|
+
stickers;
|
|
1462
|
+
axesInfo;
|
|
1463
|
+
stickerTargets = [];
|
|
1464
|
+
controlTargets = [];
|
|
1465
|
+
movingObj;
|
|
1466
|
+
filler;
|
|
1467
|
+
foundationBound;
|
|
1468
|
+
// before this: colored; after: black
|
|
1469
|
+
fixedGeo;
|
|
1470
|
+
lastPos;
|
|
1471
|
+
lastMoveTransformation;
|
|
1472
|
+
hintMaterial;
|
|
1473
|
+
stickerMaterial;
|
|
1474
|
+
materialArray1;
|
|
1475
|
+
materialArray2;
|
|
1476
|
+
textured = false;
|
|
1477
|
+
showHintStickers = false;
|
|
1478
|
+
showFoundations = false;
|
|
1479
|
+
hintMaterialDisposable;
|
|
1480
|
+
stickerMaterialDisposable;
|
|
1481
|
+
#pendingStickeringUpdate = false;
|
|
1482
|
+
dispose() {
|
|
1483
|
+
if (this.fixedGeo) {
|
|
1484
|
+
this.fixedGeo.dispose();
|
|
1485
|
+
}
|
|
1486
|
+
if (this.stickerMaterialDisposable) {
|
|
1487
|
+
this.stickerMaterial.dispose();
|
|
1488
|
+
this.stickerMaterial = basicStickerMaterial;
|
|
1489
|
+
this.stickerMaterialDisposable = false;
|
|
1490
|
+
}
|
|
1491
|
+
if (this.hintMaterialDisposable) {
|
|
1492
|
+
this.hintMaterial.dispose();
|
|
1493
|
+
this.hintMaterial = basicStickerMaterial;
|
|
1494
|
+
this.hintMaterialDisposable = false;
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
experimentalGetStickerTargets() {
|
|
1498
|
+
return this.stickerTargets;
|
|
1499
|
+
}
|
|
1500
|
+
experimentalGetControlTargets() {
|
|
1501
|
+
return this.controlTargets;
|
|
1502
|
+
}
|
|
1503
|
+
#isValidMove(move) {
|
|
1504
|
+
try {
|
|
1505
|
+
this.kpuzzle.moveToTransformation(move);
|
|
1506
|
+
return true;
|
|
1507
|
+
} catch (_) {
|
|
1508
|
+
return false;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
getClosestMoveToAxis(point, transformations) {
|
|
1512
|
+
let closestMove = null;
|
|
1513
|
+
let closestMoveDotProduct = 0;
|
|
1514
|
+
let modify = (m) => m;
|
|
1515
|
+
switch (transformations.depth) {
|
|
1516
|
+
case "secondSlice": {
|
|
1517
|
+
modify = (m) => m.modified({ innerLayer: 2 });
|
|
1518
|
+
break;
|
|
1519
|
+
}
|
|
1520
|
+
case "rotation": {
|
|
1521
|
+
modify = (m) => m.modified({ family: `${m.family}v` });
|
|
1522
|
+
break;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
for (const axis of this.stickerDat.axis) {
|
|
1526
|
+
const product = point.dot(new Vector32(...axis.coordinates));
|
|
1527
|
+
if (product > closestMoveDotProduct) {
|
|
1528
|
+
const modified = this.stickerDat.notationMapper.notationToExternal(
|
|
1529
|
+
modify(axis.quantumMove)
|
|
1530
|
+
);
|
|
1531
|
+
if (!modified) {
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
console.log(modified.family);
|
|
1535
|
+
if (modified.family === "T" && transformations.depth === "none") {
|
|
1536
|
+
continue;
|
|
1537
|
+
}
|
|
1538
|
+
if (this.#isValidMove(modified)) {
|
|
1539
|
+
closestMoveDotProduct = product;
|
|
1540
|
+
closestMove = modified;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
if (!closestMove) {
|
|
1545
|
+
return null;
|
|
1546
|
+
}
|
|
1547
|
+
if (transformations.invert) {
|
|
1548
|
+
closestMove = closestMove.invert();
|
|
1549
|
+
}
|
|
1550
|
+
const order = this.kpuzzle.moveToTransformation(closestMove).repetitionOrder();
|
|
1551
|
+
return { move: closestMove, order };
|
|
1552
|
+
}
|
|
1553
|
+
setStickeringMask(stickeringMask) {
|
|
1554
|
+
this.params.stickeringMask = stickeringMask;
|
|
1555
|
+
if (stickeringMask.specialBehaviour !== "picture") {
|
|
1556
|
+
for (const orbitDefinition of this.kpuzzle.definition.orbits) {
|
|
1557
|
+
const { numPieces, numOrientations } = orbitDefinition;
|
|
1558
|
+
for (let pieceIdx = 0; pieceIdx < numPieces; pieceIdx++) {
|
|
1559
|
+
for (let faceletIdx = 0; faceletIdx < numOrientations; faceletIdx++) {
|
|
1560
|
+
const faceletStickeringMask = getFaceletStickeringMask(
|
|
1561
|
+
stickeringMask,
|
|
1562
|
+
orbitDefinition.orbitName,
|
|
1563
|
+
pieceIdx,
|
|
1564
|
+
faceletIdx,
|
|
1565
|
+
false
|
|
1566
|
+
);
|
|
1567
|
+
const stickerDef = this.stickers[orbitDefinition.orbitName][faceletIdx][pieceIdx];
|
|
1568
|
+
if (this.textured && this.hintMaterialDisposable && faceletStickeringMask === "invisible") {
|
|
1569
|
+
} else {
|
|
1570
|
+
stickerDef.setStickeringMask(this.filler, faceletStickeringMask);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
this.#pendingStickeringUpdate = true;
|
|
1577
|
+
if (this.lastPos) {
|
|
1578
|
+
this.onPositionChange(this.lastPos);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
onPositionChange(p) {
|
|
1582
|
+
const { pattern } = p;
|
|
1583
|
+
const noRotation = new Euler2();
|
|
1584
|
+
this.movingObj.rotation.copy(noRotation);
|
|
1585
|
+
let colormods = 0;
|
|
1586
|
+
const filler = this.filler;
|
|
1587
|
+
const ind = filler.ind;
|
|
1588
|
+
if (!this.lastPos || this.#pendingStickeringUpdate || !this.lastPos.pattern.isIdentical(pattern)) {
|
|
1589
|
+
for (const orbit in this.stickers) {
|
|
1590
|
+
const pieces = this.stickers[orbit];
|
|
1591
|
+
const pos2 = pattern.patternData[orbit];
|
|
1592
|
+
const orin = pieces.length;
|
|
1593
|
+
if (orin === 1) {
|
|
1594
|
+
const pieces2 = pieces[0];
|
|
1595
|
+
for (let i = 0; i < pieces2.length; i++) {
|
|
1596
|
+
const ni = pos2.pieces[i];
|
|
1597
|
+
if (this.textured) {
|
|
1598
|
+
colormods += pieces2[i].setTexture(filler, pieces2[ni]);
|
|
1599
|
+
} else {
|
|
1600
|
+
colormods += pieces2[i].setColor(filler, pieces2[ni]);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
} else {
|
|
1604
|
+
for (let ori = 0; ori < orin; ori++) {
|
|
1605
|
+
const pieces2 = pieces[ori];
|
|
1606
|
+
for (let i = 0; i < pieces2.length; i++) {
|
|
1607
|
+
const nori = (ori + orin - pos2.orientation[i]) % orin;
|
|
1608
|
+
const ni = pos2.pieces[i];
|
|
1609
|
+
if (this.textured) {
|
|
1610
|
+
colormods += pieces2[i].setTexture(filler, pieces[nori][ni]);
|
|
1611
|
+
} else {
|
|
1612
|
+
colormods += pieces2[i].setColor(filler, pieces[nori][ni]);
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
this.lastPos = p;
|
|
1619
|
+
}
|
|
1620
|
+
let vismods = 0;
|
|
1621
|
+
for (const moveProgress of p.movesInProgress) {
|
|
1622
|
+
const externalMove = moveProgress.move;
|
|
1623
|
+
const unswizzled = this.stickerDat.unswizzle(externalMove);
|
|
1624
|
+
if (!unswizzled) {
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
const move = externalMove;
|
|
1628
|
+
let quantumTransformation;
|
|
1629
|
+
try {
|
|
1630
|
+
quantumTransformation = this.kpuzzle.moveToTransformation(
|
|
1631
|
+
move.modified({ amount: 1 })
|
|
1632
|
+
);
|
|
1633
|
+
} catch (e) {
|
|
1634
|
+
const move1 = this.stickerDat.notationMapper.notationToInternal(move);
|
|
1635
|
+
if (move1) {
|
|
1636
|
+
const move2 = this.stickerDat.notationMapper.notationToExternal(
|
|
1637
|
+
move1.modified({ amount: 1 })
|
|
1638
|
+
);
|
|
1639
|
+
if (move2) {
|
|
1640
|
+
quantumTransformation = this.kpuzzle.moveToTransformation(move2);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
if (!quantumTransformation) {
|
|
1644
|
+
console.log(e);
|
|
1645
|
+
throw e;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
const ax = this.axesInfo[unswizzled.family];
|
|
1649
|
+
const turnNormal = ax.axis;
|
|
1650
|
+
const angle = -this.ease(moveProgress.fraction) * moveProgress.direction * unswizzled.amount * TAU / ax.order;
|
|
1651
|
+
this.movingObj.rotateOnAxis(turnNormal, angle);
|
|
1652
|
+
if (this.lastMoveTransformation !== quantumTransformation) {
|
|
1653
|
+
for (const orbit in this.stickers) {
|
|
1654
|
+
const pieces = this.stickers[orbit];
|
|
1655
|
+
const orin = pieces.length;
|
|
1656
|
+
const bmv = quantumTransformation.transformationData[orbit];
|
|
1657
|
+
for (let ori = 0; ori < orin; ori++) {
|
|
1658
|
+
const pieces2 = pieces[ori];
|
|
1659
|
+
for (let i = 0; i < pieces2.length; i++) {
|
|
1660
|
+
const p2 = pieces2[i];
|
|
1661
|
+
const ni = bmv.permutation[i];
|
|
1662
|
+
let tv = 0;
|
|
1663
|
+
if (ni !== i || bmv.orientationDelta[i] !== 0) {
|
|
1664
|
+
tv = 1;
|
|
1665
|
+
}
|
|
1666
|
+
if (tv !== p2.twistVal) {
|
|
1667
|
+
if (tv) {
|
|
1668
|
+
for (let j = p2.stickerStart; j < p2.stickerEnd; j++) {
|
|
1669
|
+
ind[j] |= 1;
|
|
1670
|
+
}
|
|
1671
|
+
for (let j = p2.hintStart; j < p2.hintEnd; j++) {
|
|
1672
|
+
ind[j] |= 1;
|
|
1673
|
+
}
|
|
1674
|
+
for (let j = p2.foundationStart; j < p2.foundationEnd; j++) {
|
|
1675
|
+
ind[j] |= 1;
|
|
1676
|
+
}
|
|
1677
|
+
} else {
|
|
1678
|
+
for (let j = p2.stickerStart; j < p2.stickerEnd; j++) {
|
|
1679
|
+
ind[j] &= ~1;
|
|
1680
|
+
}
|
|
1681
|
+
for (let j = p2.hintStart; j < p2.hintEnd; j++) {
|
|
1682
|
+
ind[j] &= ~1;
|
|
1683
|
+
}
|
|
1684
|
+
for (let j = p2.foundationStart; j < p2.foundationEnd; j++) {
|
|
1685
|
+
ind[j] &= ~1;
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
p2.twistVal = tv;
|
|
1689
|
+
vismods++;
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
this.lastMoveTransformation = quantumTransformation;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
if (this.#pendingStickeringUpdate || vismods) {
|
|
1698
|
+
this.filler.makeGroups(this.fixedGeo);
|
|
1699
|
+
}
|
|
1700
|
+
if (this.#pendingStickeringUpdate || colormods) {
|
|
1701
|
+
if (this.textured) {
|
|
1702
|
+
this.fixedGeo.getAttribute("uv").addUpdateRange(
|
|
1703
|
+
0,
|
|
1704
|
+
6 * this.foundationBound
|
|
1705
|
+
);
|
|
1706
|
+
this.fixedGeo.getAttribute("uv").needsUpdate = true;
|
|
1707
|
+
}
|
|
1708
|
+
if (this.#pendingStickeringUpdate || !this.textured) {
|
|
1709
|
+
this.fixedGeo.getAttribute("color").addUpdateRange(
|
|
1710
|
+
0,
|
|
1711
|
+
9 * this.foundationBound
|
|
1712
|
+
);
|
|
1713
|
+
this.fixedGeo.getAttribute("color").needsUpdate = true;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
this.scheduleRenderCallback();
|
|
1717
|
+
this.#pendingStickeringUpdate = false;
|
|
1718
|
+
}
|
|
1719
|
+
ease(fraction) {
|
|
1720
|
+
return smootherStep(fraction);
|
|
1721
|
+
}
|
|
1722
|
+
showHintFacelets(v) {
|
|
1723
|
+
this.showHintStickers = v;
|
|
1724
|
+
}
|
|
1725
|
+
updateMaterialArrays() {
|
|
1726
|
+
for (let i = 0; i < 8; i++) {
|
|
1727
|
+
this.materialArray1[i] = invisMaterial;
|
|
1728
|
+
this.materialArray2[i] = invisMaterial;
|
|
1729
|
+
}
|
|
1730
|
+
this.materialArray1[0] = this.stickerMaterial;
|
|
1731
|
+
this.materialArray2[1] = this.stickerMaterial;
|
|
1732
|
+
if (this.showHintStickers) {
|
|
1733
|
+
this.materialArray1[2] = this.hintMaterial;
|
|
1734
|
+
this.materialArray2[3] = this.hintMaterial;
|
|
1735
|
+
} else {
|
|
1736
|
+
this.materialArray1[2] = invisMaterial;
|
|
1737
|
+
this.materialArray2[3] = invisMaterial;
|
|
1738
|
+
}
|
|
1739
|
+
if (this.showFoundations) {
|
|
1740
|
+
this.materialArray1[6] = foundationMaterial;
|
|
1741
|
+
this.materialArray2[7] = foundationMaterial;
|
|
1742
|
+
} else {
|
|
1743
|
+
this.materialArray1[6] = invisMaterial;
|
|
1744
|
+
this.materialArray2[7] = invisMaterial;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
showFoundation(v) {
|
|
1748
|
+
this.showFoundations = v;
|
|
1749
|
+
}
|
|
1750
|
+
setHintStickerOpacity(v) {
|
|
1751
|
+
if (this.hintMaterialDisposable) {
|
|
1752
|
+
this.hintMaterial.dispose();
|
|
1753
|
+
this.hintMaterialDisposable = false;
|
|
1754
|
+
}
|
|
1755
|
+
if (v === 0) {
|
|
1756
|
+
this.hintMaterial = invisMaterial;
|
|
1757
|
+
} else if (v === 1) {
|
|
1758
|
+
this.hintMaterial = this.stickerMaterial;
|
|
1759
|
+
} else {
|
|
1760
|
+
this.hintMaterial = new MeshBasicMaterial2({
|
|
1761
|
+
vertexColors: true,
|
|
1762
|
+
transparent: true,
|
|
1763
|
+
opacity: v
|
|
1764
|
+
});
|
|
1765
|
+
this.hintMaterialDisposable = true;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
experimentalUpdateOptions(options) {
|
|
1769
|
+
if (options.hintFacelets !== void 0) {
|
|
1770
|
+
this.showHintFacelets(options.hintFacelets !== "none");
|
|
1771
|
+
}
|
|
1772
|
+
if (options.showFoundation !== void 0) {
|
|
1773
|
+
this.showFoundation(options.showFoundation);
|
|
1774
|
+
}
|
|
1775
|
+
if (options.hintStickerOpacity !== void 0) {
|
|
1776
|
+
this.setHintStickerOpacity(options.hintStickerOpacity);
|
|
1777
|
+
}
|
|
1778
|
+
this.#pendingStickeringUpdate = true;
|
|
1779
|
+
if (this.lastPos) {
|
|
1780
|
+
this.onPositionChange(this.lastPos);
|
|
1781
|
+
}
|
|
1782
|
+
if (typeof options.faceletScale !== "undefined" && options.faceletScale !== this.faceletScale) {
|
|
1783
|
+
console.warn(
|
|
1784
|
+
"Dynamic facelet scale is not yet supported for PG3D. For now, re-create the TwistyPlayer to change the facelet scale."
|
|
1785
|
+
);
|
|
1786
|
+
}
|
|
1787
|
+
this.updateMaterialArrays();
|
|
1788
|
+
this.scheduleRenderCallback();
|
|
1789
|
+
}
|
|
1790
|
+
adduvs() {
|
|
1791
|
+
const filler = this.filler;
|
|
1792
|
+
if (filler.uvs) {
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
this.filler.uvs = new Float32Array(12 * filler.sz);
|
|
1796
|
+
for (const orbit in this.stickers) {
|
|
1797
|
+
const pieces = this.stickers[orbit];
|
|
1798
|
+
const orin = pieces.length;
|
|
1799
|
+
for (let ori = 0; ori < orin; ori++) {
|
|
1800
|
+
const pieces2 = pieces[ori];
|
|
1801
|
+
for (const piece2 of pieces2) {
|
|
1802
|
+
piece2.addUVs(this.filler);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
filler.uvs.copyWithin(6 * filler.sz, 0, 6 * filler.sz);
|
|
1807
|
+
const sa1 = filler.uvs.subarray(0, 6 * filler.sz);
|
|
1808
|
+
this.fixedGeo.setAttribute("uv", new BufferAttribute2(sa1, 2, true));
|
|
1809
|
+
}
|
|
1810
|
+
experimentalUpdateTexture(enabled, stickerTexture, hintTexture) {
|
|
1811
|
+
if (!stickerTexture) {
|
|
1812
|
+
enabled = false;
|
|
1813
|
+
}
|
|
1814
|
+
if (enabled && !this.filler.uvs) {
|
|
1815
|
+
this.adduvs();
|
|
1816
|
+
}
|
|
1817
|
+
this.textured = enabled;
|
|
1818
|
+
if (this.stickerMaterialDisposable) {
|
|
1819
|
+
this.stickerMaterial.dispose();
|
|
1820
|
+
this.stickerMaterialDisposable = false;
|
|
1821
|
+
}
|
|
1822
|
+
if (enabled) {
|
|
1823
|
+
this.stickerMaterial = new MeshBasicMaterial2({
|
|
1824
|
+
map: stickerTexture,
|
|
1825
|
+
side: FrontSide2,
|
|
1826
|
+
transparent: false
|
|
1827
|
+
});
|
|
1828
|
+
this.stickerMaterialDisposable = true;
|
|
1829
|
+
} else {
|
|
1830
|
+
this.stickerMaterial = basicStickerMaterial;
|
|
1831
|
+
}
|
|
1832
|
+
if (this.hintMaterialDisposable) {
|
|
1833
|
+
this.hintMaterial.dispose();
|
|
1834
|
+
this.hintMaterialDisposable = false;
|
|
1835
|
+
}
|
|
1836
|
+
if (enabled) {
|
|
1837
|
+
this.hintMaterial = new MeshBasicMaterial2({
|
|
1838
|
+
map: hintTexture,
|
|
1839
|
+
side: FrontSide2,
|
|
1840
|
+
transparent: true
|
|
1841
|
+
});
|
|
1842
|
+
this.hintMaterialDisposable = true;
|
|
1843
|
+
} else {
|
|
1844
|
+
this.hintMaterial = basicStickerMaterial;
|
|
1845
|
+
}
|
|
1846
|
+
if (enabled) {
|
|
1847
|
+
this.showHintFacelets(hintTexture !== null);
|
|
1848
|
+
}
|
|
1849
|
+
this.updateMaterialArrays();
|
|
1850
|
+
this.#pendingStickeringUpdate = true;
|
|
1851
|
+
if (this.lastPos) {
|
|
1852
|
+
this.onPositionChange(this.lastPos);
|
|
1853
|
+
}
|
|
1854
|
+
this.scheduleRenderCallback();
|
|
1855
|
+
}
|
|
1856
|
+
};
|
|
1857
|
+
|
|
1858
|
+
// src/cubing/twisty/heavy-code-imports/dynamic-entries/twisty-dynamic-3d.ts
|
|
1859
|
+
import { PerspectiveCamera } from "three/src/cameras/PerspectiveCamera.js";
|
|
1860
|
+
import { Raycaster } from "three/src/core/Raycaster.js";
|
|
1861
|
+
import { TextureLoader as TextureLoader2 } from "three/src/loaders/TextureLoader.js";
|
|
1862
|
+
import { Spherical } from "three/src/math/Spherical.js";
|
|
1863
|
+
import { Vector2 as Vector22 } from "three/src/math/Vector2.js";
|
|
1864
|
+
import { Vector3 as Vector33 } from "three/src/math/Vector3.js";
|
|
1865
|
+
import { WebGLRenderer } from "three/src/renderers/WebGLRenderer.js";
|
|
1866
|
+
import { Scene } from "three/src/scenes/Scene.js";
|
|
1867
|
+
|
|
1868
|
+
// src/cubing/twisty/views/3D/Twisty3DScene.ts
|
|
1869
|
+
var Twisty3DScene = class {
|
|
1870
|
+
renderTargets = /* @__PURE__ */ new Set();
|
|
1871
|
+
twisty3Ds = /* @__PURE__ */ new Set();
|
|
1872
|
+
threeJSScene = (async () => new (await bulk3DCode()).ThreeScene())();
|
|
1873
|
+
addRenderTarget(renderTarget) {
|
|
1874
|
+
this.renderTargets.add(renderTarget);
|
|
1875
|
+
}
|
|
1876
|
+
scheduleRender() {
|
|
1877
|
+
for (const renderTarget of this.renderTargets) {
|
|
1878
|
+
renderTarget.scheduleRender();
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
async addTwisty3DPuzzle(twisty3DPuzzle) {
|
|
1882
|
+
this.twisty3Ds.add(twisty3DPuzzle);
|
|
1883
|
+
(await this.threeJSScene).add(twisty3DPuzzle);
|
|
1884
|
+
}
|
|
1885
|
+
async removeTwisty3DPuzzle(twisty3DPuzzle) {
|
|
1886
|
+
this.twisty3Ds.delete(twisty3DPuzzle);
|
|
1887
|
+
(await this.threeJSScene).remove(twisty3DPuzzle);
|
|
1888
|
+
}
|
|
1889
|
+
async clearPuzzles() {
|
|
1890
|
+
for (const puz of this.twisty3Ds) {
|
|
1891
|
+
(await this.threeJSScene).remove(puz);
|
|
1892
|
+
}
|
|
1893
|
+
this.twisty3Ds.clear();
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
|
|
1897
|
+
// src/cubing/twisty/heavy-code-imports/dynamic-entries/twisty-dynamic-3d.ts
|
|
1898
|
+
async function cube3DShim(renderCallback, options) {
|
|
1899
|
+
return new Cube3D(await cube3x3x3.kpuzzle(), renderCallback, options);
|
|
1900
|
+
}
|
|
1901
|
+
async function pg3dShim(renderCallback, puzzleLoader, hintFacelets, faceletScale, darkIgnoredOrbits) {
|
|
1902
|
+
return new PG3D(
|
|
1903
|
+
renderCallback,
|
|
1904
|
+
await puzzleLoader.kpuzzle(),
|
|
1905
|
+
(await puzzleLoader.pg()).get3d({ darkIgnoredOrbits }),
|
|
1906
|
+
true,
|
|
1907
|
+
hintFacelets === "floating",
|
|
1908
|
+
void 0,
|
|
1909
|
+
faceletScale
|
|
1910
|
+
);
|
|
1911
|
+
}
|
|
1912
|
+
export {
|
|
1913
|
+
Cube3D,
|
|
1914
|
+
PG3D,
|
|
1915
|
+
PerspectiveCamera as ThreePerspectiveCamera,
|
|
1916
|
+
Raycaster as ThreeRaycaster,
|
|
1917
|
+
Scene as ThreeScene,
|
|
1918
|
+
Spherical as ThreeSpherical,
|
|
1919
|
+
TextureLoader2 as ThreeTextureLoader,
|
|
1920
|
+
Vector22 as ThreeVector2,
|
|
1921
|
+
Vector33 as ThreeVector3,
|
|
1922
|
+
WebGLRenderer as ThreeWebGLRenderer,
|
|
1923
|
+
Twisty3DScene,
|
|
1924
|
+
cube3DShim,
|
|
1925
|
+
pg3dShim
|
|
1926
|
+
};
|
|
1927
|
+
//# sourceMappingURL=twisty-dynamic-3d-VGZIQ64W.js.map
|