@expofp/renderer 3.2.5 → 3.27.1
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 +111 -0
- package/dist/Renderer.d.ts +88 -0
- package/dist/Renderer.js +53 -0
- package/dist/controls/CameraControls.d.ts +102 -0
- package/dist/controls/CameraControls.js +239 -0
- package/dist/controls/camera-api.d.ts +206 -0
- package/dist/controls/camera-api.js +181 -0
- package/dist/controls/camera-move.d.ts +13 -0
- package/dist/controls/camera-move.js +18 -0
- package/dist/controls/camera-state.d.ts +40 -0
- package/dist/controls/camera-state.js +65 -0
- package/dist/controls/gestures.d.ts +70 -0
- package/dist/controls/gestures.js +84 -0
- package/dist/controls/handlers/Inertia.d.ts +111 -0
- package/dist/controls/handlers/Inertia.js +215 -0
- package/dist/controls/handlers/Pan.d.ts +23 -0
- package/dist/controls/handlers/Pan.js +32 -0
- package/dist/controls/handlers/Pitch.d.ts +94 -0
- package/dist/controls/handlers/Pitch.js +191 -0
- package/dist/controls/handlers/Roll.d.ts +103 -0
- package/dist/controls/handlers/Roll.js +182 -0
- package/dist/controls/handlers/Zoom.d.ts +15 -0
- package/dist/controls/handlers/Zoom.js +26 -0
- package/dist/controls/index.d.ts +56 -0
- package/dist/controls/index.js +58 -0
- package/dist/controls/zoom-to.d.ts +89 -0
- package/dist/controls/zoom-to.js +91 -0
- package/dist/core/InstanceUniforms.d.ts +93 -0
- package/dist/core/InstanceUniforms.js +266 -0
- package/dist/core/SquareDataTexture.d.ts +277 -0
- package/dist/core/SquareDataTexture.js +476 -0
- package/dist/core/batch/BatchedMesh.d.ts +74 -0
- package/dist/core/batch/BatchedMesh.js +149 -0
- package/dist/core/instanced/FrustumCulling.d.ts +141 -0
- package/dist/core/instanced/FrustumCulling.js +246 -0
- package/dist/core/instanced/InstancedMesh.d.ts +302 -0
- package/dist/core/instanced/InstancedMesh.js +497 -0
- package/dist/core/instanced/Instances.d.ts +119 -0
- package/dist/core/instanced/Instances.js +230 -0
- package/dist/core/instanced/Raycasting.d.ts +118 -0
- package/dist/core/instanced/Raycasting.js +134 -0
- package/dist/core/instanced/instanced-material.d.ts +77 -0
- package/dist/core/instanced/instanced-material.js +224 -0
- package/dist/core/lines/BatchedLines.d.ts +135 -0
- package/dist/core/lines/BatchedLines.js +213 -0
- package/dist/core/lines/FrustumCulling.d.ts +43 -0
- package/dist/core/lines/FrustumCulling.js +85 -0
- package/dist/core/lines/Raycasting.d.ts +44 -0
- package/dist/core/lines/Raycasting.js +91 -0
- package/dist/core/lines/lines-material.d.ts +47 -0
- package/dist/core/lines/lines-material.js +115 -0
- package/dist/core/shader-source.d.ts +50 -0
- package/dist/core/shader-source.js +84 -0
- package/dist/core/text/BatchedText.d.ts +227 -0
- package/dist/core/text/BatchedText.js +467 -0
- package/dist/core/text/MemberTexture.d.ts +90 -0
- package/dist/core/text/MemberTexture.js +194 -0
- package/dist/core/text/Text.d.ts +73 -0
- package/dist/core/text/Text.js +215 -0
- package/dist/core/text/batched-text-material.d.ts +56 -0
- package/dist/core/text/batched-text-material.js +121 -0
- package/dist/core/text/glyph-packing.d.ts +17 -0
- package/dist/core/text/glyph-packing.js +61 -0
- package/dist/core/typed-array.d.ts +16 -0
- package/dist/core/typed-array.js +20 -0
- package/dist/debug/components/DebugPanelProvider.d.ts +20 -0
- package/dist/debug/components/DebugPanelProvider.js +38 -0
- package/dist/debug/components/DebugTools.d.ts +22 -0
- package/dist/debug/components/DebugTools.js +28 -0
- package/dist/debug/components/Gui.d.ts +20 -0
- package/dist/debug/components/Gui.js +32 -0
- package/dist/debug/components/MemoryInfo.d.ts +22 -0
- package/dist/debug/components/MemoryInfo.js +42 -0
- package/dist/debug/components/Panel.d.ts +31 -0
- package/dist/debug/components/Panel.js +98 -0
- package/dist/debug/components/Stats.d.ts +9 -0
- package/dist/debug/components/Stats.js +24 -0
- package/dist/debug/debug-context.d.ts +41 -0
- package/dist/debug/debug-context.js +59 -0
- package/dist/debug/index.d.ts +51 -0
- package/dist/debug/index.js +64 -0
- package/dist/events/LayoutDriver.d.ts +31 -0
- package/dist/events/LayoutDriver.js +88 -0
- package/dist/events/PointerMissed.d.ts +23 -0
- package/dist/events/PointerMissed.js +58 -0
- package/dist/events/def-culling.d.ts +46 -0
- package/dist/events/def-culling.js +69 -0
- package/dist/events/layout-targets.d.ts +104 -0
- package/dist/events/layout-targets.js +245 -0
- package/dist/events/pointer.d.ts +118 -0
- package/dist/events/pointer.js +168 -0
- package/dist/external/ExternalCanvas.d.ts +56 -0
- package/dist/external/ExternalCanvas.js +178 -0
- package/dist/external/external-camera.d.ts +17 -0
- package/dist/external/external-camera.js +82 -0
- package/dist/external/external-events.d.ts +14 -0
- package/dist/external/external-events.js +33 -0
- package/dist/index.d.ts +11 -783
- package/dist/index.js +12 -8031
- package/dist/objects/Background.d.ts +31 -0
- package/dist/objects/Background.js +37 -0
- package/dist/objects/Lighting.d.ts +20 -0
- package/dist/objects/Lighting.js +85 -0
- package/dist/objects/containers/SlotContainer.d.ts +266 -0
- package/dist/objects/containers/SlotContainer.js +251 -0
- package/dist/objects/containers/hooks.d.ts +46 -0
- package/dist/objects/containers/hooks.js +118 -0
- package/dist/objects/containers/index.d.ts +6 -0
- package/dist/objects/containers/index.js +4 -0
- package/dist/objects/containers/keys.d.ts +10 -0
- package/dist/objects/containers/keys.js +18 -0
- package/dist/objects/containers/mesh-writes.d.ts +106 -0
- package/dist/objects/containers/mesh-writes.js +97 -0
- package/dist/objects/containers/props.d.ts +23 -0
- package/dist/objects/containers/props.js +1 -0
- package/dist/objects/images/ImageInstance.d.ts +29 -0
- package/dist/objects/images/ImageInstance.js +83 -0
- package/dist/objects/images/Images.d.ts +37 -0
- package/dist/objects/images/Images.js +204 -0
- package/dist/objects/images/atlas-packer.d.ts +128 -0
- package/dist/objects/images/atlas-packer.js +315 -0
- package/dist/objects/images/image-container.d.ts +51 -0
- package/dist/objects/images/image-container.js +70 -0
- package/dist/objects/images/index.d.ts +2 -0
- package/dist/objects/images/index.js +1 -0
- package/dist/objects/images/texture-budget.d.ts +120 -0
- package/dist/objects/images/texture-budget.js +215 -0
- package/dist/objects/layer/Layer.d.ts +27 -0
- package/dist/objects/layer/Layer.js +114 -0
- package/dist/objects/layer/index.d.ts +2 -0
- package/dist/objects/layer/index.js +1 -0
- package/dist/objects/layer/mount-scheduler.d.ts +102 -0
- package/dist/objects/layer/mount-scheduler.js +145 -0
- package/dist/objects/layer/visibility-gui.d.ts +19 -0
- package/dist/objects/layer/visibility-gui.js +93 -0
- package/dist/objects/lines/LineInstance.d.ts +21 -0
- package/dist/objects/lines/LineInstance.js +73 -0
- package/dist/objects/lines/Lines.d.ts +17 -0
- package/dist/objects/lines/Lines.js +29 -0
- package/dist/objects/lines/index.d.ts +2 -0
- package/dist/objects/lines/index.js +1 -0
- package/dist/objects/lines/line-container.d.ts +35 -0
- package/dist/objects/lines/line-container.js +40 -0
- package/dist/objects/materials/ColorMaterial.d.ts +85 -0
- package/dist/objects/materials/ColorMaterial.js +89 -0
- package/dist/objects/materials/LineMaterial.d.ts +44 -0
- package/dist/objects/materials/LineMaterial.js +72 -0
- package/dist/objects/materials/ModelMaterial.d.ts +41 -0
- package/dist/objects/materials/ModelMaterial.js +84 -0
- package/dist/objects/materials/TextureMaterial.d.ts +30 -0
- package/dist/objects/materials/TextureMaterial.js +29 -0
- package/dist/objects/materials/dim.d.ts +123 -0
- package/dist/objects/materials/dim.js +213 -0
- package/dist/objects/materials/shared.d.ts +6 -0
- package/dist/objects/materials/shared.js +51 -0
- package/dist/objects/models/ModelInstance.d.ts +22 -0
- package/dist/objects/models/ModelInstance.js +33 -0
- package/dist/objects/models/Models.d.ts +22 -0
- package/dist/objects/models/Models.js +177 -0
- package/dist/objects/models/gltf-cache.d.ts +17 -0
- package/dist/objects/models/gltf-cache.js +50 -0
- package/dist/objects/models/index.d.ts +2 -0
- package/dist/objects/models/index.js +1 -0
- package/dist/objects/models/model-asset.d.ts +48 -0
- package/dist/objects/models/model-asset.js +77 -0
- package/dist/objects/models/model-container.d.ts +139 -0
- package/dist/objects/models/model-container.js +227 -0
- package/dist/objects/shapes/ShapeInstance.d.ts +26 -0
- package/dist/objects/shapes/ShapeInstance.js +40 -0
- package/dist/objects/shapes/Shapes.d.ts +21 -0
- package/dist/objects/shapes/Shapes.js +120 -0
- package/dist/objects/shapes/index.d.ts +2 -0
- package/dist/objects/shapes/index.js +1 -0
- package/dist/objects/shapes/shape-container.d.ts +165 -0
- package/dist/objects/shapes/shape-container.js +272 -0
- package/dist/objects/shapes/shape-geometry.d.ts +27 -0
- package/dist/objects/shapes/shape-geometry.js +94 -0
- package/dist/objects/text/TextInstance.d.ts +22 -0
- package/dist/objects/text/TextInstance.js +95 -0
- package/dist/objects/text/Texts.d.ts +30 -0
- package/dist/objects/text/Texts.js +41 -0
- package/dist/objects/text/index.d.ts +2 -0
- package/dist/objects/text/index.js +1 -0
- package/dist/objects/text/text-container.d.ts +105 -0
- package/dist/objects/text/text-container.js +206 -0
- package/dist/objects/text/text-layout.d.ts +83 -0
- package/dist/objects/text/text-layout.js +154 -0
- package/dist/space/Camera.d.ts +103 -0
- package/dist/space/Camera.js +321 -0
- package/dist/space/Scene.d.ts +44 -0
- package/dist/space/Scene.js +112 -0
- package/dist/space/Space.d.ts +288 -0
- package/dist/space/Space.js +329 -0
- package/dist/space/VisibleRect.d.ts +72 -0
- package/dist/space/VisibleRect.js +129 -0
- package/dist/space/camera-handle.d.ts +67 -0
- package/dist/space/camera-handle.js +63 -0
- package/dist/space/camera-kind.d.ts +26 -0
- package/dist/space/camera-kind.js +30 -0
- package/dist/space/canvas-size.d.ts +24 -0
- package/dist/space/canvas-size.js +20 -0
- package/dist/space/clipping.d.ts +55 -0
- package/dist/space/clipping.js +108 -0
- package/dist/space/layout-measure.d.ts +65 -0
- package/dist/space/layout-measure.js +173 -0
- package/dist/space/viewport.d.ts +112 -0
- package/dist/space/viewport.js +67 -0
- package/dist/types/defs.d.ts +169 -0
- package/dist/types/defs.js +1 -0
- package/dist/types/events.d.ts +183 -0
- package/dist/types/events.js +1 -0
- package/dist/types/guards.d.ts +14 -0
- package/dist/types/guards.js +42 -0
- package/dist/update/index.d.ts +3 -0
- package/dist/update/index.js +2 -0
- package/dist/update/slot-writers.d.ts +30 -0
- package/dist/update/slot-writers.js +72 -0
- package/dist/update/store.d.ts +41 -0
- package/dist/update/store.js +98 -0
- package/dist/utils/arrays.d.ts +13 -0
- package/dist/utils/arrays.js +20 -0
- package/dist/utils/colors.d.ts +19 -0
- package/dist/utils/colors.js +27 -0
- package/dist/utils/logging.d.ts +26 -0
- package/dist/utils/logging.js +47 -0
- package/dist/utils/math.d.ts +24 -0
- package/dist/utils/math.js +27 -0
- package/package.json +67 -19
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ColorInput } from '../types/defs';
|
|
3
|
+
/** Props for {@link Background}. */
|
|
4
|
+
export interface BackgroundProps {
|
|
5
|
+
/** The background color. */
|
|
6
|
+
color: ColorInput;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The scene's background: a screen-space quad drawn below every layer, replacing what a clear
|
|
10
|
+
* color would paint — and unlike one, dimmed with the venue. The root `Layer` renders it inside
|
|
11
|
+
* its own group, under the root layer's dim provider, so the dim reaches this material exactly as
|
|
12
|
+
* it reaches a layer's.
|
|
13
|
+
*
|
|
14
|
+
* **Screen-space in the vertex shader**, as the imperative renderer drew it: projection is
|
|
15
|
+
* replaced with the quad's own xy in clip space at the far plane, so it covers the canvas edge to
|
|
16
|
+
* edge under any camera — fit, zoom, roll, pitch — and no matrix above it is ever read.
|
|
17
|
+
*
|
|
18
|
+
* It draws through the same {@link ColorMaterial} as the layers, with one addition through the
|
|
19
|
+
* material's pre-dim hook: a quad has no batch prologue, so the per-instance dim uniform the
|
|
20
|
+
* unmodified dim patch looks for is declared here as a constant pinned to "inherit" — every
|
|
21
|
+
* fragment defers to the layer amount, which is the point.
|
|
22
|
+
*
|
|
23
|
+
* **Draw order**: `renderOrder` 0 puts it level with the first layer group, and the tie falls to
|
|
24
|
+
* `material.id` — this material is created as the root layer mounts, before the scheduler admits
|
|
25
|
+
* any leaf, so it draws first. That ordering is load-bearing: flat content writes no depth, so
|
|
26
|
+
* anything drawn after the quad simply paints over it.
|
|
27
|
+
* @param props - The color.
|
|
28
|
+
* @returns The quad.
|
|
29
|
+
*/
|
|
30
|
+
export declare function Background(props: BackgroundProps): ReactNode;
|
|
31
|
+
//# sourceMappingURL=Background.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { declareBeforeMain } from '../core/shader-source';
|
|
4
|
+
import { ColorMaterial } from './materials/ColorMaterial';
|
|
5
|
+
import { DIM_INHERIT, DIM_UNIFORM } from './materials/dim';
|
|
6
|
+
/**
|
|
7
|
+
* The scene's background: a screen-space quad drawn below every layer, replacing what a clear
|
|
8
|
+
* color would paint — and unlike one, dimmed with the venue. The root `Layer` renders it inside
|
|
9
|
+
* its own group, under the root layer's dim provider, so the dim reaches this material exactly as
|
|
10
|
+
* it reaches a layer's.
|
|
11
|
+
*
|
|
12
|
+
* **Screen-space in the vertex shader**, as the imperative renderer drew it: projection is
|
|
13
|
+
* replaced with the quad's own xy in clip space at the far plane, so it covers the canvas edge to
|
|
14
|
+
* edge under any camera — fit, zoom, roll, pitch — and no matrix above it is ever read.
|
|
15
|
+
*
|
|
16
|
+
* It draws through the same {@link ColorMaterial} as the layers, with one addition through the
|
|
17
|
+
* material's pre-dim hook: a quad has no batch prologue, so the per-instance dim uniform the
|
|
18
|
+
* unmodified dim patch looks for is declared here as a constant pinned to "inherit" — every
|
|
19
|
+
* fragment defers to the layer amount, which is the point.
|
|
20
|
+
*
|
|
21
|
+
* **Draw order**: `renderOrder` 0 puts it level with the first layer group, and the tie falls to
|
|
22
|
+
* `material.id` — this material is created as the root layer mounts, before the scheduler admits
|
|
23
|
+
* any leaf, so it draws first. That ordering is load-bearing: flat content writes no depth, so
|
|
24
|
+
* anything drawn after the quad simply paints over it.
|
|
25
|
+
* @param props - The color.
|
|
26
|
+
* @returns The quad.
|
|
27
|
+
*/
|
|
28
|
+
export function Background(props) {
|
|
29
|
+
// One handler for the material's life, per `ColorMaterial`'s contract for its pre-dim hook.
|
|
30
|
+
const [onBeforeCompile] = useState(() => (parameters) => {
|
|
31
|
+
parameters.vertexShader = parameters.vertexShader.replace('#include <project_vertex>',
|
|
32
|
+
/* glsl */ `gl_Position = vec4(transformed.xy, 1.0, 1.0);`);
|
|
33
|
+
parameters.fragmentShader = declareBeforeMain(parameters.fragmentShader,
|
|
34
|
+
/* glsl */ `const float ${DIM_UNIFORM} = ${DIM_INHERIT}.0;`);
|
|
35
|
+
});
|
|
36
|
+
return (_jsxs("mesh", { name: "background", renderOrder: 0, frustumCulled: false, children: [_jsx("planeGeometry", { args: [2, 2] }), _jsx(ColorMaterial, { color: props.color, onBeforeCompile: onBeforeCompile })] }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene lighting: a hemisphere fill from above the plan plus a directional key that follows the
|
|
3
|
+
* camera, so a surface square-on to the viewer is shaded by exactly its own color (see
|
|
4
|
+
* {@link HALF_ALBEDO}).
|
|
5
|
+
*
|
|
6
|
+
* Only lit materials see any of this — solid shape batches and models. Every 2D primitive draws
|
|
7
|
+
* through a `MeshBasicMaterial`, so lines, text and images are unaffected by a light no matter what
|
|
8
|
+
* the scene holds. That is deliberate: a route line or a booth label has no meaningful surface
|
|
9
|
+
* normal, and shading one would make its color depend on where the camera is.
|
|
10
|
+
*
|
|
11
|
+
* **These sit inside the scene's world matrix**, so every direction below is expressed in the plan's
|
|
12
|
+
* own space and taken there through {@link Space.matrixInverse} — one inverse, shared, rather than
|
|
13
|
+
* one per light. Three reads a light's direction from where it ends up in the *world*, so the two
|
|
14
|
+
* transforms cancel and the light points where it was aimed under any fit. The key light needs a
|
|
15
|
+
* target inside the same space for that to hold: its direction is the difference of two world
|
|
16
|
+
* positions, and only a target under the same matrix cancels the fit's translation.
|
|
17
|
+
* @returns The fill and key lights, and the key's target.
|
|
18
|
+
*/
|
|
19
|
+
export declare function Lighting(): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=Lighting.d.ts.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFrame } from '@react-three/fiber';
|
|
3
|
+
import { useLayoutEffect, useRef } from 'react';
|
|
4
|
+
import { Color } from 'three';
|
|
5
|
+
import { useSpace } from '../space/Space';
|
|
6
|
+
/**
|
|
7
|
+
* Scene lighting: a hemisphere fill from above the plan plus a directional key that follows the
|
|
8
|
+
* camera, so a surface square-on to the viewer is shaded by exactly its own color (see
|
|
9
|
+
* {@link HALF_ALBEDO}).
|
|
10
|
+
*
|
|
11
|
+
* Only lit materials see any of this — solid shape batches and models. Every 2D primitive draws
|
|
12
|
+
* through a `MeshBasicMaterial`, so lines, text and images are unaffected by a light no matter what
|
|
13
|
+
* the scene holds. That is deliberate: a route line or a booth label has no meaningful surface
|
|
14
|
+
* normal, and shading one would make its color depend on where the camera is.
|
|
15
|
+
*
|
|
16
|
+
* **These sit inside the scene's world matrix**, so every direction below is expressed in the plan's
|
|
17
|
+
* own space and taken there through {@link Space.matrixInverse} — one inverse, shared, rather than
|
|
18
|
+
* one per light. Three reads a light's direction from where it ends up in the *world*, so the two
|
|
19
|
+
* transforms cancel and the light points where it was aimed under any fit. The key light needs a
|
|
20
|
+
* target inside the same space for that to hold: its direction is the difference of two world
|
|
21
|
+
* positions, and only a target under the same matrix cancels the fit's translation.
|
|
22
|
+
* @returns The fill and key lights, and the key's target.
|
|
23
|
+
*/
|
|
24
|
+
export function Lighting() {
|
|
25
|
+
const fillRef = useRef(null);
|
|
26
|
+
const keyRef = useRef(null);
|
|
27
|
+
const targetRef = useRef(null);
|
|
28
|
+
const space = useSpace();
|
|
29
|
+
useLayoutEffect(() => {
|
|
30
|
+
keyRef.current.target = targetRef.current;
|
|
31
|
+
}, []);
|
|
32
|
+
// Taken from the camera's own backward axis rather than from the controls' target: only the
|
|
33
|
+
// direction matters for a directional light — the target below pins the other end — so this needs
|
|
34
|
+
// no access to `controls`, and unlike normalizing the camera's *position* it stays correct when
|
|
35
|
+
// the plan's coordinates are far from the origin, which SVG viewboxes routinely are.
|
|
36
|
+
//
|
|
37
|
+
// Column 2 of `matrixWorld` is that backward axis: where the light belongs, shining from the
|
|
38
|
+
// camera toward what it looks at. Read with `setFromMatrixColumn` rather than through
|
|
39
|
+
// `Camera.getWorldDirection`, which negates the axis and, worse, re-runs `updateWorldMatrix` —
|
|
40
|
+
// leaving the camera's `matrixWorldNeedsUpdate` set on every single call, which kept the scene
|
|
41
|
+
// perpetually dirty and no screenshot ever settled.
|
|
42
|
+
//
|
|
43
|
+
// Under the on-demand loop this runs only on frames something already asked for, and camera
|
|
44
|
+
// movement is what asks for them, so a still plan costs nothing.
|
|
45
|
+
useFrame((state) => {
|
|
46
|
+
keyRef.current.position
|
|
47
|
+
.setFromMatrixColumn(state.camera.matrixWorld, 2)
|
|
48
|
+
.transformDirection(space.matrixInverse);
|
|
49
|
+
// The plan's own up axis, as a point whose world position lands back on it — which is what three
|
|
50
|
+
// reads a hemisphere light's sky axis from. Under the viewbox fit that axis is world -z, the
|
|
51
|
+
// side the camera is on; under a caller's own transform it is wherever that transform puts it.
|
|
52
|
+
//
|
|
53
|
+
// Computed here rather than memoized against the space because the space is refitted in place
|
|
54
|
+
// and so never changes identity — and it is four vector operations on a frame that was going to
|
|
55
|
+
// aim the key light anyway.
|
|
56
|
+
fillRef.current.position
|
|
57
|
+
.setFromMatrixColumn(space.matrix, 2)
|
|
58
|
+
.normalize()
|
|
59
|
+
.applyMatrix4(space.matrixInverse);
|
|
60
|
+
});
|
|
61
|
+
return (_jsxs(_Fragment, { children: [_jsx("hemisphereLight", { ref: fillRef, color: LIGHT_COLOR, groundColor: GROUND_COLOR, intensity: HALF_ALBEDO }), _jsx("directionalLight", { ref: keyRef, color: LIGHT_COLOR, intensity: HALF_ALBEDO }), _jsx("object3D", { ref: targetRef })] }));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Each light's intensity, so the two together sum to `π`.
|
|
65
|
+
*
|
|
66
|
+
* three's diffuse BRDF is `albedo / π`, so a light of intensity `I` reaching a surface head-on
|
|
67
|
+
* contributes `I · albedo / π`. At `0.5π` each contributes half the albedo, and the pair sums to
|
|
68
|
+
* exactly the albedo — a surface facing the camera therefore renders at precisely the color the plan
|
|
69
|
+
* author picked, and only faces turning away darken. The key light tracks the camera and the fill's
|
|
70
|
+
* sky axis points at it too, so "facing the camera" is the same set of surfaces for both.
|
|
71
|
+
*
|
|
72
|
+
* Two things elsewhere are load-bearing for that identity rather than cosmetic: the lit material sets
|
|
73
|
+
* `ior = 1` and `specularIntensity = 0`, which drive `F0` to zero so no specular lobe pushes a facing
|
|
74
|
+
* surface *above* its albedo, and `<Canvas flat>` keeps tone mapping off, which would remap the
|
|
75
|
+
* result. Change either and the identity quietly stops holding.
|
|
76
|
+
*/
|
|
77
|
+
const HALF_ALBEDO = 0.5 * Math.PI;
|
|
78
|
+
/**
|
|
79
|
+
* Both lights' color — one shared constant, because the {@link HALF_ALBEDO} identity is a property
|
|
80
|
+
* of the pair: two halves sum back to the author's color only when they are halves of the *same*
|
|
81
|
+
* color. Each light copies it on mount, so writing to a light's own color never reaches the other.
|
|
82
|
+
*/
|
|
83
|
+
const LIGHT_COLOR = new Color('white');
|
|
84
|
+
/** The fill's ground half: pure black, so the side facing away from the sky axis adds nothing. */
|
|
85
|
+
const GROUND_COLOR = new Color('black');
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { type Intersection, type Object3D } from 'three';
|
|
2
|
+
import { type UniformSchemaShader } from '../../core/InstanceUniforms';
|
|
3
|
+
import { type UniformValue } from '../../core/SquareDataTexture';
|
|
4
|
+
import { type RenderableDef } from '../../types/defs';
|
|
5
|
+
/**
|
|
6
|
+
* What a container needs from the mesh it writes into.
|
|
7
|
+
*
|
|
8
|
+
* A capability rather than a union of our mesh classes: `BatchedMeshExt`, `InstancedMeshExt`,
|
|
9
|
+
* `BatchedLinesExt` and `BatchedTextExt` share no base below `Object3D`, yet every one of them
|
|
10
|
+
* declares per-instance uniforms and hides an instance the same way — which is all a container
|
|
11
|
+
* touches generically. Everything else it reaches through its own mesh type, which the subclass
|
|
12
|
+
* names.
|
|
13
|
+
*/
|
|
14
|
+
export interface SlotMesh extends Object3D {
|
|
15
|
+
/**
|
|
16
|
+
* Declares per-instance uniforms, merged with whatever is already declared.
|
|
17
|
+
* @param schema - The uniforms to add.
|
|
18
|
+
*/
|
|
19
|
+
addUniforms(schema: UniformSchemaShader): void;
|
|
20
|
+
/**
|
|
21
|
+
* Writes one instance's uniform.
|
|
22
|
+
* @param slot - The instance to write.
|
|
23
|
+
* @param name - The uniform's name.
|
|
24
|
+
* @param value - The value to write.
|
|
25
|
+
*/
|
|
26
|
+
setUniformAt(slot: number, name: string, value: UniformValue): void;
|
|
27
|
+
/**
|
|
28
|
+
* Shows or hides one instance.
|
|
29
|
+
* @param slot - The instance to show or hide.
|
|
30
|
+
* @param visible - Whether it draws.
|
|
31
|
+
*/
|
|
32
|
+
setVisibleAt(slot: number, visible: boolean): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* An entry in a mesh's render list. Every mesh's sort callback receives a list of these — the
|
|
36
|
+
* published shapes differ in what else they carry, but each entry identifies its instance by
|
|
37
|
+
* `index`, which is all a paint-order sort needs.
|
|
38
|
+
*/
|
|
39
|
+
export interface RenderListItem {
|
|
40
|
+
/** The instance id the entry draws. */
|
|
41
|
+
index: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One entry in the list `BatchedMesh.customSort` receives. three's published types describe only
|
|
45
|
+
* `start`, `count`, and `z`, but the runtime also passes `index` — the instance id — which is the
|
|
46
|
+
* only way a sort can map an entry back to the instance that produced it.
|
|
47
|
+
*/
|
|
48
|
+
export interface BatchedMeshRenderItem extends RenderListItem {
|
|
49
|
+
/** Offset of the instance's geometry in the shared draw range. */
|
|
50
|
+
start: number;
|
|
51
|
+
/** Length of the instance's geometry draw range. */
|
|
52
|
+
count: number;
|
|
53
|
+
/** Instance depth along the camera's view direction. */
|
|
54
|
+
z: number;
|
|
55
|
+
}
|
|
56
|
+
/** How one container differs from the default, passed up by its constructor. */
|
|
57
|
+
export interface SlotContainerOptions {
|
|
58
|
+
/**
|
|
59
|
+
* The per-instance uniforms the mesh declares on {@link SlotContainer.bind}. Defaults to the dim
|
|
60
|
+
* alone, which every def type carries. A container whose mesh needs more (an image's uv region, a
|
|
61
|
+
* model's opacity) passes the merged schema rather than declaring twice: `InstanceUniforms.add`
|
|
62
|
+
* rebuilds the backing texture, so two calls would build it twice per bind.
|
|
63
|
+
*/
|
|
64
|
+
schema?: UniformSchemaShader;
|
|
65
|
+
/**
|
|
66
|
+
* Sort the draw list descending, so the *first* instance drawn is the one that paints on top.
|
|
67
|
+
*
|
|
68
|
+
* For a batch whose material keeps the first fragment to reach a pixel and rejects the rest,
|
|
69
|
+
* which is how the line material stops translucent lines darkening where they overlap: there,
|
|
70
|
+
* draw order is the reverse of paint order. Slots are still labeled in paint order either way.
|
|
71
|
+
*/
|
|
72
|
+
reverse?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One layer's mesh bookkeeping: the bound mesh, which slot each def holds, and the paint order
|
|
76
|
+
* across them.
|
|
77
|
+
*
|
|
78
|
+
* A container is what stands between a layer's defs and one mesh. It is created during render,
|
|
79
|
+
* sized to the membership it first sees, and held in `useState` for as long as its component is
|
|
80
|
+
* mounted; the mesh itself is R3F's, constructed from the subclass's args and handed back through
|
|
81
|
+
* {@link bind}, so R3F owns its lifetime and disposal. Instances claim and release slots from their
|
|
82
|
+
* own effects, and write their type-specific state through the subclass's own methods.
|
|
83
|
+
*
|
|
84
|
+
* What lives here is everything that does not depend on which def type is drawn:
|
|
85
|
+
*
|
|
86
|
+
* - **Slot allocation**, in both directions. `slotOf` is what a paint-order pass over the layer's
|
|
87
|
+
* defs looks each def up with, and {@link defAt} is what turns a pointer hit — which names a slot
|
|
88
|
+
* — back into the def that drew it. Slots come from a mesh's free list, so a released slot may be
|
|
89
|
+
* handed to a different def later; freeing by slot keeps both directions from outliving the claim
|
|
90
|
+
* they describe.
|
|
91
|
+
* - **Paint order**, explicitly. Instance ids come from a mesh's free list, so they do not track
|
|
92
|
+
* sibling order — a container that let slot order stand in for paint order would reorder itself
|
|
93
|
+
* after any claim/release churn, and again under StrictMode's remount, which re-claims in reverse.
|
|
94
|
+
* Explicit order is also what the 2D painter's algorithm needs: 2D content never writes depth, so
|
|
95
|
+
* nothing it draws is in the buffer for the next 2D fragment to test against, and the draw list's
|
|
96
|
+
* order is the only thing that decides overlap.
|
|
97
|
+
* - **The two fields every def type carries**, `hidden` and `dim`, through {@link setVisibleAt} and
|
|
98
|
+
* {@link setDimAt} — which is what lets one hook drive them for every def type.
|
|
99
|
+
*
|
|
100
|
+
* A subclass supplies {@link addInstance} and {@link removeInstance}, names its mesh and def types,
|
|
101
|
+
* and adds whatever its own defs need.
|
|
102
|
+
* @template R - The per-instance resource a claim allocates against (a geometry, a texture region,
|
|
103
|
+
* a line count); compared by identity, so a stable reference means a stable slot. `null` for a
|
|
104
|
+
* container whose members share everything.
|
|
105
|
+
* @template M - The mesh this container writes into.
|
|
106
|
+
* @template T - The def kind the layer holds.
|
|
107
|
+
*/
|
|
108
|
+
export declare abstract class SlotContainer<R, M extends SlotMesh = SlotMesh, T extends RenderableDef = RenderableDef> {
|
|
109
|
+
/**
|
|
110
|
+
* Sorts a mesh's render list into paint order. Assigned straight to the mesh's `customSort` JSX
|
|
111
|
+
* prop, whose R3F-generated type leaves the value effectively unchecked — so the entry type here
|
|
112
|
+
* needs no cast against three's published one, which omits `index`.
|
|
113
|
+
*
|
|
114
|
+
* An arrow property rather than a method, because it is handed over as a bare value and a
|
|
115
|
+
* prototype method would arrive unbound.
|
|
116
|
+
* @param list - The render list, sorted in place.
|
|
117
|
+
*/
|
|
118
|
+
readonly customSort: (list: RenderListItem[]) => void;
|
|
119
|
+
/**
|
|
120
|
+
* The layer's membership, in authored paint order. Kept so a def whose own dim changes can re-run
|
|
121
|
+
* the order pass without this container having re-rendered — `update(def)` reaches the instance,
|
|
122
|
+
* not here.
|
|
123
|
+
*/
|
|
124
|
+
protected layerDefs: readonly T[];
|
|
125
|
+
/**
|
|
126
|
+
* Whether the layer is dimmed, which is what a def without a `dim` of its own inherits.
|
|
127
|
+
*
|
|
128
|
+
* A flag rather than the layer's amount, because the amount is the shader's business and this is
|
|
129
|
+
* only ever asked a yes-or-no question. It is also what makes an eased layer dim cheap: the order
|
|
130
|
+
* pass re-runs when the value crosses zero, not on every frame of the ease.
|
|
131
|
+
*/
|
|
132
|
+
protected layerDimmed: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Whether each slot currently draws dimmed, so a dim write that does not cross the split costs
|
|
135
|
+
* nothing.
|
|
136
|
+
*/
|
|
137
|
+
protected readonly dimmedBySlot: (boolean | undefined)[];
|
|
138
|
+
/**
|
|
139
|
+
* Each def's order, durable and weak — collected with the def. It outlives a slot, so a re-claim
|
|
140
|
+
* can seed the new slot's order without waiting for the next order pass.
|
|
141
|
+
*/
|
|
142
|
+
private readonly orderByDef;
|
|
143
|
+
/** Each slot's place in the paint order, read by {@link customSort}. */
|
|
144
|
+
private readonly orderBySlot;
|
|
145
|
+
private readonly slotByDef;
|
|
146
|
+
private readonly defBySlot;
|
|
147
|
+
private readonly schema;
|
|
148
|
+
private readonly sortDirection;
|
|
149
|
+
/** Set by {@link bind}, which runs before any effect can claim a slot. */
|
|
150
|
+
private boundMesh;
|
|
151
|
+
/**
|
|
152
|
+
* @param options - How this container differs from the default.
|
|
153
|
+
*/
|
|
154
|
+
constructor(options?: SlotContainerOptions);
|
|
155
|
+
/**
|
|
156
|
+
* The mesh every instance writes into. Undefined until {@link bind}; refs attach before passive
|
|
157
|
+
* effects run, so every claim and slot write sees it bound.
|
|
158
|
+
*/
|
|
159
|
+
get mesh(): M;
|
|
160
|
+
/**
|
|
161
|
+
* Binds the mesh R3F constructed from this container's args, declaring its per-instance uniforms.
|
|
162
|
+
*
|
|
163
|
+
* Bind-once: the ref-cleanup `null` and any re-bind are ignored, because React StrictMode cycles
|
|
164
|
+
* refs (attach → cleanup → attach) around a passive effect cycle — a container that forgot its
|
|
165
|
+
* mesh there would turn {@link release} into a no-op and leak the slot when the remounted instance
|
|
166
|
+
* re-claims, and one that re-declared its uniforms would strand the values already written into
|
|
167
|
+
* them.
|
|
168
|
+
* @param mesh - The mounted mesh, or the ref-cleanup `null`.
|
|
169
|
+
*/
|
|
170
|
+
bind(mesh: M | null): void;
|
|
171
|
+
/**
|
|
172
|
+
* Reserves a slot for one instance, backed by `resource`.
|
|
173
|
+
*
|
|
174
|
+
* Paint order is deliberately not a parameter: it is a property of the whole sibling list, so the
|
|
175
|
+
* component writes it for every def in one pass after each membership change (see
|
|
176
|
+
* {@link setPaintOrder}) — an instance never learns its index, which is what lets a memoized
|
|
177
|
+
* instance ignore structural re-renders entirely.
|
|
178
|
+
* @param def - The def the slot will draw; def-to-slot bookkeeping is keyed by its identity.
|
|
179
|
+
* @param resource - The per-instance resource to allocate against.
|
|
180
|
+
* @returns The slot index.
|
|
181
|
+
*/
|
|
182
|
+
claim(def: RenderableDef, resource: R): number;
|
|
183
|
+
/**
|
|
184
|
+
* Frees a slot, and everything recorded about the claim it held.
|
|
185
|
+
* @param slot - The slot to free.
|
|
186
|
+
*/
|
|
187
|
+
release(slot: number): void;
|
|
188
|
+
/**
|
|
189
|
+
* The def holding a slot — the reverse of {@link claim}.
|
|
190
|
+
* @param slot - The slot to look up, or `undefined` for a hit that named none.
|
|
191
|
+
* @returns The def, or `undefined` when the slot is free.
|
|
192
|
+
*/
|
|
193
|
+
defAt(slot: number | undefined): RenderableDef | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* The def an intersection with this container's mesh hit.
|
|
196
|
+
*
|
|
197
|
+
* Which field of an intersection names a slot is the container's own knowledge — `instanceId` for
|
|
198
|
+
* an instanced mesh, `batchId` for a batched one, the member id for a text batch, whose defs own
|
|
199
|
+
* several — so it is answered here rather than at each registration site.
|
|
200
|
+
* @param hit - The intersection to trace.
|
|
201
|
+
* @returns The def, or `undefined` when the hit cannot be traced to one.
|
|
202
|
+
*/
|
|
203
|
+
defFromHit(hit: Intersection): RenderableDef | undefined;
|
|
204
|
+
/**
|
|
205
|
+
* Shows or hides one instance. Every def type carries `hidden`, so `useDefSync` drives this for
|
|
206
|
+
* all of them.
|
|
207
|
+
* @param slot - The slot to show or hide.
|
|
208
|
+
* @param visible - Whether the instance should draw.
|
|
209
|
+
*/
|
|
210
|
+
setVisibleAt(slot: number, visible: boolean): void;
|
|
211
|
+
/**
|
|
212
|
+
* Sets one instance's own dim, or clears it back to its layer's.
|
|
213
|
+
*
|
|
214
|
+
* The counterpart to {@link setVisibleAt}, and here for the same reason: `dim` is a `SharedDef`
|
|
215
|
+
* field, so `useDefSync` drives it for every def type. The raw field is passed through rather than
|
|
216
|
+
* an encoded amount, which keeps the sentinel — and the rest of the shader's contract — inside the
|
|
217
|
+
* material module that reads it.
|
|
218
|
+
* @param slot - The slot to dim.
|
|
219
|
+
* @param dim - The def's `dim`; `undefined` defers to the layer's.
|
|
220
|
+
*/
|
|
221
|
+
setDimAt(slot: number, dim: number | undefined): void;
|
|
222
|
+
/**
|
|
223
|
+
* Writes an encoded dim into a slot's uniform — the part of {@link setDimAt} that knows how a slot
|
|
224
|
+
* maps onto the mesh, split out so a container whose slot spans several mesh instances overrides
|
|
225
|
+
* only that and keeps the split-crossing check above.
|
|
226
|
+
* @param slot - The slot to write.
|
|
227
|
+
* @param amount - The encoded amount, from `instanceDim`.
|
|
228
|
+
*/
|
|
229
|
+
protected writeDim(slot: number, amount: number): void;
|
|
230
|
+
/**
|
|
231
|
+
* Declares the layer's membership and dim, and re-runs the order pass over them.
|
|
232
|
+
*
|
|
233
|
+
* The component calls this from an effect after each structural change — child effects run first,
|
|
234
|
+
* so every mounted instance has claimed by then. Defs that have not claimed yet are recorded
|
|
235
|
+
* anyway: a later claim seeds its slot's order from this assignment, which is what keeps a
|
|
236
|
+
* re-claim correctly ordered without React involvement.
|
|
237
|
+
* @param defs - The current membership, in paint order.
|
|
238
|
+
* @param layerDimmed - Whether the layer is dimmed, inherited by defs without a `dim` of their own.
|
|
239
|
+
*/
|
|
240
|
+
setPaintOrder(defs: readonly T[], layerDimmed: boolean): void;
|
|
241
|
+
/**
|
|
242
|
+
* Labels every claimed slot with its place in the layer's draw order, undimmed defs last.
|
|
243
|
+
*
|
|
244
|
+
* Overridden by a container whose mesh has no sortable draw list, where ordering means handing the
|
|
245
|
+
* mesh a rebuilt member list instead.
|
|
246
|
+
*/
|
|
247
|
+
protected applyOrder(): void;
|
|
248
|
+
/**
|
|
249
|
+
* The slot a def holds, for an order pass walking the layer's defs.
|
|
250
|
+
* @param def - The def to look up.
|
|
251
|
+
* @returns The slot, or `undefined` when the def has not claimed one.
|
|
252
|
+
*/
|
|
253
|
+
protected slotOf(def: RenderableDef): number | undefined;
|
|
254
|
+
/**
|
|
255
|
+
* Allocates one instance in the mesh.
|
|
256
|
+
* @param resource - The per-instance resource to allocate against.
|
|
257
|
+
* @returns The slot the mesh allocated.
|
|
258
|
+
*/
|
|
259
|
+
protected abstract addInstance(resource: R): number;
|
|
260
|
+
/**
|
|
261
|
+
* Frees one instance in the mesh.
|
|
262
|
+
* @param slot - The slot to free.
|
|
263
|
+
*/
|
|
264
|
+
protected abstract removeInstance(slot: number): void;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=SlotContainer.d.ts.map
|