@rednaxela101/cubing 0.63.9 → 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.
- package/dist/bin/chunks/{chunk-F63RAIBR.js → chunk-3WUR6UXA.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/bin/svg.js +1 -1
- package/dist/lib/cubing/alg/index.d.ts +1 -1
- package/dist/lib/cubing/bluetooth/index.d.ts +2 -2
- package/dist/lib/cubing/chunks/{chunk-F765ZFNM.js → chunk-IOHGEWB2.js} +2 -2
- package/dist/lib/cubing/chunks/{twisty-dynamic-3d-MF76FSDA.js → twisty-dynamic-3d-3MGVD3TG.js} +634 -172
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-3MGVD3TG.js.map +7 -0
- package/dist/lib/cubing/{index-ylnTp4i5.d.ts → index-0OM9yjf0.d.ts} +1 -1
- package/dist/lib/cubing/{index-FT5_Vsnm.d.ts → index-B_TS5TTk.d.ts} +13 -0
- package/dist/lib/cubing/kpuzzle/index.d.ts +1 -1
- package/dist/lib/cubing/notation/index.d.ts +1 -1
- package/dist/lib/cubing/{outside-D3tRtsxV.d.ts → outside-BUsE7O5Q.d.ts} +1 -1
- package/dist/lib/cubing/protocol/index.d.ts +1 -1
- package/dist/lib/cubing/puzzle-geometry/index.d.ts +1 -1
- package/dist/lib/cubing/puzzles/index.d.ts +1 -1
- package/dist/lib/cubing/scramble/index.d.ts +1 -1
- package/dist/lib/cubing/search/index.d.ts +1 -1
- package/dist/lib/cubing/stream/index.d.ts +1 -1
- package/dist/lib/cubing/twisty/index.d.ts +1 -1
- package/dist/lib/cubing/twisty/index.js +31 -2
- package/dist/lib/cubing/twisty/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/lib/cubing/chunks/twisty-dynamic-3d-MF76FSDA.js.map +0 -7
- /package/dist/bin/chunks/{chunk-F63RAIBR.js.map → chunk-3WUR6UXA.js.map} +0 -0
- /package/dist/lib/cubing/chunks/{chunk-F765ZFNM.js.map → chunk-IOHGEWB2.js.map} +0 -0
package/dist/lib/cubing/chunks/{twisty-dynamic-3d-MF76FSDA.js → twisty-dynamic-3d-3MGVD3TG.js}
RENAMED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
bulk3DCode,
|
|
4
4
|
haveStartedSharingRenderers,
|
|
5
5
|
hintFaceletStyles
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IOHGEWB2.js";
|
|
7
7
|
import "./chunk-3ODTF4HE.js";
|
|
8
8
|
import {
|
|
9
9
|
cube3x3x3,
|
|
@@ -15,20 +15,20 @@ import {
|
|
|
15
15
|
} from "./chunk-XPDJUSZ7.js";
|
|
16
16
|
|
|
17
17
|
// src/cubing/twisty/views/3D/puzzles/Cube3D.ts
|
|
18
|
-
import { BackSide, DoubleSide, FrontSide } from "three/src/constants.js";
|
|
19
|
-
import { BufferAttribute as
|
|
20
|
-
import { BufferGeometry as
|
|
18
|
+
import { BackSide, DoubleSide, FrontSide as FrontSide2 } from "three/src/constants.js";
|
|
19
|
+
import { BufferAttribute as BufferAttribute3 } from "three/src/core/BufferAttribute.js";
|
|
20
|
+
import { BufferGeometry as BufferGeometry3 } from "three/src/core/BufferGeometry.js";
|
|
21
21
|
import { Object3D } from "three/src/core/Object3D.js";
|
|
22
22
|
import { BoxGeometry } from "three/src/geometries/BoxGeometry.js";
|
|
23
23
|
import { TextureLoader } from "three/src/loaders/TextureLoader.js";
|
|
24
|
-
import { MeshBasicMaterial as
|
|
24
|
+
import { MeshBasicMaterial as MeshBasicMaterial3 } from "three/src/materials/MeshBasicMaterial.js";
|
|
25
25
|
import { Color as Color2 } from "three/src/math/Color.js";
|
|
26
26
|
import { Matrix4 } from "three/src/math/Matrix4.js";
|
|
27
27
|
import { Quaternion } from "three/src/math/Quaternion.js";
|
|
28
28
|
import { Vector2 } from "three/src/math/Vector2.js";
|
|
29
|
-
import { Vector3 as
|
|
29
|
+
import { Vector3 as Vector34 } from "three/src/math/Vector3.js";
|
|
30
30
|
import { Group } from "three/src/objects/Group.js";
|
|
31
|
-
import { Mesh } from "three/src/objects/Mesh.js";
|
|
31
|
+
import { Mesh as Mesh2 } from "three/src/objects/Mesh.js";
|
|
32
32
|
|
|
33
33
|
// src/cubing/twisty/controllers/easing.ts
|
|
34
34
|
function smootherStep(x) {
|
|
@@ -288,34 +288,240 @@ var hintMaskStyles = {
|
|
|
288
288
|
mystery: { color: 15911883, opacity: 0.5 }
|
|
289
289
|
};
|
|
290
290
|
|
|
291
|
+
// src/cubing/twisty/views/3D/puzzles/PuzzleLogo.ts
|
|
292
|
+
import { FrontSide } from "three/src/constants.js";
|
|
293
|
+
import { BufferAttribute as BufferAttribute2 } from "three/src/core/BufferAttribute.js";
|
|
294
|
+
import { BufferGeometry as BufferGeometry2 } from "three/src/core/BufferGeometry.js";
|
|
295
|
+
import { MeshBasicMaterial as MeshBasicMaterial2 } from "three/src/materials/MeshBasicMaterial.js";
|
|
296
|
+
import { Vector3 as Vector33 } from "three/src/math/Vector3.js";
|
|
297
|
+
import { Mesh } from "three/src/objects/Mesh.js";
|
|
298
|
+
var LOGO_FIT = 0.8;
|
|
299
|
+
var EPSILON = 1e-9;
|
|
300
|
+
function logoSurface(polygon, normal2, elevation) {
|
|
301
|
+
if (polygon.length < 3) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
const center = new Vector33();
|
|
305
|
+
for (const vertex of polygon) {
|
|
306
|
+
center.addScaledVector(vertex, 1 / polygon.length);
|
|
307
|
+
}
|
|
308
|
+
const u = new Vector33().subVectors(polygon[1], polygon[0]).addScaledVector(
|
|
309
|
+
normal2,
|
|
310
|
+
-new Vector33().subVectors(polygon[1], polygon[0]).dot(normal2)
|
|
311
|
+
);
|
|
312
|
+
if (u.lengthSq() < EPSILON) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
u.normalize();
|
|
316
|
+
const v = new Vector33().crossVectors(normal2, u).normalize();
|
|
317
|
+
let half = Number.POSITIVE_INFINITY;
|
|
318
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
319
|
+
const edge = new Vector33().subVectors(
|
|
320
|
+
polygon[(i + 1) % polygon.length],
|
|
321
|
+
polygon[i]
|
|
322
|
+
);
|
|
323
|
+
const outward = new Vector33().crossVectors(edge, normal2);
|
|
324
|
+
if (outward.lengthSq() < EPSILON) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
outward.normalize();
|
|
328
|
+
const distance = Math.abs(
|
|
329
|
+
new Vector33().subVectors(polygon[i], center).dot(outward)
|
|
330
|
+
);
|
|
331
|
+
const reach = Math.abs(outward.dot(u)) + Math.abs(outward.dot(v));
|
|
332
|
+
if (reach > EPSILON) {
|
|
333
|
+
half = Math.min(half, distance / reach);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (!Number.isFinite(half) || half <= 0) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
half *= LOGO_FIT;
|
|
340
|
+
return {
|
|
341
|
+
center: center.addScaledVector(normal2, elevation),
|
|
342
|
+
u: u.multiplyScalar(half),
|
|
343
|
+
v: v.multiplyScalar(half)
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function rectangleLogoSurface(center, u, v) {
|
|
347
|
+
const half = LOGO_FIT * Math.min(u.length(), v.length());
|
|
348
|
+
return {
|
|
349
|
+
center,
|
|
350
|
+
u: u.clone().setLength(half),
|
|
351
|
+
v: v.clone().setLength(half)
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function surfaceMatrix(surface, into) {
|
|
355
|
+
return into.makeBasis(
|
|
356
|
+
surface.u,
|
|
357
|
+
surface.v,
|
|
358
|
+
new Vector33().crossVectors(surface.u, surface.v).normalize()
|
|
359
|
+
).setPosition(surface.center);
|
|
360
|
+
}
|
|
361
|
+
var cachedLogoGeometry;
|
|
362
|
+
function logoGeometry() {
|
|
363
|
+
if (cachedLogoGeometry) {
|
|
364
|
+
return cachedLogoGeometry;
|
|
365
|
+
}
|
|
366
|
+
const geometry = new BufferGeometry2();
|
|
367
|
+
geometry.setAttribute(
|
|
368
|
+
"position",
|
|
369
|
+
new BufferAttribute2(
|
|
370
|
+
// biome-ignore format: one vertex per line is less readable than one triangle per line.
|
|
371
|
+
new Float32Array([
|
|
372
|
+
-1,
|
|
373
|
+
-1,
|
|
374
|
+
0,
|
|
375
|
+
1,
|
|
376
|
+
-1,
|
|
377
|
+
0,
|
|
378
|
+
1,
|
|
379
|
+
1,
|
|
380
|
+
0,
|
|
381
|
+
-1,
|
|
382
|
+
-1,
|
|
383
|
+
0,
|
|
384
|
+
1,
|
|
385
|
+
1,
|
|
386
|
+
0,
|
|
387
|
+
-1,
|
|
388
|
+
1,
|
|
389
|
+
0
|
|
390
|
+
]),
|
|
391
|
+
3
|
|
392
|
+
)
|
|
393
|
+
);
|
|
394
|
+
geometry.setAttribute(
|
|
395
|
+
"uv",
|
|
396
|
+
// biome-ignore format: see above.
|
|
397
|
+
new BufferAttribute2(new Float32Array([
|
|
398
|
+
0,
|
|
399
|
+
0,
|
|
400
|
+
1,
|
|
401
|
+
0,
|
|
402
|
+
1,
|
|
403
|
+
1,
|
|
404
|
+
0,
|
|
405
|
+
0,
|
|
406
|
+
1,
|
|
407
|
+
1,
|
|
408
|
+
0,
|
|
409
|
+
1
|
|
410
|
+
]), 2)
|
|
411
|
+
);
|
|
412
|
+
cachedLogoGeometry = geometry;
|
|
413
|
+
return geometry;
|
|
414
|
+
}
|
|
415
|
+
function newLogoMesh(texture) {
|
|
416
|
+
const mesh = new Mesh(
|
|
417
|
+
logoGeometry(),
|
|
418
|
+
new MeshBasicMaterial2({
|
|
419
|
+
map: texture,
|
|
420
|
+
side: FrontSide,
|
|
421
|
+
transparent: true,
|
|
422
|
+
// The logo floats just above the plastic, so it never has to compete with
|
|
423
|
+
// it for depth, and writing depth would let its transparent corners
|
|
424
|
+
// punch a hole in anything drawn after it.
|
|
425
|
+
depthWrite: false
|
|
426
|
+
})
|
|
427
|
+
);
|
|
428
|
+
mesh.matrixAutoUpdate = false;
|
|
429
|
+
mesh.renderOrder = 1;
|
|
430
|
+
return mesh;
|
|
431
|
+
}
|
|
432
|
+
var logoSpots = {
|
|
433
|
+
// Every piece of a 2×2×2 is a corner, so this is just "a piece of the white
|
|
434
|
+
// face".
|
|
435
|
+
"2x2x2": { face: "U", corner: true, toward: [1, 1, 1] },
|
|
436
|
+
// `Cube3D` draws the 3×3×3 by default and places its own logo; this is for
|
|
437
|
+
// `visualization="PG3D"`.
|
|
438
|
+
"3x3x3": { face: "U" },
|
|
439
|
+
"4x4x4": { face: "U", corner: true, toward: [1, 1, 1] },
|
|
440
|
+
"5x5x5": { face: "U", corner: true, toward: [1, 1, 1] },
|
|
441
|
+
"6x6x6": { face: "U", corner: true, toward: [1, 1, 1] },
|
|
442
|
+
"7x7x7": { face: "U", corner: true, toward: [1, 1, 1] },
|
|
443
|
+
megaminx: { face: "U" },
|
|
444
|
+
// A pyraminx has no center piece: the middle of a face is an edge's facelet.
|
|
445
|
+
pyraminx: { face: "D" },
|
|
446
|
+
skewb: { face: "U" }
|
|
447
|
+
// No logo on the FTO or the clock.
|
|
448
|
+
};
|
|
449
|
+
function centroid(coords) {
|
|
450
|
+
const center = new Vector33();
|
|
451
|
+
const vertices = coords.length / 3;
|
|
452
|
+
for (let i = 0; i < coords.length; i += 3) {
|
|
453
|
+
center.x += coords[i] / vertices;
|
|
454
|
+
center.y += coords[i + 1] / vertices;
|
|
455
|
+
center.z += coords[i + 2] / vertices;
|
|
456
|
+
}
|
|
457
|
+
return center;
|
|
458
|
+
}
|
|
459
|
+
function logoFaceletAddress(puzzleID, stickerDat) {
|
|
460
|
+
const spot = logoSpots[puzzleID];
|
|
461
|
+
if (!spot) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
const faceIdx = stickerDat.faces.findIndex((face2) => face2.name === spot.face);
|
|
465
|
+
if (faceIdx === -1) {
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
const faceCenter = centroid(stickerDat.faces[faceIdx].coords);
|
|
469
|
+
const faceletCounts = /* @__PURE__ */ new Map();
|
|
470
|
+
for (const sticker of stickerDat.stickers) {
|
|
471
|
+
if (sticker.isDup) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
const key = `${sticker.orbit}/${sticker.ord}`;
|
|
475
|
+
faceletCounts.set(key, (faceletCounts.get(key) ?? 0) + 1);
|
|
476
|
+
}
|
|
477
|
+
const toward = spot.toward ? new Vector33(...spot.toward) : null;
|
|
478
|
+
let best = null;
|
|
479
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
480
|
+
for (const sticker of stickerDat.stickers) {
|
|
481
|
+
if (sticker.isDup || sticker.face !== faceIdx) {
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (spot.corner && faceletCounts.get(`${sticker.orbit}/${sticker.ord}`) !== 3) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const center = centroid(sticker.coords);
|
|
488
|
+
const score = toward ? center.dot(toward) : -center.distanceTo(faceCenter);
|
|
489
|
+
if (score > bestScore) {
|
|
490
|
+
bestScore = score;
|
|
491
|
+
best = { orbit: sticker.orbit, ord: sticker.ord, ori: sticker.ori };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return best;
|
|
495
|
+
}
|
|
496
|
+
|
|
291
497
|
// src/cubing/twisty/views/3D/puzzles/Cube3D.ts
|
|
292
498
|
var svgLoader = new TextureLoader();
|
|
293
499
|
function newHintMaterial(style) {
|
|
294
|
-
return new
|
|
500
|
+
return new MeshBasicMaterial3({
|
|
295
501
|
color: new Color2(style.color).convertLinearToSRGB(),
|
|
296
502
|
side: BackSide,
|
|
297
503
|
transparent: true,
|
|
298
504
|
opacity: style.opacity
|
|
299
505
|
});
|
|
300
506
|
}
|
|
301
|
-
var ignoredMaterial = new
|
|
507
|
+
var ignoredMaterial = new MeshBasicMaterial3({
|
|
302
508
|
color: new Color2(bodyMaskColors.ignored).convertLinearToSRGB()
|
|
303
509
|
});
|
|
304
510
|
var ignoredMaterialHint = newHintMaterial(hintMaskStyles.ignored);
|
|
305
|
-
var invisibleMaterial = new
|
|
511
|
+
var invisibleMaterial = new MeshBasicMaterial3({
|
|
306
512
|
visible: false
|
|
307
513
|
});
|
|
308
|
-
var orientedMaterial = new
|
|
514
|
+
var orientedMaterial = new MeshBasicMaterial3({
|
|
309
515
|
color: bodyMaskColors.oriented
|
|
310
516
|
});
|
|
311
517
|
var orientedMaterialHint = newHintMaterial(hintMaskStyles.oriented);
|
|
312
|
-
var experimentalOriented2Material = new
|
|
518
|
+
var experimentalOriented2Material = new MeshBasicMaterial3({
|
|
313
519
|
color: bodyMaskColors.experimentalOriented2
|
|
314
520
|
});
|
|
315
521
|
var experimentalOriented2MaterialHint = newHintMaterial(
|
|
316
522
|
hintMaskStyles.experimentalOriented2
|
|
317
523
|
);
|
|
318
|
-
var mysteryMaterial = new
|
|
524
|
+
var mysteryMaterial = new MeshBasicMaterial3({
|
|
319
525
|
color: bodyMaskColors.mystery
|
|
320
526
|
});
|
|
321
527
|
var mysterMaterialHint = newHintMaterial(hintMaskStyles.mystery);
|
|
@@ -339,14 +545,14 @@ var AxisInfo = class {
|
|
|
339
545
|
const colorLinearSRGB = new Color2(color).convertLinearToSRGB();
|
|
340
546
|
const dimColorLinearSRGB = new Color2(dimColor).convertLinearToSRGB();
|
|
341
547
|
this.stickerMaterial = {
|
|
342
|
-
regular: new
|
|
548
|
+
regular: new MeshBasicMaterial3({
|
|
343
549
|
color: colorLinearSRGB,
|
|
344
|
-
side:
|
|
550
|
+
side: FrontSide2
|
|
345
551
|
// TODO: set to `DoubleSide` when hint facelets are disabled.
|
|
346
552
|
}),
|
|
347
|
-
dim: new
|
|
553
|
+
dim: new MeshBasicMaterial3({
|
|
348
554
|
color: dimColorLinearSRGB,
|
|
349
|
-
side:
|
|
555
|
+
side: FrontSide2
|
|
350
556
|
// TODO: set to `DoubleSide` when hint facelets are disabled.
|
|
351
557
|
}),
|
|
352
558
|
oriented: orientedMaterial,
|
|
@@ -437,6 +643,8 @@ var cubieDimensions = {
|
|
|
437
643
|
*/
|
|
438
644
|
bodyVertexCut: 0.45
|
|
439
645
|
};
|
|
646
|
+
var LOGO_PIECE = { orbit: "CENTERS", ord: 0, faceletIdx: 0 };
|
|
647
|
+
var LOGO_ELEVATION = 0.01;
|
|
440
648
|
var EXPERIMENTAL_PICTURE_CUBE_HINT_ELEVATION = 2;
|
|
441
649
|
var cube3DOptionsDefaults = {
|
|
442
650
|
showMainStickers: true,
|
|
@@ -457,12 +665,12 @@ function getFaceletScale(options) {
|
|
|
457
665
|
}
|
|
458
666
|
return options.faceletScale;
|
|
459
667
|
}
|
|
460
|
-
var blackMesh = new
|
|
668
|
+
var blackMesh = new MeshBasicMaterial3({
|
|
461
669
|
color: 0,
|
|
462
670
|
opacity: 1,
|
|
463
671
|
transparent: true
|
|
464
672
|
});
|
|
465
|
-
var blackTranslucentMesh = new
|
|
673
|
+
var blackTranslucentMesh = new MeshBasicMaterial3({
|
|
466
674
|
color: 0,
|
|
467
675
|
opacity: 0.3,
|
|
468
676
|
transparent: true
|
|
@@ -485,18 +693,18 @@ function t(v, t4) {
|
|
|
485
693
|
return new Quaternion().setFromAxisAngle(v, TAU * t4 / 4);
|
|
486
694
|
}
|
|
487
695
|
var r = {
|
|
488
|
-
O: new
|
|
489
|
-
U: new
|
|
490
|
-
L: new
|
|
491
|
-
F: new
|
|
492
|
-
R: new
|
|
493
|
-
B: new
|
|
494
|
-
D: new
|
|
696
|
+
O: new Vector34(0, 0, 0),
|
|
697
|
+
U: new Vector34(0, -1, 0),
|
|
698
|
+
L: new Vector34(1, 0, 0),
|
|
699
|
+
F: new Vector34(0, 0, -1),
|
|
700
|
+
R: new Vector34(-1, 0, 0),
|
|
701
|
+
B: new Vector34(0, 0, 1),
|
|
702
|
+
D: new Vector34(0, 1, 0)
|
|
495
703
|
};
|
|
496
704
|
var firstPiecePosition = {
|
|
497
|
-
EDGES: new
|
|
498
|
-
CORNERS: new
|
|
499
|
-
CENTERS: new
|
|
705
|
+
EDGES: new Vector34(0, 1, 1),
|
|
706
|
+
CORNERS: new Vector34(1, 1, 1),
|
|
707
|
+
CENTERS: new Vector34(0, 1, 0)
|
|
500
708
|
};
|
|
501
709
|
var orientationRotation = {
|
|
502
710
|
EDGES: [0, 1].map(
|
|
@@ -668,11 +876,11 @@ function sharedCubieFoundationGeometry() {
|
|
|
668
876
|
));
|
|
669
877
|
}
|
|
670
878
|
function newStickerGeometry() {
|
|
671
|
-
const r2 = new
|
|
879
|
+
const r2 = new BufferGeometry3();
|
|
672
880
|
const half = 0.5;
|
|
673
881
|
r2.setAttribute(
|
|
674
882
|
"position",
|
|
675
|
-
new
|
|
883
|
+
new BufferAttribute3(
|
|
676
884
|
new Float32Array([
|
|
677
885
|
half,
|
|
678
886
|
half,
|
|
@@ -698,7 +906,7 @@ function newStickerGeometry() {
|
|
|
698
906
|
);
|
|
699
907
|
r2.setAttribute(
|
|
700
908
|
"uv",
|
|
701
|
-
new
|
|
909
|
+
new BufferAttribute3(
|
|
702
910
|
new Float32Array([
|
|
703
911
|
1,
|
|
704
912
|
1,
|
|
@@ -977,7 +1185,9 @@ var Cube3D = class extends Object3D {
|
|
|
977
1185
|
this.setHintFaceletsElevation(hintFaceletsElevation);
|
|
978
1186
|
}
|
|
979
1187
|
}
|
|
1188
|
+
#lastPosition = null;
|
|
980
1189
|
onPositionChange(p) {
|
|
1190
|
+
this.#lastPosition = p;
|
|
981
1191
|
const reid333 = p.pattern;
|
|
982
1192
|
for (const orbit in pieceDefs) {
|
|
983
1193
|
const pieces = pieceDefs[orbit];
|
|
@@ -1007,6 +1217,7 @@ var Cube3D = class extends Object3D {
|
|
|
1007
1217
|
}
|
|
1008
1218
|
}
|
|
1009
1219
|
}
|
|
1220
|
+
this.#placeLogo(p);
|
|
1010
1221
|
this.scheduleRenderCallback();
|
|
1011
1222
|
}
|
|
1012
1223
|
// TODO: Always create (but sometimes hide parts) so we can show them later,
|
|
@@ -1015,7 +1226,7 @@ var Cube3D = class extends Object3D {
|
|
|
1015
1226
|
const cubieFaceletInfo = [];
|
|
1016
1227
|
orbitFacelets.push(cubieFaceletInfo);
|
|
1017
1228
|
const cubie = new Group();
|
|
1018
|
-
const body = this.#stickerless() ? new
|
|
1229
|
+
const body = this.#stickerless() ? new Mesh2(
|
|
1019
1230
|
cubieBodyGeometry(
|
|
1020
1231
|
orbit,
|
|
1021
1232
|
cubieStickerOrder.slice(0, piece.stickerFaces.length)
|
|
@@ -1064,7 +1275,7 @@ var Cube3D = class extends Object3D {
|
|
|
1064
1275
|
axesInfo[piece.stickerFaces[i]],
|
|
1065
1276
|
hint
|
|
1066
1277
|
);
|
|
1067
|
-
mesh.material = new
|
|
1278
|
+
mesh.material = new MeshBasicMaterial3({
|
|
1068
1279
|
map: texture,
|
|
1069
1280
|
side: hint ? BackSide : DoubleSide,
|
|
1070
1281
|
transparent: true
|
|
@@ -1093,7 +1304,7 @@ var Cube3D = class extends Object3D {
|
|
|
1093
1304
|
}
|
|
1094
1305
|
mesh.geometry.setAttribute(
|
|
1095
1306
|
"uv",
|
|
1096
|
-
new
|
|
1307
|
+
new BufferAttribute3(
|
|
1097
1308
|
new Float32Array([
|
|
1098
1309
|
v3.x,
|
|
1099
1310
|
v3.y,
|
|
@@ -1127,14 +1338,14 @@ var Cube3D = class extends Object3D {
|
|
|
1127
1338
|
// TODO: Support creating only the outward-facing parts?
|
|
1128
1339
|
createCubieFoundation() {
|
|
1129
1340
|
const box = sharedCubieFoundationGeometry();
|
|
1130
|
-
return new
|
|
1341
|
+
return new Mesh2(
|
|
1131
1342
|
box,
|
|
1132
1343
|
this.options.experimentalStickeringMask?.specialBehaviour === "picture" ? blackMesh : blackTranslucentMesh
|
|
1133
1344
|
);
|
|
1134
1345
|
}
|
|
1135
1346
|
createSticker(posAxisInfo, materialAxisInfo, isHint) {
|
|
1136
1347
|
const geo = this.options.experimentalStickeringMask?.specialBehaviour === "picture" ? newStickerGeometry() : isHint ? this.#sharedHintStickerGeometry() : sharedStickerGeometry();
|
|
1137
|
-
const stickerMesh = new
|
|
1348
|
+
const stickerMesh = new Mesh2(
|
|
1138
1349
|
geo,
|
|
1139
1350
|
isHint ? materialAxisInfo.hintStickerMaterial.regular : materialAxisInfo.stickerMaterial.regular
|
|
1140
1351
|
);
|
|
@@ -1161,6 +1372,82 @@ var Cube3D = class extends Object3D {
|
|
|
1161
1372
|
stickerMesh.translateZ(elevation - 1);
|
|
1162
1373
|
return stickerMesh;
|
|
1163
1374
|
}
|
|
1375
|
+
#logoMesh = null;
|
|
1376
|
+
/** The logo's placement on its facelet, in the piece's own frame. */
|
|
1377
|
+
#logoSurface = null;
|
|
1378
|
+
#logoPieceMatrix = new Matrix4();
|
|
1379
|
+
/**
|
|
1380
|
+
* Prints a logo on the white center, or takes it off again when passed
|
|
1381
|
+
* `null`.
|
|
1382
|
+
*
|
|
1383
|
+
* The image is stretched onto a square sized to the piece, so its own
|
|
1384
|
+
* proportions don't matter. It rides the piece, so a rotation of the whole
|
|
1385
|
+
* cube carries it to whichever face the white center ends up on.
|
|
1386
|
+
*/
|
|
1387
|
+
experimentalSetLogo(texture) {
|
|
1388
|
+
if (this.#logoMesh) {
|
|
1389
|
+
this.#logoMesh.removeFromParent();
|
|
1390
|
+
this.#logoMesh.material.dispose();
|
|
1391
|
+
this.#logoMesh = null;
|
|
1392
|
+
this.#logoSurface = null;
|
|
1393
|
+
}
|
|
1394
|
+
if (texture) {
|
|
1395
|
+
const normal2 = axesInfo[cubieStickerOrder[LOGO_PIECE.faceletIdx]].vector;
|
|
1396
|
+
const u = new Vector34(normal2.y, normal2.z, normal2.x);
|
|
1397
|
+
const v = new Vector34().crossVectors(normal2, u);
|
|
1398
|
+
const surface = rectangleLogoSurface(
|
|
1399
|
+
normal2.clone().multiplyScalar(this.#faceletDistance() + LOGO_ELEVATION),
|
|
1400
|
+
// Half-axes of the facelet, which is one cubie wide.
|
|
1401
|
+
u.multiplyScalar(0.5),
|
|
1402
|
+
v.multiplyScalar(0.5)
|
|
1403
|
+
);
|
|
1404
|
+
this.#logoMesh = newLogoMesh(texture);
|
|
1405
|
+
this.#logoSurface = surfaceMatrix(surface, new Matrix4());
|
|
1406
|
+
this.add(this.#logoMesh);
|
|
1407
|
+
if (this.#lastPosition) {
|
|
1408
|
+
this.#placeLogo(this.#lastPosition);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
this.scheduleRenderCallback?.();
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Puts the logo where its piece is.
|
|
1415
|
+
*
|
|
1416
|
+
* Almost all of this is the piece's own matrix, but not quite: the 3×3×3's
|
|
1417
|
+
* `KPuzzle` does not track how a center is turned (`orientationMod` is 1),
|
|
1418
|
+
* so a `U` ends in the state it started in as far as the white center is
|
|
1419
|
+
* concerned. Riding that animation would spin the logo through the turn and
|
|
1420
|
+
* snap it back at the end, so a move that leaves the piece in its own slot
|
|
1421
|
+
* leaves the logo alone. A move that carries the piece elsewhere — a cube
|
|
1422
|
+
* rotation — still takes the logo with it.
|
|
1423
|
+
*/
|
|
1424
|
+
#placeLogo(p) {
|
|
1425
|
+
const mesh = this.#logoMesh;
|
|
1426
|
+
if (!mesh || !this.#logoSurface) {
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1429
|
+
const { orbit, ord } = LOGO_PIECE;
|
|
1430
|
+
const orbitPattern = p.pattern.patternData[orbit];
|
|
1431
|
+
const slot = orbitPattern.pieces.indexOf(ord);
|
|
1432
|
+
if (slot === -1) {
|
|
1433
|
+
mesh.visible = false;
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
mesh.visible = true;
|
|
1437
|
+
const untracked = orbitPattern.orientationMod?.[slot] === 1;
|
|
1438
|
+
const staysPut = untracked && p.movesInProgress.every(
|
|
1439
|
+
(moveProgress) => this.kpuzzle.moveToTransformation(
|
|
1440
|
+
moveProgress.move.modified({ amount: 1 })
|
|
1441
|
+
).transformationData[orbit].permutation[slot] === slot
|
|
1442
|
+
);
|
|
1443
|
+
const pieceMatrix = staysPut ? this.#logoPieceMatrix.copy(pieceDefs[orbit][slot].matrix).multiply(orientationRotation[orbit][orbitPattern.orientation[slot]]) : this.pieces[orbit][ord].matrix;
|
|
1444
|
+
mesh.matrix.multiplyMatrices(pieceMatrix, this.#logoSurface);
|
|
1445
|
+
mesh.matrixWorldNeedsUpdate = true;
|
|
1446
|
+
}
|
|
1447
|
+
/** How far a facelet's surface sits from the center of its cubie. */
|
|
1448
|
+
#faceletDistance() {
|
|
1449
|
+
return this.#stickerless() ? cubieBodyDimensions.halfWidth * cubieBodyDimensions.pieceScale : cubieDimensions.stickerElevation;
|
|
1450
|
+
}
|
|
1164
1451
|
/** @deprecated */
|
|
1165
1452
|
experimentalSetFoundationOpacity(opacity) {
|
|
1166
1453
|
if (this.experimentalFoundationMeshes.length === 0) {
|
|
@@ -1205,10 +1492,10 @@ var Cube3D = class extends Object3D {
|
|
|
1205
1492
|
};
|
|
1206
1493
|
|
|
1207
1494
|
// src/cubing/twisty/views/3D/puzzles/CubePieces.ts
|
|
1208
|
-
import { BufferAttribute as
|
|
1209
|
-
import { BufferGeometry as
|
|
1495
|
+
import { BufferAttribute as BufferAttribute4 } from "three/src/core/BufferAttribute.js";
|
|
1496
|
+
import { BufferGeometry as BufferGeometry4 } from "three/src/core/BufferGeometry.js";
|
|
1210
1497
|
import { Matrix4 as Matrix42 } from "three/src/math/Matrix4.js";
|
|
1211
|
-
import { Vector3 as
|
|
1498
|
+
import { Vector3 as Vector35 } from "three/src/math/Vector3.js";
|
|
1212
1499
|
|
|
1213
1500
|
// src/cubing/twisty/views/3D/puzzles/StickerlessPlan.ts
|
|
1214
1501
|
var HINT_FACELET_ELEVATION = 0.5;
|
|
@@ -1308,6 +1595,7 @@ function paintInternal(colors, ranges) {
|
|
|
1308
1595
|
// src/cubing/twisty/views/3D/puzzles/CubePieces.ts
|
|
1309
1596
|
var PG_SCALE = 0.5;
|
|
1310
1597
|
var FACE_COUNT = 6;
|
|
1598
|
+
var LOGO_ELEVATION2 = 0.01;
|
|
1311
1599
|
function faceIdxForNormal(x, y, z) {
|
|
1312
1600
|
for (let faceIdx = 0; faceIdx < FACE_COUNT; faceIdx++) {
|
|
1313
1601
|
const { vector } = cubeFaceStyles[faceIdx];
|
|
@@ -1344,20 +1632,20 @@ function cubeLayout(stickerDat) {
|
|
|
1344
1632
|
const faceColors = new Array(FACE_COUNT);
|
|
1345
1633
|
const cubiesByPiece = /* @__PURE__ */ new Map();
|
|
1346
1634
|
const cubies = [];
|
|
1347
|
-
const
|
|
1635
|
+
const centroid2 = [0, 0, 0];
|
|
1348
1636
|
for (const sticker of stickers) {
|
|
1349
1637
|
const { coords } = sticker;
|
|
1350
1638
|
for (let axis = 0; axis < 3; axis++) {
|
|
1351
|
-
|
|
1639
|
+
centroid2[axis] = (coords[axis] + coords[axis + 3] + coords[axis + 6] + coords[axis + 9]) / 4;
|
|
1352
1640
|
}
|
|
1353
1641
|
let normalAxis = 0;
|
|
1354
1642
|
for (let axis = 1; axis < 3; axis++) {
|
|
1355
|
-
if (Math.abs(
|
|
1643
|
+
if (Math.abs(centroid2[axis]) > Math.abs(centroid2[normalAxis])) {
|
|
1356
1644
|
normalAxis = axis;
|
|
1357
1645
|
}
|
|
1358
1646
|
}
|
|
1359
|
-
const outward = Math.sign(
|
|
1360
|
-
const center = new
|
|
1647
|
+
const outward = Math.sign(centroid2[normalAxis]);
|
|
1648
|
+
const center = new Vector35();
|
|
1361
1649
|
for (let axis = 0; axis < 3; axis++) {
|
|
1362
1650
|
let expected;
|
|
1363
1651
|
if (axis === normalAxis) {
|
|
@@ -1365,7 +1653,7 @@ function cubeLayout(stickerDat) {
|
|
|
1365
1653
|
center.setComponent(axis, outward * (halfExtent - slotWidth / 2));
|
|
1366
1654
|
} else {
|
|
1367
1655
|
const slot = Math.round(
|
|
1368
|
-
(
|
|
1656
|
+
(centroid2[axis] + halfExtent) / slotWidth - 0.5
|
|
1369
1657
|
);
|
|
1370
1658
|
if (slot < 0 || slot >= layers) {
|
|
1371
1659
|
return null;
|
|
@@ -1373,7 +1661,7 @@ function cubeLayout(stickerDat) {
|
|
|
1373
1661
|
expected = -halfExtent + (slot + 0.5) * slotWidth;
|
|
1374
1662
|
center.setComponent(axis, expected);
|
|
1375
1663
|
}
|
|
1376
|
-
if (Math.abs(
|
|
1664
|
+
if (Math.abs(centroid2[axis] - expected) > epsilon) {
|
|
1377
1665
|
return null;
|
|
1378
1666
|
}
|
|
1379
1667
|
const halfSpan = axis === normalAxis ? 0 : slotWidth / 2;
|
|
@@ -1451,13 +1739,23 @@ function newCubieShape(outwardFaces, slotWidth) {
|
|
|
1451
1739
|
const hintVertexRanges = /* @__PURE__ */ new Map();
|
|
1452
1740
|
const hintHalfWidth = HINT_FACELET_SCALE * slotWidth / 2;
|
|
1453
1741
|
const hintDistance = slotWidth / 2 + HINT_FACELET_ELEVATION;
|
|
1454
|
-
const
|
|
1455
|
-
const
|
|
1456
|
-
const
|
|
1742
|
+
const logoSurfaces = /* @__PURE__ */ new Map();
|
|
1743
|
+
const faceDistance = cubieBodyDimensions.halfWidth * cubieBodyDimensions.pieceScale * slotWidth;
|
|
1744
|
+
const u = new Vector35();
|
|
1745
|
+
const v = new Vector35();
|
|
1746
|
+
const corner = new Vector35();
|
|
1457
1747
|
for (const faceIdx of outwardFaces) {
|
|
1458
1748
|
const normal2 = cubeFaceStyles[faceIdx].vector;
|
|
1459
1749
|
u.set(normal2.y, normal2.z, normal2.x);
|
|
1460
1750
|
v.crossVectors(normal2, u);
|
|
1751
|
+
logoSurfaces.set(
|
|
1752
|
+
faceIdx,
|
|
1753
|
+
rectangleLogoSurface(
|
|
1754
|
+
normal2.clone().multiplyScalar(faceDistance + LOGO_ELEVATION2 * slotWidth),
|
|
1755
|
+
u.clone().multiplyScalar(slotWidth / 2),
|
|
1756
|
+
v.clone().multiplyScalar(slotWidth / 2)
|
|
1757
|
+
)
|
|
1758
|
+
);
|
|
1461
1759
|
const start = hintPositions.length / 3;
|
|
1462
1760
|
for (const [su, sv] of [
|
|
1463
1761
|
[-1, -1],
|
|
@@ -1473,21 +1771,22 @@ function newCubieShape(outwardFaces, slotWidth) {
|
|
|
1473
1771
|
}
|
|
1474
1772
|
body.dispose();
|
|
1475
1773
|
return {
|
|
1476
|
-
bodyPosition: new
|
|
1477
|
-
bodyIndex: new
|
|
1774
|
+
bodyPosition: new BufferAttribute4(bodyPositions.slice(), 3),
|
|
1775
|
+
bodyIndex: new BufferAttribute4(new Uint16Array(bodyIndices), 1),
|
|
1478
1776
|
bodyVertexCount: bodyPositions.length / 3,
|
|
1479
|
-
hintPosition: new
|
|
1480
|
-
hintIndex: new
|
|
1777
|
+
hintPosition: new BufferAttribute4(new Float32Array(hintPositions), 3),
|
|
1778
|
+
hintIndex: new BufferAttribute4(new Uint16Array(hintIndices), 1),
|
|
1481
1779
|
hintVertexCount: hintPositions.length / 3,
|
|
1482
1780
|
faceVertexRanges,
|
|
1483
|
-
hintVertexRanges
|
|
1781
|
+
hintVertexRanges,
|
|
1782
|
+
logoSurfaces
|
|
1484
1783
|
};
|
|
1485
1784
|
}
|
|
1486
1785
|
function newPieceMesh(position, index, vertexCount) {
|
|
1487
|
-
const geometry = new
|
|
1786
|
+
const geometry = new BufferGeometry4();
|
|
1488
1787
|
geometry.setAttribute("position", position);
|
|
1489
1788
|
geometry.setIndex(index);
|
|
1490
|
-
const colors = new
|
|
1789
|
+
const colors = new BufferAttribute4(new Uint8Array(4 * vertexCount), 4, true);
|
|
1491
1790
|
geometry.setAttribute("color", colors);
|
|
1492
1791
|
return { geometry, colors };
|
|
1493
1792
|
}
|
|
@@ -1505,7 +1804,10 @@ function newCubiePiece(cubie, shape) {
|
|
|
1505
1804
|
// A duplicate shares its square with the real facelet, which is the one
|
|
1506
1805
|
// that gets painted.
|
|
1507
1806
|
body: sticker.isDup ? [] : [shape.faceVertexRanges[sticker.faceIdx]],
|
|
1508
|
-
hint: sticker.isDup ? [] : [shape.hintVertexRanges.get(sticker.faceIdx)].filter(Boolean)
|
|
1807
|
+
hint: sticker.isDup ? [] : [shape.hintVertexRanges.get(sticker.faceIdx)].filter(Boolean),
|
|
1808
|
+
// Set for a duplicate too: it is the same square, seen through another of
|
|
1809
|
+
// the piece's facelets.
|
|
1810
|
+
logo: shape.logoSurfaces.get(sticker.faceIdx) ?? null
|
|
1509
1811
|
}));
|
|
1510
1812
|
return {
|
|
1511
1813
|
orbit: cubie.orbit,
|
|
@@ -1542,23 +1844,23 @@ function cubePuzzlePlan(stickerDat) {
|
|
|
1542
1844
|
}
|
|
1543
1845
|
|
|
1544
1846
|
// src/cubing/twisty/views/3D/puzzles/PG3D.ts
|
|
1545
|
-
import { DoubleSide as DoubleSide2, FrontSide as
|
|
1546
|
-
import { BufferAttribute as
|
|
1547
|
-
import { BufferGeometry as
|
|
1847
|
+
import { DoubleSide as DoubleSide2, FrontSide as FrontSide3 } from "three/src/constants.js";
|
|
1848
|
+
import { BufferAttribute as BufferAttribute5 } from "three/src/core/BufferAttribute.js";
|
|
1849
|
+
import { BufferGeometry as BufferGeometry5 } from "three/src/core/BufferGeometry.js";
|
|
1548
1850
|
import { Object3D as Object3D2 } from "three/src/core/Object3D.js";
|
|
1549
|
-
import { MeshBasicMaterial as
|
|
1851
|
+
import { MeshBasicMaterial as MeshBasicMaterial4 } from "three/src/materials/MeshBasicMaterial.js";
|
|
1550
1852
|
import { Color as Color3 } from "three/src/math/Color.js";
|
|
1551
|
-
import { Vector3 as
|
|
1853
|
+
import { Vector3 as Vector36 } from "three/src/math/Vector3.js";
|
|
1552
1854
|
import { Group as Group2 } from "three/src/objects/Group.js";
|
|
1553
|
-
import { Mesh as
|
|
1554
|
-
var foundationMaterial = new
|
|
1855
|
+
import { Mesh as Mesh3 } from "three/src/objects/Mesh.js";
|
|
1856
|
+
var foundationMaterial = new MeshBasicMaterial4({
|
|
1555
1857
|
side: DoubleSide2,
|
|
1556
1858
|
color: 0
|
|
1557
1859
|
});
|
|
1558
|
-
var invisMaterial = new
|
|
1860
|
+
var invisMaterial = new MeshBasicMaterial4({
|
|
1559
1861
|
visible: false
|
|
1560
1862
|
});
|
|
1561
|
-
var basicStickerMaterial = new
|
|
1863
|
+
var basicStickerMaterial = new MeshBasicMaterial4({
|
|
1562
1864
|
vertexColors: true
|
|
1563
1865
|
});
|
|
1564
1866
|
function dist(coords, a, b) {
|
|
@@ -1693,9 +1995,9 @@ var Filler = class {
|
|
|
1693
1995
|
}
|
|
1694
1996
|
}
|
|
1695
1997
|
setAttributes(geo) {
|
|
1696
|
-
geo.setAttribute("position", new
|
|
1998
|
+
geo.setAttribute("position", new BufferAttribute5(this.vertices, 3));
|
|
1697
1999
|
const sa2 = this.colors.subarray(0, 9 * this.sz);
|
|
1698
|
-
geo.setAttribute("color", new
|
|
2000
|
+
geo.setAttribute("color", new BufferAttribute5(sa2, 3, true));
|
|
1699
2001
|
}
|
|
1700
2002
|
makeGroups(geo) {
|
|
1701
2003
|
geo.clearGroups();
|
|
@@ -1921,9 +2223,9 @@ var HitPlaneDef = class {
|
|
|
1921
2223
|
filler.addUncolored(coords, g);
|
|
1922
2224
|
filler.addUncolored(coords, g + 1);
|
|
1923
2225
|
}
|
|
1924
|
-
this.geo = new
|
|
2226
|
+
this.geo = new BufferGeometry5();
|
|
1925
2227
|
filler.setAttributes(this.geo);
|
|
1926
|
-
const obj = new
|
|
2228
|
+
const obj = new Mesh3(this.geo, invisMaterial);
|
|
1927
2229
|
obj.userData["quantumMove"] = stickerDat.notationMapper.notationToExternal(
|
|
1928
2230
|
new Move(hitface.name)
|
|
1929
2231
|
);
|
|
@@ -1936,7 +2238,7 @@ var AxisInfo2 = class {
|
|
|
1936
2238
|
order;
|
|
1937
2239
|
constructor(axisDat) {
|
|
1938
2240
|
const vec = axisDat.coordinates;
|
|
1939
|
-
this.axis = new
|
|
2241
|
+
this.axis = new Vector36(vec[0], vec[1], vec[2]);
|
|
1940
2242
|
this.order = axisDat.order;
|
|
1941
2243
|
}
|
|
1942
2244
|
};
|
|
@@ -1953,7 +2255,7 @@ var PG3D = class extends Object3D2 {
|
|
|
1953
2255
|
if (stickerDat.stickers.length === 0) {
|
|
1954
2256
|
throw Error("Reuse of stickerdat from pg; please don't do that.");
|
|
1955
2257
|
}
|
|
1956
|
-
this.hintMaterial = new
|
|
2258
|
+
this.hintMaterial = new MeshBasicMaterial4({
|
|
1957
2259
|
vertexColors: true,
|
|
1958
2260
|
transparent: true,
|
|
1959
2261
|
opacity: 0.5
|
|
@@ -2041,13 +2343,13 @@ var PG3D = class extends Object3D2 {
|
|
|
2041
2343
|
this.stickers[orbit][ori][ord].addFoundation(filler, sticker, black);
|
|
2042
2344
|
}
|
|
2043
2345
|
}
|
|
2044
|
-
const fixedGeo = new
|
|
2346
|
+
const fixedGeo = new BufferGeometry5();
|
|
2045
2347
|
filler.setAttributes(fixedGeo);
|
|
2046
2348
|
filler.makeGroups(fixedGeo);
|
|
2047
|
-
const obj = new
|
|
2349
|
+
const obj = new Mesh3(fixedGeo, this.materialArray1);
|
|
2048
2350
|
obj.scale.set(PG_SCALE2, PG_SCALE2, PG_SCALE2);
|
|
2049
2351
|
this.add(obj);
|
|
2050
|
-
const obj2 = new
|
|
2352
|
+
const obj2 = new Mesh3(fixedGeo, this.materialArray2);
|
|
2051
2353
|
obj2.scale.set(PG_SCALE2, PG_SCALE2, PG_SCALE2);
|
|
2052
2354
|
this.add(obj2);
|
|
2053
2355
|
const hitfaces = this.stickerDat.faces;
|
|
@@ -2138,7 +2440,7 @@ var PG3D = class extends Object3D2 {
|
|
|
2138
2440
|
}
|
|
2139
2441
|
}
|
|
2140
2442
|
for (const axis of this.stickerDat.axis) {
|
|
2141
|
-
const product = point.dot(new
|
|
2443
|
+
const product = point.dot(new Vector36(...axis.coordinates));
|
|
2142
2444
|
if (product > closestMoveDotProduct) {
|
|
2143
2445
|
const modified = this.stickerDat.notationMapper.notationToExternal(
|
|
2144
2446
|
modify(axis.quantumMove)
|
|
@@ -2372,7 +2674,7 @@ var PG3D = class extends Object3D2 {
|
|
|
2372
2674
|
} else if (v === 1) {
|
|
2373
2675
|
this.hintMaterial = this.stickerMaterial;
|
|
2374
2676
|
} else {
|
|
2375
|
-
this.hintMaterial = new
|
|
2677
|
+
this.hintMaterial = new MeshBasicMaterial4({
|
|
2376
2678
|
vertexColors: true,
|
|
2377
2679
|
transparent: true,
|
|
2378
2680
|
opacity: v
|
|
@@ -2420,7 +2722,7 @@ var PG3D = class extends Object3D2 {
|
|
|
2420
2722
|
}
|
|
2421
2723
|
filler.uvs.copyWithin(6 * filler.sz, 0, 6 * filler.sz);
|
|
2422
2724
|
const sa1 = filler.uvs.subarray(0, 6 * filler.sz);
|
|
2423
|
-
this.fixedGeo.setAttribute("uv", new
|
|
2725
|
+
this.fixedGeo.setAttribute("uv", new BufferAttribute5(sa1, 2, true));
|
|
2424
2726
|
}
|
|
2425
2727
|
experimentalUpdateTexture(enabled, stickerTexture, hintTexture) {
|
|
2426
2728
|
if (!stickerTexture) {
|
|
@@ -2435,9 +2737,9 @@ var PG3D = class extends Object3D2 {
|
|
|
2435
2737
|
this.stickerMaterialDisposable = false;
|
|
2436
2738
|
}
|
|
2437
2739
|
if (enabled) {
|
|
2438
|
-
this.stickerMaterial = new
|
|
2740
|
+
this.stickerMaterial = new MeshBasicMaterial4({
|
|
2439
2741
|
map: stickerTexture,
|
|
2440
|
-
side:
|
|
2742
|
+
side: FrontSide3,
|
|
2441
2743
|
transparent: false
|
|
2442
2744
|
});
|
|
2443
2745
|
this.stickerMaterialDisposable = true;
|
|
@@ -2449,9 +2751,9 @@ var PG3D = class extends Object3D2 {
|
|
|
2449
2751
|
this.hintMaterialDisposable = false;
|
|
2450
2752
|
}
|
|
2451
2753
|
if (enabled) {
|
|
2452
|
-
this.hintMaterial = new
|
|
2754
|
+
this.hintMaterial = new MeshBasicMaterial4({
|
|
2453
2755
|
map: hintTexture,
|
|
2454
|
-
side:
|
|
2756
|
+
side: FrontSide3,
|
|
2455
2757
|
transparent: true
|
|
2456
2758
|
});
|
|
2457
2759
|
this.hintMaterialDisposable = true;
|
|
@@ -2471,21 +2773,21 @@ var PG3D = class extends Object3D2 {
|
|
|
2471
2773
|
};
|
|
2472
2774
|
|
|
2473
2775
|
// src/cubing/twisty/views/3D/puzzles/SolidPieces.ts
|
|
2474
|
-
import { BufferAttribute as
|
|
2475
|
-
import { BufferGeometry as
|
|
2776
|
+
import { BufferAttribute as BufferAttribute6 } from "three/src/core/BufferAttribute.js";
|
|
2777
|
+
import { BufferGeometry as BufferGeometry6 } from "three/src/core/BufferGeometry.js";
|
|
2476
2778
|
import { Color as Color4 } from "three/src/math/Color.js";
|
|
2477
2779
|
import { Matrix4 as Matrix43 } from "three/src/math/Matrix4.js";
|
|
2478
|
-
import { Vector3 as
|
|
2780
|
+
import { Vector3 as Vector38 } from "three/src/math/Vector3.js";
|
|
2479
2781
|
|
|
2480
2782
|
// src/cubing/twisty/views/3D/puzzles/SolidPieceGeometry.ts
|
|
2481
|
-
import { Vector3 as
|
|
2783
|
+
import { Vector3 as Vector37 } from "three/src/math/Vector3.js";
|
|
2482
2784
|
var SOLID_PIECE_GROOVE = 0.018;
|
|
2483
2785
|
var SOLID_PIECE_CHAMFER = 5e-3;
|
|
2484
2786
|
var BOX_PLANE = -1;
|
|
2485
2787
|
function boxFacet(planeIdx, normal2, size) {
|
|
2486
|
-
const reference = Math.abs(normal2.y) > 0.5 ? new
|
|
2487
|
-
const u = new
|
|
2488
|
-
const v = new
|
|
2788
|
+
const reference = Math.abs(normal2.y) > 0.5 ? new Vector37(0, 0, 1) : new Vector37(0, 1, 0);
|
|
2789
|
+
const u = new Vector37().crossVectors(reference, normal2).normalize();
|
|
2790
|
+
const v = new Vector37().crossVectors(normal2, u);
|
|
2489
2791
|
const center = normal2.clone().multiplyScalar(size);
|
|
2490
2792
|
return {
|
|
2491
2793
|
plane: planeIdx,
|
|
@@ -2500,23 +2802,23 @@ function boxFacet(planeIdx, normal2, size) {
|
|
|
2500
2802
|
};
|
|
2501
2803
|
}
|
|
2502
2804
|
var BOX_NORMALS = [
|
|
2503
|
-
new
|
|
2504
|
-
new
|
|
2505
|
-
new
|
|
2506
|
-
new
|
|
2507
|
-
new
|
|
2508
|
-
new
|
|
2805
|
+
new Vector37(1, 0, 0),
|
|
2806
|
+
new Vector37(-1, 0, 0),
|
|
2807
|
+
new Vector37(0, 1, 0),
|
|
2808
|
+
new Vector37(0, -1, 0),
|
|
2809
|
+
new Vector37(0, 0, 1),
|
|
2810
|
+
new Vector37(0, 0, -1)
|
|
2509
2811
|
];
|
|
2510
2812
|
function orderInPlane(points, normal2) {
|
|
2511
|
-
const
|
|
2813
|
+
const centroid2 = new Vector37();
|
|
2512
2814
|
for (const point of points) {
|
|
2513
|
-
|
|
2815
|
+
centroid2.addScaledVector(point, 1 / points.length);
|
|
2514
2816
|
}
|
|
2515
|
-
const reference = new
|
|
2516
|
-
const other = new
|
|
2517
|
-
const offset = new
|
|
2817
|
+
const reference = new Vector37().subVectors(points[0], centroid2).normalize();
|
|
2818
|
+
const other = new Vector37().crossVectors(normal2, reference);
|
|
2819
|
+
const offset = new Vector37();
|
|
2518
2820
|
return points.map((point) => {
|
|
2519
|
-
offset.subVectors(point,
|
|
2821
|
+
offset.subVectors(point, centroid2);
|
|
2520
2822
|
return {
|
|
2521
2823
|
point,
|
|
2522
2824
|
angle: Math.atan2(offset.dot(other), offset.dot(reference))
|
|
@@ -2618,7 +2920,7 @@ function chamferPlanes(facets, planes, chamfer, epsilon) {
|
|
|
2618
2920
|
continue;
|
|
2619
2921
|
}
|
|
2620
2922
|
seen.add(pairKey);
|
|
2621
|
-
const sum = new
|
|
2923
|
+
const sum = new Vector37().addVectors(
|
|
2622
2924
|
planes[colored].normal,
|
|
2623
2925
|
planes[internal].normal
|
|
2624
2926
|
);
|
|
@@ -2681,9 +2983,10 @@ function solidPieceGeometry(planes, options) {
|
|
|
2681
2983
|
|
|
2682
2984
|
// src/cubing/twisty/views/3D/puzzles/SolidPieces.ts
|
|
2683
2985
|
var PG_SCALE3 = 0.5;
|
|
2684
|
-
var
|
|
2986
|
+
var EPSILON2 = 1e-6;
|
|
2987
|
+
var LOGO_ELEVATION3 = 0.01;
|
|
2685
2988
|
function vertexAt(sticker, index) {
|
|
2686
|
-
return new
|
|
2989
|
+
return new Vector38(
|
|
2687
2990
|
sticker.coords[3 * index],
|
|
2688
2991
|
sticker.coords[3 * index + 1],
|
|
2689
2992
|
sticker.coords[3 * index + 2]
|
|
@@ -2697,11 +3000,11 @@ function polygonOf(sticker) {
|
|
|
2697
3000
|
return vertices;
|
|
2698
3001
|
}
|
|
2699
3002
|
function outwardNormal(polygon) {
|
|
2700
|
-
const normal2 = new
|
|
2701
|
-
new
|
|
2702
|
-
new
|
|
3003
|
+
const normal2 = new Vector38().crossVectors(
|
|
3004
|
+
new Vector38().subVectors(polygon[1], polygon[0]),
|
|
3005
|
+
new Vector38().subVectors(polygon[2], polygon[0])
|
|
2703
3006
|
);
|
|
2704
|
-
if (normal2.length() <
|
|
3007
|
+
if (normal2.length() < EPSILON2) {
|
|
2705
3008
|
return null;
|
|
2706
3009
|
}
|
|
2707
3010
|
normal2.normalize();
|
|
@@ -2742,13 +3045,13 @@ function faceStyles(faceNormals, faceColors) {
|
|
|
2742
3045
|
return styles;
|
|
2743
3046
|
}
|
|
2744
3047
|
function hintPolygon(polygon, normal2) {
|
|
2745
|
-
const
|
|
3048
|
+
const centroid2 = new Vector38();
|
|
2746
3049
|
for (const vertex of polygon) {
|
|
2747
|
-
|
|
3050
|
+
centroid2.addScaledVector(vertex, 1 / polygon.length);
|
|
2748
3051
|
}
|
|
2749
3052
|
return polygon.map(
|
|
2750
|
-
(vertex) =>
|
|
2751
|
-
new
|
|
3053
|
+
(vertex) => centroid2.clone().addScaledVector(
|
|
3054
|
+
new Vector38().subVectors(vertex, centroid2),
|
|
2752
3055
|
HINT_FACELET_SCALE
|
|
2753
3056
|
).addScaledVector(normal2, HINT_FACELET_ELEVATION)
|
|
2754
3057
|
);
|
|
@@ -2825,7 +3128,7 @@ function solidPuzzlePlan(stickerDat) {
|
|
|
2825
3128
|
}
|
|
2826
3129
|
faceletCount++;
|
|
2827
3130
|
for (let i = 1; i < polygon.length - 1; i++) {
|
|
2828
|
-
faceletArea += new
|
|
3131
|
+
faceletArea += new Vector38().subVectors(polygon[i], polygon[0]).cross(new Vector38().subVectors(polygon[i + 1], polygon[0])).length() / 2;
|
|
2829
3132
|
}
|
|
2830
3133
|
piece.stickers.push({ sticker, polygon });
|
|
2831
3134
|
for (let i = 0; i < polygon.length; i++) {
|
|
@@ -2852,7 +3155,7 @@ function solidPuzzlePlan(stickerDat) {
|
|
|
2852
3155
|
const cuts = cutPlanes(
|
|
2853
3156
|
order,
|
|
2854
3157
|
edges,
|
|
2855
|
-
stickerDat.axis.map((axis) => new
|
|
3158
|
+
stickerDat.axis.map((axis) => new Vector38(...axis.coordinates).normalize()),
|
|
2856
3159
|
quantum
|
|
2857
3160
|
);
|
|
2858
3161
|
if (!cuts) {
|
|
@@ -2946,7 +3249,7 @@ function newSolidPiece(piece, cuts, sizes) {
|
|
|
2946
3249
|
}
|
|
2947
3250
|
const planes = [];
|
|
2948
3251
|
const planeOfSticker = /* @__PURE__ */ new Map();
|
|
2949
|
-
const interior = new
|
|
3252
|
+
const interior = new Vector38();
|
|
2950
3253
|
for (const { polygon } of piece.stickers) {
|
|
2951
3254
|
for (const vertex of polygon) {
|
|
2952
3255
|
interior.addScaledVector(
|
|
@@ -3046,18 +3349,31 @@ function newSolidPiece(piece, cuts, sizes) {
|
|
|
3046
3349
|
const body = newPieceMesh2(solid.positions);
|
|
3047
3350
|
const hint = hintPositions.length > 0 ? newPieceMesh2(new Float32Array(hintPositions)) : null;
|
|
3048
3351
|
paintInternal(body.colors, solid.internalRanges);
|
|
3352
|
+
const logoByFace = /* @__PURE__ */ new Map();
|
|
3353
|
+
for (const { sticker, polygon } of piece.stickers) {
|
|
3354
|
+
logoByFace.set(
|
|
3355
|
+
sticker.face,
|
|
3356
|
+
logoSurface(
|
|
3357
|
+
polygon,
|
|
3358
|
+
outwardNormal(polygon),
|
|
3359
|
+
LOGO_ELEVATION3 * sizes.featureScale
|
|
3360
|
+
)
|
|
3361
|
+
);
|
|
3362
|
+
}
|
|
3049
3363
|
const facelets = piece.stickers.map(({ sticker }) => ({
|
|
3050
3364
|
ori: sticker.ori,
|
|
3051
3365
|
faceStyle: sticker.face,
|
|
3052
3366
|
body: solid.ranges[planeOfSticker.get(sticker)],
|
|
3053
|
-
hint: [hintRanges.get(sticker)]
|
|
3367
|
+
hint: [hintRanges.get(sticker)],
|
|
3368
|
+
logo: logoByFace.get(sticker.face) ?? null
|
|
3054
3369
|
}));
|
|
3055
3370
|
for (const sticker of piece.duplicates) {
|
|
3056
3371
|
facelets.push({
|
|
3057
3372
|
ori: sticker.ori,
|
|
3058
3373
|
faceStyle: sticker.face,
|
|
3059
3374
|
body: [],
|
|
3060
|
-
hint: []
|
|
3375
|
+
hint: [],
|
|
3376
|
+
logo: logoByFace.get(sticker.face) ?? null
|
|
3061
3377
|
});
|
|
3062
3378
|
}
|
|
3063
3379
|
return {
|
|
@@ -3071,9 +3387,9 @@ function newSolidPiece(piece, cuts, sizes) {
|
|
|
3071
3387
|
};
|
|
3072
3388
|
}
|
|
3073
3389
|
function newPieceMesh2(positions) {
|
|
3074
|
-
const geometry = new
|
|
3075
|
-
geometry.setAttribute("position", new
|
|
3076
|
-
const colors = new
|
|
3390
|
+
const geometry = new BufferGeometry6();
|
|
3391
|
+
geometry.setAttribute("position", new BufferAttribute6(positions, 3));
|
|
3392
|
+
const colors = new BufferAttribute6(
|
|
3077
3393
|
new Uint8Array(4 * positions.length / 3),
|
|
3078
3394
|
4,
|
|
3079
3395
|
true
|
|
@@ -3084,15 +3400,15 @@ function newPieceMesh2(positions) {
|
|
|
3084
3400
|
|
|
3085
3401
|
// src/cubing/twisty/views/3D/puzzles/Square1_3D.ts
|
|
3086
3402
|
import { DoubleSide as DoubleSide3 } from "three/src/constants.js";
|
|
3087
|
-
import { BufferAttribute as
|
|
3088
|
-
import { BufferGeometry as
|
|
3403
|
+
import { BufferAttribute as BufferAttribute7 } from "three/src/core/BufferAttribute.js";
|
|
3404
|
+
import { BufferGeometry as BufferGeometry7 } from "three/src/core/BufferGeometry.js";
|
|
3089
3405
|
import { Object3D as Object3D3 } from "three/src/core/Object3D.js";
|
|
3090
|
-
import { MeshBasicMaterial as
|
|
3406
|
+
import { MeshBasicMaterial as MeshBasicMaterial5 } from "three/src/materials/MeshBasicMaterial.js";
|
|
3091
3407
|
import { Color as Color5 } from "three/src/math/Color.js";
|
|
3092
3408
|
import { Quaternion as Quaternion2 } from "three/src/math/Quaternion.js";
|
|
3093
|
-
import { Vector3 as
|
|
3409
|
+
import { Vector3 as Vector39 } from "three/src/math/Vector3.js";
|
|
3094
3410
|
import { Group as Group3 } from "three/src/objects/Group.js";
|
|
3095
|
-
import { Mesh as
|
|
3411
|
+
import { Mesh as Mesh4 } from "three/src/objects/Mesh.js";
|
|
3096
3412
|
var DEGREE = TAU / 360;
|
|
3097
3413
|
var SLOT_ANGLE_DEGREES = 30;
|
|
3098
3414
|
var WEDGES_PER_LAYER = 12;
|
|
@@ -3107,8 +3423,8 @@ var RING_COLORS = [2254591, 16750848, 65280, 16711680];
|
|
|
3107
3423
|
var FRAME_OFFSET_DEGREES = 180;
|
|
3108
3424
|
var BODY_COLOR = 1118481;
|
|
3109
3425
|
var MIRROR = -1;
|
|
3110
|
-
var Y_AXIS = new
|
|
3111
|
-
var SLICE_AXIS = new
|
|
3426
|
+
var Y_AXIS = new Vector39(0, 1, 0);
|
|
3427
|
+
var SLICE_AXIS = new Vector39(
|
|
3112
3428
|
MIRROR * Math.sin(15 * DEGREE),
|
|
3113
3429
|
0,
|
|
3114
3430
|
Math.cos(15 * DEGREE)
|
|
@@ -3125,7 +3441,7 @@ function slotQuaternion(slot) {
|
|
|
3125
3441
|
);
|
|
3126
3442
|
if (slot >= WEDGES_PER_LAYER) {
|
|
3127
3443
|
quaternion.multiply(
|
|
3128
|
-
new Quaternion2().setFromAxisAngle(new
|
|
3444
|
+
new Quaternion2().setFromAxisAngle(new Vector39(0, 0, 1), TAU / 2)
|
|
3129
3445
|
);
|
|
3130
3446
|
}
|
|
3131
3447
|
return quaternion;
|
|
@@ -3214,15 +3530,15 @@ function prismStickerSpecs(spec) {
|
|
|
3214
3530
|
const specs = [];
|
|
3215
3531
|
if (topColor !== null) {
|
|
3216
3532
|
specs.push({
|
|
3217
|
-
corners: polygon.map(([x, z]) => new
|
|
3218
|
-
normal: new
|
|
3533
|
+
corners: polygon.map(([x, z]) => new Vector39(x, yTop, z)),
|
|
3534
|
+
normal: new Vector39(0, 1, 0),
|
|
3219
3535
|
color: topColor
|
|
3220
3536
|
});
|
|
3221
3537
|
}
|
|
3222
3538
|
if (bottomColor !== null) {
|
|
3223
3539
|
specs.push({
|
|
3224
|
-
corners: polygon.map(([x, z]) => new
|
|
3225
|
-
normal: new
|
|
3540
|
+
corners: polygon.map(([x, z]) => new Vector39(x, yBottom, z)),
|
|
3541
|
+
normal: new Vector39(0, -1, 0),
|
|
3226
3542
|
color: bottomColor
|
|
3227
3543
|
});
|
|
3228
3544
|
}
|
|
@@ -3239,17 +3555,17 @@ function prismStickerSpecs(spec) {
|
|
|
3239
3555
|
}
|
|
3240
3556
|
const [x0, z0] = polygon[i];
|
|
3241
3557
|
const [x1, z1] = polygon[(i + 1) % polygon.length];
|
|
3242
|
-
const normal2 = new
|
|
3558
|
+
const normal2 = new Vector39(z1 - z0, 0, -(x1 - x0)).normalize();
|
|
3243
3559
|
const outward = normal2.x * ((x0 + x1) / 2 - centroidX) + normal2.z * ((z0 + z1) / 2 - centroidZ);
|
|
3244
3560
|
if (outward < 0) {
|
|
3245
3561
|
normal2.negate();
|
|
3246
3562
|
}
|
|
3247
3563
|
specs.push({
|
|
3248
3564
|
corners: [
|
|
3249
|
-
new
|
|
3250
|
-
new
|
|
3251
|
-
new
|
|
3252
|
-
new
|
|
3565
|
+
new Vector39(x0, yBottom, z0),
|
|
3566
|
+
new Vector39(x1, yBottom, z1),
|
|
3567
|
+
new Vector39(x1, yTop, z1),
|
|
3568
|
+
new Vector39(x0, yTop, z0)
|
|
3253
3569
|
],
|
|
3254
3570
|
normal: normal2,
|
|
3255
3571
|
color
|
|
@@ -3258,7 +3574,7 @@ function prismStickerSpecs(spec) {
|
|
|
3258
3574
|
return specs;
|
|
3259
3575
|
}
|
|
3260
3576
|
function stickerPositions(spec, faceletScale) {
|
|
3261
|
-
const center = new
|
|
3577
|
+
const center = new Vector39();
|
|
3262
3578
|
for (const corner of spec.corners) {
|
|
3263
3579
|
center.addScaledVector(corner, 1 / spec.corners.length);
|
|
3264
3580
|
}
|
|
@@ -3287,9 +3603,9 @@ var PUZZLE_RADIUS = CUBE_HALF_EDGE * Math.SQRT2;
|
|
|
3287
3603
|
function prismPlanes(spec) {
|
|
3288
3604
|
const { polygon, sideColors } = spec;
|
|
3289
3605
|
const planes = [
|
|
3290
|
-
{ normal: new
|
|
3606
|
+
{ normal: new Vector39(0, 1, 0), offset: spec.yTop, color: spec.topColor },
|
|
3291
3607
|
{
|
|
3292
|
-
normal: new
|
|
3608
|
+
normal: new Vector39(0, -1, 0),
|
|
3293
3609
|
offset: -spec.yBottom,
|
|
3294
3610
|
color: spec.bottomColor
|
|
3295
3611
|
}
|
|
@@ -3303,7 +3619,7 @@ function prismPlanes(spec) {
|
|
|
3303
3619
|
for (let i = 0; i < polygon.length; i++) {
|
|
3304
3620
|
const [x0, z0] = polygon[i];
|
|
3305
3621
|
const [x1, z1] = polygon[(i + 1) % polygon.length];
|
|
3306
|
-
const normal2 = new
|
|
3622
|
+
const normal2 = new Vector39(z1 - z0, 0, -(x1 - x0)).normalize();
|
|
3307
3623
|
if (normal2.x * (x0 - centroidX) + normal2.z * (z0 - centroidZ) < 0) {
|
|
3308
3624
|
normal2.negate();
|
|
3309
3625
|
}
|
|
@@ -3343,12 +3659,12 @@ function stickerlessPieceGeometry(spec) {
|
|
|
3343
3659
|
paint(piece.ranges[i], color);
|
|
3344
3660
|
}
|
|
3345
3661
|
}
|
|
3346
|
-
const geometry = new
|
|
3347
|
-
geometry.setAttribute("position", new
|
|
3348
|
-
geometry.setAttribute("color", new
|
|
3662
|
+
const geometry = new BufferGeometry7();
|
|
3663
|
+
geometry.setAttribute("position", new BufferAttribute7(piece.positions, 3));
|
|
3664
|
+
geometry.setAttribute("color", new BufferAttribute7(colors, 4, true));
|
|
3349
3665
|
return geometry;
|
|
3350
3666
|
}
|
|
3351
|
-
var bodyMaterial = new
|
|
3667
|
+
var bodyMaterial = new MeshBasicMaterial5({
|
|
3352
3668
|
color: new Color5(BODY_COLOR).convertLinearToSRGB(),
|
|
3353
3669
|
side: DoubleSide3
|
|
3354
3670
|
});
|
|
@@ -3360,7 +3676,7 @@ var stickerMaterialCache = /* @__PURE__ */ new Map();
|
|
|
3360
3676
|
function stickerMaterial(color) {
|
|
3361
3677
|
let material = stickerMaterialCache.get(color);
|
|
3362
3678
|
if (!material) {
|
|
3363
|
-
material = new
|
|
3679
|
+
material = new MeshBasicMaterial5({
|
|
3364
3680
|
color: new Color5(color).convertLinearToSRGB(),
|
|
3365
3681
|
side: DoubleSide3
|
|
3366
3682
|
});
|
|
@@ -3375,28 +3691,28 @@ var Square1Piece = class extends Group3 {
|
|
|
3375
3691
|
constructor(spec, faceletScale, stickerless) {
|
|
3376
3692
|
super();
|
|
3377
3693
|
if (stickerless) {
|
|
3378
|
-
this.body = new
|
|
3694
|
+
this.body = new Mesh4(
|
|
3379
3695
|
stickerlessPieceGeometry(spec),
|
|
3380
3696
|
stickerlessMaterial()
|
|
3381
3697
|
);
|
|
3382
3698
|
this.add(this.body);
|
|
3383
3699
|
return;
|
|
3384
3700
|
}
|
|
3385
|
-
const bodyGeometry = new
|
|
3701
|
+
const bodyGeometry = new BufferGeometry7();
|
|
3386
3702
|
bodyGeometry.setAttribute(
|
|
3387
3703
|
"position",
|
|
3388
|
-
new
|
|
3704
|
+
new BufferAttribute7(prismBodyPositions(spec), 3)
|
|
3389
3705
|
);
|
|
3390
|
-
this.body = new
|
|
3706
|
+
this.body = new Mesh4(bodyGeometry, bodyMaterial);
|
|
3391
3707
|
this.add(this.body);
|
|
3392
3708
|
this.#stickerSpecs = prismStickerSpecs(spec);
|
|
3393
3709
|
for (const stickerSpec of this.#stickerSpecs) {
|
|
3394
|
-
const geometry = new
|
|
3710
|
+
const geometry = new BufferGeometry7();
|
|
3395
3711
|
geometry.setAttribute(
|
|
3396
3712
|
"position",
|
|
3397
|
-
new
|
|
3713
|
+
new BufferAttribute7(stickerPositions(stickerSpec, faceletScale), 3)
|
|
3398
3714
|
);
|
|
3399
|
-
const mesh = new
|
|
3715
|
+
const mesh = new Mesh4(geometry, stickerMaterial(stickerSpec.color));
|
|
3400
3716
|
this.#stickerMeshes.push(mesh);
|
|
3401
3717
|
this.add(mesh);
|
|
3402
3718
|
}
|
|
@@ -3406,7 +3722,7 @@ var Square1Piece = class extends Group3 {
|
|
|
3406
3722
|
const geometry = this.#stickerMeshes[i].geometry;
|
|
3407
3723
|
geometry.setAttribute(
|
|
3408
3724
|
"position",
|
|
3409
|
-
new
|
|
3725
|
+
new BufferAttribute7(
|
|
3410
3726
|
stickerPositions(this.#stickerSpecs[i], faceletScale),
|
|
3411
3727
|
3
|
|
3412
3728
|
)
|
|
@@ -3461,6 +3777,38 @@ function equatorPrismSpec(homePiece) {
|
|
|
3461
3777
|
]
|
|
3462
3778
|
};
|
|
3463
3779
|
}
|
|
3780
|
+
var LOGO_EQUATOR_PIECE = 0;
|
|
3781
|
+
var LOGO_ELEVATION4 = 2 * STICKER_ELEVATION;
|
|
3782
|
+
function equatorLogoSurface(spec) {
|
|
3783
|
+
const { polygon, yBottom, yTop, sideColors } = spec;
|
|
3784
|
+
let best = null;
|
|
3785
|
+
let bestWidth = 0;
|
|
3786
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
3787
|
+
if (sideColors[i] === null || sideColors[i] === void 0) {
|
|
3788
|
+
continue;
|
|
3789
|
+
}
|
|
3790
|
+
const [x0, z0] = polygon[i];
|
|
3791
|
+
const [x1, z1] = polygon[(i + 1) % polygon.length];
|
|
3792
|
+
const width = Math.hypot(x1 - x0, z1 - z0);
|
|
3793
|
+
if (width <= bestWidth) {
|
|
3794
|
+
continue;
|
|
3795
|
+
}
|
|
3796
|
+
const normal2 = new Vector39(z1 - z0, 0, -(x1 - x0)).normalize();
|
|
3797
|
+
const u = new Vector39(x1 - x0, 0, z1 - z0).multiplyScalar(0.5);
|
|
3798
|
+
const v = new Vector39(0, (yTop - yBottom) / 2, 0);
|
|
3799
|
+
if (new Vector39().crossVectors(u, v).dot(normal2) < 0) {
|
|
3800
|
+
u.negate();
|
|
3801
|
+
}
|
|
3802
|
+
const center = new Vector39(
|
|
3803
|
+
(x0 + x1) / 2,
|
|
3804
|
+
(yBottom + yTop) / 2,
|
|
3805
|
+
(z0 + z1) / 2
|
|
3806
|
+
).addScaledVector(normal2, LOGO_ELEVATION4);
|
|
3807
|
+
bestWidth = width;
|
|
3808
|
+
best = rectangleLogoSurface(center, u, v);
|
|
3809
|
+
}
|
|
3810
|
+
return best;
|
|
3811
|
+
}
|
|
3464
3812
|
function ringColorAt(phiDegrees) {
|
|
3465
3813
|
const faceIndex = Math.round(phiDegrees / 90);
|
|
3466
3814
|
return RING_COLORS[(faceIndex % 4 + 4) % 4];
|
|
@@ -3617,6 +3965,31 @@ var Square1_3D = class extends Object3D3 {
|
|
|
3617
3965
|
}
|
|
3618
3966
|
setStickeringMask(_stickeringMask) {
|
|
3619
3967
|
}
|
|
3968
|
+
#logoMesh = null;
|
|
3969
|
+
/**
|
|
3970
|
+
* Prints a logo on the equator block, or takes it off again when passed
|
|
3971
|
+
* `null`.
|
|
3972
|
+
*
|
|
3973
|
+
* The image is stretched onto a square sized to the face, so its own
|
|
3974
|
+
* proportions don't matter. It is a child of the piece, so it turns and flips
|
|
3975
|
+
* with the equator.
|
|
3976
|
+
*/
|
|
3977
|
+
experimentalSetLogo(texture) {
|
|
3978
|
+
if (this.#logoMesh) {
|
|
3979
|
+
this.#logoMesh.removeFromParent();
|
|
3980
|
+
this.#logoMesh.material.dispose();
|
|
3981
|
+
this.#logoMesh = null;
|
|
3982
|
+
}
|
|
3983
|
+
if (texture) {
|
|
3984
|
+
const surface = equatorLogoSurface(equatorPrismSpec(LOGO_EQUATOR_PIECE));
|
|
3985
|
+
if (surface) {
|
|
3986
|
+
this.#logoMesh = newLogoMesh(texture);
|
|
3987
|
+
surfaceMatrix(surface, this.#logoMesh.matrix);
|
|
3988
|
+
this.#equatorPieces[LOGO_EQUATOR_PIECE].add(this.#logoMesh);
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
this.scheduleRenderCallback?.();
|
|
3992
|
+
}
|
|
3620
3993
|
experimentalUpdateOptions(options) {
|
|
3621
3994
|
let changed = false;
|
|
3622
3995
|
if (typeof options.showFoundation === "boolean") {
|
|
@@ -3651,15 +4024,15 @@ var Square1_3D = class extends Object3D3 {
|
|
|
3651
4024
|
|
|
3652
4025
|
// src/cubing/twisty/views/3D/puzzles/Stickerless3D.ts
|
|
3653
4026
|
import { BackSide as BackSide2 } from "three/src/constants.js";
|
|
3654
|
-
import { BufferAttribute as
|
|
3655
|
-
import { BufferGeometry as
|
|
4027
|
+
import { BufferAttribute as BufferAttribute8 } from "three/src/core/BufferAttribute.js";
|
|
4028
|
+
import { BufferGeometry as BufferGeometry8 } from "three/src/core/BufferGeometry.js";
|
|
3656
4029
|
import { Object3D as Object3D4 } from "three/src/core/Object3D.js";
|
|
3657
|
-
import { MeshBasicMaterial as
|
|
4030
|
+
import { MeshBasicMaterial as MeshBasicMaterial6 } from "three/src/materials/MeshBasicMaterial.js";
|
|
3658
4031
|
import { Matrix4 as Matrix44 } from "three/src/math/Matrix4.js";
|
|
3659
|
-
import { Vector3 as
|
|
4032
|
+
import { Vector3 as Vector310 } from "three/src/math/Vector3.js";
|
|
3660
4033
|
import { BatchedMesh } from "three/src/objects/BatchedMesh.js";
|
|
3661
|
-
import { Mesh as
|
|
3662
|
-
var invisibleMaterial2 = new
|
|
4034
|
+
import { Mesh as Mesh5 } from "three/src/objects/Mesh.js";
|
|
4035
|
+
var invisibleMaterial2 = new MeshBasicMaterial6({ visible: false });
|
|
3663
4036
|
function newBatch(meshes, material) {
|
|
3664
4037
|
let vertices = 0;
|
|
3665
4038
|
let indices = 0;
|
|
@@ -3684,7 +4057,8 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3684
4057
|
this.kpuzzle = kpuzzle;
|
|
3685
4058
|
this.stickerDat = stickerDat;
|
|
3686
4059
|
this.plan = plan;
|
|
3687
|
-
this.#
|
|
4060
|
+
this.#logoFacelet = options.logoFacelet ?? null;
|
|
4061
|
+
this.#hintMaterial = new MeshBasicMaterial6({
|
|
3688
4062
|
vertexColors: true,
|
|
3689
4063
|
transparent: true,
|
|
3690
4064
|
// Hint facelets show the faces turned away from the camera, so they are
|
|
@@ -3694,7 +4068,7 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3694
4068
|
this.#bodyMaterial = newVertexColorBodyMaterial();
|
|
3695
4069
|
for (const axis of stickerDat.axis) {
|
|
3696
4070
|
this.#axesInfo[axis.quantumMove.family] = {
|
|
3697
|
-
axis: new
|
|
4071
|
+
axis: new Vector310(...axis.coordinates),
|
|
3698
4072
|
order: axis.order
|
|
3699
4073
|
};
|
|
3700
4074
|
}
|
|
@@ -3758,6 +4132,11 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3758
4132
|
#dirtyColors = /* @__PURE__ */ new Map();
|
|
3759
4133
|
#lastPosition = null;
|
|
3760
4134
|
#pendingStickeringUpdate = false;
|
|
4135
|
+
/** The facelet a logo is printed on, and where it currently shows. */
|
|
4136
|
+
#logoFacelet = null;
|
|
4137
|
+
#logoMesh = null;
|
|
4138
|
+
#logoSlot = null;
|
|
4139
|
+
#logoSurfaceMatrix = new Matrix44();
|
|
3761
4140
|
#addPiece(plan) {
|
|
3762
4141
|
const bodyInstance = addToBatch(this.#bodyBatch, plan.body, plan.home);
|
|
3763
4142
|
const hintInstance = plan.hint && this.#hintBatch ? addToBatch(this.#hintBatch, plan.hint, plan.home) : -1;
|
|
@@ -3782,7 +4161,8 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3782
4161
|
hint: hintInstance === -1 ? [] : shift(facelet.hint, hintInstance.vertexStart),
|
|
3783
4162
|
appearanceKey: -1,
|
|
3784
4163
|
mask: "regular",
|
|
3785
|
-
hintMask: "regular"
|
|
4164
|
+
hintMask: "regular",
|
|
4165
|
+
logo: facelet.logo
|
|
3786
4166
|
};
|
|
3787
4167
|
}
|
|
3788
4168
|
}
|
|
@@ -3807,15 +4187,94 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3807
4187
|
}
|
|
3808
4188
|
}
|
|
3809
4189
|
}
|
|
3810
|
-
const geometry = new
|
|
3811
|
-
geometry.setAttribute("position", new
|
|
3812
|
-
const mesh = new
|
|
4190
|
+
const geometry = new BufferGeometry8();
|
|
4191
|
+
geometry.setAttribute("position", new BufferAttribute8(positions, 3));
|
|
4192
|
+
const mesh = new Mesh5(geometry, invisibleMaterial2);
|
|
3813
4193
|
mesh.userData["quantumMove"] = this.stickerDat.notationMapper.notationToExternal(new Move(face2.name));
|
|
3814
4194
|
mesh.scale.setScalar(0.99);
|
|
3815
4195
|
this.add(mesh);
|
|
3816
4196
|
this.#controlTargets.push(mesh);
|
|
3817
4197
|
}
|
|
4198
|
+
/**
|
|
4199
|
+
* Prints a logo on the piece this puzzle keeps one on, or takes it off again
|
|
4200
|
+
* when passed `null`.
|
|
4201
|
+
*
|
|
4202
|
+
* The image is stretched onto the square {@link PuzzlePlan} sized for that
|
|
4203
|
+
* facelet, so its own proportions don't matter. It follows the piece: the
|
|
4204
|
+
* logo is drawn wherever the piece currently is, including part-way through a
|
|
4205
|
+
* move. The one thing it does not follow is a piece turning in place — a
|
|
4206
|
+
* megaminx or skewb center whose facelets are all one square — which leaves
|
|
4207
|
+
* the logo upright rather than rotating it with the plastic.
|
|
4208
|
+
*/
|
|
4209
|
+
experimentalSetLogo(texture) {
|
|
4210
|
+
if (!texture || !this.#logoFacelet) {
|
|
4211
|
+
this.#disposeLogo();
|
|
4212
|
+
this.scheduleRenderCallback();
|
|
4213
|
+
return;
|
|
4214
|
+
}
|
|
4215
|
+
if (this.#logoMesh) {
|
|
4216
|
+
const material = this.#logoMesh.material;
|
|
4217
|
+
material.map = texture;
|
|
4218
|
+
material.needsUpdate = true;
|
|
4219
|
+
} else {
|
|
4220
|
+
this.#logoMesh = newLogoMesh(texture);
|
|
4221
|
+
this.add(this.#logoMesh);
|
|
4222
|
+
}
|
|
4223
|
+
this.#updateLogoSlot();
|
|
4224
|
+
this.#placeLogo();
|
|
4225
|
+
this.scheduleRenderCallback();
|
|
4226
|
+
}
|
|
4227
|
+
#disposeLogo() {
|
|
4228
|
+
if (!this.#logoMesh) {
|
|
4229
|
+
return;
|
|
4230
|
+
}
|
|
4231
|
+
this.remove(this.#logoMesh);
|
|
4232
|
+
this.#logoMesh.material.dispose();
|
|
4233
|
+
this.#logoMesh = null;
|
|
4234
|
+
this.#logoSlot = null;
|
|
4235
|
+
}
|
|
4236
|
+
/** Which slot is showing the logo's facelet, as of the last position. */
|
|
4237
|
+
#updateLogoSlot() {
|
|
4238
|
+
this.#logoSlot = null;
|
|
4239
|
+
const address = this.#logoFacelet;
|
|
4240
|
+
const pattern = this.#lastPosition?.pattern;
|
|
4241
|
+
if (!address || !pattern) {
|
|
4242
|
+
return;
|
|
4243
|
+
}
|
|
4244
|
+
const orbitFacelets = this.#facelets[address.orbit];
|
|
4245
|
+
const orbitPattern = pattern.patternData[address.orbit];
|
|
4246
|
+
if (!orbitFacelets || !orbitPattern) {
|
|
4247
|
+
return;
|
|
4248
|
+
}
|
|
4249
|
+
const numOrientations = orbitFacelets.length;
|
|
4250
|
+
for (let ord = 0; ord < orbitPattern.pieces.length; ord++) {
|
|
4251
|
+
if (orbitPattern.pieces[ord] !== address.ord) {
|
|
4252
|
+
continue;
|
|
4253
|
+
}
|
|
4254
|
+
const ori = numOrientations === 1 ? 0 : (address.ori + orbitPattern.orientation[ord]) % numOrientations;
|
|
4255
|
+
this.#logoSlot = orbitFacelets[ori]?.[ord] ?? null;
|
|
4256
|
+
return;
|
|
4257
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
#placeLogo() {
|
|
4260
|
+
const mesh = this.#logoMesh;
|
|
4261
|
+
if (!mesh) {
|
|
4262
|
+
return;
|
|
4263
|
+
}
|
|
4264
|
+
const slot = this.#logoSlot;
|
|
4265
|
+
if (!slot?.logo) {
|
|
4266
|
+
mesh.visible = false;
|
|
4267
|
+
return;
|
|
4268
|
+
}
|
|
4269
|
+
mesh.visible = true;
|
|
4270
|
+
mesh.matrix.multiplyMatrices(
|
|
4271
|
+
slot.piece.matrix,
|
|
4272
|
+
surfaceMatrix(slot.logo, this.#logoSurfaceMatrix)
|
|
4273
|
+
);
|
|
4274
|
+
mesh.matrixWorldNeedsUpdate = true;
|
|
4275
|
+
}
|
|
3818
4276
|
dispose() {
|
|
4277
|
+
this.#disposeLogo();
|
|
3819
4278
|
this.#bodyBatch.dispose();
|
|
3820
4279
|
this.#bodyBatch.geometry.dispose();
|
|
3821
4280
|
this.#hintBatch?.dispose();
|
|
@@ -3852,7 +4311,7 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3852
4311
|
}
|
|
3853
4312
|
}
|
|
3854
4313
|
for (const axis of this.stickerDat.axis) {
|
|
3855
|
-
const product = point.dot(new
|
|
4314
|
+
const product = point.dot(new Vector310(...axis.coordinates));
|
|
3856
4315
|
if (product > closestMoveDotProduct) {
|
|
3857
4316
|
const modified = this.stickerDat.notationMapper.notationToExternal(
|
|
3858
4317
|
modify(axis.quantumMove)
|
|
@@ -3929,6 +4388,7 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3929
4388
|
this.#updateColors(position);
|
|
3930
4389
|
this.#lastPosition = position;
|
|
3931
4390
|
this.#pendingStickeringUpdate = false;
|
|
4391
|
+
this.#updateLogoSlot();
|
|
3932
4392
|
}
|
|
3933
4393
|
const wereTurning = this.#turningPieces;
|
|
3934
4394
|
for (const piece of wereTurning) {
|
|
@@ -3968,6 +4428,7 @@ var Stickerless3D = class extends Object3D4 {
|
|
|
3968
4428
|
for (const piece of this.#turningPieces) {
|
|
3969
4429
|
this.#setMatrix(piece);
|
|
3970
4430
|
}
|
|
4431
|
+
this.#placeLogo();
|
|
3971
4432
|
this.scheduleRenderCallback();
|
|
3972
4433
|
}
|
|
3973
4434
|
/**
|
|
@@ -4086,7 +4547,7 @@ import { Raycaster } from "three/src/core/Raycaster.js";
|
|
|
4086
4547
|
import { TextureLoader as TextureLoader2 } from "three/src/loaders/TextureLoader.js";
|
|
4087
4548
|
import { Spherical } from "three/src/math/Spherical.js";
|
|
4088
4549
|
import { Vector2 as Vector22 } from "three/src/math/Vector2.js";
|
|
4089
|
-
import { Vector3 as
|
|
4550
|
+
import { Vector3 as Vector311 } from "three/src/math/Vector3.js";
|
|
4090
4551
|
import { WebGLRenderer } from "three/src/renderers/WebGLRenderer.js";
|
|
4091
4552
|
import { Scene } from "three/src/scenes/Scene.js";
|
|
4092
4553
|
|
|
@@ -4134,7 +4595,8 @@ async function pg3dShim(renderCallback, puzzleLoader, hintFacelets, faceletScale
|
|
|
4134
4595
|
const plan = darkIgnoredOrbits || pictureCube ? null : cubePuzzlePlan(stickerDat) ?? solidPuzzlePlan(stickerDat);
|
|
4135
4596
|
if (plan) {
|
|
4136
4597
|
return new Stickerless3D(renderCallback, kpuzzle, stickerDat, plan, {
|
|
4137
|
-
hintFacelets
|
|
4598
|
+
hintFacelets,
|
|
4599
|
+
logoFacelet: logoFaceletAddress(puzzleLoader.id, stickerDat)
|
|
4138
4600
|
});
|
|
4139
4601
|
}
|
|
4140
4602
|
return new PG3D(
|
|
@@ -4158,11 +4620,11 @@ export {
|
|
|
4158
4620
|
Spherical as ThreeSpherical,
|
|
4159
4621
|
TextureLoader2 as ThreeTextureLoader,
|
|
4160
4622
|
Vector22 as ThreeVector2,
|
|
4161
|
-
|
|
4623
|
+
Vector311 as ThreeVector3,
|
|
4162
4624
|
WebGLRenderer as ThreeWebGLRenderer,
|
|
4163
4625
|
Twisty3DScene,
|
|
4164
4626
|
cube3DShim,
|
|
4165
4627
|
pg3dShim,
|
|
4166
4628
|
square1_3DShim
|
|
4167
4629
|
};
|
|
4168
|
-
//# sourceMappingURL=twisty-dynamic-3d-
|
|
4630
|
+
//# sourceMappingURL=twisty-dynamic-3d-3MGVD3TG.js.map
|