@layoutit/polycss-react 0.2.1 → 0.2.2
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/README.md +16 -13
- package/dist/index.cjs +1196 -627
- package/dist/index.d.cts +89 -31
- package/dist/index.d.ts +89 -31
- package/dist/index.js +969 -390
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -98,8 +98,9 @@ function usePolyCamera(options) {
|
|
|
98
98
|
const cssX = wy * tileSize;
|
|
99
99
|
const cssY = wx * tileSize;
|
|
100
100
|
const cssZ = wz * tileSize;
|
|
101
|
+
const cssZoom = s.zoom / tileSize;
|
|
101
102
|
const distancePart = s.distance !== 0 ? `translateZ(${-s.distance}px) ` : "";
|
|
102
|
-
el.style.transform = `${distancePart}scale(${
|
|
103
|
+
el.style.transform = `${distancePart}scale(${cssZoom}) rotateX(${s.rotX}deg) rotate(${s.rotY}deg) translate3d(${-cssX}px, ${-cssY}px, ${-cssZ}px)`;
|
|
103
104
|
}
|
|
104
105
|
store.updateCameraFromRef(handle);
|
|
105
106
|
store.notifyAll();
|
|
@@ -118,8 +119,9 @@ function usePolyCamera(options) {
|
|
|
118
119
|
const cssX = wy * tileSize;
|
|
119
120
|
const cssY = wx * tileSize;
|
|
120
121
|
const cssZ = wz * tileSize;
|
|
122
|
+
const cssZoom = s.zoom / tileSize;
|
|
121
123
|
const distancePart = s.distance !== 0 ? `translateZ(${-s.distance}px) ` : "";
|
|
122
|
-
el.style.transform = `${distancePart}scale(${
|
|
124
|
+
el.style.transform = `${distancePart}scale(${cssZoom}) rotateX(${s.rotX}deg) rotate(${s.rotY}deg) translate3d(${-cssX}px, ${-cssY}px, ${-cssZ}px)`;
|
|
123
125
|
}, [store]);
|
|
124
126
|
return {
|
|
125
127
|
store,
|
|
@@ -132,7 +134,7 @@ function usePolyCamera(options) {
|
|
|
132
134
|
|
|
133
135
|
// src/camera/PolyPerspectiveCamera.tsx
|
|
134
136
|
import { jsx } from "react/jsx-runtime";
|
|
135
|
-
var DEFAULT_PERSPECTIVE =
|
|
137
|
+
var DEFAULT_PERSPECTIVE = 32e3;
|
|
136
138
|
function PolyPerspectiveCameraInner({
|
|
137
139
|
zoom,
|
|
138
140
|
target,
|
|
@@ -198,7 +200,12 @@ function PolyOrthographicCameraInner({
|
|
|
198
200
|
);
|
|
199
201
|
const cameraStyle = {
|
|
200
202
|
...style,
|
|
201
|
-
perspective:
|
|
203
|
+
// Vanilla emits 1000000px instead of "none" because true `perspective: none`
|
|
204
|
+
// sends Chrome down a compositor fast path that mis-rasterizes <u>
|
|
205
|
+
// border-triangle leaves. A very large finite value is visually orthographic
|
|
206
|
+
// but routes through the normal compositor path. Mirror that here so React
|
|
207
|
+
// produces byte-identical output to vanilla.
|
|
208
|
+
perspective: "1000000px"
|
|
202
209
|
};
|
|
203
210
|
return /* @__PURE__ */ jsx2(PolyCameraContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx2(
|
|
204
211
|
"div",
|
|
@@ -213,8 +220,8 @@ function PolyOrthographicCameraInner({
|
|
|
213
220
|
var PolyOrthographicCamera = memo2(PolyOrthographicCameraInner);
|
|
214
221
|
|
|
215
222
|
// src/scene/PolyScene.tsx
|
|
216
|
-
import { memo as
|
|
217
|
-
import { BASE_TILE as BASE_TILE2, DEFAULT_SEAM_BLEED, parseHexColor } from "@layoutit/polycss-core";
|
|
223
|
+
import { memo as memo8, useCallback as useCallback5, useEffect as useEffect3, useLayoutEffect, useMemo as useMemo6, useRef as useRef4, useState as useState2 } from "react";
|
|
224
|
+
import { BASE_TILE as BASE_TILE2, DEFAULT_SEAM_BLEED, parseHexColor, worldDirectionToCss } from "@layoutit/polycss-core";
|
|
218
225
|
|
|
219
226
|
// src/scene/useSceneContext.ts
|
|
220
227
|
import { useMemo as useMemo4 } from "react";
|
|
@@ -267,21 +274,24 @@ var CORE_BASE_STYLES = `
|
|
|
267
274
|
will-change: transform;
|
|
268
275
|
}
|
|
269
276
|
|
|
270
|
-
/* \u2500\u2500 Camera wrapper
|
|
277
|
+
/* \u2500\u2500 Camera wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
271
278
|
|
|
279
|
+
/* Matches vanilla .polycss-camera: a simple positioned block that fills the
|
|
280
|
+
host. PolyPerspectiveCamera / PolyOrthographicCamera apply perspective
|
|
281
|
+
inline (driven by their perspective prop), so the CSS file does not bake a
|
|
282
|
+
default. Earlier React/Vue copies added flex centering, overflow:hidden,
|
|
283
|
+
contain:paint, isolation:isolate which shifted layout vs vanilla; removed
|
|
284
|
+
so cross-renderer iframes lay out identically. */
|
|
272
285
|
.polycss-camera {
|
|
273
|
-
|
|
286
|
+
position: relative;
|
|
287
|
+
display: block;
|
|
274
288
|
width: 100%;
|
|
275
|
-
justify-content: center;
|
|
276
|
-
align-items: center;
|
|
277
|
-
perspective: 8000px;
|
|
278
|
-
min-height: inherit;
|
|
279
289
|
height: 100%;
|
|
280
|
-
position: relative;
|
|
281
|
-
overflow: hidden;
|
|
282
|
-
contain: paint;
|
|
283
|
-
isolation: isolate;
|
|
284
290
|
}
|
|
291
|
+
/* React-only descendant default: applies preserve-3d to controls + helpers
|
|
292
|
+
that ride on the camera; vanilla does not need this because every internal
|
|
293
|
+
element sets the property directly. Kept here so user-supplied wrapper
|
|
294
|
+
divs inside PolyCamera still participate in 3D layout. */
|
|
285
295
|
.polycss-camera * {
|
|
286
296
|
transform-style: preserve-3d;
|
|
287
297
|
position: absolute;
|
|
@@ -303,6 +313,17 @@ var CORE_BASE_STYLES = `
|
|
|
303
313
|
transform-style: preserve-3d !important;
|
|
304
314
|
}
|
|
305
315
|
|
|
316
|
+
/* \u2500\u2500 Mesh wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
317
|
+
|
|
318
|
+
.polycss-mesh {
|
|
319
|
+
position: absolute;
|
|
320
|
+
transform-style: preserve-3d;
|
|
321
|
+
/* Pivot at wrapper local (0,0,0) for three.js mesh.position/rotation/scale
|
|
322
|
+
parity. Geometry is positioned by the parser (bbox-min-at-origin by
|
|
323
|
+
default, or pre-centered via loadMesh { center: true }). */
|
|
324
|
+
transform-origin: 0 0 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
306
327
|
/* \u2500\u2500 Polygon leaf element \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
307
328
|
|
|
308
329
|
/*
|
|
@@ -388,19 +409,34 @@ var CORE_BASE_STYLES = `
|
|
|
388
409
|
border-width: 0 16px 32px 16px;
|
|
389
410
|
}
|
|
390
411
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
412
|
+
@supports (corner-top-left-shape: bevel) and (corner-top-right-shape: bevel) {
|
|
413
|
+
.polycss-scene > u,
|
|
414
|
+
.polycss-mesh > u,
|
|
415
|
+
.polycss-bucket > u {
|
|
416
|
+
border-width: 0;
|
|
417
|
+
width: 32px;
|
|
418
|
+
height: 32px;
|
|
419
|
+
background-color: currentColor;
|
|
420
|
+
border-top-left-radius: 50% 100%;
|
|
421
|
+
border-top-right-radius: 50% 100%;
|
|
422
|
+
corner-top-left-shape: bevel;
|
|
423
|
+
corner-top-right-shape: bevel;
|
|
424
|
+
}
|
|
394
425
|
|
|
395
|
-
.polycss-scene u.polycss-corner-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
426
|
+
.polycss-scene > u.polycss-corner-shape-solid,
|
|
427
|
+
.polycss-mesh > u.polycss-corner-shape-solid,
|
|
428
|
+
.polycss-bucket > u.polycss-corner-shape-solid {
|
|
429
|
+
width: 16px;
|
|
430
|
+
height: 16px;
|
|
431
|
+
box-sizing: border-box;
|
|
432
|
+
border: 0;
|
|
433
|
+
background: currentColor;
|
|
434
|
+
border-radius: 0;
|
|
435
|
+
corner-top-left-shape: initial;
|
|
436
|
+
corner-top-right-shape: initial;
|
|
437
|
+
corner-bottom-right-shape: initial;
|
|
438
|
+
corner-bottom-left-shape: initial;
|
|
439
|
+
}
|
|
404
440
|
}
|
|
405
441
|
|
|
406
442
|
/* \u2500\u2500 Gizmo override \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -505,22 +541,33 @@ var CORE_BASE_STYLES = `
|
|
|
505
541
|
here (not inline per polygon) so each leaf only carries its tiny normal
|
|
506
542
|
declarations \u2014 ~12\xD7 smaller per-polygon style payload on big meshes. */
|
|
507
543
|
.polycss-scene[data-polycss-lighting="dynamic"] s {
|
|
544
|
+
/*
|
|
545
|
+
* Three.js MeshLambertMaterial parity for textured surfaces. See
|
|
546
|
+
* packages/polycss/src/styles/styles.ts for derivation and probe data.
|
|
547
|
+
* Kept in lockstep across renderer copies per cross-package discipline.
|
|
548
|
+
*/
|
|
508
549
|
background-color: rgb(
|
|
509
|
-
calc(255 * (
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
550
|
+
calc(255 * max(0, 1.055 * pow(min(1, (
|
|
551
|
+
pow((var(--par) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
552
|
+
pow((var(--plr) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
553
|
+
var(--pnx) * var(--plx) +
|
|
554
|
+
var(--pny) * var(--ply) +
|
|
555
|
+
var(--pnz) * var(--plz))
|
|
556
|
+
) / 3.14159265), 0.4167) - 0.055))
|
|
557
|
+
calc(255 * max(0, 1.055 * pow(min(1, (
|
|
558
|
+
pow((var(--pag) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
559
|
+
pow((var(--plg) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
560
|
+
var(--pnx) * var(--plx) +
|
|
561
|
+
var(--pny) * var(--ply) +
|
|
562
|
+
var(--pnz) * var(--plz))
|
|
563
|
+
) / 3.14159265), 0.4167) - 0.055))
|
|
564
|
+
calc(255 * max(0, 1.055 * pow(min(1, (
|
|
565
|
+
pow((var(--pab) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
566
|
+
pow((var(--plb) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
567
|
+
var(--pnx) * var(--plx) +
|
|
568
|
+
var(--pny) * var(--ply) +
|
|
569
|
+
var(--pnz) * var(--plz))
|
|
570
|
+
) / 3.14159265), 0.4167) - 0.055))
|
|
524
571
|
);
|
|
525
572
|
background-blend-mode: multiply;
|
|
526
573
|
background-image: var(--polycss-atlas-url);
|
|
@@ -539,35 +586,48 @@ var CORE_BASE_STYLES = `
|
|
|
539
586
|
}
|
|
540
587
|
|
|
541
588
|
.polycss-scene[data-polycss-lighting="dynamic"] b,
|
|
589
|
+
.polycss-scene[data-polycss-lighting="dynamic"] i,
|
|
542
590
|
.polycss-scene[data-polycss-lighting="dynamic"] u {
|
|
591
|
+
/*
|
|
592
|
+
* Three.js MeshLambertMaterial parity (default useLegacyLights=false,
|
|
593
|
+
* physically-correct pipeline). See packages/polycss/src/styles/styles.ts
|
|
594
|
+
* for the derivation and probe data \u2014 kept in lockstep across the three
|
|
595
|
+
* renderer copies per cross-package discipline.
|
|
596
|
+
*/
|
|
543
597
|
color: rgb(
|
|
544
|
-
calc(255 *
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
598
|
+
calc(255 * max(0, 1.055 * pow(min(1,
|
|
599
|
+
pow((var(--psr) + 0.055) / 1.055, 2.4) * (
|
|
600
|
+
pow((var(--par) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
601
|
+
pow((var(--plr) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
602
|
+
var(--pnx) * var(--plx) +
|
|
603
|
+
var(--pny) * var(--ply) +
|
|
604
|
+
var(--pnz) * var(--plz))
|
|
605
|
+
) / 3.14159265
|
|
606
|
+
), 0.4167) - 0.055))
|
|
607
|
+
calc(255 * max(0, 1.055 * pow(min(1,
|
|
608
|
+
pow((var(--psg) + 0.055) / 1.055, 2.4) * (
|
|
609
|
+
pow((var(--pag) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
610
|
+
pow((var(--plg) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
611
|
+
var(--pnx) * var(--plx) +
|
|
612
|
+
var(--pny) * var(--ply) +
|
|
613
|
+
var(--pnz) * var(--plz))
|
|
614
|
+
) / 3.14159265
|
|
615
|
+
), 0.4167) - 0.055))
|
|
616
|
+
calc(255 * max(0, 1.055 * pow(min(1,
|
|
617
|
+
pow((var(--psb) + 0.055) / 1.055, 2.4) * (
|
|
618
|
+
pow((var(--pab) + 0.055) / 1.055, 2.4) * var(--pai) +
|
|
619
|
+
pow((var(--plb) + 0.055) / 1.055, 2.4) * var(--pli) * max(0,
|
|
620
|
+
var(--pnx) * var(--plx) +
|
|
621
|
+
var(--pny) * var(--ply) +
|
|
622
|
+
var(--pnz) * var(--plz))
|
|
623
|
+
) / 3.14159265
|
|
624
|
+
), 0.4167) - 0.055))
|
|
559
625
|
);
|
|
560
626
|
}
|
|
561
627
|
|
|
562
|
-
/* <q>
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
through every dynamic-mode color rule. backface-visibility must be
|
|
566
|
-
visible because the projection matrix is near-rank-deficient and the
|
|
567
|
-
resulting plane's normal can read as back-facing under some camera
|
|
568
|
-
angles; the leaf is intentionally always painted. Strip the UA's
|
|
569
|
-
default ::before/::after open-/close-quote so the element is just a
|
|
570
|
-
styled box. */
|
|
628
|
+
/* Reserved internal <q> shadow element rules. Current shadow emission uses SVG
|
|
629
|
+
surfaces; these rules keep any retained <q> markup styled as a plain
|
|
630
|
+
border-shape leaf instead of inheriting UA quote styling. */
|
|
571
631
|
.polycss-scene q {
|
|
572
632
|
position: absolute;
|
|
573
633
|
display: block;
|
|
@@ -590,11 +650,12 @@ var CORE_BASE_STYLES = `
|
|
|
590
650
|
content: none;
|
|
591
651
|
}
|
|
592
652
|
|
|
593
|
-
/* \u2500\u2500
|
|
653
|
+
/* \u2500\u2500 Retained <q> shadow projection (dynamic-mode CSS path) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
594
654
|
|
|
595
655
|
/*
|
|
596
|
-
*
|
|
597
|
-
* ground plane (cssZ \u2248 G) along the CSS-space
|
|
656
|
+
* Projection matrix for retained internal <q> shadow leaves. Projects any
|
|
657
|
+
* 3D point P onto the horizontal ground plane (cssZ \u2248 G) along the CSS-space
|
|
658
|
+
* light direction (--clx/y/z).
|
|
598
659
|
*
|
|
599
660
|
* In PolyCSS's world convention world Z is up (red-green plane is the
|
|
600
661
|
* floor in the axes helper). After the world\u2192CSS swap (Y\u2194X), world Z stays
|
|
@@ -607,7 +668,7 @@ var CORE_BASE_STYLES = `
|
|
|
607
668
|
* has a valid layout box. The fix: collapse along z by a near-zero
|
|
608
669
|
* scale (Z_SQUASH = 0.01) instead of exactly zero \u2014 output.z is then
|
|
609
670
|
* approximately G with ~1% drift from the input, full-rank and renderable.
|
|
610
|
-
* The
|
|
671
|
+
* The result still looks flat to the eye (the drift is sub-pixel for
|
|
611
672
|
* any realistic scene size).
|
|
612
673
|
*
|
|
613
674
|
* out.cssX = P.cssX - (--clx/--clz) * (P.cssZ - G)
|
|
@@ -635,17 +696,9 @@ var CORE_BASE_STYLES = `
|
|
|
635
696
|
);
|
|
636
697
|
}
|
|
637
698
|
|
|
638
|
-
/* <q>
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
* 10 multiplier sharpens the cutoff so small positive Lambert values
|
|
642
|
-
jump quickly to 1, giving a near-binary visibility decision with a
|
|
643
|
-
smooth edge transition. Pure CSS calc \u2014 no JS at light-change time.
|
|
644
|
-
|
|
645
|
-
Scoped to dynamic mode: baked-mode shadow leaves are dropped up-front
|
|
646
|
-
by isBakedShadowCaster() and don't carry --pnx/--pny/--pnz, so an
|
|
647
|
-
unscoped gate would silently zero them via the @property initial
|
|
648
|
-
values. */
|
|
699
|
+
/* Retained <q> opacity gate. Polygons facing the light cast full shadow;
|
|
700
|
+
polygons facing away cast zero shadow. The * 10 multiplier sharpens the
|
|
701
|
+
cutoff so small positive Lambert values jump quickly to 1. */
|
|
649
702
|
.polycss-scene[data-polycss-lighting="dynamic"] q {
|
|
650
703
|
opacity: clamp(0, calc((var(--pnx) * var(--clx) + var(--pny) * var(--cly) + var(--pnz) * var(--clz)) * 10), 1);
|
|
651
704
|
}
|
|
@@ -681,6 +734,7 @@ function borderShapeSupported(doc) {
|
|
|
681
734
|
return media("(pointer: fine)").matches && media("(hover: hover)").matches;
|
|
682
735
|
}
|
|
683
736
|
function solidTriangleSupported(doc) {
|
|
737
|
+
if (cornerTriangleSupported(doc)) return true;
|
|
684
738
|
const win = doc.defaultView ?? (typeof window !== "undefined" ? window : void 0);
|
|
685
739
|
const userAgent = win?.navigator?.userAgent ?? "";
|
|
686
740
|
if (!userAgent) return true;
|
|
@@ -690,6 +744,10 @@ function cornerShapeSupported(doc) {
|
|
|
690
744
|
const css = doc.defaultView?.CSS ?? (typeof CSS !== "undefined" ? CSS : void 0);
|
|
691
745
|
return !!css?.supports?.("corner-top-left-shape", "bevel") && !!css.supports("corner-top-right-shape", "bevel") && !!css.supports("corner-bottom-right-shape", "bevel") && !!css.supports("corner-bottom-left-shape", "bevel");
|
|
692
746
|
}
|
|
747
|
+
function cornerTriangleSupported(doc) {
|
|
748
|
+
const css = doc.defaultView?.CSS ?? (typeof CSS !== "undefined" ? CSS : void 0);
|
|
749
|
+
return !!css?.supports?.("corner-top-left-shape", "bevel") && !!css.supports("corner-top-right-shape", "bevel");
|
|
750
|
+
}
|
|
693
751
|
function projectiveQuadSupported(doc) {
|
|
694
752
|
const win = doc.defaultView ?? (typeof window !== "undefined" ? window : void 0);
|
|
695
753
|
const userAgent = win?.navigator?.userAgent ?? "";
|
|
@@ -734,6 +792,8 @@ function isBorderShapeSupported(doc) {
|
|
|
734
792
|
function isSolidTriangleSupported(doc) {
|
|
735
793
|
const d = doc ?? (typeof document !== "undefined" ? document : null);
|
|
736
794
|
if (!d) {
|
|
795
|
+
const css = typeof CSS !== "undefined" ? CSS : void 0;
|
|
796
|
+
if (!!css?.supports?.("corner-top-left-shape", "bevel") && !!css.supports("corner-top-right-shape", "bevel")) return true;
|
|
737
797
|
const userAgent = (typeof navigator !== "undefined" ? navigator : globalThis.navigator)?.userAgent ?? "";
|
|
738
798
|
if (!userAgent) return true;
|
|
739
799
|
const isChromiumFamily = /\b(?:Chrome|HeadlessChrome|Chromium|Edg|OPR)\//.test(userAgent);
|
|
@@ -748,9 +808,12 @@ import {
|
|
|
748
808
|
filterAtlasPlans as filterAtlasPlansCore
|
|
749
809
|
} from "@layoutit/polycss-core";
|
|
750
810
|
function filterAtlasPlans(plans, textureLighting, disabled, doc) {
|
|
811
|
+
const d = doc ?? (typeof document !== "undefined" ? document : null);
|
|
751
812
|
return filterAtlasPlansCore(plans, textureLighting, disabled, {
|
|
752
813
|
solidTriangleSupported: isSolidTriangleSupported(doc),
|
|
753
|
-
|
|
814
|
+
projectiveQuadSupported: doc ? projectiveQuadSupported(doc) : true,
|
|
815
|
+
borderShapeSupported: isBorderShapeSupported(doc),
|
|
816
|
+
cornerShapeSupported: d ? cornerShapeSupported(d) : false
|
|
754
817
|
});
|
|
755
818
|
}
|
|
756
819
|
|
|
@@ -772,7 +835,6 @@ function packTextureAtlasPlansWithScale(plans, textureQualityInput, doc) {
|
|
|
772
835
|
// src/scene/atlas/buildAtlasPages.ts
|
|
773
836
|
import {
|
|
774
837
|
expandClipPoints,
|
|
775
|
-
tintToCss,
|
|
776
838
|
TEXTURE_TRIANGLE_BLEED,
|
|
777
839
|
TEXTURE_EDGE_REPAIR_ALPHA_MIN,
|
|
778
840
|
TEXTURE_EDGE_REPAIR_SOURCE_ALPHA_MIN,
|
|
@@ -812,16 +874,29 @@ function setCssTransform(ctx, atlasScale, a = 1, b = 0, c = 0, d = 1, e = 0, f =
|
|
|
812
874
|
f * atlasScale
|
|
813
875
|
);
|
|
814
876
|
}
|
|
877
|
+
function srgbByteToLinear(c) {
|
|
878
|
+
const u = c / 255;
|
|
879
|
+
return u <= 0.04045 ? u / 12.92 : Math.pow((u + 0.055) / 1.055, 2.4);
|
|
880
|
+
}
|
|
881
|
+
function linearToSrgbByte(c) {
|
|
882
|
+
const s = c <= 31308e-7 ? c * 12.92 : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
883
|
+
return Math.max(0, Math.min(255, Math.round(s * 255)));
|
|
884
|
+
}
|
|
815
885
|
function applyTextureTint(ctx, x, y, width, height, tint, atlasScale) {
|
|
816
|
-
|
|
817
|
-
|
|
886
|
+
const px = Math.round(x * atlasScale);
|
|
887
|
+
const py = Math.round(y * atlasScale);
|
|
888
|
+
const pw = Math.max(1, Math.round(width * atlasScale));
|
|
889
|
+
const ph = Math.max(1, Math.round(height * atlasScale));
|
|
890
|
+
const img = ctx.getImageData(px, py, pw, ph);
|
|
891
|
+
const data = img.data;
|
|
892
|
+
const tr = tint.r, tg = tint.g, tb = tint.b;
|
|
893
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
894
|
+
if (data[i + 3] === 0) continue;
|
|
895
|
+
data[i] = linearToSrgbByte(srgbByteToLinear(data[i]) * tr);
|
|
896
|
+
data[i + 1] = linearToSrgbByte(srgbByteToLinear(data[i + 1]) * tg);
|
|
897
|
+
data[i + 2] = linearToSrgbByte(srgbByteToLinear(data[i + 2]) * tb);
|
|
818
898
|
}
|
|
819
|
-
ctx.
|
|
820
|
-
setCssTransform(ctx, atlasScale);
|
|
821
|
-
ctx.globalCompositeOperation = "multiply";
|
|
822
|
-
ctx.fillStyle = tintToCss(tint);
|
|
823
|
-
ctx.fillRect(x, y, width, height);
|
|
824
|
-
ctx.restore();
|
|
899
|
+
ctx.putImageData(img, px, py);
|
|
825
900
|
}
|
|
826
901
|
function drawImageCover(ctx, img, x, y, width, height, atlasScale) {
|
|
827
902
|
const srcW = img.naturalWidth || img.width || 1;
|
|
@@ -1235,6 +1310,15 @@ var SOLID_TRIANGLE_LARGE_BORDER_CANONICAL_SIZE = 96;
|
|
|
1235
1310
|
var SOLID_TRIANGLE_LARGE_BORDER_WIDTH = "0 48px 96px 48px";
|
|
1236
1311
|
var cachedSolidTriangleUserAgent;
|
|
1237
1312
|
var cachedSolidTriangleCanonicalSize = SOLID_TRIANGLE_CANONICAL_SIZE;
|
|
1313
|
+
function cornerTriangleSupported2() {
|
|
1314
|
+
const css = typeof CSS !== "undefined" ? CSS : void 0;
|
|
1315
|
+
return !!css?.supports?.("corner-top-left-shape", "bevel") && !!css.supports("corner-top-right-shape", "bevel");
|
|
1316
|
+
}
|
|
1317
|
+
function solidTrianglePrimitive() {
|
|
1318
|
+
if (cornerTriangleSupported2()) return "corner-bevel";
|
|
1319
|
+
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
1320
|
+
return /\bFirefox\//.test(ua) ? "border-large" : "border";
|
|
1321
|
+
}
|
|
1238
1322
|
function solidTriangleCanonicalSize() {
|
|
1239
1323
|
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
1240
1324
|
if (ua !== cachedSolidTriangleUserAgent) {
|
|
@@ -1244,7 +1328,35 @@ function solidTriangleCanonicalSize() {
|
|
|
1244
1328
|
return cachedSolidTriangleCanonicalSize;
|
|
1245
1329
|
}
|
|
1246
1330
|
function solidTriangleBorderWidth() {
|
|
1247
|
-
return
|
|
1331
|
+
return solidTrianglePrimitive() === "border-large" ? SOLID_TRIANGLE_LARGE_BORDER_WIDTH : void 0;
|
|
1332
|
+
}
|
|
1333
|
+
function solidTrianglePaintStyle() {
|
|
1334
|
+
const primitive = solidTrianglePrimitive();
|
|
1335
|
+
if (primitive === "corner-bevel") return void 0;
|
|
1336
|
+
const borderWidth = primitive === "border-large" ? SOLID_TRIANGLE_LARGE_BORDER_WIDTH : void 0;
|
|
1337
|
+
return borderWidth ? { borderWidth } : void 0;
|
|
1338
|
+
}
|
|
1339
|
+
function applySolidTrianglePaintStyle(el) {
|
|
1340
|
+
const primitive = solidTrianglePrimitive();
|
|
1341
|
+
if (primitive === "corner-bevel") {
|
|
1342
|
+
el.style.width = "";
|
|
1343
|
+
el.style.height = "";
|
|
1344
|
+
el.style.backgroundColor = "";
|
|
1345
|
+
el.style.borderWidth = "";
|
|
1346
|
+
el.style.borderTopLeftRadius = "";
|
|
1347
|
+
el.style.borderTopRightRadius = "";
|
|
1348
|
+
el.style.removeProperty("corner-top-left-shape");
|
|
1349
|
+
el.style.removeProperty("corner-top-right-shape");
|
|
1350
|
+
} else {
|
|
1351
|
+
el.style.width = "";
|
|
1352
|
+
el.style.height = "";
|
|
1353
|
+
el.style.backgroundColor = "";
|
|
1354
|
+
el.style.borderTopLeftRadius = "";
|
|
1355
|
+
el.style.borderTopRightRadius = "";
|
|
1356
|
+
el.style.removeProperty("corner-top-left-shape");
|
|
1357
|
+
el.style.removeProperty("corner-top-right-shape");
|
|
1358
|
+
el.style.borderWidth = primitive === "border-large" ? SOLID_TRIANGLE_LARGE_BORDER_WIDTH : "";
|
|
1359
|
+
}
|
|
1248
1360
|
}
|
|
1249
1361
|
function parseHex2(hex) {
|
|
1250
1362
|
const parsed = parsePureColor(hex);
|
|
@@ -1659,9 +1771,10 @@ function solidTriangleStyle(entry, textureLighting, pointerEvents, solidPaintDef
|
|
|
1659
1771
|
txCol[2],
|
|
1660
1772
|
1
|
|
1661
1773
|
].map((v) => (Math.round(v * 1e3) / 1e3 || 0).toString()).join(",");
|
|
1774
|
+
const primitiveStyle = solidTrianglePaintStyle();
|
|
1662
1775
|
return {
|
|
1663
1776
|
transform: `matrix3d(${canonicalMatrix})`,
|
|
1664
|
-
|
|
1777
|
+
...primitiveStyle ?? {},
|
|
1665
1778
|
...sharedStyle
|
|
1666
1779
|
};
|
|
1667
1780
|
}
|
|
@@ -1890,6 +2003,7 @@ function updateStableTriangleDom(root, polygons, options = {}) {
|
|
|
1890
2003
|
const el = leaves[i];
|
|
1891
2004
|
if (el.style.visibility) el.style.visibility = "";
|
|
1892
2005
|
el.__polycssStableTriangleBasis = style.basis;
|
|
2006
|
+
applySolidTrianglePaintStyle(el);
|
|
1893
2007
|
el.style.transform = style.transform;
|
|
1894
2008
|
if (style.borderWidth !== void 0) el.style.borderWidth = style.borderWidth;
|
|
1895
2009
|
if (style.color !== void 0) applyStableTriangleColor(el, i, style.color, options);
|
|
@@ -1899,8 +2013,8 @@ function updateStableTriangleDom(root, polygons, options = {}) {
|
|
|
1899
2013
|
|
|
1900
2014
|
// src/scene/atlas/paintDefaults.ts
|
|
1901
2015
|
import { computeTextureAtlasPlanPublic } from "@layoutit/polycss-core";
|
|
1902
|
-
function computeTextureAtlasPlan(polygon, index, options = {}) {
|
|
1903
|
-
return computeTextureAtlasPlanPublic(polygon, index, options);
|
|
2016
|
+
function computeTextureAtlasPlan(polygon, index, options = {}, basisHint) {
|
|
2017
|
+
return computeTextureAtlasPlanPublic(polygon, index, options, void 0, basisHint);
|
|
1904
2018
|
}
|
|
1905
2019
|
function getSolidPaintDefaults(plans, textureLighting, strategies) {
|
|
1906
2020
|
const disabled = new Set(strategies?.disable ?? []);
|
|
@@ -1908,24 +2022,44 @@ function getSolidPaintDefaults(plans, textureLighting, strategies) {
|
|
|
1908
2022
|
}
|
|
1909
2023
|
|
|
1910
2024
|
// src/scene/atlas/useTextureAtlas.ts
|
|
1911
|
-
import { useEffect as useEffect2, useMemo as useMemo5, useState } from "react";
|
|
2025
|
+
import { useEffect as useEffect2, useMemo as useMemo5, useRef as useRef3, useState } from "react";
|
|
1912
2026
|
function pageShells(pages) {
|
|
1913
2027
|
return pages.map((page) => ({ width: page.width, height: page.height, url: null }));
|
|
1914
2028
|
}
|
|
1915
|
-
function
|
|
1916
|
-
return
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
2029
|
+
function blobUrlsOf(pages) {
|
|
2030
|
+
return pages.flatMap((page) => page.url?.startsWith("blob:") ? [page.url] : []);
|
|
2031
|
+
}
|
|
2032
|
+
function decodeBlobUrls(urls) {
|
|
2033
|
+
if (urls.length === 0 || typeof Image === "undefined") return Promise.resolve();
|
|
2034
|
+
return Promise.all(urls.map((url) => {
|
|
2035
|
+
const img = new Image();
|
|
2036
|
+
img.src = url;
|
|
2037
|
+
const decoded = img.decode?.();
|
|
2038
|
+
return decoded ? decoded.catch(() => {
|
|
2039
|
+
}) : Promise.resolve();
|
|
2040
|
+
})).then(() => void 0);
|
|
2041
|
+
}
|
|
2042
|
+
function deferRevoke(urls) {
|
|
2043
|
+
if (urls.length === 0) return;
|
|
2044
|
+
const run = () => {
|
|
2045
|
+
for (const url of urls) URL.revokeObjectURL(url);
|
|
2046
|
+
};
|
|
2047
|
+
if (typeof requestAnimationFrame === "function") requestAnimationFrame(run);
|
|
2048
|
+
else setTimeout(run, 0);
|
|
1920
2049
|
}
|
|
1921
|
-
function useTextureAtlas(plans, textureLighting, textureQualityInput, strategies) {
|
|
2050
|
+
function useTextureAtlas(plans, textureLighting, textureQualityInput, strategies, atomic = false) {
|
|
1922
2051
|
const disabled = useMemo5(
|
|
1923
2052
|
() => new Set(strategies?.disable ?? []),
|
|
1924
2053
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1925
2054
|
[strategies?.disable?.join(",")]
|
|
1926
2055
|
);
|
|
1927
2056
|
const atlasPlans = useMemo5(
|
|
1928
|
-
() => filterAtlasPlans(
|
|
2057
|
+
() => filterAtlasPlans(
|
|
2058
|
+
plans,
|
|
2059
|
+
textureLighting,
|
|
2060
|
+
disabled,
|
|
2061
|
+
typeof document !== "undefined" ? document : null
|
|
2062
|
+
),
|
|
1929
2063
|
[plans, textureLighting, disabled]
|
|
1930
2064
|
);
|
|
1931
2065
|
const { packed, atlasScale } = useMemo5(
|
|
@@ -1936,38 +2070,93 @@ function useTextureAtlas(plans, textureLighting, textureQualityInput, strategies
|
|
|
1936
2070
|
),
|
|
1937
2071
|
[atlasPlans, textureQualityInput]
|
|
1938
2072
|
);
|
|
1939
|
-
const [pages, setPages] = useState(
|
|
1940
|
-
|
|
1941
|
-
|
|
2073
|
+
const [pages, setPages] = useState(() => pageShells(packed.pages));
|
|
2074
|
+
const [frame, setFrame] = useState(() => ({
|
|
2075
|
+
plans,
|
|
2076
|
+
entries: packed.entries,
|
|
2077
|
+
pages: pageShells(packed.pages)
|
|
2078
|
+
}));
|
|
2079
|
+
const shownUrls = useRef3([]);
|
|
2080
|
+
const seqRef = useRef3(0);
|
|
2081
|
+
const mountedRef = useRef3(true);
|
|
1942
2082
|
useEffect2(() => {
|
|
2083
|
+
mountedRef.current = true;
|
|
2084
|
+
return () => {
|
|
2085
|
+
mountedRef.current = false;
|
|
2086
|
+
for (const url of shownUrls.current) URL.revokeObjectURL(url);
|
|
2087
|
+
shownUrls.current = [];
|
|
2088
|
+
};
|
|
2089
|
+
}, []);
|
|
2090
|
+
useEffect2(() => {
|
|
2091
|
+
if (atomic) {
|
|
2092
|
+
const seq = ++seqRef.current;
|
|
2093
|
+
const snapPlans = plans;
|
|
2094
|
+
const snapEntries = packed.entries;
|
|
2095
|
+
if (packed.pages.length === 0 || typeof document === "undefined") {
|
|
2096
|
+
deferRevoke(shownUrls.current);
|
|
2097
|
+
shownUrls.current = [];
|
|
2098
|
+
setFrame({ plans: snapPlans, entries: snapEntries, pages: pageShells(packed.pages) });
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
const stale = () => seq !== seqRef.current;
|
|
2102
|
+
let built2 = [];
|
|
2103
|
+
buildAtlasPages(packed.pages, textureLighting, document, atlasScale, stale).then(async (nextPages) => {
|
|
2104
|
+
built2 = blobUrlsOf(nextPages);
|
|
2105
|
+
await decodeBlobUrls(built2);
|
|
2106
|
+
if (!mountedRef.current || stale()) {
|
|
2107
|
+
deferRevoke(built2);
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
2110
|
+
const prev = shownUrls.current;
|
|
2111
|
+
shownUrls.current = built2;
|
|
2112
|
+
built2 = [];
|
|
2113
|
+
deferRevoke(prev);
|
|
2114
|
+
setFrame({ plans: snapPlans, entries: snapEntries, pages: nextPages });
|
|
2115
|
+
}).catch(() => {
|
|
2116
|
+
});
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
1943
2119
|
let cancelled = false;
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
2120
|
+
if (packed.pages.length === 0) {
|
|
2121
|
+
deferRevoke(shownUrls.current);
|
|
2122
|
+
shownUrls.current = [];
|
|
2123
|
+
setPages((prev) => prev.length === 0 ? prev : []);
|
|
1948
2124
|
return () => {
|
|
1949
2125
|
};
|
|
1950
2126
|
}
|
|
1951
|
-
|
|
2127
|
+
if (typeof document === "undefined") return () => {
|
|
2128
|
+
};
|
|
2129
|
+
setPages((prev) => prev.some((page) => page.url) ? prev : pageShells(packed.pages));
|
|
2130
|
+
let built = [];
|
|
2131
|
+
buildAtlasPages(packed.pages, textureLighting, document, atlasScale, () => cancelled).then(async (nextPages) => {
|
|
2132
|
+
built = blobUrlsOf(nextPages);
|
|
2133
|
+
await decodeBlobUrls(built);
|
|
1952
2134
|
if (cancelled) {
|
|
1953
|
-
|
|
1954
|
-
if (page.url?.startsWith("blob:")) URL.revokeObjectURL(page.url);
|
|
1955
|
-
}
|
|
2135
|
+
deferRevoke(built);
|
|
1956
2136
|
return;
|
|
1957
2137
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
2138
|
+
const stale = shownUrls.current;
|
|
2139
|
+
shownUrls.current = built;
|
|
2140
|
+
built = [];
|
|
2141
|
+
deferRevoke(stale);
|
|
2142
|
+
setPages(nextPages);
|
|
1960
2143
|
}).catch(() => {
|
|
1961
|
-
if (!cancelled) {
|
|
1962
|
-
setPages((prev) => textureAtlasPagesEqual(prev, nextPageShells) ? prev : nextPageShells);
|
|
1963
|
-
}
|
|
1964
2144
|
});
|
|
1965
2145
|
return () => {
|
|
1966
2146
|
cancelled = true;
|
|
1967
|
-
|
|
2147
|
+
deferRevoke(built);
|
|
2148
|
+
};
|
|
2149
|
+
}, [packed, textureLighting, atlasScale, atomic]);
|
|
2150
|
+
if (atomic) {
|
|
2151
|
+
return {
|
|
2152
|
+
plans: frame.plans,
|
|
2153
|
+
entries: frame.entries,
|
|
2154
|
+
pages: frame.pages,
|
|
2155
|
+
ready: frame.pages.length === 0 || frame.pages.every((page) => !!page.url)
|
|
1968
2156
|
};
|
|
1969
|
-
}
|
|
2157
|
+
}
|
|
1970
2158
|
return {
|
|
2159
|
+
plans,
|
|
1971
2160
|
entries: packed.entries,
|
|
1972
2161
|
pages,
|
|
1973
2162
|
ready: pages.length === 0 || pages.every((page) => !!page.url)
|
|
@@ -1998,6 +2187,7 @@ var TextureTrianglePoly = memo3(function TextureTrianglePoly2({
|
|
|
1998
2187
|
{
|
|
1999
2188
|
className: elementClassName,
|
|
2000
2189
|
style: { ...triangleStyle, ...styleProp },
|
|
2190
|
+
"data-poly-index": entry.index,
|
|
2001
2191
|
...domEventHandlers,
|
|
2002
2192
|
...dataAttrs,
|
|
2003
2193
|
...domAttrs
|
|
@@ -2034,6 +2224,7 @@ function orderBrushInlineStyle(el) {
|
|
|
2034
2224
|
}
|
|
2035
2225
|
var TextureBorderShapePoly = memo4(function TextureBorderShapePoly2({
|
|
2036
2226
|
entry,
|
|
2227
|
+
textureLighting,
|
|
2037
2228
|
solidPaintDefaults,
|
|
2038
2229
|
className,
|
|
2039
2230
|
style: styleProp,
|
|
@@ -2046,7 +2237,9 @@ var TextureBorderShapePoly = memo4(function TextureBorderShapePoly2({
|
|
|
2046
2237
|
const bDisabled = disabledStrategies?.has("b") ?? false;
|
|
2047
2238
|
const useIForFullRect = bDisabled && isBorderShapeSupported();
|
|
2048
2239
|
const borderShape = !fullRect || useIForFullRect ? cssBorderShapeForPlan(entry) : null;
|
|
2049
|
-
const
|
|
2240
|
+
const dynamic = textureLighting === "dynamic";
|
|
2241
|
+
const base = parseHex2(entry.polygon.color ?? "#cccccc");
|
|
2242
|
+
const useDefaultDynamicColor = dynamic && rgbKey2(base) === solidPaintDefaults?.dynamicColorKey;
|
|
2050
2243
|
const setElementRef = useCallback3((el) => {
|
|
2051
2244
|
if (!el) return;
|
|
2052
2245
|
if (borderShape) el.style.setProperty("border-shape", borderShape);
|
|
@@ -2056,8 +2249,25 @@ var TextureBorderShapePoly = memo4(function TextureBorderShapePoly2({
|
|
|
2056
2249
|
const transform = borderShape ? formatBorderShapeEntryMatrix(entry) : formatSolidQuadEntryMatrix(entry);
|
|
2057
2250
|
const style = {
|
|
2058
2251
|
transform,
|
|
2059
|
-
|
|
2252
|
+
// Baked mode: always emit per-leaf shaded color when known so the
|
|
2253
|
+
// first render matches the post-light-nudge commit path. Vanilla
|
|
2254
|
+
// dropped the `=== solidPaintDefaults.paintColor` shortcut in
|
|
2255
|
+
// commit 0423777 — leaves with undefined shadedColor would inherit
|
|
2256
|
+
// the (often-wrong) wrapper --polycss-paint default, producing
|
|
2257
|
+
// facets that look dimmer than they should until a light change
|
|
2258
|
+
// forced an explicit re-bake.
|
|
2259
|
+
color: dynamic ? void 0 : entry.shadedColor,
|
|
2060
2260
|
pointerEvents: pointerEvents === "none" ? "none" : void 0,
|
|
2261
|
+
...dynamic ? {
|
|
2262
|
+
["--pnx"]: entry.normal[0].toFixed(4),
|
|
2263
|
+
["--pny"]: entry.normal[1].toFixed(4),
|
|
2264
|
+
["--pnz"]: entry.normal[2].toFixed(4),
|
|
2265
|
+
...useDefaultDynamicColor ? null : {
|
|
2266
|
+
["--psr"]: (base.r / 255).toFixed(4),
|
|
2267
|
+
["--psg"]: (base.g / 255).toFixed(4),
|
|
2268
|
+
["--psb"]: (base.b / 255).toFixed(4)
|
|
2269
|
+
}
|
|
2270
|
+
} : null,
|
|
2061
2271
|
...styleProp
|
|
2062
2272
|
};
|
|
2063
2273
|
const dataAttrs = entry.polygon.data ? Object.fromEntries(
|
|
@@ -2070,6 +2280,7 @@ var TextureBorderShapePoly = memo4(function TextureBorderShapePoly2({
|
|
|
2070
2280
|
{
|
|
2071
2281
|
className: elementClassName,
|
|
2072
2282
|
style,
|
|
2283
|
+
"data-poly-index": entry.index,
|
|
2073
2284
|
...domEventHandlers,
|
|
2074
2285
|
...dataAttrs,
|
|
2075
2286
|
...domAttrs
|
|
@@ -2082,6 +2293,7 @@ var TextureBorderShapePoly = memo4(function TextureBorderShapePoly2({
|
|
|
2082
2293
|
ref: setElementRef,
|
|
2083
2294
|
className: elementClassName,
|
|
2084
2295
|
style,
|
|
2296
|
+
"data-poly-index": entry.index,
|
|
2085
2297
|
...domEventHandlers,
|
|
2086
2298
|
...dataAttrs,
|
|
2087
2299
|
...domAttrs
|
|
@@ -2111,7 +2323,8 @@ var TextureProjectiveSolidPoly = memo5(function TextureProjectiveSolidPoly2({
|
|
|
2111
2323
|
// would drop it to 3 decimals and leave visible seam gaps between
|
|
2112
2324
|
// adjacent projective quads at zoom-out (matches vanilla scene.add).
|
|
2113
2325
|
transform: `matrix3d(${entry.projectiveMatrix})`,
|
|
2114
|
-
|
|
2326
|
+
// Baked: always emit per-leaf shaded color (vanilla commit 0423777).
|
|
2327
|
+
color: dynamic ? void 0 : entry.shadedColor,
|
|
2115
2328
|
pointerEvents: pointerEvents === "none" ? "none" : void 0,
|
|
2116
2329
|
...dynamic && !useDefaultDynamicColor ? {
|
|
2117
2330
|
["--pnx"]: entry.normal[0].toFixed(4),
|
|
@@ -2136,6 +2349,69 @@ var TextureProjectiveSolidPoly = memo5(function TextureProjectiveSolidPoly2({
|
|
|
2136
2349
|
{
|
|
2137
2350
|
className: elementClassName,
|
|
2138
2351
|
style,
|
|
2352
|
+
"data-poly-index": entry.index,
|
|
2353
|
+
...domEventHandlers,
|
|
2354
|
+
...dataAttrs,
|
|
2355
|
+
...domAttrs
|
|
2356
|
+
}
|
|
2357
|
+
);
|
|
2358
|
+
});
|
|
2359
|
+
|
|
2360
|
+
// src/scene/atlas/cornerShapeSolid.tsx
|
|
2361
|
+
import { memo as memo6, useCallback as useCallback4 } from "react";
|
|
2362
|
+
import {
|
|
2363
|
+
formatCornerShapeElementStyle,
|
|
2364
|
+
parseHex as parseHex3,
|
|
2365
|
+
rgbKey as rgbKey4
|
|
2366
|
+
} from "@layoutit/polycss-core";
|
|
2367
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2368
|
+
function formatPaintCss(entry, textureLighting, solidPaintDefaults) {
|
|
2369
|
+
if (textureLighting === "dynamic") {
|
|
2370
|
+
const base = parseHex3(entry.polygon.color ?? "#cccccc");
|
|
2371
|
+
let style = `;--pnx:${entry.normal[0].toFixed(4)};--pny:${entry.normal[1].toFixed(4)};--pnz:${entry.normal[2].toFixed(4)}`;
|
|
2372
|
+
if (rgbKey4(base) !== solidPaintDefaults?.dynamicColorKey) {
|
|
2373
|
+
style += `;--psr:${(base.r / 255).toFixed(4)};--psg:${(base.g / 255).toFixed(4)};--psb:${(base.b / 255).toFixed(4)}`;
|
|
2374
|
+
}
|
|
2375
|
+
return style;
|
|
2376
|
+
}
|
|
2377
|
+
return entry.shadedColor ? `;color:${entry.shadedColor}` : "";
|
|
2378
|
+
}
|
|
2379
|
+
var TextureCornerShapeSolidPoly = memo6(function TextureCornerShapeSolidPoly2({
|
|
2380
|
+
entry,
|
|
2381
|
+
geometry,
|
|
2382
|
+
textureLighting,
|
|
2383
|
+
solidPaintDefaults,
|
|
2384
|
+
className,
|
|
2385
|
+
style: styleProp,
|
|
2386
|
+
domAttrs,
|
|
2387
|
+
domEventHandlers,
|
|
2388
|
+
pointerEvents = "auto"
|
|
2389
|
+
}) {
|
|
2390
|
+
const cornerShapeCss = formatCornerShapeElementStyle(entry, geometry);
|
|
2391
|
+
const paintCss = formatPaintCss(entry, textureLighting, solidPaintDefaults);
|
|
2392
|
+
const pointerCss = pointerEvents === "none" ? ";pointer-events:none" : "";
|
|
2393
|
+
const fullCss = cornerShapeCss + paintCss + pointerCss;
|
|
2394
|
+
const setRef = useCallback4((el) => {
|
|
2395
|
+
if (!el) return;
|
|
2396
|
+
el.setAttribute("style", fullCss);
|
|
2397
|
+
if (styleProp) {
|
|
2398
|
+
for (const [k, v] of Object.entries(styleProp)) {
|
|
2399
|
+
if (v === void 0 || v === null) continue;
|
|
2400
|
+
if (k.startsWith("--")) el.style.setProperty(k, String(v));
|
|
2401
|
+
else el.style[k] = String(v);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
}, [fullCss, styleProp]);
|
|
2405
|
+
const dataAttrs = entry.polygon.data ? Object.fromEntries(
|
|
2406
|
+
Object.entries(entry.polygon.data).map(([k, v]) => [`data-${k}`, String(v)])
|
|
2407
|
+
) : {};
|
|
2408
|
+
const elementClassName = className?.trim() || void 0;
|
|
2409
|
+
return /* @__PURE__ */ jsx6(
|
|
2410
|
+
"u",
|
|
2411
|
+
{
|
|
2412
|
+
ref: setRef,
|
|
2413
|
+
className: elementClassName,
|
|
2414
|
+
"data-poly-index": entry.index,
|
|
2139
2415
|
...domEventHandlers,
|
|
2140
2416
|
...dataAttrs,
|
|
2141
2417
|
...domAttrs
|
|
@@ -2144,10 +2420,10 @@ var TextureProjectiveSolidPoly = memo5(function TextureProjectiveSolidPoly2({
|
|
|
2144
2420
|
});
|
|
2145
2421
|
|
|
2146
2422
|
// src/scene/atlas/atlasPoly.tsx
|
|
2147
|
-
import { memo as
|
|
2423
|
+
import { memo as memo7 } from "react";
|
|
2148
2424
|
import { formatMatrix3d, formatCssLengthPx } from "@layoutit/polycss-core";
|
|
2149
|
-
import { jsx as
|
|
2150
|
-
var TextureAtlasPoly =
|
|
2425
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2426
|
+
var TextureAtlasPoly = memo7(function TextureAtlasPoly2({
|
|
2151
2427
|
entry,
|
|
2152
2428
|
page,
|
|
2153
2429
|
textureLighting,
|
|
@@ -2170,10 +2446,16 @@ var TextureAtlasPoly = memo6(function TextureAtlasPoly2({
|
|
|
2170
2446
|
const style = {
|
|
2171
2447
|
transform: formatMatrix3d(entry.atlasMatrix),
|
|
2172
2448
|
["--polycss-atlas-size"]: `${atlasCanonicalSize}px`,
|
|
2173
|
-
background
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2449
|
+
// Listing the `background` shorthand alongside the `background-*` longhands
|
|
2450
|
+
// in one inline style object makes React warn on every update (mixing
|
|
2451
|
+
// shorthand and non-shorthand for the same property). Branch so only the
|
|
2452
|
+
// current mode's keys are assigned — baked gets `background`, dynamic gets
|
|
2453
|
+
// the longhands.
|
|
2454
|
+
...dynamic ? {
|
|
2455
|
+
backgroundImage: page?.url ? `url(${page.url})` : void 0,
|
|
2456
|
+
backgroundPosition: atlasPosition,
|
|
2457
|
+
backgroundSize: atlasSize
|
|
2458
|
+
} : { background },
|
|
2177
2459
|
...dynamic ? {
|
|
2178
2460
|
["--pnx"]: entry.normal[0].toFixed(4),
|
|
2179
2461
|
["--pny"]: entry.normal[1].toFixed(4),
|
|
@@ -2198,11 +2480,12 @@ var TextureAtlasPoly = memo6(function TextureAtlasPoly2({
|
|
|
2198
2480
|
Object.entries(entry.polygon.data).map(([k, v]) => [`data-${k}`, String(v)])
|
|
2199
2481
|
) : {};
|
|
2200
2482
|
const elementClassName = className?.trim() || void 0;
|
|
2201
|
-
return /* @__PURE__ */
|
|
2483
|
+
return /* @__PURE__ */ jsx7(
|
|
2202
2484
|
"s",
|
|
2203
2485
|
{
|
|
2204
2486
|
className: elementClassName,
|
|
2205
2487
|
style,
|
|
2488
|
+
"data-poly-index": entry.index,
|
|
2206
2489
|
...domEventHandlers,
|
|
2207
2490
|
...dataAttrs,
|
|
2208
2491
|
...domAttrs
|
|
@@ -2218,7 +2501,7 @@ function usePolySceneContext2() {
|
|
|
2218
2501
|
}
|
|
2219
2502
|
|
|
2220
2503
|
// src/scene/PolyScene.tsx
|
|
2221
|
-
import { jsx as
|
|
2504
|
+
import { jsx as jsx8, jsxs } from "react/jsx-runtime";
|
|
2222
2505
|
function PolySceneInner({
|
|
2223
2506
|
polygons: polygonsProp,
|
|
2224
2507
|
centerPolygons: centerPolygonsProp,
|
|
@@ -2244,9 +2527,11 @@ function PolySceneInner({
|
|
|
2244
2527
|
debugShowBackfaces
|
|
2245
2528
|
}) {
|
|
2246
2529
|
const { store, sceneElRef, applyTransformDirect } = useCameraContext();
|
|
2247
|
-
const
|
|
2530
|
+
const [sceneEl, setSceneEl] = useState2(null);
|
|
2531
|
+
const localSceneRef = useCallback5(
|
|
2248
2532
|
(el) => {
|
|
2249
2533
|
sceneElRef.current = el;
|
|
2534
|
+
setSceneEl(el);
|
|
2250
2535
|
},
|
|
2251
2536
|
[sceneElRef]
|
|
2252
2537
|
);
|
|
@@ -2255,7 +2540,7 @@ function PolySceneInner({
|
|
|
2255
2540
|
if (!el) return;
|
|
2256
2541
|
el.classList.toggle("polycss-debug-show-backfaces", !!debugShowBackfaces);
|
|
2257
2542
|
}, [debugShowBackfaces, sceneElRef]);
|
|
2258
|
-
const injectedRef =
|
|
2543
|
+
const injectedRef = useRef4(false);
|
|
2259
2544
|
useEffect3(() => {
|
|
2260
2545
|
if (injectedRef.current) return;
|
|
2261
2546
|
if (typeof document !== "undefined") {
|
|
@@ -2326,7 +2611,8 @@ function PolySceneInner({
|
|
|
2326
2611
|
const textureAtlas = useTextureAtlas(textureAtlasPlans, textureLighting, textureQuality, strategies);
|
|
2327
2612
|
const dynamicLightVars = useMemo6(() => {
|
|
2328
2613
|
if (textureLighting !== "dynamic") return null;
|
|
2329
|
-
const
|
|
2614
|
+
const userDir = directionalLight?.direction ?? [0.4, -0.7, 0.59];
|
|
2615
|
+
const dir = worldDirectionToCss(userDir);
|
|
2330
2616
|
const len = Math.hypot(dir[0], dir[1], dir[2]) || 1;
|
|
2331
2617
|
const lx = dir[0] / len, ly = dir[1] / len, lz = dir[2] / len;
|
|
2332
2618
|
const lightRgb = parseHexColor(directionalLight?.color ?? "#ffffff")?.rgb ?? [255, 255, 255];
|
|
@@ -2337,9 +2623,9 @@ function PolySceneInner({
|
|
|
2337
2623
|
const rawClz = lz;
|
|
2338
2624
|
const clz = Math.sign(rawClz || 1) * Math.max(Math.abs(rawClz), 0.01);
|
|
2339
2625
|
return {
|
|
2340
|
-
["--plx"]: lx.toFixed(
|
|
2341
|
-
["--ply"]: ly.toFixed(
|
|
2342
|
-
["--plz"]: lz.toFixed(
|
|
2626
|
+
["--plx"]: lx.toFixed(2),
|
|
2627
|
+
["--ply"]: ly.toFixed(2),
|
|
2628
|
+
["--plz"]: lz.toFixed(2),
|
|
2343
2629
|
["--plr"]: ch(lightRgb[0]),
|
|
2344
2630
|
["--plg"]: ch(lightRgb[1]),
|
|
2345
2631
|
["--plb"]: ch(lightRgb[2]),
|
|
@@ -2348,19 +2634,23 @@ function PolySceneInner({
|
|
|
2348
2634
|
["--pag"]: ch(ambRgb[1]),
|
|
2349
2635
|
["--pab"]: ch(ambRgb[2]),
|
|
2350
2636
|
["--pai"]: ambientIntensity.toFixed(4),
|
|
2351
|
-
["--clx"]: lx.toFixed(
|
|
2352
|
-
["--cly"]: ly.toFixed(
|
|
2353
|
-
["--clz"]: clz.toFixed(
|
|
2637
|
+
["--clx"]: lx.toFixed(2),
|
|
2638
|
+
["--cly"]: ly.toFixed(2),
|
|
2639
|
+
["--clz"]: clz.toFixed(2)
|
|
2354
2640
|
};
|
|
2355
2641
|
}, [textureLighting, directionalLight, ambientLight]);
|
|
2356
|
-
const shadowCastersRef =
|
|
2642
|
+
const shadowCastersRef = useRef4(/* @__PURE__ */ new Map());
|
|
2643
|
+
const shadowReceiversRef = useRef4(/* @__PURE__ */ new Set());
|
|
2357
2644
|
const [groundCssZ, setGroundCssZ] = useState2(null);
|
|
2358
|
-
const
|
|
2645
|
+
const [shadowCastersVersion, setShadowCastersVersion] = useState2(0);
|
|
2646
|
+
const [hasShadowReceiver, setHasShadowReceiver] = useState2(false);
|
|
2647
|
+
const recomputeGroundCssZ = useCallback5(() => {
|
|
2359
2648
|
let minWorldZ = Infinity;
|
|
2360
|
-
for (const
|
|
2361
|
-
for (const poly of
|
|
2649
|
+
for (const data of shadowCastersRef.current.values()) {
|
|
2650
|
+
for (const poly of data.polygons) {
|
|
2362
2651
|
for (const v of poly.vertices) {
|
|
2363
|
-
|
|
2652
|
+
const z = v[2] + (data.position[2] ?? 0);
|
|
2653
|
+
if (z < minWorldZ) minWorldZ = z;
|
|
2364
2654
|
}
|
|
2365
2655
|
}
|
|
2366
2656
|
}
|
|
@@ -2368,12 +2658,13 @@ function PolySceneInner({
|
|
|
2368
2658
|
const lift = shadow?.lift ?? 0.05;
|
|
2369
2659
|
return (minWorldZ + lift) * BASE_TILE2;
|
|
2370
2660
|
}, [shadow]);
|
|
2371
|
-
const registerShadowCaster =
|
|
2372
|
-
if (
|
|
2661
|
+
const registerShadowCaster = useCallback5((meshId, data) => {
|
|
2662
|
+
if (data === null) {
|
|
2373
2663
|
shadowCastersRef.current.delete(meshId);
|
|
2374
2664
|
} else {
|
|
2375
|
-
shadowCastersRef.current.set(meshId,
|
|
2665
|
+
shadowCastersRef.current.set(meshId, data);
|
|
2376
2666
|
}
|
|
2667
|
+
setShadowCastersVersion((v) => v + 1);
|
|
2377
2668
|
const next = recomputeGroundCssZ();
|
|
2378
2669
|
setGroundCssZ((prev) => prev === next ? prev : next);
|
|
2379
2670
|
const el = sceneElRef.current;
|
|
@@ -2384,6 +2675,11 @@ function PolySceneInner({
|
|
|
2384
2675
|
el.style.removeProperty("--shadow-ground-cssz");
|
|
2385
2676
|
}
|
|
2386
2677
|
}, [sceneElRef, textureLighting, recomputeGroundCssZ]);
|
|
2678
|
+
const registerShadowReceiver = useCallback5((meshId, registered) => {
|
|
2679
|
+
if (registered) shadowReceiversRef.current.add(meshId);
|
|
2680
|
+
else shadowReceiversRef.current.delete(meshId);
|
|
2681
|
+
setHasShadowReceiver(shadowReceiversRef.current.size > 0);
|
|
2682
|
+
}, []);
|
|
2387
2683
|
useEffect3(() => {
|
|
2388
2684
|
const el = sceneElRef.current;
|
|
2389
2685
|
if (!el) return;
|
|
@@ -2405,7 +2701,7 @@ function PolySceneInner({
|
|
|
2405
2701
|
);
|
|
2406
2702
|
const polyChildren = textureAtlas.entries.map((entry, index) => {
|
|
2407
2703
|
if (entry) {
|
|
2408
|
-
return /* @__PURE__ */
|
|
2704
|
+
return /* @__PURE__ */ jsx8(
|
|
2409
2705
|
TextureAtlasPoly,
|
|
2410
2706
|
{
|
|
2411
2707
|
entry,
|
|
@@ -2420,7 +2716,7 @@ function PolySceneInner({
|
|
|
2420
2716
|
const useU = !disabledStrategies?.has("u");
|
|
2421
2717
|
const useProjectiveSolid = !disabledStrategies?.has("b");
|
|
2422
2718
|
if (useU && isSolidTrianglePlan2(plan)) {
|
|
2423
|
-
return /* @__PURE__ */
|
|
2719
|
+
return /* @__PURE__ */ jsx8(
|
|
2424
2720
|
TextureTrianglePoly,
|
|
2425
2721
|
{
|
|
2426
2722
|
entry: plan,
|
|
@@ -2430,9 +2726,9 @@ function PolySceneInner({
|
|
|
2430
2726
|
);
|
|
2431
2727
|
}
|
|
2432
2728
|
if (useProjectiveSolid && isProjectiveQuadPlan(plan)) {
|
|
2433
|
-
return /* @__PURE__ */
|
|
2729
|
+
return /* @__PURE__ */ jsx8(TextureProjectiveSolidPoly, { entry: plan, textureLighting }, plan.index);
|
|
2434
2730
|
}
|
|
2435
|
-
return /* @__PURE__ */
|
|
2731
|
+
return /* @__PURE__ */ jsx8(TextureBorderShapePoly, { entry: plan, textureLighting, disabledStrategies }, plan.index);
|
|
2436
2732
|
});
|
|
2437
2733
|
const sceneCtxValue = useMemo6(
|
|
2438
2734
|
() => ({
|
|
@@ -2443,11 +2739,16 @@ function PolySceneInner({
|
|
|
2443
2739
|
seamBleed,
|
|
2444
2740
|
shadow,
|
|
2445
2741
|
registerShadowCaster,
|
|
2446
|
-
|
|
2742
|
+
registerShadowReceiver,
|
|
2743
|
+
shadowCasters: shadowCastersRef.current,
|
|
2744
|
+
shadowCastersVersion,
|
|
2745
|
+
hasShadowReceiver,
|
|
2746
|
+
groundCssZ,
|
|
2747
|
+
sceneEl
|
|
2447
2748
|
}),
|
|
2448
|
-
[textureLighting, directionalLight, ambientLight, strategies, seamBleed, shadow, registerShadowCaster, groundCssZ]
|
|
2749
|
+
[textureLighting, directionalLight, ambientLight, strategies, seamBleed, shadow, registerShadowCaster, registerShadowReceiver, shadowCastersVersion, hasShadowReceiver, groundCssZ, sceneEl]
|
|
2449
2750
|
);
|
|
2450
|
-
return /* @__PURE__ */
|
|
2751
|
+
return /* @__PURE__ */ jsx8(PolySceneContext.Provider, { value: sceneCtxValue, children: /* @__PURE__ */ jsxs(
|
|
2451
2752
|
"div",
|
|
2452
2753
|
{
|
|
2453
2754
|
ref: localSceneRef,
|
|
@@ -2465,33 +2766,40 @@ function PolySceneInner({
|
|
|
2465
2766
|
}
|
|
2466
2767
|
) });
|
|
2467
2768
|
}
|
|
2468
|
-
var PolyScene =
|
|
2769
|
+
var PolyScene = memo8(PolySceneInner);
|
|
2469
2770
|
|
|
2470
2771
|
// src/scene/PolyMesh.tsx
|
|
2471
2772
|
import {
|
|
2472
2773
|
forwardRef,
|
|
2473
|
-
useCallback as
|
|
2774
|
+
useCallback as useCallback7,
|
|
2474
2775
|
useContext as useContext3,
|
|
2475
2776
|
useEffect as useEffect5,
|
|
2476
2777
|
useImperativeHandle,
|
|
2477
2778
|
useLayoutEffect as useLayoutEffect2,
|
|
2478
2779
|
useMemo as useMemo7,
|
|
2479
|
-
useRef as
|
|
2780
|
+
useRef as useRef6,
|
|
2480
2781
|
useState as useState4
|
|
2481
2782
|
} from "react";
|
|
2482
2783
|
import {
|
|
2483
2784
|
BASE_TILE as BASE_TILE4,
|
|
2785
|
+
buildSharedEdgeMap,
|
|
2786
|
+
computeReceiverShadowFaces,
|
|
2484
2787
|
computeSceneBbox,
|
|
2485
2788
|
DEFAULT_SEAM_BLEED as DEFAULT_SEAM_BLEED2,
|
|
2486
2789
|
ensureCcw2D,
|
|
2487
2790
|
findOverlappingPolygonDuplicates,
|
|
2488
2791
|
inverseRotateVec3,
|
|
2792
|
+
optimizeMeshPolygons,
|
|
2489
2793
|
parseHexColor as parseHexColor2,
|
|
2490
|
-
|
|
2794
|
+
prepareCasterEdgeOwners,
|
|
2795
|
+
prepareCasterPolyItems,
|
|
2796
|
+
prepareReceiverFacePlanes,
|
|
2797
|
+
projectCssVertexToGround,
|
|
2798
|
+
worldDirectionToCss as worldDirectionToCss2
|
|
2491
2799
|
} from "@layoutit/polycss-core";
|
|
2492
2800
|
|
|
2493
2801
|
// src/scene/useMesh.ts
|
|
2494
|
-
import { useCallback as
|
|
2802
|
+
import { useCallback as useCallback6, useEffect as useEffect4, useRef as useRef5, useState as useState3 } from "react";
|
|
2495
2803
|
import { loadMesh } from "@layoutit/polycss-core";
|
|
2496
2804
|
var EMPTY_POLYGONS = [];
|
|
2497
2805
|
var EMPTY_WARNINGS = [];
|
|
@@ -2503,8 +2811,8 @@ function usePolyMesh(src, options) {
|
|
|
2503
2811
|
error: null,
|
|
2504
2812
|
warnings: EMPTY_WARNINGS
|
|
2505
2813
|
});
|
|
2506
|
-
const activeResultRef =
|
|
2507
|
-
const dispose =
|
|
2814
|
+
const activeResultRef = useRef5(null);
|
|
2815
|
+
const dispose = useCallback6(() => {
|
|
2508
2816
|
const r = activeResultRef.current;
|
|
2509
2817
|
if (r) {
|
|
2510
2818
|
try {
|
|
@@ -2579,6 +2887,10 @@ function usePolyMesh(src, options) {
|
|
|
2579
2887
|
};
|
|
2580
2888
|
}
|
|
2581
2889
|
|
|
2890
|
+
// src/scene/PolyMesh.tsx
|
|
2891
|
+
import { buildBasisHints, cornerShapeGeometryForPlan, worldDirectionalLightToCss } from "@layoutit/polycss-core";
|
|
2892
|
+
import { createPortal } from "react-dom";
|
|
2893
|
+
|
|
2582
2894
|
// src/scene/voxelRenderer.ts
|
|
2583
2895
|
import {
|
|
2584
2896
|
BASE_TILE as BASE_TILE3,
|
|
@@ -2588,6 +2900,7 @@ import {
|
|
|
2588
2900
|
PROJECTIVE_QUAD_BLEED,
|
|
2589
2901
|
resolveProjectiveQuadGuards,
|
|
2590
2902
|
rotateVec3,
|
|
2903
|
+
shadePolygon as shadePolygon2,
|
|
2591
2904
|
SOLID_QUAD_CANONICAL_SIZE
|
|
2592
2905
|
} from "@layoutit/polycss-core";
|
|
2593
2906
|
var DEFAULT_LIGHT_DIR2 = [0.4, -0.7, 0.59];
|
|
@@ -2848,9 +3161,6 @@ function clampChannel(value) {
|
|
|
2848
3161
|
return Math.round(Math.max(0, Math.min(255, value)));
|
|
2849
3162
|
}
|
|
2850
3163
|
function shadeBrushColor(normal, baseColor, directionalLight, ambientLight) {
|
|
2851
|
-
const base = parseColor(baseColor);
|
|
2852
|
-
const light = parseColor(directionalLight?.color ?? DEFAULT_LIGHT_COLOR2);
|
|
2853
|
-
const ambient = parseColor(ambientLight?.color ?? DEFAULT_AMBIENT_COLOR2);
|
|
2854
3164
|
const lightDir = directionalLight?.direction ?? DEFAULT_LIGHT_DIR2;
|
|
2855
3165
|
const lightLen = Math.hypot(lightDir[0], lightDir[1], lightDir[2]) || 1;
|
|
2856
3166
|
const lx = lightDir[0] / lightLen;
|
|
@@ -2858,16 +3168,15 @@ function shadeBrushColor(normal, baseColor, directionalLight, ambientLight) {
|
|
|
2858
3168
|
const lz = lightDir[2] / lightLen;
|
|
2859
3169
|
const directScale = Math.max(0, directionalLight?.intensity ?? DEFAULT_LIGHT_INTENSITY2) * Math.max(0, normal[0] * lx + normal[1] * ly + normal[2] * lz);
|
|
2860
3170
|
const ambientIntensity = Math.max(0, ambientLight?.intensity ?? DEFAULT_AMBIENT_INTENSITY2);
|
|
2861
|
-
const
|
|
2862
|
-
const
|
|
2863
|
-
const
|
|
2864
|
-
const
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
}
|
|
2870
|
-
return shaded.alpha < 1 ? `rgba(${clampChannel(shaded.r)}, ${clampChannel(shaded.g)}, ${clampChannel(shaded.b)}, ${shaded.alpha})` : rgbToHex2(shaded);
|
|
3171
|
+
const lightColor = directionalLight?.color ?? DEFAULT_LIGHT_COLOR2;
|
|
3172
|
+
const ambientColor = ambientLight?.color ?? DEFAULT_AMBIENT_COLOR2;
|
|
3173
|
+
const shaded = shadePolygon2(baseColor, directScale, lightColor, ambientColor, ambientIntensity);
|
|
3174
|
+
const base = parseColor(baseColor);
|
|
3175
|
+
if (base.alpha >= 1) return shaded;
|
|
3176
|
+
const r = parseInt(shaded.slice(1, 3), 16);
|
|
3177
|
+
const g = parseInt(shaded.slice(3, 5), 16);
|
|
3178
|
+
const b = parseInt(shaded.slice(5, 7), 16);
|
|
3179
|
+
return `rgba(${r}, ${g}, ${b}, ${base.alpha})`;
|
|
2871
3180
|
}
|
|
2872
3181
|
function buildDirectMatrixItems(polygons) {
|
|
2873
3182
|
if (!polygons?.length) return [];
|
|
@@ -3313,7 +3622,9 @@ function findMeshUnderPoint(clientX, clientY, filter) {
|
|
|
3313
3622
|
}
|
|
3314
3623
|
|
|
3315
3624
|
// src/scene/PolyMesh.tsx
|
|
3316
|
-
import { Fragment, jsx as
|
|
3625
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
3626
|
+
var reactEdgeOwnersCache = /* @__PURE__ */ new WeakMap();
|
|
3627
|
+
var reactEdgeOwnersCacheKey = /* @__PURE__ */ new WeakMap();
|
|
3317
3628
|
function solidPaintVars(defaults) {
|
|
3318
3629
|
const out = {};
|
|
3319
3630
|
if (defaults.paintColor) out["--polycss-paint"] = defaults.paintColor;
|
|
@@ -3325,21 +3636,23 @@ function solidPaintVars(defaults) {
|
|
|
3325
3636
|
return Object.keys(out).length > 0 ? out : null;
|
|
3326
3637
|
}
|
|
3327
3638
|
function buildTransform(position, scale, rotation) {
|
|
3639
|
+
const sx = typeof scale === "number" ? scale : scale?.[0] ?? 1;
|
|
3640
|
+
const sy = typeof scale === "number" ? scale : scale?.[1] ?? 1;
|
|
3641
|
+
const sz = typeof scale === "number" ? scale : scale?.[2] ?? 1;
|
|
3642
|
+
const hasScale = sx !== 1 || sy !== 1 || sz !== 1;
|
|
3643
|
+
const hasRotation = !!rotation && (!!rotation[0] || !!rotation[1] || !!rotation[2]);
|
|
3644
|
+
const cssPos = position ? [position[1] * BASE_TILE4, position[0] * BASE_TILE4, position[2] * BASE_TILE4] : [0, 0, 0];
|
|
3328
3645
|
const parts = [];
|
|
3329
|
-
if (
|
|
3330
|
-
parts.push(`translate3d(${
|
|
3646
|
+
if (cssPos[0] !== 0 || cssPos[1] !== 0 || cssPos[2] !== 0) {
|
|
3647
|
+
parts.push(`translate3d(${cssPos[0]}px, ${cssPos[1]}px, ${cssPos[2]}px)`);
|
|
3331
3648
|
}
|
|
3332
|
-
if (
|
|
3333
|
-
if (
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
parts.push(`scale3d(${scale[0]}, ${scale[1]}, ${scale[2]})`);
|
|
3337
|
-
}
|
|
3649
|
+
if (hasRotation) {
|
|
3650
|
+
if (rotation[0]) parts.push(`rotateY(${-rotation[0]}deg)`);
|
|
3651
|
+
if (rotation[1]) parts.push(`rotateX(${-rotation[1]}deg)`);
|
|
3652
|
+
if (rotation[2]) parts.push(`rotateZ(${-rotation[2]}deg)`);
|
|
3338
3653
|
}
|
|
3339
|
-
if (
|
|
3340
|
-
|
|
3341
|
-
if (rotation[1]) parts.push(`rotateY(${rotation[1]}deg)`);
|
|
3342
|
-
if (rotation[2]) parts.push(`rotateZ(${rotation[2]}deg)`);
|
|
3654
|
+
if (hasScale) {
|
|
3655
|
+
parts.push(`scale3d(${sx}, ${sy}, ${sz})`);
|
|
3343
3656
|
}
|
|
3344
3657
|
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
3345
3658
|
}
|
|
@@ -3367,11 +3680,16 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3367
3680
|
src,
|
|
3368
3681
|
mtl,
|
|
3369
3682
|
polygons: polygonsProp,
|
|
3683
|
+
voxelSource: voxelSourceProp,
|
|
3370
3684
|
autoCenter,
|
|
3371
3685
|
textureLighting,
|
|
3372
3686
|
textureQuality,
|
|
3373
3687
|
seamBleed,
|
|
3688
|
+
atomicAtlas,
|
|
3689
|
+
onFrameReady,
|
|
3374
3690
|
castShadow,
|
|
3691
|
+
receiveShadow,
|
|
3692
|
+
merge = true,
|
|
3375
3693
|
children,
|
|
3376
3694
|
fallback,
|
|
3377
3695
|
errorFallback,
|
|
@@ -3405,14 +3723,18 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3405
3723
|
}, [mtl, parseOptions, meshResolution]);
|
|
3406
3724
|
const fetched = usePolyMesh(src ?? "", mergedOptions);
|
|
3407
3725
|
const externalPolygons = src ? fetched.polygons : polygonsProp ?? [];
|
|
3408
|
-
const externalVoxelSource = src ? fetched.voxelSource :
|
|
3726
|
+
const externalVoxelSource = src ? fetched.voxelSource : voxelSourceProp;
|
|
3409
3727
|
const [localPolygons, setLocalPolygons] = useState4(null);
|
|
3410
|
-
const prevExternalRef =
|
|
3728
|
+
const prevExternalRef = useRef6(externalPolygons);
|
|
3411
3729
|
if (prevExternalRef.current !== externalPolygons) {
|
|
3412
3730
|
prevExternalRef.current = externalPolygons;
|
|
3413
3731
|
if (localPolygons !== null) setLocalPolygons(null);
|
|
3414
3732
|
}
|
|
3415
|
-
const
|
|
3733
|
+
const rawSourcePolygons = localPolygons ?? externalPolygons;
|
|
3734
|
+
const sourcePolygons = useMemo7(
|
|
3735
|
+
() => merge ? optimizeMeshPolygons(rawSourcePolygons, meshResolution !== void 0 ? { meshResolution } : void 0) : rawSourcePolygons,
|
|
3736
|
+
[rawSourcePolygons, merge, meshResolution]
|
|
3737
|
+
);
|
|
3416
3738
|
const hasRenderProp = typeof children === "function";
|
|
3417
3739
|
const renderPolygon = hasRenderProp ? children : null;
|
|
3418
3740
|
const staticChildren = hasRenderProp ? null : children;
|
|
@@ -3422,35 +3744,14 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3422
3744
|
[sourcePolygons, autoCenter]
|
|
3423
3745
|
);
|
|
3424
3746
|
const transform = buildTransform(position, scale, rotation);
|
|
3425
|
-
const
|
|
3426
|
-
|
|
3427
|
-
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
3428
|
-
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
3429
|
-
for (const poly of polygons) {
|
|
3430
|
-
for (const v of poly.vertices) {
|
|
3431
|
-
if (v[0] < minX) minX = v[0];
|
|
3432
|
-
if (v[0] > maxX) maxX = v[0];
|
|
3433
|
-
if (v[1] < minY) minY = v[1];
|
|
3434
|
-
if (v[1] > maxY) maxY = v[1];
|
|
3435
|
-
if (v[2] < minZ) minZ = v[2];
|
|
3436
|
-
if (v[2] > maxZ) maxZ = v[2];
|
|
3437
|
-
}
|
|
3438
|
-
}
|
|
3439
|
-
if (!Number.isFinite(minX)) return void 0;
|
|
3440
|
-
const tile = 50;
|
|
3441
|
-
const x = (minY + maxY) / 2 * tile;
|
|
3442
|
-
const y = (minX + maxX) / 2 * tile;
|
|
3443
|
-
const z = (minZ + maxZ) / 2 * tile;
|
|
3444
|
-
return `${x}px ${y}px ${z}px`;
|
|
3445
|
-
}, [polygons]);
|
|
3446
|
-
const wrapperRef = useRef5(null);
|
|
3447
|
-
const propsRef = useRef5({ position, scale, rotation });
|
|
3747
|
+
const wrapperRef = useRef6(null);
|
|
3748
|
+
const propsRef = useRef6({ position, scale, rotation });
|
|
3448
3749
|
propsRef.current = { position, scale, rotation };
|
|
3449
|
-
const polygonsRef =
|
|
3750
|
+
const polygonsRef = useRef6(polygons);
|
|
3450
3751
|
polygonsRef.current = polygons;
|
|
3451
3752
|
const [bakedRotation, setBakedRotation] = useState4(rotation);
|
|
3452
|
-
const stableTriangleColorFrameRef =
|
|
3453
|
-
const setPolygonsImplRef =
|
|
3753
|
+
const stableTriangleColorFrameRef = useRef6(0);
|
|
3754
|
+
const setPolygonsImplRef = useRef6(() => {
|
|
3454
3755
|
});
|
|
3455
3756
|
const handle = useMemo7(() => ({
|
|
3456
3757
|
get element() {
|
|
@@ -3482,8 +3783,8 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3482
3783
|
}, [handle]);
|
|
3483
3784
|
const cameraCtx = useContext3(PolyCameraContext);
|
|
3484
3785
|
const cameraElRef = cameraCtx?.cameraElRef ?? null;
|
|
3485
|
-
const pointerDownAtRef =
|
|
3486
|
-
const makeEvent =
|
|
3786
|
+
const pointerDownAtRef = useRef6(null);
|
|
3787
|
+
const makeEvent = useCallback7(
|
|
3487
3788
|
function makeEvent2(nativeEvent, clientX, clientY) {
|
|
3488
3789
|
const intersections = [];
|
|
3489
3790
|
if (typeof document !== "undefined" && typeof document.elementsFromPoint === "function") {
|
|
@@ -3606,9 +3907,13 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3606
3907
|
const sceneCtx = usePolySceneContext2();
|
|
3607
3908
|
const effectiveTextureLighting = textureLighting ?? sceneCtx?.textureLighting ?? "baked";
|
|
3608
3909
|
const effectiveStrategies = sceneCtx?.strategies;
|
|
3910
|
+
const disabledStrategies = useMemo7(
|
|
3911
|
+
() => effectiveStrategies?.disable?.length ? new Set(effectiveStrategies.disable) : void 0,
|
|
3912
|
+
[effectiveStrategies]
|
|
3913
|
+
);
|
|
3609
3914
|
const effectiveSeamBleed = seamBleed ?? sceneCtx?.seamBleed ?? DEFAULT_SEAM_BLEED2;
|
|
3610
|
-
const effectiveDirectional =
|
|
3611
|
-
const effectiveAmbient =
|
|
3915
|
+
const effectiveDirectional = sceneCtx?.directionalLight;
|
|
3916
|
+
const effectiveAmbient = sceneCtx?.ambientLight;
|
|
3612
3917
|
const directVoxelEnabled = Boolean(
|
|
3613
3918
|
externalVoxelSource && localPolygons === null && !renderPolygon && !hasStaticChildren && effectiveTextureLighting === "baked" && !castShadow
|
|
3614
3919
|
);
|
|
@@ -3621,20 +3926,22 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3621
3926
|
const localDir = inverseRotateVec3(dir, rotation);
|
|
3622
3927
|
const len = Math.hypot(localDir[0], localDir[1], localDir[2]) || 1;
|
|
3623
3928
|
return {
|
|
3624
|
-
["--plx"]: (localDir[0] / len).toFixed(
|
|
3625
|
-
["--ply"]: (localDir[1] / len).toFixed(
|
|
3626
|
-
["--plz"]: (localDir[2] / len).toFixed(
|
|
3929
|
+
["--plx"]: (localDir[0] / len).toFixed(2),
|
|
3930
|
+
["--ply"]: (localDir[1] / len).toFixed(2),
|
|
3931
|
+
["--plz"]: (localDir[2] / len).toFixed(2)
|
|
3627
3932
|
};
|
|
3628
3933
|
}, [effectiveTextureLighting, rotation, sceneDirectionalLight]);
|
|
3629
3934
|
const bakedDirectional = useMemo7(() => {
|
|
3630
3935
|
if (!effectiveDirectional) return effectiveDirectional;
|
|
3631
3936
|
const rot = bakedRotation ?? [0, 0, 0];
|
|
3632
|
-
|
|
3937
|
+
const cssLight = worldDirectionalLightToCss(effectiveDirectional);
|
|
3938
|
+
if (rot[0] === 0 && rot[1] === 0 && rot[2] === 0) return cssLight;
|
|
3633
3939
|
return {
|
|
3634
|
-
...
|
|
3635
|
-
direction: inverseRotateVec3(
|
|
3940
|
+
...cssLight,
|
|
3941
|
+
direction: inverseRotateVec3(cssLight.direction, rot)
|
|
3636
3942
|
};
|
|
3637
3943
|
}, [effectiveDirectional, bakedRotation]);
|
|
3944
|
+
const lightOccludedPolyIndices = void 0;
|
|
3638
3945
|
const atlasPlans = useMemo7(
|
|
3639
3946
|
() => {
|
|
3640
3947
|
if (renderPolygon || directVoxelEnabled) return [];
|
|
@@ -3643,53 +3950,101 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3643
3950
|
directionalLight: bakedDirectional,
|
|
3644
3951
|
ambientLight: effectiveAmbient
|
|
3645
3952
|
}) : null;
|
|
3646
|
-
|
|
3953
|
+
const basisHints = buildBasisHints(polygons, {
|
|
3647
3954
|
directionalLight: bakedDirectional,
|
|
3648
|
-
ambientLight: effectiveAmbient
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3955
|
+
ambientLight: effectiveAmbient
|
|
3956
|
+
});
|
|
3957
|
+
return polygons.map((p, i) => computeTextureAtlasPlan(
|
|
3958
|
+
p,
|
|
3959
|
+
i,
|
|
3960
|
+
{
|
|
3961
|
+
directionalLight: bakedDirectional,
|
|
3962
|
+
ambientLight: effectiveAmbient,
|
|
3963
|
+
seamBleed: seamBleedEdges?.has(i) ? effectiveSeamBleed : void 0,
|
|
3964
|
+
seamEdges: seamBleedEdges?.get(i),
|
|
3965
|
+
textureEdgeRepairEdges: repairEdges[i],
|
|
3966
|
+
lightOccludedPolyIndices
|
|
3967
|
+
},
|
|
3968
|
+
basisHints[i]
|
|
3969
|
+
));
|
|
3653
3970
|
},
|
|
3654
|
-
[renderPolygon, directVoxelEnabled, polygons, bakedDirectional, effectiveAmbient, effectiveSeamBleed]
|
|
3971
|
+
[renderPolygon, directVoxelEnabled, polygons, bakedDirectional, effectiveAmbient, effectiveSeamBleed, lightOccludedPolyIndices]
|
|
3655
3972
|
);
|
|
3656
3973
|
const textureAtlas = useTextureAtlas(
|
|
3657
3974
|
atlasPlans,
|
|
3658
3975
|
effectiveTextureLighting,
|
|
3659
3976
|
textureQuality,
|
|
3660
|
-
effectiveStrategies
|
|
3977
|
+
effectiveStrategies,
|
|
3978
|
+
atomicAtlas
|
|
3661
3979
|
);
|
|
3662
3980
|
const solidPaintDefaults = useMemo7(
|
|
3663
|
-
() => !renderPolygon ? getSolidPaintDefaults(
|
|
3664
|
-
[renderPolygon,
|
|
3981
|
+
() => !renderPolygon ? getSolidPaintDefaults(textureAtlas.plans, effectiveTextureLighting, effectiveStrategies) : {},
|
|
3982
|
+
[renderPolygon, textureAtlas.plans, effectiveTextureLighting, effectiveStrategies]
|
|
3665
3983
|
);
|
|
3984
|
+
const onFrameReadyRef = useRef6(onFrameReady);
|
|
3985
|
+
onFrameReadyRef.current = onFrameReady;
|
|
3986
|
+
useLayoutEffect2(() => {
|
|
3987
|
+
if (atomicAtlas && textureAtlas.ready) onFrameReadyRef.current?.();
|
|
3988
|
+
}, [textureAtlas.entries]);
|
|
3666
3989
|
const defaultPaintVars = useMemo7(
|
|
3667
3990
|
() => solidPaintVars(solidPaintDefaults),
|
|
3668
3991
|
[solidPaintDefaults]
|
|
3669
3992
|
);
|
|
3670
|
-
const meshIdRef =
|
|
3993
|
+
const meshIdRef = useRef6(/* @__PURE__ */ Symbol());
|
|
3671
3994
|
const sceneRegisterShadowCaster = sceneCtx?.registerShadowCaster;
|
|
3995
|
+
const renderedPolygonIndices = useMemo7(() => {
|
|
3996
|
+
const dedupDrop = findOverlappingPolygonDuplicates(polygons, {
|
|
3997
|
+
normalTolerance: 0.1,
|
|
3998
|
+
distanceTolerance: 0.5,
|
|
3999
|
+
overlapFraction: 0.95,
|
|
4000
|
+
preserveDoubleSidedBackfaces: false
|
|
4001
|
+
});
|
|
4002
|
+
const s = /* @__PURE__ */ new Set();
|
|
4003
|
+
for (let i = 0; i < atlasPlans.length; i++) {
|
|
4004
|
+
if (atlasPlans[i] && !dedupDrop.has(i)) s.add(i);
|
|
4005
|
+
}
|
|
4006
|
+
return s;
|
|
4007
|
+
}, [atlasPlans, polygons]);
|
|
3672
4008
|
useEffect5(() => {
|
|
3673
4009
|
if (!sceneRegisterShadowCaster) return;
|
|
3674
4010
|
if (castShadow) {
|
|
3675
|
-
sceneRegisterShadowCaster(meshIdRef.current,
|
|
4011
|
+
sceneRegisterShadowCaster(meshIdRef.current, {
|
|
4012
|
+
polygons,
|
|
4013
|
+
position: position ?? [0, 0, 0],
|
|
4014
|
+
scale,
|
|
4015
|
+
rotation,
|
|
4016
|
+
renderedPolygonIndices
|
|
4017
|
+
});
|
|
3676
4018
|
} else {
|
|
3677
4019
|
sceneRegisterShadowCaster(meshIdRef.current, null);
|
|
3678
4020
|
}
|
|
3679
4021
|
return () => {
|
|
3680
4022
|
sceneRegisterShadowCaster(meshIdRef.current, null);
|
|
3681
4023
|
};
|
|
3682
|
-
}, [sceneRegisterShadowCaster, castShadow, polygons]);
|
|
4024
|
+
}, [sceneRegisterShadowCaster, castShadow, polygons, position, scale, rotation, renderedPolygonIndices]);
|
|
4025
|
+
const sceneRegisterShadowReceiver = sceneCtx?.registerShadowReceiver;
|
|
4026
|
+
useEffect5(() => {
|
|
4027
|
+
if (!sceneRegisterShadowReceiver) return;
|
|
4028
|
+
sceneRegisterShadowReceiver(meshIdRef.current, !!receiveShadow);
|
|
4029
|
+
return () => {
|
|
4030
|
+
sceneRegisterShadowReceiver(meshIdRef.current, false);
|
|
4031
|
+
};
|
|
4032
|
+
}, [sceneRegisterShadowReceiver, receiveShadow]);
|
|
3683
4033
|
const bakedShadowGroundCssZ = sceneCtx?.groundCssZ ?? null;
|
|
3684
4034
|
const sceneShadow = sceneCtx?.shadow;
|
|
4035
|
+
const sceneHasReceiver = sceneCtx?.hasShadowReceiver ?? false;
|
|
3685
4036
|
const shadowSvgNode = useMemo7(() => {
|
|
3686
4037
|
if (!castShadow || renderPolygon) return null;
|
|
4038
|
+
if (sceneHasReceiver) return null;
|
|
3687
4039
|
if (bakedShadowGroundCssZ === null) return null;
|
|
3688
|
-
const
|
|
4040
|
+
const userGroundLightDir = sceneDirectionalLight?.direction ?? [0.4, -0.7, 0.59];
|
|
4041
|
+
const lightDir = worldDirectionToCss2(userGroundLightDir);
|
|
4042
|
+
const meshPosZ = position?.[2] ?? 0;
|
|
4043
|
+
const localGroundCssZ = bakedShadowGroundCssZ - meshPosZ * BASE_TILE4;
|
|
3689
4044
|
const shadowDedupDrop = findOverlappingPolygonDuplicates(polygons, {
|
|
3690
4045
|
normalTolerance: 0.1,
|
|
3691
4046
|
distanceTolerance: 0.5,
|
|
3692
|
-
overlapFraction: 0.
|
|
4047
|
+
overlapFraction: 0.95,
|
|
3693
4048
|
preserveDoubleSidedBackfaces: false
|
|
3694
4049
|
});
|
|
3695
4050
|
const projections = [];
|
|
@@ -3711,7 +4066,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3711
4066
|
if (cssVertex[1] < fpMinY) fpMinY = cssVertex[1];
|
|
3712
4067
|
if (cssVertex[0] > fpMaxX) fpMaxX = cssVertex[0];
|
|
3713
4068
|
if (cssVertex[1] > fpMaxY) fpMaxY = cssVertex[1];
|
|
3714
|
-
const p = projectCssVertexToGround(cssVertex, lightDir,
|
|
4069
|
+
const p = projectCssVertexToGround(cssVertex, lightDir, localGroundCssZ);
|
|
3715
4070
|
projected.push(p);
|
|
3716
4071
|
if (p[0] < minX) minX = p[0];
|
|
3717
4072
|
if (p[1] < minY) minY = p[1];
|
|
@@ -3741,7 +4096,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3741
4096
|
}
|
|
3742
4097
|
d += "Z";
|
|
3743
4098
|
}
|
|
3744
|
-
return /* @__PURE__ */
|
|
4099
|
+
return /* @__PURE__ */ jsx9(
|
|
3745
4100
|
"svg",
|
|
3746
4101
|
{
|
|
3747
4102
|
className: "polycss-shadow polycss-shadow-svg",
|
|
@@ -3757,16 +4112,16 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3757
4112
|
transformOrigin: "0 0",
|
|
3758
4113
|
pointerEvents: "none",
|
|
3759
4114
|
willChange: "transform",
|
|
3760
|
-
transform: `translate3d(${bx0.toFixed(3)}px,${by0.toFixed(3)}px,${
|
|
4115
|
+
transform: `translate3d(${bx0.toFixed(3)}px,${by0.toFixed(3)}px,${localGroundCssZ.toFixed(3)}px)`
|
|
3761
4116
|
},
|
|
3762
|
-
children: /* @__PURE__ */
|
|
4117
|
+
children: /* @__PURE__ */ jsx9(
|
|
3763
4118
|
"path",
|
|
3764
4119
|
{
|
|
3765
4120
|
d,
|
|
3766
4121
|
fill: `rgb(${parsed[0]},${parsed[1]},${parsed[2]})`,
|
|
3767
4122
|
fillRule: "nonzero",
|
|
3768
4123
|
stroke: `rgb(${parsed[0]},${parsed[1]},${parsed[2]})`,
|
|
3769
|
-
strokeWidth: "
|
|
4124
|
+
strokeWidth: "3",
|
|
3770
4125
|
strokeLinejoin: "round",
|
|
3771
4126
|
opacity: shadowOpacity.toFixed(4)
|
|
3772
4127
|
}
|
|
@@ -3774,7 +4129,125 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3774
4129
|
},
|
|
3775
4130
|
"shadow-svg"
|
|
3776
4131
|
);
|
|
3777
|
-
}, [castShadow, renderPolygon, polygons, atlasPlans, sceneDirectionalLight, bakedShadowGroundCssZ, sceneShadow]);
|
|
4132
|
+
}, [castShadow, renderPolygon, polygons, atlasPlans, sceneDirectionalLight, bakedShadowGroundCssZ, sceneShadow, sceneHasReceiver]);
|
|
4133
|
+
const shadowCasters = sceneCtx?.shadowCasters;
|
|
4134
|
+
const shadowCastersVersion = sceneCtx?.shadowCastersVersion ?? 0;
|
|
4135
|
+
const [cameraTick, setCameraTick] = useState4(0);
|
|
4136
|
+
useEffect5(() => {
|
|
4137
|
+
if (!receiveShadow) return;
|
|
4138
|
+
return cameraCtx?.store.subscribe(() => setCameraTick((n) => n + 1));
|
|
4139
|
+
}, [receiveShadow, cameraCtx?.store]);
|
|
4140
|
+
void cameraTick;
|
|
4141
|
+
const selfShadowEdgeMap = useMemo7(
|
|
4142
|
+
() => receiveShadow ? buildSharedEdgeMap(polygons) : void 0,
|
|
4143
|
+
[polygons, receiveShadow]
|
|
4144
|
+
);
|
|
4145
|
+
const receiverShadowSvgs = useMemo7(() => {
|
|
4146
|
+
if (!receiveShadow) return null;
|
|
4147
|
+
if (!shadowCasters || shadowCasters.size === 0) return null;
|
|
4148
|
+
const userLightDir = sceneDirectionalLight?.direction ?? [0.4, -0.7, 0.59];
|
|
4149
|
+
const lightDir = worldDirectionToCss2(userLightDir);
|
|
4150
|
+
const shadowLift = sceneShadow?.lift ?? 1e-3;
|
|
4151
|
+
const planes = prepareReceiverFacePlanes(
|
|
4152
|
+
polygons,
|
|
4153
|
+
position ?? [0, 0, 0],
|
|
4154
|
+
scale,
|
|
4155
|
+
/* @__PURE__ */ new Set(),
|
|
4156
|
+
shadowLift,
|
|
4157
|
+
rotation
|
|
4158
|
+
);
|
|
4159
|
+
if (planes.length === 0) return null;
|
|
4160
|
+
const casterInputs = [];
|
|
4161
|
+
for (const [casterId, data] of shadowCasters) {
|
|
4162
|
+
const rendered = data.renderedPolygonIndices;
|
|
4163
|
+
const items = prepareCasterPolyItems(
|
|
4164
|
+
data.polygons,
|
|
4165
|
+
data.position,
|
|
4166
|
+
data.scale,
|
|
4167
|
+
rendered ? (idx) => rendered.has(idx) : () => true,
|
|
4168
|
+
data.rotation ?? null
|
|
4169
|
+
);
|
|
4170
|
+
const isSelf = data.polygons === polygons;
|
|
4171
|
+
const selfMap = isSelf ? selfShadowEdgeMap : void 0;
|
|
4172
|
+
let edgeOwners;
|
|
4173
|
+
if (!isSelf && data.polygons.length >= 40) {
|
|
4174
|
+
const dposArr = data.position;
|
|
4175
|
+
const drot = data.rotation ?? null;
|
|
4176
|
+
const dsKey = JSON.stringify(data.scale ?? null);
|
|
4177
|
+
const eoKey = `${dposArr[0]},${dposArr[1]},${dposArr[2]}|${drot ? drot.join(",") : "n"}|${dsKey}`;
|
|
4178
|
+
let cachedOwners = reactEdgeOwnersCache.get(data.polygons);
|
|
4179
|
+
if (cachedOwners === void 0 || reactEdgeOwnersCacheKey.get(data.polygons) !== eoKey) {
|
|
4180
|
+
cachedOwners = prepareCasterEdgeOwners(data.polygons, dposArr, data.scale, drot);
|
|
4181
|
+
reactEdgeOwnersCache.set(data.polygons, cachedOwners);
|
|
4182
|
+
reactEdgeOwnersCacheKey.set(data.polygons, eoKey);
|
|
4183
|
+
}
|
|
4184
|
+
edgeOwners = cachedOwners;
|
|
4185
|
+
}
|
|
4186
|
+
casterInputs.push({
|
|
4187
|
+
id: casterId,
|
|
4188
|
+
items,
|
|
4189
|
+
selfShadowEdgeMap: selfMap,
|
|
4190
|
+
edgeOwners,
|
|
4191
|
+
casterPolygonCount: data.polygons.length
|
|
4192
|
+
});
|
|
4193
|
+
}
|
|
4194
|
+
const cameraState = cameraCtx?.store.getState().cameraState;
|
|
4195
|
+
const cameraRot = {
|
|
4196
|
+
rotX: cameraState?.rotX ?? 65,
|
|
4197
|
+
rotY: cameraState?.rotY ?? 45,
|
|
4198
|
+
meshRotation: rotation
|
|
4199
|
+
};
|
|
4200
|
+
const specs = computeReceiverShadowFaces({
|
|
4201
|
+
receiverPlanes: planes,
|
|
4202
|
+
receiverPolygons: polygons,
|
|
4203
|
+
receiverHasTexture: polygons.some((p) => p.texture !== void 0),
|
|
4204
|
+
casters: casterInputs,
|
|
4205
|
+
lightDir,
|
|
4206
|
+
cameraRot,
|
|
4207
|
+
ambientLight: sceneCtx?.ambientLight,
|
|
4208
|
+
directionalLight: sceneDirectionalLight,
|
|
4209
|
+
shadow: { color: sceneShadow?.color, opacity: sceneShadow?.opacity ?? 0.25, maxExtend: sceneShadow?.maxExtend }
|
|
4210
|
+
});
|
|
4211
|
+
return /* @__PURE__ */ jsx9(Fragment, { children: specs.map((spec) => /* @__PURE__ */ jsx9(
|
|
4212
|
+
"svg",
|
|
4213
|
+
{
|
|
4214
|
+
className: "polycss-shadow polycss-shadow-svg polycss-shadow-receiver",
|
|
4215
|
+
"data-poly-shadow-type": "receiver",
|
|
4216
|
+
"data-poly-shadow-receiver-face": spec.faceIndex,
|
|
4217
|
+
"data-poly-shadow-receiver-polys": JSON.stringify(spec.memberPolyIndices),
|
|
4218
|
+
width: spec.width,
|
|
4219
|
+
height: spec.height,
|
|
4220
|
+
viewBox: `0 0 ${spec.width} ${spec.height}`,
|
|
4221
|
+
style: {
|
|
4222
|
+
position: "absolute",
|
|
4223
|
+
top: 0,
|
|
4224
|
+
left: 0,
|
|
4225
|
+
display: "block",
|
|
4226
|
+
overflow: "hidden",
|
|
4227
|
+
transformOrigin: "0 0",
|
|
4228
|
+
pointerEvents: "none",
|
|
4229
|
+
willChange: "transform",
|
|
4230
|
+
transform: spec.matrixCss
|
|
4231
|
+
},
|
|
4232
|
+
children: spec.paths.map((p, i) => /* @__PURE__ */ jsx9(
|
|
4233
|
+
"path",
|
|
4234
|
+
{
|
|
4235
|
+
d: p.d,
|
|
4236
|
+
fill: spec.fill,
|
|
4237
|
+
stroke: spec.fill,
|
|
4238
|
+
strokeWidth: "3",
|
|
4239
|
+
strokeLinejoin: "round",
|
|
4240
|
+
opacity: spec.opacity.toFixed(4),
|
|
4241
|
+
"data-poly-shadow-caster-polys": JSON.stringify(p.casterPolygonIndices)
|
|
4242
|
+
},
|
|
4243
|
+
i
|
|
4244
|
+
))
|
|
4245
|
+
},
|
|
4246
|
+
`receiver-${spec.faceIndex}`
|
|
4247
|
+
)) });
|
|
4248
|
+
}, [receiveShadow, shadowCasters, shadowCastersVersion, polygons, position, scale, rotation, sceneDirectionalLight, sceneShadow, sceneCtx?.ambientLight, cameraCtx?.store, cameraTick, selfShadowEdgeMap]);
|
|
4249
|
+
const portalSceneEl = sceneCtx?.sceneEl ?? null;
|
|
4250
|
+
const portaledReceiverShadowSvgs = portalSceneEl && receiverShadowSvgs ? createPortal(receiverShadowSvgs, portalSceneEl) : null;
|
|
3778
4251
|
setPolygonsImplRef.current = (nextPolygons) => {
|
|
3779
4252
|
const nextRenderedPolygons = autoCenter ? recenterPolygons(nextPolygons) : nextPolygons;
|
|
3780
4253
|
polygonsRef.current = nextRenderedPolygons;
|
|
@@ -3794,7 +4267,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3794
4267
|
}
|
|
3795
4268
|
setLocalPolygons([...nextPolygons]);
|
|
3796
4269
|
};
|
|
3797
|
-
const voxelRendererRef =
|
|
4270
|
+
const voxelRendererRef = useRef6(null);
|
|
3798
4271
|
useLayoutEffect2(() => {
|
|
3799
4272
|
const root = wrapperRef.current;
|
|
3800
4273
|
voxelRendererRef.current?.dispose();
|
|
@@ -3836,7 +4309,6 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3836
4309
|
]);
|
|
3837
4310
|
const wrapperStyle = {
|
|
3838
4311
|
transform,
|
|
3839
|
-
...transformOrigin ? { transformOrigin } : null,
|
|
3840
4312
|
...dynamicLightOverride,
|
|
3841
4313
|
...style,
|
|
3842
4314
|
...defaultPaintVars
|
|
@@ -3844,10 +4316,10 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3844
4316
|
const renderedPolygons = renderPolygon ? polygons.map((p, i) => (
|
|
3845
4317
|
// Render-prop: caller controls how each polygon renders. We still
|
|
3846
4318
|
// wrap in a fragment with key so React reconciliation works.
|
|
3847
|
-
/* @__PURE__ */
|
|
4319
|
+
/* @__PURE__ */ jsx9(RenderPropPolygon, { polygon: p, index: i, children: renderPolygon }, i)
|
|
3848
4320
|
)) : textureAtlas.entries.map((entry, index) => {
|
|
3849
4321
|
if (entry) {
|
|
3850
|
-
return /* @__PURE__ */
|
|
4322
|
+
return /* @__PURE__ */ jsx9(
|
|
3851
4323
|
TextureAtlasPoly,
|
|
3852
4324
|
{
|
|
3853
4325
|
entry,
|
|
@@ -3858,10 +4330,10 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3858
4330
|
entry.index
|
|
3859
4331
|
);
|
|
3860
4332
|
}
|
|
3861
|
-
const plan =
|
|
4333
|
+
const plan = textureAtlas.plans[index];
|
|
3862
4334
|
if (!plan || plan.texture) return null;
|
|
3863
4335
|
if (isProjectiveQuadPlan(plan)) {
|
|
3864
|
-
return /* @__PURE__ */
|
|
4336
|
+
return /* @__PURE__ */ jsx9(
|
|
3865
4337
|
TextureProjectiveSolidPoly,
|
|
3866
4338
|
{
|
|
3867
4339
|
entry: plan,
|
|
@@ -3871,26 +4343,44 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3871
4343
|
plan.index
|
|
3872
4344
|
);
|
|
3873
4345
|
}
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
4346
|
+
if (isSolidTrianglePlan2(plan)) {
|
|
4347
|
+
return /* @__PURE__ */ jsx9(
|
|
4348
|
+
TextureTrianglePoly,
|
|
4349
|
+
{
|
|
4350
|
+
entry: plan,
|
|
4351
|
+
textureLighting: effectiveTextureLighting,
|
|
4352
|
+
solidPaintDefaults
|
|
4353
|
+
},
|
|
4354
|
+
plan.index
|
|
4355
|
+
);
|
|
4356
|
+
}
|
|
4357
|
+
const cornerGeo = !disabledStrategies?.has("i") ? cornerShapeGeometryForPlan(plan) : null;
|
|
4358
|
+
if (cornerGeo) {
|
|
4359
|
+
return /* @__PURE__ */ jsx9(
|
|
4360
|
+
TextureCornerShapeSolidPoly,
|
|
4361
|
+
{
|
|
4362
|
+
entry: plan,
|
|
4363
|
+
geometry: cornerGeo,
|
|
4364
|
+
textureLighting: effectiveTextureLighting,
|
|
4365
|
+
solidPaintDefaults
|
|
4366
|
+
},
|
|
4367
|
+
plan.index
|
|
4368
|
+
);
|
|
4369
|
+
}
|
|
4370
|
+
return /* @__PURE__ */ jsx9(
|
|
3883
4371
|
TextureBorderShapePoly,
|
|
3884
4372
|
{
|
|
3885
4373
|
entry: plan,
|
|
3886
|
-
|
|
4374
|
+
textureLighting: effectiveTextureLighting,
|
|
4375
|
+
solidPaintDefaults,
|
|
4376
|
+
disabledStrategies
|
|
3887
4377
|
},
|
|
3888
4378
|
plan.index
|
|
3889
4379
|
);
|
|
3890
4380
|
});
|
|
3891
4381
|
if (src) {
|
|
3892
4382
|
if (fetched.loading && fetched.polygons.length === 0) {
|
|
3893
|
-
return /* @__PURE__ */
|
|
4383
|
+
return /* @__PURE__ */ jsx9(
|
|
3894
4384
|
"div",
|
|
3895
4385
|
{
|
|
3896
4386
|
ref: wrapperRef,
|
|
@@ -3903,7 +4393,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3903
4393
|
);
|
|
3904
4394
|
}
|
|
3905
4395
|
if (fetched.error && fetched.polygons.length === 0) {
|
|
3906
|
-
return /* @__PURE__ */
|
|
4396
|
+
return /* @__PURE__ */ jsx9(
|
|
3907
4397
|
"div",
|
|
3908
4398
|
{
|
|
3909
4399
|
ref: wrapperRef,
|
|
@@ -3926,6 +4416,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3926
4416
|
...wrapperHandlers,
|
|
3927
4417
|
children: [
|
|
3928
4418
|
shadowSvgNode,
|
|
4419
|
+
portaledReceiverShadowSvgs,
|
|
3929
4420
|
renderedPolygons,
|
|
3930
4421
|
staticChildren
|
|
3931
4422
|
]
|
|
@@ -3937,12 +4428,89 @@ function RenderPropPolygon({
|
|
|
3937
4428
|
index,
|
|
3938
4429
|
children
|
|
3939
4430
|
}) {
|
|
3940
|
-
return /* @__PURE__ */
|
|
4431
|
+
return /* @__PURE__ */ jsx9(Fragment, { children: children(polygon, index) });
|
|
4432
|
+
}
|
|
4433
|
+
|
|
4434
|
+
// src/scene/PolyIframe.tsx
|
|
4435
|
+
import { BASE_TILE as BASE_TILE5 } from "@layoutit/polycss-core";
|
|
4436
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
4437
|
+
function buildIframeTransform(position, rotation, scale, cssWidth, cssHeight) {
|
|
4438
|
+
const sx = typeof scale === "number" ? scale : scale?.[0] ?? 1;
|
|
4439
|
+
const sy = typeof scale === "number" ? scale : scale?.[1] ?? 1;
|
|
4440
|
+
const sz = typeof scale === "number" ? scale : scale?.[2] ?? 1;
|
|
4441
|
+
const hasScale = sx !== 1 || sy !== 1 || sz !== 1;
|
|
4442
|
+
const hasRotation = !!rotation && (!!rotation[0] || !!rotation[1] || !!rotation[2]);
|
|
4443
|
+
const cssX = (position?.[1] ?? 0) * BASE_TILE5;
|
|
4444
|
+
const cssY = (position?.[0] ?? 0) * BASE_TILE5;
|
|
4445
|
+
const cssZ = (position?.[2] ?? 0) * BASE_TILE5;
|
|
4446
|
+
const parts = [];
|
|
4447
|
+
parts.push(`translate3d(${cssX}px, ${cssY}px, ${cssZ}px)`);
|
|
4448
|
+
if (hasRotation) {
|
|
4449
|
+
if (rotation[0]) parts.push(`rotateY(${-rotation[0]}deg)`);
|
|
4450
|
+
if (rotation[1]) parts.push(`rotateX(${-rotation[1]}deg)`);
|
|
4451
|
+
if (rotation[2]) parts.push(`rotateZ(${-rotation[2]}deg)`);
|
|
4452
|
+
}
|
|
4453
|
+
if (hasScale) parts.push(`scale3d(${sx}, ${sy}, ${sz})`);
|
|
4454
|
+
parts.push(`translate(${-cssWidth / 2}px, ${-cssHeight / 2}px)`);
|
|
4455
|
+
return parts.join(" ");
|
|
4456
|
+
}
|
|
4457
|
+
function PolyIframe({
|
|
4458
|
+
src,
|
|
4459
|
+
width,
|
|
4460
|
+
height,
|
|
4461
|
+
position,
|
|
4462
|
+
rotation,
|
|
4463
|
+
scale,
|
|
4464
|
+
allow,
|
|
4465
|
+
sandbox,
|
|
4466
|
+
loading,
|
|
4467
|
+
referrerPolicy,
|
|
4468
|
+
title,
|
|
4469
|
+
className,
|
|
4470
|
+
style
|
|
4471
|
+
}) {
|
|
4472
|
+
const cssW = width * BASE_TILE5;
|
|
4473
|
+
const cssH = height * BASE_TILE5;
|
|
4474
|
+
const transform = buildIframeTransform(position, rotation, scale, cssW, cssH);
|
|
4475
|
+
const wrapperStyle = {
|
|
4476
|
+
position: "absolute",
|
|
4477
|
+
left: 0,
|
|
4478
|
+
top: 0,
|
|
4479
|
+
transformOrigin: "0 0",
|
|
4480
|
+
transformStyle: "preserve-3d",
|
|
4481
|
+
transform,
|
|
4482
|
+
...style
|
|
4483
|
+
};
|
|
4484
|
+
return /* @__PURE__ */ jsx10(
|
|
4485
|
+
"div",
|
|
4486
|
+
{
|
|
4487
|
+
className: `polycss-iframe${className ? ` ${className}` : ""}`,
|
|
4488
|
+
style: wrapperStyle,
|
|
4489
|
+
children: /* @__PURE__ */ jsx10(
|
|
4490
|
+
"iframe",
|
|
4491
|
+
{
|
|
4492
|
+
src,
|
|
4493
|
+
allow,
|
|
4494
|
+
sandbox,
|
|
4495
|
+
loading,
|
|
4496
|
+
referrerPolicy,
|
|
4497
|
+
title,
|
|
4498
|
+
style: {
|
|
4499
|
+
width: cssW,
|
|
4500
|
+
height: cssH,
|
|
4501
|
+
border: 0,
|
|
4502
|
+
display: "block",
|
|
4503
|
+
background: "#000"
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
)
|
|
4507
|
+
}
|
|
4508
|
+
);
|
|
3941
4509
|
}
|
|
3942
4510
|
|
|
3943
4511
|
// src/scene/PolyGround.tsx
|
|
3944
4512
|
import { useMemo as useMemo8 } from "react";
|
|
3945
|
-
import { jsx as
|
|
4513
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
3946
4514
|
function PolyGround({
|
|
3947
4515
|
size = 6,
|
|
3948
4516
|
z = 0,
|
|
@@ -3961,7 +4529,7 @@ function PolyGround({
|
|
|
3961
4529
|
];
|
|
3962
4530
|
return [{ vertices, color }];
|
|
3963
4531
|
}, [size, z, center, color]);
|
|
3964
|
-
return /* @__PURE__ */
|
|
4532
|
+
return /* @__PURE__ */ jsx11(
|
|
3965
4533
|
PolyMesh,
|
|
3966
4534
|
{
|
|
3967
4535
|
polygons,
|
|
@@ -3982,8 +4550,8 @@ function usePolyMaterial(options) {
|
|
|
3982
4550
|
}
|
|
3983
4551
|
|
|
3984
4552
|
// src/shapes/Poly.tsx
|
|
3985
|
-
import { memo as
|
|
3986
|
-
import { jsx as
|
|
4553
|
+
import { memo as memo9, useMemo as useMemo10 } from "react";
|
|
4554
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
3987
4555
|
var DIRECT_TEXTURE_CSS_DECIMALS = 4;
|
|
3988
4556
|
function formatCssLength(value, decimals = DIRECT_TEXTURE_CSS_DECIMALS) {
|
|
3989
4557
|
const next = value.toFixed(decimals).replace(/\.?0+$/, "");
|
|
@@ -4035,7 +4603,7 @@ function MaterialDirectPoly({
|
|
|
4035
4603
|
Object.entries(plan.polygon.data).map(([k, v]) => [`data-${k}`, String(v)])
|
|
4036
4604
|
) : {};
|
|
4037
4605
|
const elementClassName = className?.trim() || void 0;
|
|
4038
|
-
return /* @__PURE__ */
|
|
4606
|
+
return /* @__PURE__ */ jsx12(
|
|
4039
4607
|
"i",
|
|
4040
4608
|
{
|
|
4041
4609
|
className: elementClassName,
|
|
@@ -4166,7 +4734,7 @@ function PolyInner({
|
|
|
4166
4734
|
const wrapperTransform = transformParts.length > 0 ? transformParts.join(" ") : void 0;
|
|
4167
4735
|
let front = null;
|
|
4168
4736
|
if (materialUvRect && material && atlasPlan) {
|
|
4169
|
-
front = /* @__PURE__ */
|
|
4737
|
+
front = /* @__PURE__ */ jsx12(
|
|
4170
4738
|
MaterialDirectPoly,
|
|
4171
4739
|
{
|
|
4172
4740
|
plan: atlasPlan,
|
|
@@ -4182,7 +4750,7 @@ function PolyInner({
|
|
|
4182
4750
|
} else {
|
|
4183
4751
|
const atlasEntry = textureAtlas.entries[0];
|
|
4184
4752
|
if (atlasEntry) {
|
|
4185
|
-
front = /* @__PURE__ */
|
|
4753
|
+
front = /* @__PURE__ */ jsx12(
|
|
4186
4754
|
TextureAtlasPoly,
|
|
4187
4755
|
{
|
|
4188
4756
|
entry: atlasEntry,
|
|
@@ -4196,7 +4764,7 @@ function PolyInner({
|
|
|
4196
4764
|
}
|
|
4197
4765
|
);
|
|
4198
4766
|
} else if (atlasPlan && !atlasPlan.texture) {
|
|
4199
|
-
front = isSolidTrianglePlan2(atlasPlan) ? /* @__PURE__ */
|
|
4767
|
+
front = isSolidTrianglePlan2(atlasPlan) ? /* @__PURE__ */ jsx12(
|
|
4200
4768
|
TextureTrianglePoly,
|
|
4201
4769
|
{
|
|
4202
4770
|
entry: atlasPlan,
|
|
@@ -4207,7 +4775,7 @@ function PolyInner({
|
|
|
4207
4775
|
domEventHandlers,
|
|
4208
4776
|
pointerEvents: pointerEventsProp ?? "auto"
|
|
4209
4777
|
}
|
|
4210
|
-
) : isProjectiveQuadPlan(atlasPlan) ? /* @__PURE__ */
|
|
4778
|
+
) : isProjectiveQuadPlan(atlasPlan) ? /* @__PURE__ */ jsx12(
|
|
4211
4779
|
TextureProjectiveSolidPoly,
|
|
4212
4780
|
{
|
|
4213
4781
|
entry: atlasPlan,
|
|
@@ -4218,10 +4786,11 @@ function PolyInner({
|
|
|
4218
4786
|
domEventHandlers,
|
|
4219
4787
|
pointerEvents: pointerEventsProp ?? "auto"
|
|
4220
4788
|
}
|
|
4221
|
-
) : /* @__PURE__ */
|
|
4789
|
+
) : /* @__PURE__ */ jsx12(
|
|
4222
4790
|
TextureBorderShapePoly,
|
|
4223
4791
|
{
|
|
4224
4792
|
entry: atlasPlan,
|
|
4793
|
+
textureLighting,
|
|
4225
4794
|
className,
|
|
4226
4795
|
style: styleProp,
|
|
4227
4796
|
domAttrs,
|
|
@@ -4233,7 +4802,7 @@ function PolyInner({
|
|
|
4233
4802
|
}
|
|
4234
4803
|
if (!front) return null;
|
|
4235
4804
|
if (!wrapperTransform) return front;
|
|
4236
|
-
return /* @__PURE__ */
|
|
4805
|
+
return /* @__PURE__ */ jsx12(
|
|
4237
4806
|
"div",
|
|
4238
4807
|
{
|
|
4239
4808
|
className: "polycss-poly-wrapper",
|
|
@@ -4246,7 +4815,7 @@ function PolyInner({
|
|
|
4246
4815
|
}
|
|
4247
4816
|
);
|
|
4248
4817
|
}
|
|
4249
|
-
var Poly =
|
|
4818
|
+
var Poly = memo9(PolyInner);
|
|
4250
4819
|
|
|
4251
4820
|
// src/shapes/PolyShapes.tsx
|
|
4252
4821
|
import { useMemo as useMemo11 } from "react";
|
|
@@ -4263,7 +4832,7 @@ import {
|
|
|
4263
4832
|
conePolygons,
|
|
4264
4833
|
torusPolygons
|
|
4265
4834
|
} from "@layoutit/polycss-core";
|
|
4266
|
-
import { jsx as
|
|
4835
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
4267
4836
|
function PolyBox({
|
|
4268
4837
|
size,
|
|
4269
4838
|
center,
|
|
@@ -4282,7 +4851,7 @@ function PolyBox({
|
|
|
4282
4851
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4283
4852
|
[size, center, min, max, color, texture, material, uvs, data, faces]
|
|
4284
4853
|
);
|
|
4285
|
-
return /* @__PURE__ */
|
|
4854
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4286
4855
|
}
|
|
4287
4856
|
function PolyPlane({
|
|
4288
4857
|
axis,
|
|
@@ -4297,7 +4866,7 @@ function PolyPlane({
|
|
|
4297
4866
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4298
4867
|
[axis, size, offset, along, color]
|
|
4299
4868
|
);
|
|
4300
|
-
return /* @__PURE__ */
|
|
4869
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4301
4870
|
}
|
|
4302
4871
|
function PolyRing({
|
|
4303
4872
|
axis,
|
|
@@ -4312,7 +4881,7 @@ function PolyRing({
|
|
|
4312
4881
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4313
4882
|
[axis, radius, halfThickness, segments, color]
|
|
4314
4883
|
);
|
|
4315
|
-
return /* @__PURE__ */
|
|
4884
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4316
4885
|
}
|
|
4317
4886
|
function PolyOctahedron({
|
|
4318
4887
|
center,
|
|
@@ -4325,7 +4894,7 @@ function PolyOctahedron({
|
|
|
4325
4894
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4326
4895
|
[center, size, color]
|
|
4327
4896
|
);
|
|
4328
|
-
return /* @__PURE__ */
|
|
4897
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4329
4898
|
}
|
|
4330
4899
|
function PolyTetrahedron({
|
|
4331
4900
|
size,
|
|
@@ -4337,7 +4906,7 @@ function PolyTetrahedron({
|
|
|
4337
4906
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4338
4907
|
[size, color]
|
|
4339
4908
|
);
|
|
4340
|
-
return /* @__PURE__ */
|
|
4909
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4341
4910
|
}
|
|
4342
4911
|
function PolyIcosahedron({
|
|
4343
4912
|
size,
|
|
@@ -4349,7 +4918,7 @@ function PolyIcosahedron({
|
|
|
4349
4918
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4350
4919
|
[size, color]
|
|
4351
4920
|
);
|
|
4352
|
-
return /* @__PURE__ */
|
|
4921
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4353
4922
|
}
|
|
4354
4923
|
function PolyDodecahedron({
|
|
4355
4924
|
size,
|
|
@@ -4361,7 +4930,7 @@ function PolyDodecahedron({
|
|
|
4361
4930
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4362
4931
|
[size, color]
|
|
4363
4932
|
);
|
|
4364
|
-
return /* @__PURE__ */
|
|
4933
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4365
4934
|
}
|
|
4366
4935
|
function PolySphere({
|
|
4367
4936
|
radius,
|
|
@@ -4374,7 +4943,7 @@ function PolySphere({
|
|
|
4374
4943
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4375
4944
|
[radius, subdivisions, color]
|
|
4376
4945
|
);
|
|
4377
|
-
return /* @__PURE__ */
|
|
4946
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4378
4947
|
}
|
|
4379
4948
|
function PolyCylinder({
|
|
4380
4949
|
radius,
|
|
@@ -4389,7 +4958,7 @@ function PolyCylinder({
|
|
|
4389
4958
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4390
4959
|
[radius, radiusTop, height, radialSegments, color]
|
|
4391
4960
|
);
|
|
4392
|
-
return /* @__PURE__ */
|
|
4961
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4393
4962
|
}
|
|
4394
4963
|
function PolyCone({
|
|
4395
4964
|
radius,
|
|
@@ -4403,7 +4972,7 @@ function PolyCone({
|
|
|
4403
4972
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4404
4973
|
[radius, height, radialSegments, color]
|
|
4405
4974
|
);
|
|
4406
|
-
return /* @__PURE__ */
|
|
4975
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4407
4976
|
}
|
|
4408
4977
|
function PolyTorus({
|
|
4409
4978
|
radius,
|
|
@@ -4418,12 +4987,12 @@ function PolyTorus({
|
|
|
4418
4987
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4419
4988
|
[radius, tube, radialSegments, tubularSegments, color]
|
|
4420
4989
|
);
|
|
4421
|
-
return /* @__PURE__ */
|
|
4990
|
+
return /* @__PURE__ */ jsx13(PolyMesh, { polygons, ...meshProps });
|
|
4422
4991
|
}
|
|
4423
4992
|
|
|
4424
4993
|
// src/controls/PolyFirstPersonControls.tsx
|
|
4425
|
-
import { useEffect as useEffect6, useRef as
|
|
4426
|
-
import { BASE_TILE as
|
|
4994
|
+
import { useEffect as useEffect6, useRef as useRef7, useImperativeHandle as useImperativeHandle2, forwardRef as forwardRef2 } from "react";
|
|
4995
|
+
import { BASE_TILE as BASE_TILE6 } from "@layoutit/polycss-core";
|
|
4427
4996
|
var DEFAULTS = {
|
|
4428
4997
|
enabled: true,
|
|
4429
4998
|
lookEnabled: true,
|
|
@@ -4483,25 +5052,25 @@ function emitEvent(registry, type) {
|
|
|
4483
5052
|
}
|
|
4484
5053
|
var PolyFirstPersonControls = forwardRef2(function PolyFirstPersonControls2(props, ref) {
|
|
4485
5054
|
const { store, cameraRef, cameraElRef, applyTransformDirect } = useCameraContext();
|
|
4486
|
-
const onChangeRef =
|
|
4487
|
-
const onInteractionStartRef =
|
|
4488
|
-
const onInteractionEndRef =
|
|
5055
|
+
const onChangeRef = useRef7(props.onChange);
|
|
5056
|
+
const onInteractionStartRef = useRef7(props.onInteractionStart);
|
|
5057
|
+
const onInteractionEndRef = useRef7(props.onInteractionEnd);
|
|
4489
5058
|
useEffect6(() => {
|
|
4490
5059
|
onChangeRef.current = props.onChange;
|
|
4491
5060
|
onInteractionStartRef.current = props.onInteractionStart;
|
|
4492
5061
|
onInteractionEndRef.current = props.onInteractionEnd;
|
|
4493
5062
|
});
|
|
4494
|
-
const optsRef =
|
|
4495
|
-
const cameraOriginRef =
|
|
4496
|
-
const rafIdRef =
|
|
4497
|
-
const lastTimeRef =
|
|
4498
|
-
const stoppedRef =
|
|
4499
|
-
const pointerLockedRef =
|
|
4500
|
-
const interactingRef =
|
|
4501
|
-
const keysHeldRef =
|
|
4502
|
-
const verticalVelRef =
|
|
4503
|
-
const jumpOffsetRef =
|
|
4504
|
-
const registryRef =
|
|
5063
|
+
const optsRef = useRef7(resolveOptions(DEFAULTS, props));
|
|
5064
|
+
const cameraOriginRef = useRef7([0, 0, 0]);
|
|
5065
|
+
const rafIdRef = useRef7(null);
|
|
5066
|
+
const lastTimeRef = useRef7(0);
|
|
5067
|
+
const stoppedRef = useRef7(false);
|
|
5068
|
+
const pointerLockedRef = useRef7(false);
|
|
5069
|
+
const interactingRef = useRef7(false);
|
|
5070
|
+
const keysHeldRef = useRef7(/* @__PURE__ */ new Set());
|
|
5071
|
+
const verticalVelRef = useRef7(0);
|
|
5072
|
+
const jumpOffsetRef = useRef7(0);
|
|
5073
|
+
const registryRef = useRef7(makeRegistry());
|
|
4505
5074
|
useImperativeHandle2(ref, () => ({
|
|
4506
5075
|
update(partial) {
|
|
4507
5076
|
const prev = optsRef.current;
|
|
@@ -4599,7 +5168,7 @@ var PolyFirstPersonControls = forwardRef2(function PolyFirstPersonControls2(prop
|
|
|
4599
5168
|
const host = cameraElRef.current;
|
|
4600
5169
|
const perspStr = host ? getComputedStyle(host).perspective : "";
|
|
4601
5170
|
const n = parseFloat(perspStr);
|
|
4602
|
-
return (Number.isFinite(n) && n > 0 ? n :
|
|
5171
|
+
return (Number.isFinite(n) && n > 0 ? n : 32e3) / BASE_TILE6;
|
|
4603
5172
|
}
|
|
4604
5173
|
function deriveTarget() {
|
|
4605
5174
|
const s = cameraRef.current.state;
|
|
@@ -4837,10 +5406,10 @@ var PolyFirstPersonControls = forwardRef2(function PolyFirstPersonControls2(prop
|
|
|
4837
5406
|
});
|
|
4838
5407
|
|
|
4839
5408
|
// src/controls/PolyMapControls.tsx
|
|
4840
|
-
import { useEffect as useEffect7, useRef as
|
|
5409
|
+
import { useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
4841
5410
|
|
|
4842
5411
|
// src/controls/sharedControls.ts
|
|
4843
|
-
import { BASE_TILE as
|
|
5412
|
+
import { BASE_TILE as BASE_TILE7 } from "@layoutit/polycss-core";
|
|
4844
5413
|
var POINTER_DRAG_SPEED = 4;
|
|
4845
5414
|
function invertFactor(invert) {
|
|
4846
5415
|
if (invert === true) return -1;
|
|
@@ -4851,7 +5420,7 @@ function applyOrbit(dx, dy, s, handle, invert) {
|
|
|
4851
5420
|
const f = invertFactor(invert);
|
|
4852
5421
|
const dX = dx / POINTER_DRAG_SPEED * f;
|
|
4853
5422
|
const dY = dy / POINTER_DRAG_SPEED * f;
|
|
4854
|
-
const rotX =
|
|
5423
|
+
const rotX = s.rotX - dY;
|
|
4855
5424
|
const rotY = ((s.rotY - dX) % 360 + 360) % 360;
|
|
4856
5425
|
handle.update({ rotX, rotY });
|
|
4857
5426
|
}
|
|
@@ -4861,7 +5430,7 @@ function applyPan(dx, dy, s, handle, _invert) {
|
|
|
4861
5430
|
const cosRotX = cosRotXRaw >= 0 ? Math.max(0.1, cosRotXRaw) : Math.min(-0.1, cosRotXRaw);
|
|
4862
5431
|
const cZ = Math.cos(s.rotY * Math.PI / 180);
|
|
4863
5432
|
const sZ = Math.sin(s.rotY * Math.PI / 180);
|
|
4864
|
-
const k = z *
|
|
5433
|
+
const k = z * BASE_TILE7;
|
|
4865
5434
|
const targetD0 = (dx * sZ - dy * cZ / cosRotX) / k;
|
|
4866
5435
|
const targetD1 = -(dx * cZ + dy * sZ / cosRotX) / k;
|
|
4867
5436
|
const t = s.target;
|
|
@@ -5010,18 +5579,18 @@ function PolyMapControls({
|
|
|
5010
5579
|
onInteractionEnd
|
|
5011
5580
|
}) {
|
|
5012
5581
|
const { store, cameraRef, cameraElRef, applyTransformDirect } = useCameraContext();
|
|
5013
|
-
const dragRef =
|
|
5014
|
-
const wheelRef =
|
|
5015
|
-
const dollyRef =
|
|
5016
|
-
const invertRef =
|
|
5017
|
-
const zoomMinRef =
|
|
5018
|
-
const zoomMaxRef =
|
|
5019
|
-
const distanceMinRef =
|
|
5020
|
-
const distanceMaxRef =
|
|
5021
|
-
const animateRef =
|
|
5022
|
-
const onChangeRef =
|
|
5023
|
-
const onInteractionStartRef =
|
|
5024
|
-
const onInteractionEndRef =
|
|
5582
|
+
const dragRef = useRef8(drag);
|
|
5583
|
+
const wheelRef = useRef8(wheel);
|
|
5584
|
+
const dollyRef = useRef8(dolly);
|
|
5585
|
+
const invertRef = useRef8(invert);
|
|
5586
|
+
const zoomMinRef = useRef8(minZoom);
|
|
5587
|
+
const zoomMaxRef = useRef8(maxZoom);
|
|
5588
|
+
const distanceMinRef = useRef8(minDistance);
|
|
5589
|
+
const distanceMaxRef = useRef8(maxDistance);
|
|
5590
|
+
const animateRef = useRef8(animate);
|
|
5591
|
+
const onChangeRef = useRef8(onChange);
|
|
5592
|
+
const onInteractionStartRef = useRef8(onInteractionStart);
|
|
5593
|
+
const onInteractionEndRef = useRef8(onInteractionEnd);
|
|
5025
5594
|
useEffect7(() => {
|
|
5026
5595
|
dragRef.current = drag;
|
|
5027
5596
|
wheelRef.current = wheel;
|
|
@@ -5067,7 +5636,7 @@ function PolyMapControls({
|
|
|
5067
5636
|
console.error("[polycss/react] PolyMapControls onInteractionEnd threw:", err);
|
|
5068
5637
|
}
|
|
5069
5638
|
};
|
|
5070
|
-
const animationPausedShared =
|
|
5639
|
+
const animationPausedShared = useRef8({ value: false }).current;
|
|
5071
5640
|
useEffect7(() => {
|
|
5072
5641
|
if (!drag) return;
|
|
5073
5642
|
const el = cameraElRef.current;
|
|
@@ -5192,7 +5761,7 @@ function PolyMapControls({
|
|
|
5192
5761
|
}
|
|
5193
5762
|
|
|
5194
5763
|
// src/controls/PolyOrbitControls.tsx
|
|
5195
|
-
import { useEffect as useEffect8, useRef as
|
|
5764
|
+
import { useEffect as useEffect8, useRef as useRef9 } from "react";
|
|
5196
5765
|
function PolyOrbitControls({
|
|
5197
5766
|
drag = true,
|
|
5198
5767
|
wheel = true,
|
|
@@ -5208,18 +5777,18 @@ function PolyOrbitControls({
|
|
|
5208
5777
|
onInteractionEnd
|
|
5209
5778
|
}) {
|
|
5210
5779
|
const { store, cameraRef, cameraElRef, applyTransformDirect } = useCameraContext();
|
|
5211
|
-
const dragRef =
|
|
5212
|
-
const wheelRef =
|
|
5213
|
-
const dollyRef =
|
|
5214
|
-
const invertRef =
|
|
5215
|
-
const zoomMinRef =
|
|
5216
|
-
const zoomMaxRef =
|
|
5217
|
-
const distanceMinRef =
|
|
5218
|
-
const distanceMaxRef =
|
|
5219
|
-
const animateRef =
|
|
5220
|
-
const onChangeRef =
|
|
5221
|
-
const onInteractionStartRef =
|
|
5222
|
-
const onInteractionEndRef =
|
|
5780
|
+
const dragRef = useRef9(drag);
|
|
5781
|
+
const wheelRef = useRef9(wheel);
|
|
5782
|
+
const dollyRef = useRef9(dolly);
|
|
5783
|
+
const invertRef = useRef9(invert);
|
|
5784
|
+
const zoomMinRef = useRef9(minZoom);
|
|
5785
|
+
const zoomMaxRef = useRef9(maxZoom);
|
|
5786
|
+
const distanceMinRef = useRef9(minDistance);
|
|
5787
|
+
const distanceMaxRef = useRef9(maxDistance);
|
|
5788
|
+
const animateRef = useRef9(animate);
|
|
5789
|
+
const onChangeRef = useRef9(onChange);
|
|
5790
|
+
const onInteractionStartRef = useRef9(onInteractionStart);
|
|
5791
|
+
const onInteractionEndRef = useRef9(onInteractionEnd);
|
|
5223
5792
|
useEffect8(() => {
|
|
5224
5793
|
dragRef.current = drag;
|
|
5225
5794
|
wheelRef.current = wheel;
|
|
@@ -5265,7 +5834,7 @@ function PolyOrbitControls({
|
|
|
5265
5834
|
console.error("[polycss/react] PolyOrbitControls onInteractionEnd threw:", err);
|
|
5266
5835
|
}
|
|
5267
5836
|
};
|
|
5268
|
-
const animationPausedShared =
|
|
5837
|
+
const animationPausedShared = useRef9({ value: false }).current;
|
|
5269
5838
|
useEffect8(() => {
|
|
5270
5839
|
if (!drag) return;
|
|
5271
5840
|
const el = cameraElRef.current;
|
|
@@ -5391,11 +5960,11 @@ function PolyOrbitControls({
|
|
|
5391
5960
|
|
|
5392
5961
|
// src/controls/TransformControls.tsx
|
|
5393
5962
|
import {
|
|
5394
|
-
useCallback as
|
|
5963
|
+
useCallback as useCallback8,
|
|
5395
5964
|
useContext as useContext4,
|
|
5396
5965
|
useEffect as useEffect9,
|
|
5397
5966
|
useMemo as useMemo12,
|
|
5398
|
-
useRef as
|
|
5967
|
+
useRef as useRef10,
|
|
5399
5968
|
useState as useState5
|
|
5400
5969
|
} from "react";
|
|
5401
5970
|
import {
|
|
@@ -5408,7 +5977,7 @@ import {
|
|
|
5408
5977
|
quatMultiply,
|
|
5409
5978
|
ringQuadPolygons
|
|
5410
5979
|
} from "@layoutit/polycss-core";
|
|
5411
|
-
import { jsx as
|
|
5980
|
+
import { jsx as jsx14, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5412
5981
|
var FALLBACK_CAMERA_STORE = createSceneStore(DEFAULT_CAMERA_STATE);
|
|
5413
5982
|
var COLOR_X = "#ff3653";
|
|
5414
5983
|
var COLOR_Y = "#8adb00";
|
|
@@ -5755,7 +6324,7 @@ function PolyTransformControls({
|
|
|
5755
6324
|
const [draggingKey, setDraggingKey] = useState5(null);
|
|
5756
6325
|
const cameraCtx = useContext4(PolyCameraContext);
|
|
5757
6326
|
const cameraElRef = cameraCtx?.cameraElRef;
|
|
5758
|
-
const dragRef =
|
|
6327
|
+
const dragRef = useRef10({
|
|
5759
6328
|
target: null,
|
|
5760
6329
|
mode: "translate",
|
|
5761
6330
|
shaftLengthCss: 0,
|
|
@@ -5886,10 +6455,13 @@ function PolyTransformControls({
|
|
|
5886
6455
|
const position = target.getPosition() ?? [0, 0, 0];
|
|
5887
6456
|
const polygons = target.getPolygons();
|
|
5888
6457
|
const bboxCenter = gizmoCenterForMesh(polygons);
|
|
6458
|
+
const cssPosX = position[1] * SCENE_TILE_SIZE;
|
|
6459
|
+
const cssPosY = position[0] * SCENE_TILE_SIZE;
|
|
6460
|
+
const cssPosZ = position[2] * SCENE_TILE_SIZE;
|
|
5889
6461
|
const wrapperPos = [
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
6462
|
+
cssPosX + bboxCenter[0],
|
|
6463
|
+
cssPosY + bboxCenter[1],
|
|
6464
|
+
cssPosZ + bboxCenter[2]
|
|
5893
6465
|
];
|
|
5894
6466
|
const baseLength = gizmoLengthForMesh(polygons);
|
|
5895
6467
|
const shaftLengthCss = baseLength * size;
|
|
@@ -5934,7 +6506,7 @@ function PolyTransformControls({
|
|
|
5934
6506
|
const dragging = draggingKey === spec.key;
|
|
5935
6507
|
const alpha = dragging ? ALPHA_DRAGGING : hovered ? ALPHA_HOVER : ALPHA_IDLE;
|
|
5936
6508
|
const backFacing = isAxisBackFacing(spec.cssAxis, spec.sign, rotX, rotY);
|
|
5937
|
-
return /* @__PURE__ */
|
|
6509
|
+
return /* @__PURE__ */ jsx14(
|
|
5938
6510
|
TranslateArrow,
|
|
5939
6511
|
{
|
|
5940
6512
|
cssAxis: spec.cssAxis,
|
|
@@ -5966,7 +6538,7 @@ function PolyTransformControls({
|
|
|
5966
6538
|
const hovered = hoveredKey === spec.key;
|
|
5967
6539
|
const dragging = draggingKey === spec.key;
|
|
5968
6540
|
const alpha = dragging ? ALPHA_DRAGGING : hovered ? ALPHA_HOVER : ALPHA_IDLE;
|
|
5969
|
-
return /* @__PURE__ */
|
|
6541
|
+
return /* @__PURE__ */ jsx14(
|
|
5970
6542
|
TranslatePlane,
|
|
5971
6543
|
{
|
|
5972
6544
|
axisA: spec.axisA,
|
|
@@ -5998,7 +6570,7 @@ function PolyTransformControls({
|
|
|
5998
6570
|
const hovered = hoveredKey === spec.key;
|
|
5999
6571
|
const dragging = draggingKey === spec.key;
|
|
6000
6572
|
const alpha = dragging ? ALPHA_DRAGGING : hovered ? ALPHA_HOVER : ALPHA_IDLE;
|
|
6001
|
-
return /* @__PURE__ */
|
|
6573
|
+
return /* @__PURE__ */ jsx14(
|
|
6002
6574
|
RotateRing,
|
|
6003
6575
|
{
|
|
6004
6576
|
cssAxis: spec.cssAxis,
|
|
@@ -6043,7 +6615,7 @@ function TranslateArrow({
|
|
|
6043
6615
|
onDraggingStart,
|
|
6044
6616
|
onDraggingStop
|
|
6045
6617
|
}) {
|
|
6046
|
-
const cbRef =
|
|
6618
|
+
const cbRef = useRef10({
|
|
6047
6619
|
onChange,
|
|
6048
6620
|
onObjectChange,
|
|
6049
6621
|
onMouseDown,
|
|
@@ -6078,7 +6650,7 @@ function TranslateArrow({
|
|
|
6078
6650
|
shaft: includeShaft
|
|
6079
6651
|
});
|
|
6080
6652
|
}, [cssAxis, sign, color, shaftLengthCss, includeShaft]);
|
|
6081
|
-
const onPointerDown =
|
|
6653
|
+
const onPointerDown = useCallback8(
|
|
6082
6654
|
(e) => {
|
|
6083
6655
|
if (!cbRef.current.enabled) return;
|
|
6084
6656
|
e.stopPropagation();
|
|
@@ -6107,7 +6679,7 @@ function TranslateArrow({
|
|
|
6107
6679
|
},
|
|
6108
6680
|
[cssAxis, sign, target, shaftLengthCss]
|
|
6109
6681
|
);
|
|
6110
|
-
return /* @__PURE__ */
|
|
6682
|
+
return /* @__PURE__ */ jsx14(
|
|
6111
6683
|
PolyMesh,
|
|
6112
6684
|
{
|
|
6113
6685
|
polygons,
|
|
@@ -6140,7 +6712,7 @@ function TranslatePlane({
|
|
|
6140
6712
|
onDraggingStart,
|
|
6141
6713
|
onDraggingStop
|
|
6142
6714
|
}) {
|
|
6143
|
-
const cbRef =
|
|
6715
|
+
const cbRef = useRef10({
|
|
6144
6716
|
onChange,
|
|
6145
6717
|
onObjectChange,
|
|
6146
6718
|
onMouseDown,
|
|
@@ -6179,7 +6751,7 @@ function TranslatePlane({
|
|
|
6179
6751
|
color
|
|
6180
6752
|
});
|
|
6181
6753
|
}, [perpAxis, color, shaftLengthCss, rotX, rotY]);
|
|
6182
|
-
const onPointerDown =
|
|
6754
|
+
const onPointerDown = useCallback8(
|
|
6183
6755
|
(e) => {
|
|
6184
6756
|
if (!cbRef.current.enabled) return;
|
|
6185
6757
|
e.stopPropagation();
|
|
@@ -6208,7 +6780,7 @@ function TranslatePlane({
|
|
|
6208
6780
|
},
|
|
6209
6781
|
[axisA, axisB, target, shaftLengthCss]
|
|
6210
6782
|
);
|
|
6211
|
-
return /* @__PURE__ */
|
|
6783
|
+
return /* @__PURE__ */ jsx14(
|
|
6212
6784
|
PolyMesh,
|
|
6213
6785
|
{
|
|
6214
6786
|
polygons,
|
|
@@ -6237,7 +6809,7 @@ function RotateRing({
|
|
|
6237
6809
|
onDraggingStart,
|
|
6238
6810
|
onDraggingStop
|
|
6239
6811
|
}) {
|
|
6240
|
-
const cbRef =
|
|
6812
|
+
const cbRef = useRef10({
|
|
6241
6813
|
onChange,
|
|
6242
6814
|
onObjectChange,
|
|
6243
6815
|
onMouseDown,
|
|
@@ -6270,7 +6842,7 @@ function RotateRing({
|
|
|
6270
6842
|
}, [cssAxis, color, radiusCss]);
|
|
6271
6843
|
const ringInnerRatio = (1 - RING_HALF_THICKNESS_RATIO) / RING_QUAD_OUTER_RATIO;
|
|
6272
6844
|
const ringOuterRatio = (1 + RING_HALF_THICKNESS_RATIO) / RING_QUAD_OUTER_RATIO;
|
|
6273
|
-
const onPointerDown =
|
|
6845
|
+
const onPointerDown = useCallback8(
|
|
6274
6846
|
(e) => {
|
|
6275
6847
|
if (!cbRef.current.enabled) return;
|
|
6276
6848
|
e.stopPropagation();
|
|
@@ -6297,7 +6869,7 @@ function RotateRing({
|
|
|
6297
6869
|
},
|
|
6298
6870
|
[cssAxis, target]
|
|
6299
6871
|
);
|
|
6300
|
-
return /* @__PURE__ */
|
|
6872
|
+
return /* @__PURE__ */ jsx14(
|
|
6301
6873
|
PolyMesh,
|
|
6302
6874
|
{
|
|
6303
6875
|
polygons,
|
|
@@ -6317,14 +6889,14 @@ function RotateRing({
|
|
|
6317
6889
|
// src/select/Select.tsx
|
|
6318
6890
|
import {
|
|
6319
6891
|
createContext as createContext3,
|
|
6320
|
-
useCallback as
|
|
6892
|
+
useCallback as useCallback9,
|
|
6321
6893
|
useContext as useContext5,
|
|
6322
6894
|
useEffect as useEffect10,
|
|
6323
6895
|
useMemo as useMemo13,
|
|
6324
|
-
useRef as
|
|
6896
|
+
useRef as useRef11,
|
|
6325
6897
|
useState as useState6
|
|
6326
6898
|
} from "react";
|
|
6327
|
-
import { jsx as
|
|
6899
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
6328
6900
|
var SelectContext = createContext3(null);
|
|
6329
6901
|
function PolySelect({
|
|
6330
6902
|
multiple = false,
|
|
@@ -6337,13 +6909,13 @@ function PolySelect({
|
|
|
6337
6909
|
style
|
|
6338
6910
|
}) {
|
|
6339
6911
|
const [selected, setSelectedState] = useState6([]);
|
|
6340
|
-
const filterRef =
|
|
6912
|
+
const filterRef = useRef11(filter);
|
|
6341
6913
|
filterRef.current = filter;
|
|
6342
|
-
const onChangeRef =
|
|
6914
|
+
const onChangeRef = useRef11(onChange);
|
|
6343
6915
|
onChangeRef.current = onChange;
|
|
6344
|
-
const multipleRef =
|
|
6916
|
+
const multipleRef = useRef11(multiple);
|
|
6345
6917
|
multipleRef.current = multiple;
|
|
6346
|
-
const apply =
|
|
6918
|
+
const apply = useCallback9((next) => {
|
|
6347
6919
|
const filtered = filterRef.current ? filterRef.current(next) : next;
|
|
6348
6920
|
setSelectedState(filtered);
|
|
6349
6921
|
if (onChangeRef.current) onChangeRef.current(filtered);
|
|
@@ -6381,14 +6953,14 @@ function PolySelect({
|
|
|
6381
6953
|
has: (h) => selected.includes(h)
|
|
6382
6954
|
};
|
|
6383
6955
|
}, [selected, apply]);
|
|
6384
|
-
const wrapperRef =
|
|
6956
|
+
const wrapperRef = useRef11(null);
|
|
6385
6957
|
const cameraCtx = useContext5(PolyCameraContext);
|
|
6386
6958
|
const cameraElRef = cameraCtx?.cameraElRef;
|
|
6387
|
-
const clearOnMissRef =
|
|
6959
|
+
const clearOnMissRef = useRef11(clearOnMiss);
|
|
6388
6960
|
clearOnMissRef.current = clearOnMiss;
|
|
6389
|
-
const onPointerMissedRef =
|
|
6961
|
+
const onPointerMissedRef = useRef11(onPointerMissed);
|
|
6390
6962
|
onPointerMissedRef.current = onPointerMissed;
|
|
6391
|
-
const findMeshUnderPoint2 =
|
|
6963
|
+
const findMeshUnderPoint2 = useCallback9(
|
|
6392
6964
|
(clientX, clientY) => findMeshUnderPoint(
|
|
6393
6965
|
clientX,
|
|
6394
6966
|
clientY,
|
|
@@ -6443,7 +7015,7 @@ function PolySelect({
|
|
|
6443
7015
|
}
|
|
6444
7016
|
};
|
|
6445
7017
|
const wrapperStyle = { display: "contents", ...style };
|
|
6446
|
-
return /* @__PURE__ */
|
|
7018
|
+
return /* @__PURE__ */ jsx15(SelectContext.Provider, { value: api, children: /* @__PURE__ */ jsx15(
|
|
6447
7019
|
"div",
|
|
6448
7020
|
{
|
|
6449
7021
|
ref: wrapperRef,
|
|
@@ -6469,7 +7041,7 @@ function usePolySelectionApi() {
|
|
|
6469
7041
|
// src/helpers/PolyAxesHelper.tsx
|
|
6470
7042
|
import { useMemo as useMemo14 } from "react";
|
|
6471
7043
|
import { axesHelperPolygons } from "@layoutit/polycss-core";
|
|
6472
|
-
import { jsx as
|
|
7044
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
6473
7045
|
function PolyAxesHelper({
|
|
6474
7046
|
size,
|
|
6475
7047
|
thickness,
|
|
@@ -6482,14 +7054,13 @@ function PolyAxesHelper({
|
|
|
6482
7054
|
() => axesHelperPolygons({ size, thickness, negative, xColor, yColor, zColor }),
|
|
6483
7055
|
[size, thickness, negative, xColor, yColor, zColor]
|
|
6484
7056
|
);
|
|
6485
|
-
return /* @__PURE__ */
|
|
7057
|
+
return /* @__PURE__ */ jsx16(PolyMesh, { polygons, merge: false });
|
|
6486
7058
|
}
|
|
6487
7059
|
|
|
6488
7060
|
// src/helpers/PolyDirectionalLightHelper.tsx
|
|
6489
7061
|
import { useMemo as useMemo15 } from "react";
|
|
6490
7062
|
import { octahedronPolygons as octahedronPolygons2 } from "@layoutit/polycss-core";
|
|
6491
|
-
import { jsx as
|
|
6492
|
-
var TILE = 50;
|
|
7063
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
6493
7064
|
function PolyDirectionalLightHelper({
|
|
6494
7065
|
light,
|
|
6495
7066
|
target,
|
|
@@ -6508,12 +7079,13 @@ function PolyDirectionalLightHelper({
|
|
|
6508
7079
|
const tx = target?.[0] ?? 0;
|
|
6509
7080
|
const ty = target?.[1] ?? 0;
|
|
6510
7081
|
const tz = target?.[2] ?? 0;
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
7082
|
+
return [
|
|
7083
|
+
tx + dx / len * distance,
|
|
7084
|
+
ty + dy / len * distance,
|
|
7085
|
+
tz + dz / len * distance
|
|
7086
|
+
];
|
|
6515
7087
|
}, [light.direction, target, distance]);
|
|
6516
|
-
return /* @__PURE__ */
|
|
7088
|
+
return /* @__PURE__ */ jsx17(PolyMesh, { polygons, position: meshPosition, merge: false });
|
|
6517
7089
|
}
|
|
6518
7090
|
|
|
6519
7091
|
// src/styles/colorResolver.ts
|
|
@@ -6571,7 +7143,7 @@ function collectPolyRenderStats(root, optionsOrPolygonCount) {
|
|
|
6571
7143
|
surfaceLeafCounts.clippedSolid += queryCount(scope, "i");
|
|
6572
7144
|
surfaceLeafCounts.atlas += queryCount(scope, "s");
|
|
6573
7145
|
surfaceLeafCounts.stableTriangle += queryCount(scope, "u");
|
|
6574
|
-
shadowLeafCount += queryCount(scope, "q");
|
|
7146
|
+
shadowLeafCount += queryCount(scope, "q, .polycss-shadow-svg");
|
|
6575
7147
|
bucketCount += queryCount(scope, ".polycss-bucket");
|
|
6576
7148
|
}
|
|
6577
7149
|
const mountedPolygonLeafCount = surfaceLeafCounts.quad + surfaceLeafCounts.clippedSolid + surfaceLeafCounts.atlas + surfaceLeafCounts.stableTriangle;
|
|
@@ -6585,7 +7157,7 @@ function collectPolyRenderStats(root, optionsOrPolygonCount) {
|
|
|
6585
7157
|
}
|
|
6586
7158
|
|
|
6587
7159
|
// src/animation/usePolyAnimation.ts
|
|
6588
|
-
import { useEffect as useEffect11, useRef as
|
|
7160
|
+
import { useEffect as useEffect11, useRef as useRef12, useMemo as useMemo16 } from "react";
|
|
6589
7161
|
import { createPolyAnimationMixer } from "@layoutit/polycss-core";
|
|
6590
7162
|
function resolveRoot(rootArg) {
|
|
6591
7163
|
if (!rootArg) return null;
|
|
@@ -6593,8 +7165,8 @@ function resolveRoot(rootArg) {
|
|
|
6593
7165
|
return rootArg;
|
|
6594
7166
|
}
|
|
6595
7167
|
function usePolyAnimation(clips, controller, root) {
|
|
6596
|
-
const internalRef =
|
|
6597
|
-
const mixerRef =
|
|
7168
|
+
const internalRef = useRef12(null);
|
|
7169
|
+
const mixerRef = useRef12(null);
|
|
6598
7170
|
useEffect11(() => {
|
|
6599
7171
|
if (!clips || clips.length === 0 || !controller) {
|
|
6600
7172
|
mixerRef.current = null;
|
|
@@ -6670,7 +7242,9 @@ import {
|
|
|
6670
7242
|
normalizePolygons,
|
|
6671
7243
|
mergePolygons as mergePolygons2,
|
|
6672
7244
|
coverPlanarPolygons,
|
|
6673
|
-
optimizeMeshPolygons,
|
|
7245
|
+
optimizeMeshPolygons as optimizeMeshPolygons2,
|
|
7246
|
+
optimizeMeshParseResult,
|
|
7247
|
+
simplifyTriangleMeshPolygons,
|
|
6674
7248
|
repairMeshSeams,
|
|
6675
7249
|
seamFacetSplitPolygons,
|
|
6676
7250
|
seamFacetSplitReport,
|
|
@@ -6691,6 +7265,7 @@ import {
|
|
|
6691
7265
|
parseObj,
|
|
6692
7266
|
parseMtl,
|
|
6693
7267
|
parseGltf,
|
|
7268
|
+
parseStl,
|
|
6694
7269
|
bakeSolidTextureSamples,
|
|
6695
7270
|
bakeSolidTextureSampledPolygons,
|
|
6696
7271
|
loadMesh as loadMesh2,
|
|
@@ -6722,7 +7297,7 @@ import {
|
|
|
6722
7297
|
planePolygons as planePolygons3,
|
|
6723
7298
|
buildSceneContext as buildSceneContext2,
|
|
6724
7299
|
computeSceneBbox as computeSceneBbox2,
|
|
6725
|
-
BASE_TILE as
|
|
7300
|
+
BASE_TILE as BASE_TILE8,
|
|
6726
7301
|
DEFAULT_CAMERA_STATE as DEFAULT_CAMERA_STATE2,
|
|
6727
7302
|
DEFAULT_PROJECTION,
|
|
6728
7303
|
normalizeInvertMultiplier,
|
|
@@ -6735,7 +7310,7 @@ import {
|
|
|
6735
7310
|
LoopPingPong
|
|
6736
7311
|
} from "@layoutit/polycss-core";
|
|
6737
7312
|
export {
|
|
6738
|
-
|
|
7313
|
+
BASE_TILE8 as BASE_TILE,
|
|
6739
7314
|
CAMERA_BACKFACE_CULL_EPS,
|
|
6740
7315
|
DEFAULT_CAMERA_STATE2 as DEFAULT_CAMERA_STATE,
|
|
6741
7316
|
DEFAULT_PROJECTION,
|
|
@@ -6756,6 +7331,7 @@ export {
|
|
|
6756
7331
|
PolyFirstPersonControls,
|
|
6757
7332
|
PolyGround,
|
|
6758
7333
|
PolyIcosahedron,
|
|
7334
|
+
PolyIframe,
|
|
6759
7335
|
PolyMapControls,
|
|
6760
7336
|
PolyMesh,
|
|
6761
7337
|
PolyOctahedron,
|
|
@@ -6810,7 +7386,8 @@ export {
|
|
|
6810
7386
|
normalizePolygons,
|
|
6811
7387
|
octahedronPolygons3 as octahedronPolygons,
|
|
6812
7388
|
optimizeAnimatedMeshPolygons,
|
|
6813
|
-
|
|
7389
|
+
optimizeMeshParseResult,
|
|
7390
|
+
optimizeMeshPolygons2 as optimizeMeshPolygons,
|
|
6814
7391
|
parseColor2 as parseColor,
|
|
6815
7392
|
parseGltf,
|
|
6816
7393
|
parseHexColor3 as parseHexColor,
|
|
@@ -6818,6 +7395,7 @@ export {
|
|
|
6818
7395
|
parseObj,
|
|
6819
7396
|
parsePureColor4 as parsePureColor,
|
|
6820
7397
|
parseRgbColor,
|
|
7398
|
+
parseStl,
|
|
6821
7399
|
parseVox,
|
|
6822
7400
|
planePolygons3 as planePolygons,
|
|
6823
7401
|
pointInMeshElement,
|
|
@@ -6833,6 +7411,7 @@ export {
|
|
|
6833
7411
|
seamOverlapPolygons,
|
|
6834
7412
|
seamOverlapReport,
|
|
6835
7413
|
shadeColor,
|
|
7414
|
+
simplifyTriangleMeshPolygons,
|
|
6836
7415
|
tetrahedronPolygons2 as tetrahedronPolygons,
|
|
6837
7416
|
torusPolygons2 as torusPolygons,
|
|
6838
7417
|
useCameraContext,
|