@layoutit/polycss-react 0.2.5 → 0.2.7
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 +1 -2
- package/dist/index.cjs +813 -195
- package/dist/index.d.cts +150 -5
- package/dist/index.d.ts +150 -5
- package/dist/index.js +732 -103
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -14,7 +14,11 @@ function useCameraContext() {
|
|
|
14
14
|
|
|
15
15
|
// src/camera/useCamera.ts
|
|
16
16
|
import { useRef as useRef2, useCallback as useCallback2, useEffect, useMemo } from "react";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
buildPolyCameraSceneTransform,
|
|
19
|
+
capturePolyCameraSnapshot,
|
|
20
|
+
createIsometricCamera
|
|
21
|
+
} from "@layoutit/polycss-core";
|
|
18
22
|
|
|
19
23
|
// src/store/sceneStore.ts
|
|
20
24
|
import { useSyncExternalStore, useRef, useCallback } from "react";
|
|
@@ -60,6 +64,18 @@ function useStoreSelector(store, selector) {
|
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
// src/camera/useCamera.ts
|
|
67
|
+
function writeCameraSnapshotAttrs(el, camera, projection, perspectiveStyle) {
|
|
68
|
+
if (!el) return;
|
|
69
|
+
const snapshot = capturePolyCameraSnapshot(camera, { projection, perspectiveStyle });
|
|
70
|
+
el.dataset.polycssCameraProjection = snapshot.projection;
|
|
71
|
+
el.dataset.polycssCameraPerspective = snapshot.perspectiveStyle;
|
|
72
|
+
el.dataset.polycssCameraAppliedPerspective = snapshot.appliedPerspectiveStyle;
|
|
73
|
+
el.dataset.polycssCameraZoom = String(snapshot.state.zoom);
|
|
74
|
+
el.dataset.polycssCameraDistance = String(snapshot.state.distance);
|
|
75
|
+
el.dataset.polycssCameraRotX = String(snapshot.state.rotX);
|
|
76
|
+
el.dataset.polycssCameraRotY = String(snapshot.state.rotY);
|
|
77
|
+
el.dataset.polycssCameraTarget = snapshot.state.target.join(",");
|
|
78
|
+
}
|
|
63
79
|
function usePolyCamera(options) {
|
|
64
80
|
const handleRef = useRef2(null);
|
|
65
81
|
if (!handleRef.current) {
|
|
@@ -89,24 +105,33 @@ function usePolyCamera(options) {
|
|
|
89
105
|
handle.update(next);
|
|
90
106
|
const el = sceneElRef.current;
|
|
91
107
|
if (el) {
|
|
92
|
-
el.style.transform =
|
|
93
|
-
...handle.state,
|
|
108
|
+
el.style.transform = buildPolyCameraSceneTransform(handle.state, {
|
|
94
109
|
autoCenterOffset: store.getState().autoCenterOffset
|
|
95
110
|
});
|
|
96
111
|
}
|
|
97
112
|
store.updateCameraFromRef(handle);
|
|
98
113
|
store.notifyAll();
|
|
99
114
|
}
|
|
100
|
-
|
|
115
|
+
writeCameraSnapshotAttrs(cameraElRef.current, handle, options.projection, options.perspectiveStyle);
|
|
116
|
+
}, [
|
|
117
|
+
options.zoom,
|
|
118
|
+
options.target,
|
|
119
|
+
options.rotX,
|
|
120
|
+
options.rotY,
|
|
121
|
+
options.distance,
|
|
122
|
+
options.projection,
|
|
123
|
+
options.perspectiveStyle,
|
|
124
|
+
store
|
|
125
|
+
]);
|
|
101
126
|
const applyTransformDirect = useCallback2(() => {
|
|
102
127
|
const el = sceneElRef.current;
|
|
103
128
|
if (!el) return;
|
|
104
129
|
const handle = handleRef.current;
|
|
105
|
-
el.style.transform =
|
|
106
|
-
...handle.state,
|
|
130
|
+
el.style.transform = buildPolyCameraSceneTransform(handle.state, {
|
|
107
131
|
autoCenterOffset: store.getState().autoCenterOffset
|
|
108
132
|
});
|
|
109
|
-
|
|
133
|
+
writeCameraSnapshotAttrs(cameraElRef.current, handle, options.projection, options.perspectiveStyle);
|
|
134
|
+
}, [store, options.projection, options.perspectiveStyle]);
|
|
110
135
|
return {
|
|
111
136
|
store,
|
|
112
137
|
cameraRef: handleRef,
|
|
@@ -130,18 +155,26 @@ function PolyPerspectiveCameraInner({
|
|
|
130
155
|
className,
|
|
131
156
|
style
|
|
132
157
|
}) {
|
|
158
|
+
const perspectiveValue = `${typeof perspective === "number" ? perspective : DEFAULT_PERSPECTIVE}px`;
|
|
133
159
|
const {
|
|
134
160
|
store,
|
|
135
161
|
cameraRef,
|
|
136
162
|
sceneElRef,
|
|
137
163
|
cameraElRef,
|
|
138
164
|
applyTransformDirect
|
|
139
|
-
} = usePolyCamera({
|
|
165
|
+
} = usePolyCamera({
|
|
166
|
+
zoom,
|
|
167
|
+
target,
|
|
168
|
+
rotX,
|
|
169
|
+
rotY,
|
|
170
|
+
distance,
|
|
171
|
+
projection: "perspective",
|
|
172
|
+
perspectiveStyle: perspectiveValue
|
|
173
|
+
});
|
|
140
174
|
const contextValue = useMemo2(
|
|
141
175
|
() => ({ store, cameraRef, sceneElRef, cameraElRef, applyTransformDirect }),
|
|
142
176
|
[store, cameraRef, sceneElRef, cameraElRef, applyTransformDirect]
|
|
143
177
|
);
|
|
144
|
-
const perspectiveValue = `${typeof perspective === "number" ? perspective : DEFAULT_PERSPECTIVE}px`;
|
|
145
178
|
const cameraStyle = {
|
|
146
179
|
...style,
|
|
147
180
|
perspective: perspectiveValue
|
|
@@ -152,6 +185,14 @@ function PolyPerspectiveCameraInner({
|
|
|
152
185
|
ref: cameraElRef,
|
|
153
186
|
className: `polycss-camera${className ? ` ${className}` : ""}`,
|
|
154
187
|
style: cameraStyle,
|
|
188
|
+
"data-polycss-camera-projection": "perspective",
|
|
189
|
+
"data-polycss-camera-perspective": perspectiveValue,
|
|
190
|
+
"data-polycss-camera-applied-perspective": perspectiveValue,
|
|
191
|
+
"data-polycss-camera-zoom": cameraRef.current.state.zoom,
|
|
192
|
+
"data-polycss-camera-distance": cameraRef.current.state.distance,
|
|
193
|
+
"data-polycss-camera-rot-x": cameraRef.current.state.rotX,
|
|
194
|
+
"data-polycss-camera-rot-y": cameraRef.current.state.rotY,
|
|
195
|
+
"data-polycss-camera-target": cameraRef.current.state.target.join(","),
|
|
155
196
|
children
|
|
156
197
|
}
|
|
157
198
|
) });
|
|
@@ -177,7 +218,15 @@ function PolyOrthographicCameraInner({
|
|
|
177
218
|
sceneElRef,
|
|
178
219
|
cameraElRef,
|
|
179
220
|
applyTransformDirect
|
|
180
|
-
} = usePolyCamera({
|
|
221
|
+
} = usePolyCamera({
|
|
222
|
+
zoom,
|
|
223
|
+
target,
|
|
224
|
+
rotX,
|
|
225
|
+
rotY,
|
|
226
|
+
distance,
|
|
227
|
+
projection: "orthographic",
|
|
228
|
+
perspectiveStyle: "none"
|
|
229
|
+
});
|
|
181
230
|
const contextValue = useMemo3(
|
|
182
231
|
() => ({ store, cameraRef, sceneElRef, cameraElRef, applyTransformDirect }),
|
|
183
232
|
[store, cameraRef, sceneElRef, cameraElRef, applyTransformDirect]
|
|
@@ -197,6 +246,14 @@ function PolyOrthographicCameraInner({
|
|
|
197
246
|
ref: cameraElRef,
|
|
198
247
|
className: `polycss-camera${className ? ` ${className}` : ""}`,
|
|
199
248
|
style: cameraStyle,
|
|
249
|
+
"data-polycss-camera-projection": "orthographic",
|
|
250
|
+
"data-polycss-camera-perspective": "none",
|
|
251
|
+
"data-polycss-camera-applied-perspective": "1000000px",
|
|
252
|
+
"data-polycss-camera-zoom": cameraRef.current.state.zoom,
|
|
253
|
+
"data-polycss-camera-distance": cameraRef.current.state.distance,
|
|
254
|
+
"data-polycss-camera-rot-x": cameraRef.current.state.rotX,
|
|
255
|
+
"data-polycss-camera-rot-y": cameraRef.current.state.rotY,
|
|
256
|
+
"data-polycss-camera-target": cameraRef.current.state.target.join(","),
|
|
200
257
|
children
|
|
201
258
|
}
|
|
202
259
|
) });
|
|
@@ -205,7 +262,13 @@ var PolyOrthographicCamera = memo2(PolyOrthographicCameraInner);
|
|
|
205
262
|
|
|
206
263
|
// src/scene/PolyScene.tsx
|
|
207
264
|
import { memo as memo8, useCallback as useCallback5, useEffect as useEffect3, useLayoutEffect, useMemo as useMemo6, useRef as useRef4, useState as useState2 } from "react";
|
|
208
|
-
import {
|
|
265
|
+
import {
|
|
266
|
+
BASE_TILE,
|
|
267
|
+
DEFAULT_SEAM_BLEED,
|
|
268
|
+
parseHexColor,
|
|
269
|
+
resolvePolyTextureLeafGeometry,
|
|
270
|
+
worldDirectionToCss
|
|
271
|
+
} from "@layoutit/polycss-core";
|
|
209
272
|
|
|
210
273
|
// src/scene/useSceneContext.ts
|
|
211
274
|
import { useMemo as useMemo4 } from "react";
|
|
@@ -379,8 +442,8 @@ var CORE_BASE_STYLES = `
|
|
|
379
442
|
}
|
|
380
443
|
|
|
381
444
|
.polycss-scene s {
|
|
382
|
-
width: var(--polycss-atlas-size, 64px);
|
|
383
|
-
height: var(--polycss-atlas-size, 64px);
|
|
445
|
+
width: var(--polycss-atlas-width, var(--polycss-atlas-size, 64px));
|
|
446
|
+
height: var(--polycss-atlas-height, var(--polycss-atlas-size, 64px));
|
|
384
447
|
}
|
|
385
448
|
|
|
386
449
|
.polycss-scene u {
|
|
@@ -791,13 +854,16 @@ function isSolidTriangleSupported(doc) {
|
|
|
791
854
|
import {
|
|
792
855
|
filterAtlasPlans as filterAtlasPlansCore
|
|
793
856
|
} from "@layoutit/polycss-core";
|
|
794
|
-
function filterAtlasPlans(plans, textureLighting, disabled, doc) {
|
|
857
|
+
function filterAtlasPlans(plans, textureLighting, disabled, doc, textureBackend, textureImageRendering, textureProjection) {
|
|
795
858
|
const d = doc ?? (typeof document !== "undefined" ? document : null);
|
|
796
859
|
return filterAtlasPlansCore(plans, textureLighting, disabled, {
|
|
797
860
|
solidTriangleSupported: isSolidTriangleSupported(doc),
|
|
798
861
|
projectiveQuadSupported: doc ? projectiveQuadSupported(doc) : true,
|
|
799
862
|
borderShapeSupported: isBorderShapeSupported(doc),
|
|
800
|
-
cornerShapeSupported: d ? cornerShapeSupported(d) : false
|
|
863
|
+
cornerShapeSupported: d ? cornerShapeSupported(d) : false,
|
|
864
|
+
textureBackend,
|
|
865
|
+
textureImageRendering,
|
|
866
|
+
textureProjection
|
|
801
867
|
});
|
|
802
868
|
}
|
|
803
869
|
|
|
@@ -812,8 +878,13 @@ function isMobileDocument(doc) {
|
|
|
812
878
|
if (!media) return false;
|
|
813
879
|
return media("(pointer: coarse)").matches || media("(hover: none)").matches;
|
|
814
880
|
}
|
|
815
|
-
function packTextureAtlasPlansWithScale(plans, textureQualityInput, doc) {
|
|
816
|
-
return packTextureAtlasPlansWithScaleCore(
|
|
881
|
+
function packTextureAtlasPlansWithScale(plans, textureQualityInput, doc, textureLeafSizing) {
|
|
882
|
+
return packTextureAtlasPlansWithScaleCore(
|
|
883
|
+
plans,
|
|
884
|
+
textureQualityInput,
|
|
885
|
+
isMobileDocument(doc),
|
|
886
|
+
textureLeafSizing
|
|
887
|
+
);
|
|
817
888
|
}
|
|
818
889
|
|
|
819
890
|
// src/scene/atlas/buildAtlasPages.ts
|
|
@@ -2031,7 +2102,7 @@ function deferRevoke(urls) {
|
|
|
2031
2102
|
if (typeof requestAnimationFrame === "function") requestAnimationFrame(run);
|
|
2032
2103
|
else setTimeout(run, 0);
|
|
2033
2104
|
}
|
|
2034
|
-
function useTextureAtlas(plans, textureLighting, textureQualityInput, strategies, atomic = false) {
|
|
2105
|
+
function useTextureAtlas(plans, textureLighting, textureQualityInput, textureLeafSizing, textureBackend, textureImageRendering, textureProjection, strategies, atomic = false) {
|
|
2035
2106
|
const disabled = useMemo5(
|
|
2036
2107
|
() => new Set(strategies?.disable ?? []),
|
|
2037
2108
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -2042,17 +2113,21 @@ function useTextureAtlas(plans, textureLighting, textureQualityInput, strategies
|
|
|
2042
2113
|
plans,
|
|
2043
2114
|
textureLighting,
|
|
2044
2115
|
disabled,
|
|
2045
|
-
typeof document !== "undefined" ? document : null
|
|
2116
|
+
typeof document !== "undefined" ? document : null,
|
|
2117
|
+
textureBackend,
|
|
2118
|
+
textureImageRendering,
|
|
2119
|
+
textureProjection
|
|
2046
2120
|
),
|
|
2047
|
-
[plans, textureLighting, disabled]
|
|
2121
|
+
[plans, textureLighting, disabled, textureBackend, textureImageRendering, textureProjection]
|
|
2048
2122
|
);
|
|
2049
2123
|
const { packed, atlasScale } = useMemo5(
|
|
2050
2124
|
() => packTextureAtlasPlansWithScale(
|
|
2051
2125
|
atlasPlans,
|
|
2052
2126
|
textureQualityInput,
|
|
2053
|
-
typeof document !== "undefined" ? document : null
|
|
2127
|
+
typeof document !== "undefined" ? document : null,
|
|
2128
|
+
textureLeafSizing
|
|
2054
2129
|
),
|
|
2055
|
-
[atlasPlans, textureQualityInput]
|
|
2130
|
+
[atlasPlans, textureQualityInput, textureLeafSizing]
|
|
2056
2131
|
);
|
|
2057
2132
|
const [pages, setPages] = useState(() => pageShells(packed.pages));
|
|
2058
2133
|
const [frame, setFrame] = useState(() => ({
|
|
@@ -2405,12 +2480,13 @@ var TextureCornerShapeSolidPoly = memo6(function TextureCornerShapeSolidPoly2({
|
|
|
2405
2480
|
|
|
2406
2481
|
// src/scene/atlas/atlasPoly.tsx
|
|
2407
2482
|
import { memo as memo7 } from "react";
|
|
2408
|
-
import { formatMatrix3d, formatCssLengthPx } from "@layoutit/polycss-core";
|
|
2483
|
+
import { formatMatrix3d, formatCssLengthPx, resolvePolyTextureImageRendering } from "@layoutit/polycss-core";
|
|
2409
2484
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2410
2485
|
var TextureAtlasPoly = memo7(function TextureAtlasPoly2({
|
|
2411
2486
|
entry,
|
|
2412
2487
|
page,
|
|
2413
2488
|
textureLighting,
|
|
2489
|
+
textureImageRendering,
|
|
2414
2490
|
solidPaintDefaults: _solidPaintDefaults,
|
|
2415
2491
|
className,
|
|
2416
2492
|
style: styleProp,
|
|
@@ -2420,26 +2496,26 @@ var TextureAtlasPoly = memo7(function TextureAtlasPoly2({
|
|
|
2420
2496
|
}) {
|
|
2421
2497
|
const ATLAS_CANONICAL_SIZE_EXPLICIT = 64;
|
|
2422
2498
|
const dynamic = textureLighting === "dynamic";
|
|
2499
|
+
const resolvedImageRendering = resolvePolyTextureImageRendering(entry.polygon, textureImageRendering);
|
|
2423
2500
|
const atlasCanonicalSize = entry.atlasCanonicalSize ?? ATLAS_CANONICAL_SIZE_EXPLICIT;
|
|
2501
|
+
const atlasLeafWidth = entry.atlasLeafWidth ?? atlasCanonicalSize;
|
|
2502
|
+
const atlasLeafHeight = entry.atlasLeafHeight ?? atlasCanonicalSize;
|
|
2424
2503
|
const atlasWidth = entry.canvasW || 1;
|
|
2425
2504
|
const atlasHeight = entry.canvasH || 1;
|
|
2426
|
-
const atlasPosition = page ? `${formatCssLengthPx(-entry.x / atlasWidth *
|
|
2427
|
-
const atlasSize = page ? `${formatCssLengthPx(page.width / atlasWidth *
|
|
2505
|
+
const atlasPosition = page ? `${formatCssLengthPx(-entry.x / atlasWidth * atlasLeafWidth)} ${formatCssLengthPx(-entry.y / atlasHeight * atlasLeafHeight)}` : void 0;
|
|
2506
|
+
const atlasSize = page ? `${formatCssLengthPx(page.width / atlasWidth * atlasLeafWidth)} ${formatCssLengthPx(page.height / atlasHeight * atlasLeafHeight)}` : void 0;
|
|
2428
2507
|
const dynamicMask = dynamic && page?.url ? `url(${page.url})` : void 0;
|
|
2429
|
-
const background = !dynamic && page?.url ? `url(${page.url}) ${atlasPosition} / ${atlasSize} no-repeat` : void 0;
|
|
2430
2508
|
const style = {
|
|
2431
2509
|
transform: formatMatrix3d(entry.atlasMatrix),
|
|
2432
2510
|
["--polycss-atlas-size"]: `${atlasCanonicalSize}px`,
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
backgroundSize: atlasSize
|
|
2442
|
-
} : { background },
|
|
2511
|
+
["--polycss-atlas-width"]: formatCssLengthPx(atlasLeafWidth),
|
|
2512
|
+
["--polycss-atlas-height"]: formatCssLengthPx(atlasLeafHeight),
|
|
2513
|
+
["--polycss-atlas-leaf-sizing"]: entry.atlasLeafSizing ?? "canonical",
|
|
2514
|
+
backgroundImage: page?.url ? `url(${page.url})` : void 0,
|
|
2515
|
+
backgroundPosition: atlasPosition,
|
|
2516
|
+
backgroundSize: atlasSize,
|
|
2517
|
+
backgroundRepeat: page?.url ? "no-repeat" : void 0,
|
|
2518
|
+
imageRendering: resolvedImageRendering === "pixelated" ? "pixelated" : void 0,
|
|
2443
2519
|
...dynamic ? {
|
|
2444
2520
|
["--pnx"]: entry.normal[0].toFixed(4),
|
|
2445
2521
|
["--pny"]: entry.normal[1].toFixed(4),
|
|
@@ -2470,6 +2546,74 @@ var TextureAtlasPoly = memo7(function TextureAtlasPoly2({
|
|
|
2470
2546
|
className: elementClassName,
|
|
2471
2547
|
style,
|
|
2472
2548
|
"data-poly-index": entry.index,
|
|
2549
|
+
"data-polycss-leaf": "polygon",
|
|
2550
|
+
"data-polycss-texture-backend": "atlas",
|
|
2551
|
+
"data-polycss-texture-leaf-sizing": entry.atlasLeafSizing ?? "canonical",
|
|
2552
|
+
"data-polycss-texture-ready": page?.url ? "true" : "false",
|
|
2553
|
+
"data-polycss-texture-image-rendering": resolvedImageRendering,
|
|
2554
|
+
"data-polycss-texture-projection": "affine",
|
|
2555
|
+
"data-polycss-texture-lighting": textureLighting,
|
|
2556
|
+
"data-polycss-texture-leaf-width": atlasLeafWidth,
|
|
2557
|
+
"data-polycss-texture-leaf-height": atlasLeafHeight,
|
|
2558
|
+
"data-polycss-double-sided": entry.polygon.doubleSided ? "true" : void 0,
|
|
2559
|
+
...domEventHandlers,
|
|
2560
|
+
...dataAttrs,
|
|
2561
|
+
...domAttrs
|
|
2562
|
+
}
|
|
2563
|
+
);
|
|
2564
|
+
});
|
|
2565
|
+
var TextureImagePoly = memo7(function TextureImagePoly2({
|
|
2566
|
+
plan,
|
|
2567
|
+
geometry,
|
|
2568
|
+
className,
|
|
2569
|
+
style: styleProp,
|
|
2570
|
+
domAttrs,
|
|
2571
|
+
domEventHandlers,
|
|
2572
|
+
pointerEvents = "auto"
|
|
2573
|
+
}) {
|
|
2574
|
+
const style = {
|
|
2575
|
+
transform: formatMatrix3d(geometry.matrix),
|
|
2576
|
+
["--polycss-atlas-width"]: formatCssLengthPx(geometry.leafWidth),
|
|
2577
|
+
["--polycss-atlas-height"]: formatCssLengthPx(geometry.leafHeight),
|
|
2578
|
+
["--polycss-atlas-leaf-sizing"]: "image",
|
|
2579
|
+
backgroundImage: `url(${geometry.url})`,
|
|
2580
|
+
backgroundPosition: `${formatCssLengthPx(geometry.backgroundPosition[0])} ${formatCssLengthPx(geometry.backgroundPosition[1])}`,
|
|
2581
|
+
backgroundSize: `${formatCssLengthPx(geometry.backgroundSize[0])} ${formatCssLengthPx(geometry.backgroundSize[1])}`,
|
|
2582
|
+
backgroundRepeat: "no-repeat",
|
|
2583
|
+
backgroundBlendMode: "normal",
|
|
2584
|
+
maskImage: "none",
|
|
2585
|
+
WebkitMaskImage: "none",
|
|
2586
|
+
imageRendering: geometry.imageRendering === "pixelated" ? "pixelated" : void 0,
|
|
2587
|
+
["--pnx"]: plan.normal[0].toFixed(4),
|
|
2588
|
+
["--pny"]: plan.normal[1].toFixed(4),
|
|
2589
|
+
["--pnz"]: plan.normal[2].toFixed(4),
|
|
2590
|
+
pointerEvents: pointerEvents === "none" ? "none" : void 0,
|
|
2591
|
+
...styleProp
|
|
2592
|
+
};
|
|
2593
|
+
const dataAttrs = plan.polygon.data ? Object.fromEntries(
|
|
2594
|
+
Object.entries(plan.polygon.data).map(([k, v]) => [`data-${k}`, String(v)])
|
|
2595
|
+
) : {};
|
|
2596
|
+
const elementClassName = className?.trim() || void 0;
|
|
2597
|
+
return /* @__PURE__ */ jsx7(
|
|
2598
|
+
"s",
|
|
2599
|
+
{
|
|
2600
|
+
className: elementClassName,
|
|
2601
|
+
style,
|
|
2602
|
+
"data-poly-index": plan.index,
|
|
2603
|
+
"data-polycss-leaf": "polygon",
|
|
2604
|
+
"data-polycss-texture-backend": "image",
|
|
2605
|
+
"data-polycss-texture-leaf-sizing": "image",
|
|
2606
|
+
"data-polycss-texture-ready": "true",
|
|
2607
|
+
"data-polycss-texture-image-rendering": geometry.imageRendering,
|
|
2608
|
+
"data-polycss-texture-projection": geometry.projection,
|
|
2609
|
+
"data-polycss-texture-lighting": geometry.lighting,
|
|
2610
|
+
"data-polycss-texture-leaf-width": geometry.leafWidth,
|
|
2611
|
+
"data-polycss-texture-leaf-height": geometry.leafHeight,
|
|
2612
|
+
"data-polycss-double-sided": plan.polygon.doubleSided ? "true" : void 0,
|
|
2613
|
+
"data-polycss-texture-source-x": geometry.sourceRect.x,
|
|
2614
|
+
"data-polycss-texture-source-y": geometry.sourceRect.y,
|
|
2615
|
+
"data-polycss-texture-source-width": geometry.sourceRect.width,
|
|
2616
|
+
"data-polycss-texture-source-height": geometry.sourceRect.height,
|
|
2473
2617
|
...domEventHandlers,
|
|
2474
2618
|
...dataAttrs,
|
|
2475
2619
|
...domAttrs
|
|
@@ -2494,9 +2638,14 @@ function PolySceneInner({
|
|
|
2494
2638
|
rotY: _rotY,
|
|
2495
2639
|
zoom: _zoom,
|
|
2496
2640
|
directionalLight,
|
|
2641
|
+
pointLights,
|
|
2497
2642
|
ambientLight,
|
|
2498
2643
|
textureLighting = "baked",
|
|
2499
2644
|
textureQuality,
|
|
2645
|
+
textureLeafSizing,
|
|
2646
|
+
textureImageRendering,
|
|
2647
|
+
textureBackend,
|
|
2648
|
+
textureProjection,
|
|
2500
2649
|
seamBleed = DEFAULT_SEAM_BLEED,
|
|
2501
2650
|
strategies,
|
|
2502
2651
|
autoCenter = false,
|
|
@@ -2547,17 +2696,19 @@ function PolySceneInner({
|
|
|
2547
2696
|
const sceneBbox = centerInputPolygons ? centerSceneBbox : renderSceneBbox;
|
|
2548
2697
|
const directionalForAtlas = textureLighting === "dynamic" ? void 0 : directionalLight;
|
|
2549
2698
|
const ambientForAtlas = textureLighting === "dynamic" ? void 0 : ambientLight;
|
|
2699
|
+
const pointLightsForAtlas = textureLighting === "dynamic" ? void 0 : pointLights;
|
|
2550
2700
|
const polyContext = useMemo6(() => {
|
|
2551
2701
|
const tileSize = 50;
|
|
2552
2702
|
return {
|
|
2553
2703
|
tileSize,
|
|
2554
2704
|
layerElevation: tileSize,
|
|
2555
2705
|
directionalLight: directionalForAtlas,
|
|
2706
|
+
pointLights: pointLightsForAtlas,
|
|
2556
2707
|
ambientLight: ambientForAtlas,
|
|
2557
2708
|
textureLighting,
|
|
2558
2709
|
seamBleed
|
|
2559
2710
|
};
|
|
2560
|
-
}, [directionalForAtlas, ambientForAtlas, textureLighting, seamBleed]);
|
|
2711
|
+
}, [directionalForAtlas, pointLightsForAtlas, ambientForAtlas, textureLighting, seamBleed]);
|
|
2561
2712
|
const autoCenterOffset = useMemo6(() => {
|
|
2562
2713
|
if (!autoCenter) return [0, 0, 0];
|
|
2563
2714
|
return [
|
|
@@ -2592,7 +2743,16 @@ function PolySceneInner({
|
|
|
2592
2743
|
},
|
|
2593
2744
|
[polygons, polyContext, seamBleed, directionalForAtlas, ambientForAtlas]
|
|
2594
2745
|
);
|
|
2595
|
-
const textureAtlas = useTextureAtlas(
|
|
2746
|
+
const textureAtlas = useTextureAtlas(
|
|
2747
|
+
textureAtlasPlans,
|
|
2748
|
+
textureLighting,
|
|
2749
|
+
textureQuality,
|
|
2750
|
+
textureLeafSizing,
|
|
2751
|
+
textureBackend,
|
|
2752
|
+
textureImageRendering,
|
|
2753
|
+
textureProjection,
|
|
2754
|
+
strategies
|
|
2755
|
+
);
|
|
2596
2756
|
const dynamicLightVars = useMemo6(() => {
|
|
2597
2757
|
if (textureLighting !== "dynamic") return null;
|
|
2598
2758
|
const userDir = directionalLight?.direction ?? [0.4, -0.7, 0.59];
|
|
@@ -2690,12 +2850,28 @@ function PolySceneInner({
|
|
|
2690
2850
|
{
|
|
2691
2851
|
entry,
|
|
2692
2852
|
page: textureAtlas.pages[entry.pageIndex],
|
|
2693
|
-
textureLighting
|
|
2853
|
+
textureLighting,
|
|
2854
|
+
textureImageRendering
|
|
2694
2855
|
},
|
|
2695
2856
|
entry.index
|
|
2696
2857
|
);
|
|
2697
2858
|
}
|
|
2698
2859
|
const plan = textureAtlasPlans[index];
|
|
2860
|
+
const imageGeometry = plan ? resolvePolyTextureLeafGeometry(plan, {
|
|
2861
|
+
imageRendering: textureImageRendering,
|
|
2862
|
+
backend: textureBackend,
|
|
2863
|
+
projection: textureProjection
|
|
2864
|
+
}) : null;
|
|
2865
|
+
if (plan && imageGeometry) {
|
|
2866
|
+
return /* @__PURE__ */ jsx8(
|
|
2867
|
+
TextureImagePoly,
|
|
2868
|
+
{
|
|
2869
|
+
plan,
|
|
2870
|
+
geometry: imageGeometry
|
|
2871
|
+
},
|
|
2872
|
+
plan.index
|
|
2873
|
+
);
|
|
2874
|
+
}
|
|
2699
2875
|
if (!plan || plan.texture) return null;
|
|
2700
2876
|
const useU = !disabledStrategies?.has("u");
|
|
2701
2877
|
const useProjectiveSolid = !disabledStrategies?.has("b");
|
|
@@ -2718,9 +2894,14 @@ function PolySceneInner({
|
|
|
2718
2894
|
() => ({
|
|
2719
2895
|
textureLighting,
|
|
2720
2896
|
directionalLight,
|
|
2897
|
+
pointLights,
|
|
2721
2898
|
ambientLight,
|
|
2722
2899
|
strategies,
|
|
2723
2900
|
seamBleed,
|
|
2901
|
+
textureLeafSizing,
|
|
2902
|
+
textureImageRendering,
|
|
2903
|
+
textureBackend,
|
|
2904
|
+
textureProjection,
|
|
2724
2905
|
shadow,
|
|
2725
2906
|
registerShadowCaster,
|
|
2726
2907
|
registerShadowReceiver,
|
|
@@ -2730,7 +2911,7 @@ function PolySceneInner({
|
|
|
2730
2911
|
groundCssZ,
|
|
2731
2912
|
sceneEl
|
|
2732
2913
|
}),
|
|
2733
|
-
[textureLighting, directionalLight, ambientLight, strategies, seamBleed, shadow, registerShadowCaster, registerShadowReceiver, shadowCastersVersion, hasShadowReceiver, groundCssZ, sceneEl]
|
|
2914
|
+
[textureLighting, directionalLight, pointLights, ambientLight, strategies, seamBleed, textureLeafSizing, textureImageRendering, textureBackend, textureProjection, shadow, registerShadowCaster, registerShadowReceiver, shadowCastersVersion, hasShadowReceiver, groundCssZ, sceneEl]
|
|
2734
2915
|
);
|
|
2735
2916
|
return /* @__PURE__ */ jsx8(PolySceneContext.Provider, { value: sceneCtxValue, children: /* @__PURE__ */ jsxs(
|
|
2736
2917
|
"div",
|
|
@@ -2766,9 +2947,10 @@ import {
|
|
|
2766
2947
|
} from "react";
|
|
2767
2948
|
import {
|
|
2768
2949
|
BASE_TILE as BASE_TILE3,
|
|
2950
|
+
buildParametricCasterOverride,
|
|
2769
2951
|
buildPolyMeshTransform,
|
|
2770
2952
|
buildSharedEdgeMap,
|
|
2771
|
-
|
|
2953
|
+
computeMergedReceiverShadows,
|
|
2772
2954
|
computeSceneBbox,
|
|
2773
2955
|
DEFAULT_SEAM_BLEED as DEFAULT_SEAM_BLEED2,
|
|
2774
2956
|
ensureCcw2D,
|
|
@@ -2780,7 +2962,9 @@ import {
|
|
|
2780
2962
|
prepareCasterPolyItems,
|
|
2781
2963
|
prepareReceiverFacePlanes,
|
|
2782
2964
|
projectCssVertexToGround,
|
|
2783
|
-
|
|
2965
|
+
resolvePolyTextureLeafGeometry as resolvePolyTextureLeafGeometry2,
|
|
2966
|
+
worldDirectionToCss as worldDirectionToCss2,
|
|
2967
|
+
worldPositionToCss
|
|
2784
2968
|
} from "@layoutit/polycss-core";
|
|
2785
2969
|
|
|
2786
2970
|
// src/scene/useMesh.ts
|
|
@@ -3648,11 +3832,16 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3648
3832
|
autoCenter,
|
|
3649
3833
|
textureLighting,
|
|
3650
3834
|
textureQuality,
|
|
3835
|
+
textureLeafSizing,
|
|
3836
|
+
textureImageRendering,
|
|
3837
|
+
textureBackend,
|
|
3838
|
+
textureProjection,
|
|
3651
3839
|
seamBleed,
|
|
3652
3840
|
atomicAtlas,
|
|
3653
3841
|
onFrameReady,
|
|
3654
3842
|
castShadow,
|
|
3655
3843
|
receiveShadow,
|
|
3844
|
+
shadowDefinition,
|
|
3656
3845
|
merge = true,
|
|
3657
3846
|
children,
|
|
3658
3847
|
fallback,
|
|
@@ -3717,6 +3906,12 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3717
3906
|
const stableTriangleColorFrameRef = useRef6(0);
|
|
3718
3907
|
const setPolygonsImplRef = useRef6(() => {
|
|
3719
3908
|
});
|
|
3909
|
+
const textureReadyRef = useRef6(true);
|
|
3910
|
+
const textureReadyWaitersRef = useRef6([]);
|
|
3911
|
+
const resolveTextureReadyWaiters = useCallback7(() => {
|
|
3912
|
+
const waiters = textureReadyWaitersRef.current.splice(0);
|
|
3913
|
+
for (const resolve of waiters) resolve();
|
|
3914
|
+
}, []);
|
|
3720
3915
|
const handle = useMemo7(() => ({
|
|
3721
3916
|
get element() {
|
|
3722
3917
|
return wrapperRef.current;
|
|
@@ -3730,6 +3925,12 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3730
3925
|
setPolygonsImplRef.current(nextPolygons);
|
|
3731
3926
|
},
|
|
3732
3927
|
rebakeAtlas: () => setBakedRotation(propsRef.current.rotation),
|
|
3928
|
+
whenTexturesReady() {
|
|
3929
|
+
if (textureReadyRef.current) return Promise.resolve();
|
|
3930
|
+
return new Promise((resolve) => {
|
|
3931
|
+
textureReadyWaitersRef.current.push(resolve);
|
|
3932
|
+
});
|
|
3933
|
+
},
|
|
3733
3934
|
updatePolygon(target, partial) {
|
|
3734
3935
|
const current = polygonsRef.current;
|
|
3735
3936
|
const idx = typeof target === "number" ? target : current.indexOf(target);
|
|
@@ -3876,6 +4077,10 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3876
4077
|
[effectiveStrategies]
|
|
3877
4078
|
);
|
|
3878
4079
|
const effectiveSeamBleed = seamBleed ?? sceneCtx?.seamBleed ?? DEFAULT_SEAM_BLEED2;
|
|
4080
|
+
const effectiveTextureLeafSizing = textureLeafSizing ?? sceneCtx?.textureLeafSizing;
|
|
4081
|
+
const effectiveTextureImageRendering = textureImageRendering ?? sceneCtx?.textureImageRendering;
|
|
4082
|
+
const effectiveTextureBackend = textureBackend ?? sceneCtx?.textureBackend;
|
|
4083
|
+
const effectiveTextureProjection = textureProjection ?? sceneCtx?.textureProjection;
|
|
3879
4084
|
const effectiveDirectional = sceneCtx?.directionalLight;
|
|
3880
4085
|
const effectiveAmbient = sceneCtx?.ambientLight;
|
|
3881
4086
|
const directVoxelEnabled = Boolean(
|
|
@@ -3905,6 +4110,18 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3905
4110
|
direction: inverseRotateVec3(cssLight.direction, rot)
|
|
3906
4111
|
};
|
|
3907
4112
|
}, [effectiveDirectional, bakedRotation]);
|
|
4113
|
+
const bakedPointLights = useMemo7(() => {
|
|
4114
|
+
const pls = sceneCtx?.pointLights;
|
|
4115
|
+
if (!pls || pls.length === 0) return void 0;
|
|
4116
|
+
const pos = position ?? [0, 0, 0];
|
|
4117
|
+
const rot = bakedRotation ?? [0, 0, 0];
|
|
4118
|
+
const hasRot = rot[0] !== 0 || rot[1] !== 0 || rot[2] !== 0;
|
|
4119
|
+
return pls.map((pl) => {
|
|
4120
|
+
const rel = [pl.position[0] - pos[0], pl.position[1] - pos[1], pl.position[2] - pos[2]];
|
|
4121
|
+
const local = hasRot ? inverseRotateVec3(rel, rot) : rel;
|
|
4122
|
+
return { ...pl, position: local };
|
|
4123
|
+
});
|
|
4124
|
+
}, [sceneCtx?.pointLights, position, bakedRotation]);
|
|
3908
4125
|
const lightOccludedPolyIndices = void 0;
|
|
3909
4126
|
const atlasPlans = useMemo7(
|
|
3910
4127
|
() => {
|
|
@@ -3923,6 +4140,7 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3923
4140
|
i,
|
|
3924
4141
|
{
|
|
3925
4142
|
directionalLight: bakedDirectional,
|
|
4143
|
+
pointLights: bakedPointLights,
|
|
3926
4144
|
ambientLight: effectiveAmbient,
|
|
3927
4145
|
seamBleed: seamBleedEdges?.has(i) ? effectiveSeamBleed : void 0,
|
|
3928
4146
|
seamEdges: seamBleedEdges?.get(i),
|
|
@@ -3932,15 +4150,24 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3932
4150
|
basisHints[i]
|
|
3933
4151
|
));
|
|
3934
4152
|
},
|
|
3935
|
-
[renderPolygon, directVoxelEnabled, polygons, bakedDirectional, effectiveAmbient, effectiveSeamBleed, lightOccludedPolyIndices]
|
|
4153
|
+
[renderPolygon, directVoxelEnabled, polygons, bakedDirectional, bakedPointLights, effectiveAmbient, effectiveSeamBleed, lightOccludedPolyIndices]
|
|
3936
4154
|
);
|
|
3937
4155
|
const textureAtlas = useTextureAtlas(
|
|
3938
4156
|
atlasPlans,
|
|
3939
4157
|
effectiveTextureLighting,
|
|
3940
4158
|
textureQuality,
|
|
4159
|
+
effectiveTextureLeafSizing,
|
|
4160
|
+
effectiveTextureBackend,
|
|
4161
|
+
effectiveTextureImageRendering,
|
|
4162
|
+
effectiveTextureProjection,
|
|
3941
4163
|
effectiveStrategies,
|
|
3942
4164
|
atomicAtlas
|
|
3943
4165
|
);
|
|
4166
|
+
textureReadyRef.current = textureAtlas.ready;
|
|
4167
|
+
useEffect5(() => {
|
|
4168
|
+
if (textureAtlas.ready) resolveTextureReadyWaiters();
|
|
4169
|
+
}, [textureAtlas.ready, resolveTextureReadyWaiters]);
|
|
4170
|
+
useEffect5(() => resolveTextureReadyWaiters, [resolveTextureReadyWaiters]);
|
|
3944
4171
|
const solidPaintDefaults = useMemo7(
|
|
3945
4172
|
() => !renderPolygon ? getSolidPaintDefaults(textureAtlas.plans, effectiveTextureLighting, effectiveStrategies) : {},
|
|
3946
4173
|
[renderPolygon, textureAtlas.plans, effectiveTextureLighting, effectiveStrategies]
|
|
@@ -3969,23 +4196,32 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
3969
4196
|
}
|
|
3970
4197
|
return s;
|
|
3971
4198
|
}, [atlasPlans, polygons]);
|
|
4199
|
+
const shadowCasterRegisteredRef = useRef6(false);
|
|
4200
|
+
const lastShadowPolyCountRef = useRef6(-1);
|
|
3972
4201
|
useEffect5(() => {
|
|
3973
|
-
if (!sceneRegisterShadowCaster) return;
|
|
3974
|
-
if (castShadow) {
|
|
3975
|
-
sceneRegisterShadowCaster(meshIdRef.current, {
|
|
3976
|
-
polygons,
|
|
3977
|
-
position: position ?? [0, 0, 0],
|
|
3978
|
-
scale,
|
|
3979
|
-
rotation,
|
|
3980
|
-
renderedPolygonIndices
|
|
3981
|
-
});
|
|
3982
|
-
} else {
|
|
3983
|
-
sceneRegisterShadowCaster(meshIdRef.current, null);
|
|
3984
|
-
}
|
|
4202
|
+
if (!sceneRegisterShadowCaster || !castShadow) return;
|
|
3985
4203
|
return () => {
|
|
3986
4204
|
sceneRegisterShadowCaster(meshIdRef.current, null);
|
|
4205
|
+
shadowCasterRegisteredRef.current = false;
|
|
4206
|
+
lastShadowPolyCountRef.current = -1;
|
|
3987
4207
|
};
|
|
3988
|
-
}, [sceneRegisterShadowCaster, castShadow
|
|
4208
|
+
}, [sceneRegisterShadowCaster, castShadow]);
|
|
4209
|
+
useEffect5(() => {
|
|
4210
|
+
if (!sceneRegisterShadowCaster || !castShadow) return;
|
|
4211
|
+
const followAnimation = sceneCtx?.shadow?.followAnimation ?? false;
|
|
4212
|
+
const topologyChanged = polygons.length !== lastShadowPolyCountRef.current;
|
|
4213
|
+
if (shadowCasterRegisteredRef.current && !followAnimation && !topologyChanged) return;
|
|
4214
|
+
lastShadowPolyCountRef.current = polygons.length;
|
|
4215
|
+
shadowCasterRegisteredRef.current = true;
|
|
4216
|
+
sceneRegisterShadowCaster(meshIdRef.current, {
|
|
4217
|
+
polygons,
|
|
4218
|
+
position: position ?? [0, 0, 0],
|
|
4219
|
+
scale,
|
|
4220
|
+
rotation,
|
|
4221
|
+
renderedPolygonIndices,
|
|
4222
|
+
shadowDefinition
|
|
4223
|
+
});
|
|
4224
|
+
}, [sceneRegisterShadowCaster, castShadow, polygons, position, scale, rotation, renderedPolygonIndices, shadowDefinition, sceneCtx?.shadow]);
|
|
3989
4225
|
const sceneRegisterShadowReceiver = sceneCtx?.registerShadowReceiver;
|
|
3990
4226
|
useEffect5(() => {
|
|
3991
4227
|
if (!sceneRegisterShadowReceiver) return;
|
|
@@ -4111,6 +4347,16 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4111
4347
|
if (!shadowCasters || shadowCasters.size === 0) return null;
|
|
4112
4348
|
const userLightDir = sceneDirectionalLight?.direction ?? [0.4, -0.7, 0.59];
|
|
4113
4349
|
const lightDir = worldDirectionToCss2(userLightDir);
|
|
4350
|
+
const dynamicShading = effectiveTextureLighting === "dynamic";
|
|
4351
|
+
const scenePoints = dynamicShading ? [] : sceneCtx?.pointLights ?? [];
|
|
4352
|
+
const allPointLightsCss = scenePoints.map((pl) => ({
|
|
4353
|
+
position: worldPositionToCss(pl.position),
|
|
4354
|
+
color: pl.color,
|
|
4355
|
+
intensity: pl.intensity
|
|
4356
|
+
}));
|
|
4357
|
+
const shadowPointIndices = scenePoints.map((pl, i) => pl.castShadow ? i : -1).filter((i) => i >= 0);
|
|
4358
|
+
const runDirectionalShadow = !!sceneDirectionalLight?.direction && (sceneDirectionalLight.intensity ?? 1) > 0;
|
|
4359
|
+
const hasShadowPoints = shadowPointIndices.length > 0;
|
|
4114
4360
|
const shadowLift = sceneShadow?.lift ?? 1e-3;
|
|
4115
4361
|
const planes = prepareReceiverFacePlanes(
|
|
4116
4362
|
polygons,
|
|
@@ -4123,18 +4369,17 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4123
4369
|
if (planes.length === 0) return null;
|
|
4124
4370
|
const casterInputs = [];
|
|
4125
4371
|
for (const [casterId, data] of shadowCasters) {
|
|
4126
|
-
const rendered = data.renderedPolygonIndices;
|
|
4127
4372
|
const items = prepareCasterPolyItems(
|
|
4128
4373
|
data.polygons,
|
|
4129
4374
|
data.position,
|
|
4130
4375
|
data.scale,
|
|
4131
|
-
|
|
4376
|
+
() => true,
|
|
4132
4377
|
data.rotation ?? null
|
|
4133
4378
|
);
|
|
4134
4379
|
const isSelf = data.polygons === polygons;
|
|
4135
4380
|
const selfMap = isSelf ? selfShadowEdgeMap : void 0;
|
|
4136
4381
|
let edgeOwners;
|
|
4137
|
-
if (!isSelf && data.polygons.length >= 40) {
|
|
4382
|
+
if (!isSelf && (data.polygons.length >= 40 || hasShadowPoints)) {
|
|
4138
4383
|
const dposArr = data.position;
|
|
4139
4384
|
const drot = data.rotation ?? null;
|
|
4140
4385
|
const dsKey = JSON.stringify(data.scale ?? null);
|
|
@@ -4147,12 +4392,29 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4147
4392
|
}
|
|
4148
4393
|
edgeOwners = cachedOwners;
|
|
4149
4394
|
}
|
|
4395
|
+
let overrideSilhouette;
|
|
4396
|
+
let overridePointSilhouettes;
|
|
4397
|
+
if (sceneShadow?.parametric) {
|
|
4398
|
+
const def = data.shadowDefinition ?? sceneShadow.definition ?? 16;
|
|
4399
|
+
const result = buildParametricCasterOverride({
|
|
4400
|
+
polysWorldVerts: items.map((it) => it.wv),
|
|
4401
|
+
lightDir,
|
|
4402
|
+
definition: def,
|
|
4403
|
+
isSelf,
|
|
4404
|
+
style: sceneShadow.style,
|
|
4405
|
+
pointLights: shadowPointIndices.map((i) => ({ position: allPointLightsCss[i].position, index: i }))
|
|
4406
|
+
});
|
|
4407
|
+
overrideSilhouette = result.overrideSilhouette;
|
|
4408
|
+
overridePointSilhouettes = result.overridePointSilhouettes;
|
|
4409
|
+
}
|
|
4150
4410
|
casterInputs.push({
|
|
4151
4411
|
id: casterId,
|
|
4152
4412
|
items,
|
|
4153
4413
|
selfShadowEdgeMap: selfMap,
|
|
4154
4414
|
edgeOwners,
|
|
4155
|
-
casterPolygonCount: data.polygons.length
|
|
4415
|
+
casterPolygonCount: data.polygons.length,
|
|
4416
|
+
overrideSilhouette,
|
|
4417
|
+
overridePointSilhouettes
|
|
4156
4418
|
});
|
|
4157
4419
|
}
|
|
4158
4420
|
const cameraState = cameraCtx?.store.getState().cameraState;
|
|
@@ -4161,27 +4423,31 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4161
4423
|
rotY: cameraState?.rotY ?? 45,
|
|
4162
4424
|
meshRotation: rotation
|
|
4163
4425
|
};
|
|
4164
|
-
const
|
|
4426
|
+
const faces = computeMergedReceiverShadows({
|
|
4165
4427
|
receiverPlanes: planes,
|
|
4166
4428
|
receiverPolygons: polygons,
|
|
4167
4429
|
receiverHasTexture: polygons.some((p) => p.texture !== void 0),
|
|
4168
4430
|
casters: casterInputs,
|
|
4169
4431
|
lightDir,
|
|
4432
|
+
runDirectional: runDirectionalShadow,
|
|
4433
|
+
pointPasses: shadowPointIndices.map((i) => ({ lightPos: allPointLightsCss[i].position, index: i })),
|
|
4434
|
+
allPointLights: allPointLightsCss,
|
|
4170
4435
|
cameraRot,
|
|
4171
4436
|
ambientLight: sceneCtx?.ambientLight,
|
|
4172
4437
|
directionalLight: sceneDirectionalLight,
|
|
4173
4438
|
shadow: { color: sceneShadow?.color, opacity: sceneShadow?.opacity ?? 0.25, maxExtend: sceneShadow?.maxExtend }
|
|
4174
4439
|
});
|
|
4175
|
-
|
|
4440
|
+
if (faces.length === 0) return null;
|
|
4441
|
+
return /* @__PURE__ */ jsx9(Fragment, { children: faces.map((fc) => /* @__PURE__ */ jsxs2(
|
|
4176
4442
|
"svg",
|
|
4177
4443
|
{
|
|
4178
4444
|
className: "polycss-shadow polycss-shadow-svg polycss-shadow-receiver",
|
|
4179
4445
|
"data-poly-shadow-type": "receiver",
|
|
4180
|
-
"data-poly-shadow-receiver-face":
|
|
4181
|
-
"data-poly-shadow-receiver-polys": JSON.stringify(
|
|
4182
|
-
width:
|
|
4183
|
-
height:
|
|
4184
|
-
viewBox: `0 0 ${
|
|
4446
|
+
"data-poly-shadow-receiver-face": fc.faceIndex,
|
|
4447
|
+
"data-poly-shadow-receiver-polys": JSON.stringify(fc.memberPolyIndices),
|
|
4448
|
+
width: fc.width,
|
|
4449
|
+
height: fc.height,
|
|
4450
|
+
viewBox: `0 0 ${fc.width} ${fc.height}`,
|
|
4185
4451
|
style: {
|
|
4186
4452
|
position: "absolute",
|
|
4187
4453
|
top: 0,
|
|
@@ -4191,25 +4457,27 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4191
4457
|
transformOrigin: "0 0",
|
|
4192
4458
|
pointerEvents: "none",
|
|
4193
4459
|
willChange: "transform",
|
|
4194
|
-
|
|
4460
|
+
opacity: fc.svgOpacity,
|
|
4461
|
+
transform: fc.matrixCss
|
|
4195
4462
|
},
|
|
4196
|
-
children:
|
|
4197
|
-
"path",
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4463
|
+
children: [
|
|
4464
|
+
fc.baseFill && fc.baseD ? /* @__PURE__ */ jsx9("path", { d: fc.baseD, fill: fc.baseFill, fillRule: "nonzero" }) : null,
|
|
4465
|
+
fc.layers.map((layer, i) => /* @__PURE__ */ jsx9(
|
|
4466
|
+
"path",
|
|
4467
|
+
{
|
|
4468
|
+
d: layer.d,
|
|
4469
|
+
fill: layer.fill,
|
|
4470
|
+
fillRule: "nonzero",
|
|
4471
|
+
opacity: layer.opacity !== 1 ? layer.opacity.toFixed(4) : void 0,
|
|
4472
|
+
style: layer.multiply ? { mixBlendMode: "multiply" } : void 0
|
|
4473
|
+
},
|
|
4474
|
+
i
|
|
4475
|
+
))
|
|
4476
|
+
]
|
|
4209
4477
|
},
|
|
4210
|
-
`receiver-${
|
|
4478
|
+
`receiver-${fc.faceIndex}`
|
|
4211
4479
|
)) });
|
|
4212
|
-
}, [receiveShadow, shadowCasters, shadowCastersVersion, polygons, position, scale, rotation, sceneDirectionalLight, sceneShadow, sceneCtx?.ambientLight, cameraCtx?.store, cameraTick, selfShadowEdgeMap]);
|
|
4480
|
+
}, [receiveShadow, shadowCasters, shadowCastersVersion, polygons, position, scale, rotation, sceneDirectionalLight, sceneCtx?.pointLights, effectiveTextureLighting, sceneShadow, sceneCtx?.ambientLight, cameraCtx?.store, cameraTick, selfShadowEdgeMap]);
|
|
4213
4481
|
const portalSceneEl = sceneCtx?.sceneEl ?? null;
|
|
4214
4482
|
const portaledReceiverShadowSvgs = portalSceneEl && receiverShadowSvgs ? createPortal(receiverShadowSvgs, portalSceneEl) : null;
|
|
4215
4483
|
setPolygonsImplRef.current = (nextPolygons) => {
|
|
@@ -4289,12 +4557,28 @@ var PolyMesh = forwardRef(function PolyMesh2({
|
|
|
4289
4557
|
entry,
|
|
4290
4558
|
page: textureAtlas.pages[entry.pageIndex],
|
|
4291
4559
|
textureLighting: effectiveTextureLighting,
|
|
4560
|
+
textureImageRendering: effectiveTextureImageRendering,
|
|
4292
4561
|
solidPaintDefaults
|
|
4293
4562
|
},
|
|
4294
4563
|
entry.index
|
|
4295
4564
|
);
|
|
4296
4565
|
}
|
|
4297
4566
|
const plan = textureAtlas.plans[index];
|
|
4567
|
+
const imageGeometry = plan ? resolvePolyTextureLeafGeometry2(plan, {
|
|
4568
|
+
imageRendering: effectiveTextureImageRendering,
|
|
4569
|
+
backend: effectiveTextureBackend,
|
|
4570
|
+
projection: effectiveTextureProjection
|
|
4571
|
+
}) : null;
|
|
4572
|
+
if (plan && imageGeometry) {
|
|
4573
|
+
return /* @__PURE__ */ jsx9(
|
|
4574
|
+
TextureImagePoly,
|
|
4575
|
+
{
|
|
4576
|
+
plan,
|
|
4577
|
+
geometry: imageGeometry
|
|
4578
|
+
},
|
|
4579
|
+
plan.index
|
|
4580
|
+
);
|
|
4581
|
+
}
|
|
4298
4582
|
if (!plan || plan.texture) return null;
|
|
4299
4583
|
if (isProjectiveQuadPlan(plan)) {
|
|
4300
4584
|
return /* @__PURE__ */ jsx9(
|
|
@@ -4515,6 +4799,7 @@ function usePolyMaterial(options) {
|
|
|
4515
4799
|
|
|
4516
4800
|
// src/shapes/Poly.tsx
|
|
4517
4801
|
import { memo as memo9, useMemo as useMemo10 } from "react";
|
|
4802
|
+
import { resolvePolyTextureLeafGeometry as resolvePolyTextureLeafGeometry3 } from "@layoutit/polycss-core";
|
|
4518
4803
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
4519
4804
|
var DIRECT_TEXTURE_CSS_DECIMALS = 4;
|
|
4520
4805
|
function formatCssLength(value, decimals = DIRECT_TEXTURE_CSS_DECIMALS) {
|
|
@@ -4545,7 +4830,8 @@ function MaterialDirectPoly({
|
|
|
4545
4830
|
style: styleProp,
|
|
4546
4831
|
domAttrs,
|
|
4547
4832
|
domEventHandlers,
|
|
4548
|
-
pointerEvents = "auto"
|
|
4833
|
+
pointerEvents = "auto",
|
|
4834
|
+
imageRendering
|
|
4549
4835
|
}) {
|
|
4550
4836
|
const { u0, u1, v0, v1 } = uvRect;
|
|
4551
4837
|
const du = u1 - u0;
|
|
@@ -4560,6 +4846,8 @@ function MaterialDirectPoly({
|
|
|
4560
4846
|
backgroundImage: `url(${material.texture})`,
|
|
4561
4847
|
backgroundSize: `${formatCssLength(sourceW)} ${formatCssLength(sourceH)}`,
|
|
4562
4848
|
backgroundPosition: `${formatCssLength(-offsetX)} ${formatCssLength(-offsetY)}`,
|
|
4849
|
+
backgroundRepeat: "no-repeat",
|
|
4850
|
+
imageRendering: imageRendering === "pixelated" ? "pixelated" : void 0,
|
|
4563
4851
|
pointerEvents: pointerEvents === "none" ? "none" : void 0,
|
|
4564
4852
|
...styleProp
|
|
4565
4853
|
};
|
|
@@ -4572,6 +4860,14 @@ function MaterialDirectPoly({
|
|
|
4572
4860
|
{
|
|
4573
4861
|
className: elementClassName,
|
|
4574
4862
|
style,
|
|
4863
|
+
"data-poly-index": plan.index,
|
|
4864
|
+
"data-polycss-leaf": "polygon",
|
|
4865
|
+
"data-polycss-texture-backend": "image",
|
|
4866
|
+
"data-polycss-texture-ready": "true",
|
|
4867
|
+
"data-polycss-texture-image-rendering": imageRendering ?? "auto",
|
|
4868
|
+
"data-polycss-texture-projection": "affine",
|
|
4869
|
+
"data-polycss-texture-lighting": "source",
|
|
4870
|
+
"data-polycss-double-sided": plan.polygon.doubleSided ? "true" : void 0,
|
|
4575
4871
|
...domEventHandlers,
|
|
4576
4872
|
...dataAttrs,
|
|
4577
4873
|
...domAttrs
|
|
@@ -4582,8 +4878,11 @@ function PolyInner({
|
|
|
4582
4878
|
vertices,
|
|
4583
4879
|
color,
|
|
4584
4880
|
texture,
|
|
4881
|
+
textureImageSource,
|
|
4882
|
+
texturePresentation,
|
|
4585
4883
|
uvs,
|
|
4586
4884
|
data,
|
|
4885
|
+
doubleSided,
|
|
4587
4886
|
material,
|
|
4588
4887
|
position,
|
|
4589
4888
|
scale,
|
|
@@ -4611,6 +4910,10 @@ function PolyInner({
|
|
|
4611
4910
|
context,
|
|
4612
4911
|
textureLighting: textureLightingProp,
|
|
4613
4912
|
textureQuality: textureQualityProp,
|
|
4913
|
+
textureLeafSizing: textureLeafSizingProp,
|
|
4914
|
+
textureImageRendering: textureImageRenderingProp,
|
|
4915
|
+
textureBackend: textureBackendProp,
|
|
4916
|
+
textureProjection: textureProjectionProp,
|
|
4614
4917
|
baseColor: baseColorProp,
|
|
4615
4918
|
...dataAttrs
|
|
4616
4919
|
}) {
|
|
@@ -4618,11 +4921,25 @@ function PolyInner({
|
|
|
4618
4921
|
const layerElevation = context?.layerElevation ?? tileSize;
|
|
4619
4922
|
const textureLighting = textureLightingProp ?? context?.textureLighting ?? "baked";
|
|
4620
4923
|
const textureQuality = textureQualityProp ?? context?.textureQuality;
|
|
4924
|
+
const textureLeafSizing = textureLeafSizingProp ?? context?.textureLeafSizing;
|
|
4925
|
+
const textureImageRendering = textureImageRenderingProp ?? context?.textureImageRendering;
|
|
4926
|
+
const textureBackend = textureBackendProp ?? context?.textureBackend;
|
|
4927
|
+
const textureProjection = textureProjectionProp ?? context?.textureProjection;
|
|
4621
4928
|
const polygonColor = baseColorProp ?? color;
|
|
4622
4929
|
const effectiveTexture = material?.texture ?? texture;
|
|
4623
4930
|
const atlasPlan = useMemo10(
|
|
4624
4931
|
() => computeTextureAtlasPlan(
|
|
4625
|
-
{
|
|
4932
|
+
{
|
|
4933
|
+
vertices,
|
|
4934
|
+
color: polygonColor,
|
|
4935
|
+
texture: effectiveTexture,
|
|
4936
|
+
textureImageSource,
|
|
4937
|
+
texturePresentation,
|
|
4938
|
+
uvs,
|
|
4939
|
+
data,
|
|
4940
|
+
doubleSided,
|
|
4941
|
+
material
|
|
4942
|
+
},
|
|
4626
4943
|
0,
|
|
4627
4944
|
{
|
|
4628
4945
|
tileSize,
|
|
@@ -4634,8 +4951,12 @@ function PolyInner({
|
|
|
4634
4951
|
vertices,
|
|
4635
4952
|
polygonColor,
|
|
4636
4953
|
effectiveTexture,
|
|
4954
|
+
textureImageSource,
|
|
4955
|
+
texturePresentation,
|
|
4637
4956
|
uvs,
|
|
4638
4957
|
data,
|
|
4958
|
+
doubleSided,
|
|
4959
|
+
material,
|
|
4639
4960
|
tileSize,
|
|
4640
4961
|
layerElevation,
|
|
4641
4962
|
context?.directionalLight
|
|
@@ -4649,7 +4970,15 @@ function PolyInner({
|
|
|
4649
4970
|
() => materialUvRect ? [] : [atlasPlan],
|
|
4650
4971
|
[materialUvRect, atlasPlan]
|
|
4651
4972
|
);
|
|
4652
|
-
const textureAtlas = useTextureAtlas(
|
|
4973
|
+
const textureAtlas = useTextureAtlas(
|
|
4974
|
+
atlasPlans,
|
|
4975
|
+
textureLighting,
|
|
4976
|
+
textureQuality,
|
|
4977
|
+
textureLeafSizing,
|
|
4978
|
+
textureBackend,
|
|
4979
|
+
textureImageRendering,
|
|
4980
|
+
textureProjection
|
|
4981
|
+
);
|
|
4653
4982
|
const domEventHandlers = {
|
|
4654
4983
|
onClick,
|
|
4655
4984
|
onDoubleClick,
|
|
@@ -4708,7 +5037,8 @@ function PolyInner({
|
|
|
4708
5037
|
style: styleProp,
|
|
4709
5038
|
domAttrs,
|
|
4710
5039
|
domEventHandlers,
|
|
4711
|
-
pointerEvents: pointerEventsProp ?? "auto"
|
|
5040
|
+
pointerEvents: pointerEventsProp ?? "auto",
|
|
5041
|
+
imageRendering: textureImageRendering
|
|
4712
5042
|
}
|
|
4713
5043
|
);
|
|
4714
5044
|
} else {
|
|
@@ -4720,6 +5050,7 @@ function PolyInner({
|
|
|
4720
5050
|
entry: atlasEntry,
|
|
4721
5051
|
page: textureAtlas.pages[atlasEntry.pageIndex],
|
|
4722
5052
|
textureLighting,
|
|
5053
|
+
textureImageRendering,
|
|
4723
5054
|
className,
|
|
4724
5055
|
style: styleProp,
|
|
4725
5056
|
domAttrs,
|
|
@@ -4727,7 +5058,28 @@ function PolyInner({
|
|
|
4727
5058
|
pointerEvents: pointerEventsProp ?? "auto"
|
|
4728
5059
|
}
|
|
4729
5060
|
);
|
|
4730
|
-
} else
|
|
5061
|
+
} else {
|
|
5062
|
+
const imageGeometry = atlasPlan ? resolvePolyTextureLeafGeometry3(atlasPlan, {
|
|
5063
|
+
imageRendering: textureImageRendering,
|
|
5064
|
+
backend: textureBackend,
|
|
5065
|
+
projection: textureProjection
|
|
5066
|
+
}) : null;
|
|
5067
|
+
if (atlasPlan && imageGeometry) {
|
|
5068
|
+
front = /* @__PURE__ */ jsx12(
|
|
5069
|
+
TextureImagePoly,
|
|
5070
|
+
{
|
|
5071
|
+
plan: atlasPlan,
|
|
5072
|
+
geometry: imageGeometry,
|
|
5073
|
+
className,
|
|
5074
|
+
style: styleProp,
|
|
5075
|
+
domAttrs,
|
|
5076
|
+
domEventHandlers,
|
|
5077
|
+
pointerEvents: pointerEventsProp ?? "auto"
|
|
5078
|
+
}
|
|
5079
|
+
);
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
if (!front && atlasPlan && !atlasPlan.texture) {
|
|
4731
5083
|
front = isSolidTrianglePlan2(atlasPlan) ? /* @__PURE__ */ jsx12(
|
|
4732
5084
|
TextureTrianglePoly,
|
|
4733
5085
|
{
|
|
@@ -7062,11 +7414,56 @@ var ZERO_SURFACE_LEAF_COUNTS = {
|
|
|
7062
7414
|
atlas: 0,
|
|
7063
7415
|
stableTriangle: 0
|
|
7064
7416
|
};
|
|
7417
|
+
var READY_TEXTURE_READINESS = {
|
|
7418
|
+
ready: true,
|
|
7419
|
+
textureLeafCount: 0,
|
|
7420
|
+
readyTextureLeafCount: 0,
|
|
7421
|
+
pendingTextureLeafCount: 0,
|
|
7422
|
+
atlasTextureLeafCount: 0,
|
|
7423
|
+
imageTextureLeafCount: 0
|
|
7424
|
+
};
|
|
7425
|
+
function emptyTextureStats() {
|
|
7426
|
+
return {
|
|
7427
|
+
ready: true,
|
|
7428
|
+
leafCount: 0,
|
|
7429
|
+
atlasCount: 0,
|
|
7430
|
+
imageCount: 0,
|
|
7431
|
+
pendingCount: 0,
|
|
7432
|
+
sizingCounts: { canonical: 0, local: 0, raster: 0, image: 0, unknown: 0 },
|
|
7433
|
+
imageRenderingCounts: { auto: 0, pixelated: 0, unknown: 0 },
|
|
7434
|
+
projectionCounts: { affine: 0, projective: 0, fallback: 0, unknown: 0 },
|
|
7435
|
+
minLeafWidth: 0,
|
|
7436
|
+
maxLeafWidth: 0,
|
|
7437
|
+
minLeafHeight: 0,
|
|
7438
|
+
maxLeafHeight: 0,
|
|
7439
|
+
doubleSidedCount: 0
|
|
7440
|
+
};
|
|
7441
|
+
}
|
|
7442
|
+
function emptySnapshotStats() {
|
|
7443
|
+
return {
|
|
7444
|
+
runtimeAtlasUrlCount: 0,
|
|
7445
|
+
snapshotAtlasCount: 0,
|
|
7446
|
+
snapshotBackgroundCount: 0,
|
|
7447
|
+
selfContained: true
|
|
7448
|
+
};
|
|
7449
|
+
}
|
|
7450
|
+
function emptyCameraStats() {
|
|
7451
|
+
return {
|
|
7452
|
+
rootFound: false,
|
|
7453
|
+
projection: "unknown",
|
|
7454
|
+
perspectiveStyle: "",
|
|
7455
|
+
appliedPerspectiveStyle: ""
|
|
7456
|
+
};
|
|
7457
|
+
}
|
|
7065
7458
|
var EMPTY_POLY_RENDER_STATS = {
|
|
7066
7459
|
polygonCount: 0,
|
|
7067
7460
|
mountedPolygonLeafCount: 0,
|
|
7068
7461
|
shadowLeafCount: 0,
|
|
7069
7462
|
surfaceLeafCounts: ZERO_SURFACE_LEAF_COUNTS,
|
|
7463
|
+
textureReadiness: READY_TEXTURE_READINESS,
|
|
7464
|
+
textureStats: emptyTextureStats(),
|
|
7465
|
+
snapshotStats: emptySnapshotStats(),
|
|
7466
|
+
cameraStats: emptyCameraStats(),
|
|
7070
7467
|
bucketCount: 0
|
|
7071
7468
|
};
|
|
7072
7469
|
function asOptions(optionsOrPolygonCount) {
|
|
@@ -7078,6 +7475,28 @@ function asOptions(optionsOrPolygonCount) {
|
|
|
7078
7475
|
function queryCount(scope, selector) {
|
|
7079
7476
|
return scope.querySelectorAll(selector).length;
|
|
7080
7477
|
}
|
|
7478
|
+
function matchingElementCount(scope, selector) {
|
|
7479
|
+
return (matchesSelector(scope, selector) ? 1 : 0) + queryCount(scope, selector);
|
|
7480
|
+
}
|
|
7481
|
+
function styleHasRuntimeUrl(styleText) {
|
|
7482
|
+
if (!styleText) return false;
|
|
7483
|
+
const urlPattern = /url\((?:"([^"]*)"|'([^']*)'|([^)]*))\)/g;
|
|
7484
|
+
let match;
|
|
7485
|
+
while (match = urlPattern.exec(styleText)) {
|
|
7486
|
+
const raw = (match[1] ?? match[2] ?? match[3] ?? "").trim();
|
|
7487
|
+
if (raw && !raw.startsWith("data:")) return true;
|
|
7488
|
+
}
|
|
7489
|
+
return false;
|
|
7490
|
+
}
|
|
7491
|
+
function runtimeUrlElementCount(scope) {
|
|
7492
|
+
let count = 0;
|
|
7493
|
+
const root = scope instanceof HTMLElement ? scope : null;
|
|
7494
|
+
if (root && styleHasRuntimeUrl(root.getAttribute("style"))) count++;
|
|
7495
|
+
for (const el of Array.from(scope.querySelectorAll("[style]"))) {
|
|
7496
|
+
if (el instanceof HTMLElement && styleHasRuntimeUrl(el.getAttribute("style"))) count++;
|
|
7497
|
+
}
|
|
7498
|
+
return count;
|
|
7499
|
+
}
|
|
7081
7500
|
function matchesSelector(root, selector) {
|
|
7082
7501
|
const candidate = root;
|
|
7083
7502
|
return typeof candidate.matches === "function" && candidate.matches(selector);
|
|
@@ -7089,12 +7508,196 @@ function collectScopes(root, selector) {
|
|
|
7089
7508
|
scopes.push(...Array.from(root.querySelectorAll(selector)));
|
|
7090
7509
|
return scopes;
|
|
7091
7510
|
}
|
|
7511
|
+
function leafStrategyForTag(tagName) {
|
|
7512
|
+
switch (tagName.toLowerCase()) {
|
|
7513
|
+
case "b":
|
|
7514
|
+
return "quad";
|
|
7515
|
+
case "i":
|
|
7516
|
+
return "clippedSolid";
|
|
7517
|
+
case "s":
|
|
7518
|
+
return "atlas";
|
|
7519
|
+
case "u":
|
|
7520
|
+
return "stableTriangle";
|
|
7521
|
+
default:
|
|
7522
|
+
return null;
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
7525
|
+
function parseOptionalInteger(value) {
|
|
7526
|
+
if (value == null || value === "") return void 0;
|
|
7527
|
+
const parsed = Number.parseInt(value, 10);
|
|
7528
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
7529
|
+
}
|
|
7530
|
+
function parseOptionalNumber(value) {
|
|
7531
|
+
if (value == null || value === "") return void 0;
|
|
7532
|
+
const parsed = Number(value);
|
|
7533
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
7534
|
+
}
|
|
7535
|
+
function parseOptionalVec3(value) {
|
|
7536
|
+
if (value == null || value === "") return void 0;
|
|
7537
|
+
const parts = value.split(",").map((part) => Number(part));
|
|
7538
|
+
if (parts.length !== 3 || parts.some((part) => !Number.isFinite(part))) return void 0;
|
|
7539
|
+
return parts;
|
|
7540
|
+
}
|
|
7541
|
+
function parseCameraProjection(value) {
|
|
7542
|
+
return value === "orthographic" || value === "perspective" ? value : "unknown";
|
|
7543
|
+
}
|
|
7544
|
+
function textureReadyForElement(el, textureBackend) {
|
|
7545
|
+
if (!textureBackend) return void 0;
|
|
7546
|
+
const attr = el.getAttribute("data-polycss-texture-ready");
|
|
7547
|
+
if (attr === "true") return true;
|
|
7548
|
+
if (attr === "false") return false;
|
|
7549
|
+
return el.style.opacity !== "0";
|
|
7550
|
+
}
|
|
7551
|
+
function queryPolyLeaves(root, optionsOrPolygonCount) {
|
|
7552
|
+
if (!root) return [];
|
|
7553
|
+
const options = asOptions(optionsOrPolygonCount);
|
|
7554
|
+
const out = [];
|
|
7555
|
+
for (const scope of collectScopes(root, options.scopeSelector)) {
|
|
7556
|
+
for (const el of Array.from(scope.querySelectorAll("b,i,s,u"))) {
|
|
7557
|
+
const htmlEl = el;
|
|
7558
|
+
const strategy = leafStrategyForTag(htmlEl.tagName);
|
|
7559
|
+
if (!strategy) continue;
|
|
7560
|
+
const textureBackend = htmlEl.getAttribute("data-polycss-texture-backend") ?? (strategy === "atlas" ? "atlas" : void 0);
|
|
7561
|
+
const textureReady = textureReadyForElement(htmlEl, textureBackend);
|
|
7562
|
+
out.push({
|
|
7563
|
+
element: htmlEl,
|
|
7564
|
+
strategy,
|
|
7565
|
+
polygonIndex: parseOptionalInteger(htmlEl.getAttribute("data-poly-index")),
|
|
7566
|
+
textureBackend,
|
|
7567
|
+
textureReady,
|
|
7568
|
+
textureLeafSizing: htmlEl.getAttribute("data-polycss-texture-leaf-sizing") ?? void 0,
|
|
7569
|
+
textureImageRendering: htmlEl.getAttribute("data-polycss-texture-image-rendering") ?? void 0,
|
|
7570
|
+
textureProjection: htmlEl.getAttribute("data-polycss-texture-projection") ?? void 0,
|
|
7571
|
+
textureLeafWidth: parseOptionalNumber(htmlEl.getAttribute("data-polycss-texture-leaf-width")),
|
|
7572
|
+
textureLeafHeight: parseOptionalNumber(htmlEl.getAttribute("data-polycss-texture-leaf-height")),
|
|
7573
|
+
doubleSided: htmlEl.getAttribute("data-polycss-double-sided") === "true"
|
|
7574
|
+
});
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7577
|
+
return out;
|
|
7578
|
+
}
|
|
7579
|
+
function collectPolyTextureReadiness(root, optionsOrPolygonCount) {
|
|
7580
|
+
const readiness = { ...READY_TEXTURE_READINESS };
|
|
7581
|
+
for (const leaf of queryPolyLeaves(root, optionsOrPolygonCount)) {
|
|
7582
|
+
if (!leaf.textureBackend) continue;
|
|
7583
|
+
readiness.textureLeafCount++;
|
|
7584
|
+
if (leaf.textureBackend === "image") readiness.imageTextureLeafCount++;
|
|
7585
|
+
else readiness.atlasTextureLeafCount++;
|
|
7586
|
+
if (leaf.textureReady === false) readiness.pendingTextureLeafCount++;
|
|
7587
|
+
else readiness.readyTextureLeafCount++;
|
|
7588
|
+
}
|
|
7589
|
+
readiness.ready = readiness.pendingTextureLeafCount === 0;
|
|
7590
|
+
return readiness;
|
|
7591
|
+
}
|
|
7592
|
+
function collectPolyTextureStats(root, optionsOrPolygonCount) {
|
|
7593
|
+
const stats = emptyTextureStats();
|
|
7594
|
+
let hasWidth = false;
|
|
7595
|
+
let hasHeight = false;
|
|
7596
|
+
for (const leaf of queryPolyLeaves(root, optionsOrPolygonCount)) {
|
|
7597
|
+
if (!leaf.textureBackend) continue;
|
|
7598
|
+
stats.leafCount++;
|
|
7599
|
+
if (leaf.textureBackend === "image") stats.imageCount++;
|
|
7600
|
+
else stats.atlasCount++;
|
|
7601
|
+
if (leaf.textureReady === false) stats.pendingCount++;
|
|
7602
|
+
switch (leaf.textureLeafSizing) {
|
|
7603
|
+
case "canonical":
|
|
7604
|
+
case "local":
|
|
7605
|
+
case "raster":
|
|
7606
|
+
case "image":
|
|
7607
|
+
stats.sizingCounts[leaf.textureLeafSizing]++;
|
|
7608
|
+
break;
|
|
7609
|
+
default:
|
|
7610
|
+
stats.sizingCounts.unknown++;
|
|
7611
|
+
break;
|
|
7612
|
+
}
|
|
7613
|
+
switch (leaf.textureImageRendering) {
|
|
7614
|
+
case "auto":
|
|
7615
|
+
case "pixelated":
|
|
7616
|
+
stats.imageRenderingCounts[leaf.textureImageRendering]++;
|
|
7617
|
+
break;
|
|
7618
|
+
default:
|
|
7619
|
+
stats.imageRenderingCounts.unknown++;
|
|
7620
|
+
break;
|
|
7621
|
+
}
|
|
7622
|
+
switch (leaf.textureProjection) {
|
|
7623
|
+
case "affine":
|
|
7624
|
+
case "projective":
|
|
7625
|
+
case "fallback":
|
|
7626
|
+
stats.projectionCounts[leaf.textureProjection]++;
|
|
7627
|
+
break;
|
|
7628
|
+
default:
|
|
7629
|
+
stats.projectionCounts.unknown++;
|
|
7630
|
+
break;
|
|
7631
|
+
}
|
|
7632
|
+
if (typeof leaf.textureLeafWidth === "number") {
|
|
7633
|
+
stats.minLeafWidth = hasWidth ? Math.min(stats.minLeafWidth, leaf.textureLeafWidth) : leaf.textureLeafWidth;
|
|
7634
|
+
stats.maxLeafWidth = hasWidth ? Math.max(stats.maxLeafWidth, leaf.textureLeafWidth) : leaf.textureLeafWidth;
|
|
7635
|
+
hasWidth = true;
|
|
7636
|
+
}
|
|
7637
|
+
if (typeof leaf.textureLeafHeight === "number") {
|
|
7638
|
+
stats.minLeafHeight = hasHeight ? Math.min(stats.minLeafHeight, leaf.textureLeafHeight) : leaf.textureLeafHeight;
|
|
7639
|
+
stats.maxLeafHeight = hasHeight ? Math.max(stats.maxLeafHeight, leaf.textureLeafHeight) : leaf.textureLeafHeight;
|
|
7640
|
+
hasHeight = true;
|
|
7641
|
+
}
|
|
7642
|
+
if (leaf.doubleSided) stats.doubleSidedCount++;
|
|
7643
|
+
}
|
|
7644
|
+
stats.pendingCount = Math.min(stats.pendingCount, stats.leafCount);
|
|
7645
|
+
stats.ready = stats.pendingCount === 0;
|
|
7646
|
+
return stats;
|
|
7647
|
+
}
|
|
7648
|
+
function collectPolySnapshotStats(root, optionsOrPolygonCount) {
|
|
7649
|
+
const stats = emptySnapshotStats();
|
|
7650
|
+
if (!root) return stats;
|
|
7651
|
+
const options = asOptions(optionsOrPolygonCount);
|
|
7652
|
+
for (const scope of collectScopes(root, options.scopeSelector)) {
|
|
7653
|
+
stats.runtimeAtlasUrlCount += runtimeUrlElementCount(scope);
|
|
7654
|
+
stats.snapshotAtlasCount += matchingElementCount(scope, "[data-polycss-snapshot-atlas]");
|
|
7655
|
+
stats.snapshotBackgroundCount += matchingElementCount(scope, "[data-polycss-snapshot-bg]");
|
|
7656
|
+
}
|
|
7657
|
+
stats.selfContained = stats.runtimeAtlasUrlCount === 0;
|
|
7658
|
+
return stats;
|
|
7659
|
+
}
|
|
7660
|
+
function findCameraRoot(scope) {
|
|
7661
|
+
const element = scope instanceof HTMLElement ? scope : null;
|
|
7662
|
+
if (element) {
|
|
7663
|
+
if (element.classList.contains("polycss-camera")) return element;
|
|
7664
|
+
const closest = element.closest(".polycss-camera");
|
|
7665
|
+
if (closest instanceof HTMLElement) return closest;
|
|
7666
|
+
}
|
|
7667
|
+
const found = scope.querySelector(".polycss-camera");
|
|
7668
|
+
return found instanceof HTMLElement ? found : null;
|
|
7669
|
+
}
|
|
7670
|
+
function collectPolyCameraStats(root, optionsOrPolygonCount) {
|
|
7671
|
+
if (!root) return emptyCameraStats();
|
|
7672
|
+
const options = asOptions(optionsOrPolygonCount);
|
|
7673
|
+
let cameraRoot = null;
|
|
7674
|
+
for (const scope of collectScopes(root, options.scopeSelector)) {
|
|
7675
|
+
cameraRoot = findCameraRoot(scope);
|
|
7676
|
+
if (cameraRoot) break;
|
|
7677
|
+
}
|
|
7678
|
+
if (!cameraRoot) return emptyCameraStats();
|
|
7679
|
+
return {
|
|
7680
|
+
rootFound: true,
|
|
7681
|
+
projection: parseCameraProjection(cameraRoot.getAttribute("data-polycss-camera-projection")),
|
|
7682
|
+
perspectiveStyle: cameraRoot.getAttribute("data-polycss-camera-perspective") ?? "",
|
|
7683
|
+
appliedPerspectiveStyle: cameraRoot.getAttribute("data-polycss-camera-applied-perspective") ?? cameraRoot.style.perspective ?? "",
|
|
7684
|
+
zoom: parseOptionalNumber(cameraRoot.getAttribute("data-polycss-camera-zoom")),
|
|
7685
|
+
distance: parseOptionalNumber(cameraRoot.getAttribute("data-polycss-camera-distance")),
|
|
7686
|
+
rotX: parseOptionalNumber(cameraRoot.getAttribute("data-polycss-camera-rot-x")),
|
|
7687
|
+
rotY: parseOptionalNumber(cameraRoot.getAttribute("data-polycss-camera-rot-y")),
|
|
7688
|
+
target: parseOptionalVec3(cameraRoot.getAttribute("data-polycss-camera-target"))
|
|
7689
|
+
};
|
|
7690
|
+
}
|
|
7092
7691
|
function collectPolyRenderStats(root, optionsOrPolygonCount) {
|
|
7093
7692
|
const options = asOptions(optionsOrPolygonCount);
|
|
7094
7693
|
if (!root) {
|
|
7095
7694
|
return {
|
|
7096
7695
|
...EMPTY_POLY_RENDER_STATS,
|
|
7097
7696
|
surfaceLeafCounts: { ...ZERO_SURFACE_LEAF_COUNTS },
|
|
7697
|
+
textureReadiness: { ...READY_TEXTURE_READINESS },
|
|
7698
|
+
textureStats: emptyTextureStats(),
|
|
7699
|
+
snapshotStats: emptySnapshotStats(),
|
|
7700
|
+
cameraStats: emptyCameraStats(),
|
|
7098
7701
|
polygonCount: options.polygonCount ?? 0
|
|
7099
7702
|
};
|
|
7100
7703
|
}
|
|
@@ -7116,6 +7719,10 @@ function collectPolyRenderStats(root, optionsOrPolygonCount) {
|
|
|
7116
7719
|
mountedPolygonLeafCount,
|
|
7117
7720
|
shadowLeafCount,
|
|
7118
7721
|
surfaceLeafCounts,
|
|
7722
|
+
textureReadiness: collectPolyTextureReadiness(root, options),
|
|
7723
|
+
textureStats: collectPolyTextureStats(root, options),
|
|
7724
|
+
snapshotStats: collectPolySnapshotStats(root, options),
|
|
7725
|
+
cameraStats: collectPolyCameraStats(root, options),
|
|
7119
7726
|
bucketCount
|
|
7120
7727
|
};
|
|
7121
7728
|
}
|
|
@@ -7261,25 +7868,35 @@ import {
|
|
|
7261
7868
|
planePolygons as planePolygons3,
|
|
7262
7869
|
buildSceneContext as buildSceneContext2,
|
|
7263
7870
|
buildPolyMeshTransform as buildPolyMeshTransform2,
|
|
7264
|
-
buildPolySceneTransform
|
|
7871
|
+
buildPolySceneTransform,
|
|
7265
7872
|
computeSceneBbox as computeSceneBbox2,
|
|
7873
|
+
cssDistanceToWorld,
|
|
7874
|
+
cssPositionToWorld,
|
|
7875
|
+
polyCssDistanceToWorld,
|
|
7876
|
+
polyCssPositionToWorld,
|
|
7877
|
+
worldDirectionToCss as worldDirectionToCss3,
|
|
7878
|
+
worldDirectionToPolyCss,
|
|
7879
|
+
worldDirectionalLightToCss as worldDirectionalLightToCss2,
|
|
7880
|
+
worldDirectionalLightToPolyCss,
|
|
7881
|
+
worldDistanceToCss,
|
|
7882
|
+
worldDistanceToPolyCss,
|
|
7883
|
+
worldPositionToCss as worldPositionToCss2,
|
|
7884
|
+
worldPositionToPolyCss,
|
|
7266
7885
|
BASE_TILE as BASE_TILE7,
|
|
7267
7886
|
DEFAULT_CAMERA_STATE as DEFAULT_CAMERA_STATE2,
|
|
7268
7887
|
DEFAULT_PROJECTION,
|
|
7269
7888
|
normalizeInvertMultiplier,
|
|
7889
|
+
buildPolyCameraSceneTransform as buildPolyCameraSceneTransform2,
|
|
7890
|
+
capturePolyCameraSnapshot as capturePolyCameraSnapshot2,
|
|
7891
|
+
polyCameraTargetToCss,
|
|
7892
|
+
resolvePolyCameraAppliedPerspectiveStyle,
|
|
7270
7893
|
createPolyAnimationMixer as createPolyAnimationMixer2,
|
|
7271
7894
|
optimizeAnimatedMeshPolygons,
|
|
7272
7895
|
DEFAULT_SEAM_FACET_SPLIT_OPTIONS,
|
|
7273
7896
|
DEFAULT_SEAM_OVERLAP_OPTIONS,
|
|
7274
7897
|
LoopOnce,
|
|
7275
7898
|
LoopRepeat,
|
|
7276
|
-
LoopPingPong
|
|
7277
|
-
cssDistanceToWorld,
|
|
7278
|
-
cssPositionToWorld,
|
|
7279
|
-
worldDistanceToCss,
|
|
7280
|
-
worldDirectionToCss as worldDirectionToCss3,
|
|
7281
|
-
worldDirectionalLightToCss as worldDirectionalLightToCss2,
|
|
7282
|
-
worldPositionToCss
|
|
7899
|
+
LoopPingPong
|
|
7283
7900
|
} from "@layoutit/polycss-core";
|
|
7284
7901
|
export {
|
|
7285
7902
|
BASE_TILE7 as BASE_TILE,
|
|
@@ -7325,16 +7942,19 @@ export {
|
|
|
7325
7942
|
bakeSolidTextureSampledPolygons,
|
|
7326
7943
|
bakeSolidTextureSamples,
|
|
7327
7944
|
boxPolygons2 as boxPolygons,
|
|
7945
|
+
buildPolyCameraSceneTransform2 as buildPolyCameraSceneTransform,
|
|
7328
7946
|
buildPolyMeshTransform2 as buildPolyMeshTransform,
|
|
7329
|
-
|
|
7947
|
+
buildPolySceneTransform,
|
|
7330
7948
|
buildSceneContext2 as buildSceneContext,
|
|
7331
7949
|
cameraCullNormalGroups,
|
|
7332
7950
|
cameraCullNormalGroupsFromPolygons,
|
|
7333
7951
|
cameraCullNormalKey,
|
|
7334
7952
|
cameraCullVisibleSignature,
|
|
7335
7953
|
cameraFacingDepth,
|
|
7954
|
+
capturePolyCameraSnapshot2 as capturePolyCameraSnapshot,
|
|
7336
7955
|
clampChannel2 as clampChannel,
|
|
7337
7956
|
collectPolyRenderStats,
|
|
7957
|
+
collectPolyTextureReadiness,
|
|
7338
7958
|
computeSceneBbox2 as computeSceneBbox,
|
|
7339
7959
|
computeShapeLighting,
|
|
7340
7960
|
computeTexturePaintMetrics,
|
|
@@ -7342,6 +7962,8 @@ export {
|
|
|
7342
7962
|
coverPlanarPolygons,
|
|
7343
7963
|
createIsometricCamera2 as createIsometricCamera,
|
|
7344
7964
|
createPolyAnimationMixer2 as createPolyAnimationMixer,
|
|
7965
|
+
cssDistanceToWorld,
|
|
7966
|
+
cssPositionToWorld,
|
|
7345
7967
|
cullInteriorPolygons,
|
|
7346
7968
|
cylinderPolygons2 as cylinderPolygons,
|
|
7347
7969
|
dodecahedronPolygons2 as dodecahedronPolygons,
|
|
@@ -7373,12 +7995,15 @@ export {
|
|
|
7373
7995
|
parseVox,
|
|
7374
7996
|
planePolygons3 as planePolygons,
|
|
7375
7997
|
pointInMeshElement,
|
|
7376
|
-
|
|
7377
|
-
|
|
7998
|
+
polyCameraTargetToCss,
|
|
7999
|
+
polyCssDistanceToWorld,
|
|
8000
|
+
polyCssPositionToWorld,
|
|
7378
8001
|
polygonCssSurfaceNormal,
|
|
7379
8002
|
polygonFaces,
|
|
7380
8003
|
polygonFacesCamera,
|
|
8004
|
+
queryPolyLeaves,
|
|
7381
8005
|
repairMeshSeams,
|
|
8006
|
+
resolvePolyCameraAppliedPerspectiveStyle,
|
|
7382
8007
|
ringPolygons2 as ringPolygons,
|
|
7383
8008
|
rotateVec32 as rotateVec3,
|
|
7384
8009
|
seamFacetSplitPolygons,
|
|
@@ -7398,8 +8023,12 @@ export {
|
|
|
7398
8023
|
usePolySceneContext,
|
|
7399
8024
|
usePolySelect,
|
|
7400
8025
|
usePolySelectionApi,
|
|
7401
|
-
worldDirectionToCss3 as
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
8026
|
+
worldDirectionToCss3 as worldDirectionToCss,
|
|
8027
|
+
worldDirectionToPolyCss,
|
|
8028
|
+
worldDirectionalLightToCss2 as worldDirectionalLightToCss,
|
|
8029
|
+
worldDirectionalLightToPolyCss,
|
|
8030
|
+
worldDistanceToCss,
|
|
8031
|
+
worldDistanceToPolyCss,
|
|
8032
|
+
worldPositionToCss2 as worldPositionToCss,
|
|
8033
|
+
worldPositionToPolyCss
|
|
7405
8034
|
};
|