@forgeax/engine-render 0.1.27 → 0.1.29
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 +842 -124
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +3 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/gpu-driven-owner.d.ts +10 -0
- package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +7 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +3 -1
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/recovery/failure-location.d.ts +12 -0
- package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +3 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +4 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
- package/dist/assembly/skin-palette-owner.d.ts +8 -0
- package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
- package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-device-loss.d.ts +15 -0
- package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
- package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +7 -3
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
- package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
- package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
- package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
- package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +7 -141
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
- package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -3
- package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
- package/dist/chunk-33XZFTQU.mjs.map +1 -0
- package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
- package/dist/chunk-BLXGONR2.mjs.map +1 -0
- package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
- package/dist/chunk-BQVQOQJH.mjs.map +1 -0
- package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
- package/dist/chunk-BTWH7BP4.mjs.map +1 -0
- package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
- package/dist/chunk-FUODTTIA.mjs.map +1 -0
- package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
- package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
- package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
- package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
- package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
- package/dist/chunk-NICXSHAT.mjs.map +1 -0
- package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
- package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
- package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
- package/dist/chunk-PA5DRJNI.mjs.map +1 -0
- package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
- package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
- package/dist/components/camera.d.ts +62 -2
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +6 -20
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/scene-instance.d.ts +2 -1
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/screen-space-reflection.d.ts +14 -0
- package/dist/components/screen-space-reflection.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +13805 -7186
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +11 -17
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/mesh-residency-lifetime.d.ts +21 -0
- package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
- package/dist/dynamic-geometry.d.ts +125 -0
- package/dist/dynamic-geometry.d.ts.map +1 -0
- package/dist/environment/background.d.ts +6 -0
- package/dist/environment/background.d.ts.map +1 -0
- package/dist/errors/gpu-driven.d.ts +6 -3
- package/dist/errors/gpu-driven.d.ts.map +1 -1
- package/dist/errors/render.d.ts +7 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +33 -3
- package/dist/extract/gpu-driven.d.ts.map +1 -1
- package/dist/features/host.d.ts +23 -1
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/noise-texture.d.ts +17 -0
- package/dist/features/noise-texture.d.ts.map +1 -0
- package/dist/features/plan.d.ts +83 -2
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +37 -4
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +5 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +5 -3
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +11 -3
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +19 -3
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +2 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/pbr-program.d.ts +10 -0
- package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +144 -23
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-views.d.ts +126 -0
- package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +18 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +2 -8
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +14 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-texture-usage.d.ts +1 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +6 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts +8 -0
- package/dist/ibl/frame-resources.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +21 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +8 -7
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +164 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +11 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -1
- package/dist/instances.d.ts +89 -44
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +118 -10
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/material-row.d.ts +5 -0
- package/dist/material-row.d.ts.map +1 -0
- package/dist/materials.d.ts +15 -0
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +21 -5
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
- package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
- package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
- package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
- package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
- package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
- package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
- package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
- package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
- package/dist/pipeline/standard-output/graph.d.ts +15 -0
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
- package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
- package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
- package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
- package/dist/pipeline/standard-output/resources.d.ts +10 -0
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
- package/dist/pipeline/standard-output/types.d.ts +39 -0
- package/dist/pipeline/standard-output/types.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +2 -2
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +4 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -9
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +1 -1
- package/dist/points-lines/standard-owner.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +3 -3
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +106 -5
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +39 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +7 -8
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +38 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +2 -10
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +12 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +15 -6
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +19 -0
- package/dist/record/prepared-material-bindings.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts +2 -9
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +76 -26
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +62 -7
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +35 -7
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -0
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +10 -2
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/recovery/render-system-roots.d.ts +11 -0
- package/dist/recovery/render-system-roots.d.ts.map +1 -0
- package/dist/recovery/types.d.ts +76 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/reflection/record-owner.d.ts +0 -2
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +185 -30
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +64 -5
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +7 -5
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +101 -41
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +22 -0
- package/dist/render-system-projections.d.ts.map +1 -0
- package/dist/render-system.d.ts +34 -77
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +14 -7
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +29 -11
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/shadow-visibility.d.ts +5 -0
- package/dist/scene/shadow-visibility.d.ts.map +1 -0
- package/dist/ssr/admission.d.ts +70 -1
- package/dist/ssr/admission.d.ts.map +1 -1
- package/dist/ssr/compose.d.ts +13 -0
- package/dist/ssr/compose.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +35 -0
- package/dist/ssr/errors.d.ts.map +1 -1
- package/dist/ssr/graph.d.ts +60 -0
- package/dist/ssr/graph.d.ts.map +1 -0
- package/dist/ssr/history.d.ts +97 -0
- package/dist/ssr/history.d.ts.map +1 -0
- package/dist/ssr/hiz.d.ts +37 -0
- package/dist/ssr/hiz.d.ts.map +1 -0
- package/dist/ssr/inspection.d.ts +42 -0
- package/dist/ssr/inspection.d.ts.map +1 -0
- package/dist/ssr/resources.d.ts +58 -0
- package/dist/ssr/resources.d.ts.map +1 -0
- package/dist/ssr/temporal.d.ts +38 -0
- package/dist/ssr/temporal.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +32 -10
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +15 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +9 -0
- package/dist/systems/transparent-dispatch.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +7 -0
- package/dist/targets/material-source.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts +7 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +8 -0
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/history.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -6
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts +2 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/temporal-view.d.ts +2 -0
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +35 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +6 -0
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
- package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
- package/src/__tests__/auto-exposure.browser.test.ts +33 -0
- package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
- package/src/__tests__/detached-inspection.integration.test.ts +5 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
- package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
- package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
- package/src/__tests__/factory-contract.integration.test.ts +73 -22
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
- package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
- package/src/__tests__/feature-noise.unit.test.ts +38 -0
- package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
- package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
- package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
- package/src/__tests__/frame-targets.unit.test.ts +24 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
- package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
- package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
- package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
- package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
- package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
- package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
- package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
- package/src/__tests__/gpu-scene.unit.test.ts +559 -33
- package/src/__tests__/instances-culling.integration.test.ts +36 -10
- package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
- package/src/__tests__/instances-store.unit.test.ts +242 -39
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
- package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
- package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
- package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
- package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
- package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
- package/src/__tests__/material-texture-source.unit.test.ts +87 -0
- package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
- package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
- package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
- package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
- package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
- package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
- package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
- package/src/__tests__/public-surface.test-d.ts +3 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
- package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
- package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
- package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
- package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
- package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
- package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
- package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
- package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
- package/src/__tests__/render-target-material-source.test-d.ts +27 -3
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
- package/src/__tests__/shader-manifest-fixture.ts +39 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
- package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
- package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
- package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
- package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
- package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
- package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
- package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
- package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
- package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
- package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
- package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
- package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
- package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
- package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
- package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
- package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
- package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
- package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
- package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
- package/src/__tests__/ssr-reprojection-probe.ts +90 -0
- package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
- package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
- package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
- package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
- package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
- package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
- package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
- package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
- package/src/__tests__/standard-output.browser.test.ts +15 -0
- package/src/__tests__/standard-output.dawn.test.ts +15 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
- package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
- package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
- package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
- package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
- package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
- package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
- package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
- package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
- package/src/__tests__/taa-stability-feedback.ts +341 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
- package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
- package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
- package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
- package/src/__tests__/visibility-extract.perf.test.ts +20 -8
- package/src/__tests__/visibility-instances.integration.test.ts +19 -7
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
- package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
- package/src/assembly/dynamic-geometry-host.ts +887 -0
- package/src/assembly/dynamic-geometry-runtime.ts +71 -0
- package/src/assembly/factory.ts +4 -0
- package/src/assembly/gpu-driven-owner.ts +29 -0
- package/src/assembly/host-contract.ts +36 -0
- package/src/assembly/material/assembly.ts +38 -0
- package/src/assembly/material-shader-policy.ts +71 -28
- package/src/assembly/recovery/failure-location.ts +62 -0
- package/src/assembly/recovery/renderer-recover.ts +19 -17
- package/src/assembly/renderer-facade.ts +29 -0
- package/src/assembly/renderer-feature-inspection.ts +13 -0
- package/src/assembly/renderer-frame-transaction.ts +63 -0
- package/src/assembly/renderer-helpers.ts +26 -0
- package/src/assembly/renderer-inspection.ts +6 -0
- package/src/assembly/shader-prewarm-policy.ts +32 -0
- package/src/assembly/skin-palette-owner.ts +21 -0
- package/src/assembly/ssr-shader-prewarm.ts +41 -0
- package/src/assembly/webgpu-device-loss.ts +75 -0
- package/src/assembly/webgpu-pbr-ready.ts +232 -0
- package/src/assembly/webgpu-ready-mipmap.ts +26 -0
- package/src/assembly/webgpu-ready.ts +142 -121
- package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
- package/src/assembly/webgpu-renderer-contract.ts +69 -0
- package/src/assembly/webgpu-renderer-guards.ts +32 -0
- package/src/assembly/webgpu-renderer-observation.ts +43 -0
- package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
- package/src/assembly/webgpu-renderer.ts +675 -614
- package/src/assembly/webgpu-vertex-layouts.ts +233 -87
- package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
- package/src/components/camera.ts +287 -7
- package/src/components/index.ts +1 -0
- package/src/components/instances.ts +45 -18
- package/src/components/scene-instance.ts +2 -1
- package/src/components/screen-space-reflection.ts +21 -0
- package/src/components/sprite-animation.ts +3 -3
- package/src/components/sprite-instances.ts +1 -1
- package/src/device/gpu-residency.ts +96 -93
- package/src/device/mesh-residency-lifetime.ts +73 -0
- package/src/dynamic-geometry.ts +736 -0
- package/src/environment/background.ts +263 -0
- package/src/errors/gpu-driven.ts +39 -5
- package/src/errors/render.ts +27 -3
- package/src/extract/camera.ts +26 -1
- package/src/extract/gpu-driven.ts +185 -10
- package/src/features/host.ts +237 -19
- package/src/features/noise-texture.ts +91 -0
- package/src/features/plan.ts +553 -24
- package/src/features/prepared-gpu-work.ts +631 -49
- package/src/features/prepared-graphics-store.ts +31 -0
- package/src/features/prepared-graphics.ts +5 -0
- package/src/features/render-graph-compute.ts +41 -8
- package/src/features/render-graph-contribution.ts +141 -3
- package/src/features/render-graph-raster.ts +143 -30
- package/src/features/types.ts +11 -0
- package/src/fullscreen-post-process-pass.ts +3 -0
- package/src/gpu-driven/batch-topology.ts +424 -102
- package/src/gpu-driven/pbr-program.ts +31 -0
- package/src/gpu-driven/prepared-draw.ts +29 -4
- package/src/gpu-driven/production-raster.ts +2267 -694
- package/src/gpu-driven/shadow-views.ts +539 -0
- package/src/gpu-driven/view-gpu.ts +188 -41
- package/src/gpu-scene-schema.ts +52 -11
- package/src/gpu-scene.ts +186 -99
- package/src/gpu-texture-usage.ts +1 -0
- package/src/hdrp-buffers.ts +72 -36
- package/src/ibl/frame-resources.ts +38 -0
- package/src/ibl/skylight-bind-group.ts +5 -4
- package/src/index.ts +125 -1
- package/src/inspection-types.ts +191 -0
- package/src/instances-derived-bounds.ts +258 -34
- package/src/instances.ts +459 -150
- package/src/internal.ts +22 -0
- package/src/lifecycle.ts +2 -0
- package/src/material-row.ts +145 -0
- package/src/materials.ts +44 -8
- package/src/pbr-pipeline.ts +159 -17
- package/src/pipeline/standard-forward-lane.ts +52 -24
- package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
- package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
- package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
- package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
- package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
- package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
- package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
- package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
- package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
- package/src/pipeline/standard-output/color-transform.ts +124 -0
- package/src/pipeline/standard-output/graph.ts +139 -0
- package/src/pipeline/standard-output/lut-admission.ts +121 -0
- package/src/pipeline/standard-output/lut-gpu.ts +399 -0
- package/src/pipeline/standard-output/lut-state.ts +176 -0
- package/src/pipeline/standard-output/resources.ts +121 -0
- package/src/pipeline/standard-output/types.ts +58 -0
- package/src/pipeline/standard-pipeline.ts +192 -59
- package/src/pipeline/standard-post.ts +186 -27
- package/src/pipeline-builder.ts +16 -6
- package/src/pipeline-spec-types.ts +4 -0
- package/src/pipeline-spec.ts +37 -29
- package/src/points-lines/standard-owner.ts +6 -14
- package/src/prepare/prepared-graphics-resolver.ts +9 -2
- package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
- package/src/record/dynamic-geometry-consumption.ts +59 -0
- package/src/record/frame-lighting.ts +12 -11
- package/src/record/frame-snapshot.ts +133 -23
- package/src/record/frame-targets.ts +9 -0
- package/src/record/frame.ts +727 -133
- package/src/record/main-pass-geometry.ts +162 -98
- package/src/record/main-pass-material.ts +115 -26
- package/src/record/main-pass-sprite-draws.ts +18 -107
- package/src/record/main-pass.ts +78 -8
- package/src/record/material-uniforms.ts +1 -1
- package/src/record/mesh-ssbo.ts +59 -15
- package/src/record/prepared-material-bindings.ts +234 -0
- package/src/record/recovery-pipeline.ts +59 -136
- package/src/record/render-context.ts +92 -22
- package/src/record/shadow-pass.ts +1231 -209
- package/src/record/skybox-post-pass.ts +14 -3
- package/src/record/typed-frame-graph.ts +1006 -53
- package/src/record/view-ubo.ts +11 -0
- package/src/recovery/render-system-candidate.ts +90 -66
- package/src/recovery/render-system-roots.ts +113 -0
- package/src/recovery/types.ts +77 -0
- package/src/reflection/record-owner.ts +26 -54
- package/src/render-contract.ts +219 -25
- package/src/render-graph-primitives.ts +6 -2
- package/src/render-pipeline.ts +70 -1
- package/src/render-system-extract-tail.ts +409 -160
- package/src/render-system-extract.ts +376 -102
- package/src/render-system-projections.ts +241 -0
- package/src/render-system.ts +692 -791
- package/src/scene/render-scene-types.ts +13 -4
- package/src/scene/render-scene.ts +569 -355
- package/src/scene/shadow-visibility.ts +21 -0
- package/src/ssr/admission.ts +380 -14
- package/src/ssr/compose.ts +144 -0
- package/src/ssr/errors.ts +48 -0
- package/src/ssr/graph.ts +777 -0
- package/src/ssr/history.ts +436 -0
- package/src/ssr/hiz.ts +124 -0
- package/src/ssr/inspection.ts +124 -0
- package/src/ssr/resources.ts +202 -0
- package/src/ssr/temporal.ts +164 -0
- package/src/systems/skin-palette-allocator.ts +495 -148
- package/src/systems/skin-palette-types.ts +17 -0
- package/src/systems/transparent-dispatch.ts +90 -0
- package/src/targets/material-source.ts +34 -0
- package/src/temporal/coverage.ts +1 -1
- package/src/temporal/frame-coordinator.ts +23 -2
- package/src/temporal/gpu.ts +74 -12
- package/src/temporal/history.ts +3 -1
- package/src/temporal/inspection.ts +2 -1
- package/src/temporal/standard-scene-data.ts +3 -1
- package/src/temporal/temporal-view.ts +3 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
- package/src/typed-render-graph-primitives.ts +266 -74
- package/src/typed-shadow-passes.ts +122 -12
- package/src/volume/temporal.ts +10 -0
- package/dist/chunk-ADHHVYLW.mjs.map +0 -1
- package/dist/chunk-FJ6P52EE.mjs.map +0 -1
- package/dist/chunk-GE3SDD72.mjs.map +0 -1
- package/dist/chunk-GF523LHF.mjs.map +0 -1
- package/dist/chunk-HKXTW355.mjs.map +0 -1
- package/dist/chunk-JDWARUOI.mjs.map +0 -1
- package/dist/chunk-KM2NOX2I.mjs.map +0 -1
- package/dist/chunk-TMIASV2N.mjs.map +0 -1
- package/dist/chunk-XDP6XE5V.mjs.map +0 -1
- package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
- package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/sprite-animation.ts","../src/components/sprite-instances.ts","../src/components/sprite-region-override.ts","../src/components/tile-layer.ts","../src/components/tilemap.ts"],"names":["defineComponent"],"mappings":";;;AAgKO,IAAM,eAAA,GAAkB,gBAAgB,iBAAA,EAAmB;AAAA,EAChE,UAAA,EAAY,EAAE,IAAA,EAAM,KAAA,EAAM;AAAA,EAC1B,aAAA,EAAe,EAAE,IAAA,EAAM,KAAA,EAAM;AAAA,EAC7B,YAAA,EAAc,EAAE,IAAA,EAAM,KAAA,EAAO,WAAW,IAAA,EAAK;AAAA,EAC7C,OAAA,EAAS,EAAE,IAAA,EAAM,KAAA,EAAO,WAAW,IAAA,EAAK;AAAA,EACxC,OAAA,EAAS,EAAE,IAAA,EAAM,YAAA,EAAa;AAAA,EAC9B,YAAA,EAAc,EAAE,IAAA,EAAM,KAAA;AACxB,CAAC;ACdM,IAAM,eAAA,GAAkBA,gBAAgB,iBAAA,EAAmB;AAAA,EAChE,UAAA,EAAY,EAAE,IAAA,EAAM,YAAA,EAAa;AAAA,EACjC,OAAA,EAAS,EAAE,IAAA,EAAM,YAAA;AACnB,CAAC;ACtDM,IAAM,oBAAA,GAAuBA,gBAAgB,sBAAA,EAAwB;AAAA,EAC1E,MAAA,EAAQ,EAAE,IAAA,EAAM,eAAA;AAClB,CAAC;AC7CM,IAAM,WAAA,GAAc,OAAO,MAAA,CAAO;AAAA,EACvC,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS;AACX,CAAC;AAuBM,SAAS,gBAAgB,GAAA,EAAoC;AAClE,EAAA,OAAO,GAAA,KAAQ,IAAI,UAAA,GAAa,OAAA;AAClC;AAwDO,IAAM,SAAA,GAAYA,gBAAgB,WAAA,EAAa;AAAA,EACpD,KAAA,EAAO,EAAE,IAAA,EAAM,YAAA,EAAa;AAAA,EAC5B,UAAA,EAAY,EAAE,IAAA,EAAM,KAAA,EAAO,SAAS,CAAA,EAAE;AAAA,EACtC,KAAA,EAAO,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,CAAA,EAAE;AAAA,EAChC,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,CAAA;AACpC,CAAC;AC7GM,IAAM,OAAA,GAAUA,gBAAgB,SAAA,EAAW;AAAA,EAChD,IAAA,EAAM,EAAE,IAAA,EAAM,KAAA,EAAO,SAAS,CAAA,EAAE;AAAA,EAChC,IAAA,EAAM,EAAE,IAAA,EAAM,KAAA,EAAO,SAAS,CAAA,EAAE;AAAA;AAAA;AAAA,EAGhC,QAAA,EAAU,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,IAAI,YAAA,CAAa,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,EAAE;AAAA,EACrE,SAAA,EAAW,EAAE,IAAA,EAAM,KAAA,EAAO,SAAS,EAAA,EAAG;AAAA,EACtC,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA;AACnB,CAAC","file":"chunk-JDWARUOI.mjs","sourcesContent":["// @forgeax/engine-runtime - SpriteAnimation (per-entity frame-tick clock).\n//\n// 6-field schema (1:1 with requirements section 2.3 table; D-5 + D-6\n// vocab keywords locked):\n//\n// frameCount : 'u32' total frames in the cycle (>= 1).\n// frameDuration : 'f32' per-frame seconds (> 0).\n// currentFrame : 'u32' live frame index, in [0, frameCount).\n// accumDt : 'f32' dt accumulator (research F-3 carries\n// fractional residue across ticks).\n// regions : 'array<f32>' flat per-frame UV rectangles\n// [uMin, vMin, uW, vH]; the M4 tick\n// system enforces\n// `regions.length === frameCount * 4`\n// on first observation (AC-09 fail-fast,\n// D-1 path).\n// playbackMode : 'u32' numeric encoding of `SpritePlaybackMode`\n// (0 = SPRITE_PLAYBACK_MODE_LOOP,\n// 1 = SPRITE_PLAYBACK_MODE_CLAMP).\n//\n// Why u32 for playbackMode? research F-2 + F-5: the ECS schema whitelist\n// rejects string-literal unions. The M1 SSOT\n// `packages/runtime/src/components/sprite-playback-mode.ts` carries the\n// numeric constants + the `spritePlaybackModeFromU32` mapper that turns\n// the column value back into a string-literal union at the M4 tick-system\n// seam — same shape as the M1 Tonemap encoding (`tonemap: 'f32'` +\n// TONEMAP_NONE / TONEMAP_REINHARD_EXTENDED + tonemapFromF32). One mental\n// model across all closed-union schema columns; charter P4 consistent\n// abstraction.\n//\n// Why array<f32> (variable) and not array<f32, N> (fixed) for regions?\n// The length `frameCount * 4` is data-dependent: `frameCount` is itself a\n// per-entity column read at runtime, not a schema-time literal. Same\n// shape as M1 `Instances.transforms: 'array<f32>'` whose length depends\n// on the live instance count; D-6 codifies the precedent.\n//\n// dt accumulator clock model (requirements section 2.5 q6 + plan-strategy\n// section 2 D-5):\n// accumDt += Time.delta\n// while (accumDt >= frameDuration) { advance currentFrame; accumDt -= frameDuration }\n// The carry-over `accumDt` survives across ticks so frame timing stays\n// stable under jittery dt; M4 T-23 implements the loop. Per-frame UV\n// is materialised by writing the slice\n// `regions[currentFrame*4 .. currentFrame*4 + 4]` into the entity's\n// `SpriteRegionOverride.region` column (T-11 + M4 T-23).\n//\n// Sprite-only consumption (requirements section 5 constraint #2): the\n// M4 tick system + the M3 extract branch read this component only when\n// the entity routes through the sprite bucket. Opaque buckets ignore\n// the component even when present. Naming keeps the `Sprite` prefix per\n// OOS-01 (no premature 3D generalisation); 3D UV animation lands in a\n// separate component in a future feat.\n//\n// 4-step recipe (charter F1 progressive disclosure — minimum walk-cycle\n// host code; full demo lands in M6 hello-sprite-atlas):\n// 1. Build atlas via `forgeax-engine-remote-asset atlas --input <glob> --name <prefix> --output <dir>`\n// (M5 build-time hook); load the emitted `<name>.atlas.png` plus\n// `<name>.atlas.meta.json` sidecar.\n// 2. Register the sprite material referencing the atlas\n// `TextureAsset` with the initial frame's `region` rectangle (the\n// runtime tick system overrides this region per entity per frame).\n// 3. `world.spawn` an entity with `MeshFilter(HANDLE_QUAD)` +\n// `MeshRenderer(spriteMaterial)` + `Instances(...)` plus this\n// `SpriteAnimation` (frameCount / frameDuration / regions /\n// playbackMode) and `SpriteRegionOverride { region }` (the tick\n// system writes per-frame UV).\n// 4. Add `spriteAnimationTickSystem` (M4 T-23) to the schedule between\n// input/time and `RenderSystem.extract`.\n//\n// @derives `defineComponent` factory (packages/ecs/src/component.ts) —\n// `'u32'` / `'f32'` are scalar tier-1 keywords; `'array<f32>'` is a\n// tier-2 schema-vocab keyword (variable-capacity; M1 feat-20260515\n// buffer-array vocab). Layer-3 default fallback fills missing\n// `currentFrame` / `accumDt` / `playbackMode` with 0\n// (component-default-fallback typeDefault table).\n// @consumes M4 T-23 (`spriteAnimationTickSystem` reads all 6 fields and\n// writes per-frame slice into SpriteRegionOverride).\n//\n// charter mapping: F1 (single-import barrel discovery + 4-step recipe\n// at the JSDoc head); P3 (4 explicit error fields surface via the M4\n// tick-system fail-fast — `regions.length` mismatch / `frameDuration`\n// non-positive routes through SpriteAnimationInvalidError, M1 T-05);\n// P4 (consistent abstraction — same numeric closed-union encoding as\n// Tonemap / TransparentSortConfig.mode); P5 (producer / consumer\n// separation — atlas regions are produced build-time by\n// vite-plugin-image and consumed runtime as a flat Float32Array; AI\n// users never call a packer at runtime).\n//\n// Anchors: plan-strategy section 2 D-5 + D-6 + section 3.1 SAC + section\n// 4 risks R-SCHEMA-1 + R-SCHEMA-2 + R-TIME-1 reaction; plan-tasks.json\n// T-12; research F-2 + F-3 + F-5; requirements section AC-02 + section\n// 2.3 + section 2.5 + section 7 boundary table.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity sprite frame-tick clock.\n *\n * Schema (6 fields, 1:1 with requirements section 2.3):\n * - `frameCount: u32` — total frames (>= 1).\n * - `frameDuration: f32` — seconds per frame (> 0).\n * - `currentFrame: u32` — live frame index (0..frameCount). Layer-3\n * default `0` when omitted at spawn.\n * - `accumDt: f32` — dt residue carried across ticks. Layer-3 default\n * `0` when omitted; lives on the component (not on a system-side\n * resource) so the system stays stateless and AI-user setFrame paths\n * can reset both `currentFrame` and `accumDt` atomically.\n * - `regions: array<f32>` — flat per-frame UV rectangles\n * `[uMin, vMin, uW, vH]`; runtime invariant\n * `regions.length === frameCount * 4` (enforced by the M4 tick system).\n * - `playbackMode: u32` — numeric encoding of `SpritePlaybackMode`;\n * `SPRITE_PLAYBACK_MODE_LOOP = 0` (default) /\n * `SPRITE_PLAYBACK_MODE_CLAMP = 1`.\n *\n * Pair with `SpriteRegionOverride` (T-11) — the tick system writes the\n * per-frame UV slice into the override column, which `render-system-\n * extract` then reads in the sprite bucket branch.\n *\n * @example Spawn a 4-frame walk cycle that loops:\n * import { MeshFilter, MeshRenderer } from '@forgeax/engine-render';\n * import {\n * SpriteAnimation, SpriteRegionOverride, SPRITE_PLAYBACK_MODE_LOOP,\n * } from '@forgeax/engine-render/authoring';\n * import { Transform } from '@forgeax/engine-scene';\n * import { HANDLE_QUAD } from '@forgeax/engine-assets-runtime';\n *\n * // 4 frames packed in an atlas, each 64x64 inside a 256x64 row:\n * const regions = new Float32Array([\n * 0.00, 0, 0.25, 1, // walk-0\n * 0.25, 0, 0.25, 1, // walk-1\n * 0.50, 0, 0.25, 1, // walk-2\n * 0.75, 0, 0.25, 1, // walk-3\n * ]);\n * world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: MeshFilter, data: { assetHandle: HANDLE_QUAD } },\n * { component: MeshRenderer, data: { materials: [spriteMaterial] } },\n * { component: SpriteAnimation,\n * data: {\n * frameCount: 4,\n * frameDuration: 0.1,\n * regions,\n * playbackMode: SPRITE_PLAYBACK_MODE_LOOP,\n * } },\n * { component: SpriteRegionOverride,\n * data: { region: new Float32Array([0, 0, 0.25, 1]) } },\n * );\n *\n * @example Manual setFrame — jump to frame 2 atomically:\n * world.set(entity, SpriteAnimation,\n * { currentFrame: 2, accumDt: 0 }).unwrap();\n *\n * Error path (M4 T-23 routes through `SpriteAnimationInvalidError`,\n * `EcsErrorCode === 'sprite-animation-invalid'`; charter P3):\n * - `regions.length !== frameCount * 4` -> detail.field = 'regions-length',\n * detail carries `regionsLength` + `frameCount`.\n * - `frameDuration <= 0` -> detail.field = 'frame-duration', detail carries\n * `frameDuration`.\n */\nexport const SpriteAnimation = defineComponent('SpriteAnimation', {\n frameCount: { type: 'u32' },\n frameDuration: { type: 'f32' },\n currentFrame: { type: 'u32', transient: true },\n accumDt: { type: 'f32', transient: true },\n regions: { type: 'array<f32>' },\n playbackMode: { type: 'u32' },\n});\n","// @forgeax/engine-runtime - SpriteInstances component (per-entity 2D\n// instanced-draw transforms + per-instance UV region).\n//\n// Schema: 2 array<f32> fields. `transforms` carries packed column-major mat4\n// instance transforms (16 f32 per instance, stride = 16). `regions` carries\n// packed per-instance UV vec4 (4 f32 per instance, stride = 4; layout\n// [uMin, vMin, uW, vH] mirroring SpriteAnimation.regions). The pair share\n// the same instance count; the SSOT invariant is\n// transforms.length / 16 === regions.length / 4\n// enforced through a TWO-LAYER contract:\n//\n// 1. AI user set-site: spawn / `world.set` / `world.push` callers pass two\n// Float32Arrays whose lengths satisfy the stride pair. The set site is\n// the AI user's responsibility — the engine cannot prove column-major\n// mat4 packing or per-instance UV intent without caller declaration.\n// 2. RenderSystem extract entry: `render-system-extract.ts` performs a\n// defensive `transforms.length / 16 === regions.length / 4` check on\n// every `world.get(e, SpriteInstances)` snapshot at frame extract time;\n// violations route a structured `SpriteInstancesCountMismatchError`\n// (`code: 'sprite-instances-count-mismatch'`,\n// `detail: { transformsLength, regionsLength, expectedStride: { transforms: 16, regions: 4 } }`)\n// through the World Layer-3 ErrorHandler and the renderable is skipped.\n// Two further extract-entry checks fire:\n// - `'sprite-instances-requires-sprite-shader'` — MaterialAsset's\n// first pass `shader` must be `'forgeax::sprite'`.\n// - `'sprite-instances-mutually-exclusive-with-instances'` — same\n// entity must not carry both Instances + SpriteInstances.\n// (Error class declarations live in `@forgeax/engine-ecs` errors.ts; the\n// extract-entry fire path is owned by feat M3 w12 / w13.)\n//\n// Peer relation to Instances (charter P4 consistent abstraction):\n// - Instances : 3D scene primitive — per-instance mat4 only (stride 16).\n// - SpriteInstances : 2D scene primitive — per-instance mat4 + per-instance\n// UV region (interleaved 80B per instance: 64B mat4 + 16B region).\n// AI users pick by data shape (does the per-instance carry UV?). Both ride\n// the array-vocab path and route through the same Layer-3 error envelope.\n//\n// Group transform chained semantics (charter proposition 5 mental migration):\n// When the same entity carries both `Transform` (entity_world) and\n// `SpriteInstances` (per-instance local transforms), the vertex shader\n// composes per instance:\n// world_position[i] = entity_world * instances_local[i] * vertex_position\n// `SpriteInstances.transforms[i*16..i*16+15]` is interpreted as a local-\n// space transform under the entity, exactly like `Instances.transforms`.\n// Set the entity's `Transform` to identity to make `instances_local[i]`\n// directly world-space.\n//\n// Uniform / storage buffer cap (research D-R-4 + AC-04): 80B per instance\n// * 128-cap fallback = 10240 B < 16384 B uniform max; the storage-buffer\n// path is uncapped and used by capable backends (RenderSystem record-stage\n// cap-gate).\n//\n// 4-segment minimum contract (read this header before reaching for the\n// source body):\n//\n// ===== (a) single-component import + spawn example =====\n//\n// import {\n// createRenderer,\n// MeshFilter, MeshRenderer, Transform,\n// SpriteInstances, type SpriteInstancesData,\n// } from '@forgeax/engine-render';\n//\n// // 1 entity rendering N instanced sprites (16N transforms f32 + 4N regions f32):\n// const transforms = new Float32Array(N * 16);\n// const regions = new Float32Array(N * 4);\n// // ... fill column-major mat4 columns + [uMin, vMin, uW, vH] per instance ...\n// world.spawn(\n// { component: MeshFilter, data: { assetHandle: HANDLE_QUAD } },\n// { component: MeshRenderer, data: { /* sprite-shaded MaterialAsset */ } },\n// { component: SpriteInstances, data: { transforms, regions } },\n// );\n//\n// ===== (b) packed mat4 + region layout =====\n//\n// const transforms = new Float32Array(N * 16); // column-major mat4 per instance\n// const regions = new Float32Array(N * 4); // [uMin, vMin, uW, vH] per instance\n// // instance i occupies floats:\n// // transforms[i*16 .. i*16+15] — column-major mat4 (translation in m03/m13/m23)\n// // regions [i* 4 .. i* 4+ 3] — uMin, vMin, uW, vH (atlas-normalized UV rect)\n//\n// `transforms.length` MUST be a non-zero multiple of 16; `regions.length`\n// MUST be a non-zero multiple of 4; the per-instance count derived from\n// both MUST agree. AI users gate at the set / push site; the RenderSystem\n// extract entry holds the second defensive (see error path 1 below).\n//\n// ===== (c) error code consumption (typed property access, no message regex) =====\n//\n// // Stride / mutual-exclusion / sprite-shader violations surface through\n// // the engine-ecs Layer-3 ErrorHandler when extract reads a malformed\n// // snapshot:\n// // on('error', (err) => {\n// // switch (err.code) {\n// // case 'sprite-instances-count-mismatch':\n// // // err.detail.transformsLength / regionsLength / expectedStride\n// // break;\n// // case 'sprite-instances-requires-sprite-shader':\n// // // err.detail.entityId / observedMaterialShaderId\n// // break;\n// // case 'sprite-instances-mutually-exclusive-with-instances':\n// // // err.detail.entityId\n// // break;\n// // }\n// // });\n//\n// charter mapping (charter v2 numbering, with round-1 v1 aliases retained\n// in parentheses so reviewers tracking the v1 spec can cross-reference;\n// SSOT for the v2 -> v1 alias map is the AI User Charter — see\n// .claude/skills/forgeax-closed-loop/agents/ai-user-charter.md):\n// F1 (alias: proposition 1) — single import surface\n// `import { SpriteInstances, type SpriteInstancesData } from\n// '@forgeax/engine-render'`;\n// P2 (alias: proposition 3) — machine-readable schema > prose:\n// `{ transforms: 'array<f32>', regions: 'array<f32>' }` is the SSOT,\n// stride pair documented here + enforced at the RenderSystem entry;\n// P3 (alias: proposition 4) — explicit failure: 3 structured EcsError\n// codes route per failure shape, not silent half-row;\n// P4 (alias: proposition 5) — consistent abstraction: SpriteInstances\n// mirrors Instances — both ride the array-vocab path; pick by data\n// shape, not by API.\n//\n// Anchors: requirements AC-01 (component schema), AC-03 (3 error codes),\n// AC-09 (IDE autocomplete + type inference); plan-strategy D-1 (interleaved\n// single binding slot), D-6 (3 codes declared in M1 ecs, fired in M3 render),\n// D-7 (type export location), D-8 (barrel re-export at runtime, not ecs).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity 2D instanced-draw primitive (ECS component).\n *\n * Carries two variable-length `array<f32>` fields:\n * - `transforms` — column-major mat4 per instance (16 f32, stride 16);\n * - `regions` — UV vec4 per instance ([uMin, vMin, uW, vH], 4 f32,\n * stride 4).\n *\n * The pair share the same instance count; the invariant\n * `transforms.length / 16 === regions.length / 4` is enforced at the\n * RenderSystem extract entry (NOT at ECS write paths). The runtime\n * RenderSystem consumer materialises a fresh `Float32Array` snapshot on\n * every `world.get(e, SpriteInstances)` access and uploads an interleaved\n * 80B-per-instance buffer to the GPU in the record stage.\n *\n * @example Spawn an entity rendering 10000 instanced sprites:\n * const transforms = new Float32Array(10000 * 16);\n * const regions = new Float32Array(10000 * 4);\n * // ... fill mat4 columns + [uMin, vMin, uW, vH] ...\n * world.spawn(\n * { component: MeshFilter, data: { assetHandle: HANDLE_QUAD } },\n * { component: MeshRenderer, data: { ... } },\n * { component: SpriteInstances, data: { transforms, regions } },\n * );\n */\nexport const SpriteInstances = defineComponent('SpriteInstances', {\n transforms: { type: 'array<f32>' },\n regions: { type: 'array<f32>' },\n});\n\n/**\n * Type-level hint for `data` at the `SpriteInstances` spawn site.\n *\n * The runtime ECS column shape for `array<f32>` accepts a `Float32Array`\n * payload at spawn / set time (the bytes are copied into the BufferPool\n * slot). Both fields are typed as `Float32Array` so AI-user IDE\n * autocomplete picks up the typed-array shape and the AC-09 inference\n * surfaces without `as` casts inside `world.get(e, SpriteInstances)` and\n * QueryRow access paths.\n *\n * @example\n * import type { SpriteInstancesData } from '@forgeax/engine-render/authoring';\n * const data: SpriteInstancesData = {\n * transforms: new Float32Array(N * 16),\n * regions: new Float32Array(N * 4),\n * };\n */\nexport type SpriteInstancesData = {\n readonly transforms: Float32Array;\n readonly regions: Float32Array;\n};\n","// @forgeax/engine-runtime - SpriteRegionOverride (per-entity UV region\n// override, sprite-only).\n//\n// Schema: 1 fixed-length array column `region: 'array<f32, 4>'` carrying a\n// packed UV sub-rectangle `[uMin, vMin, uW, vH]`. The fixed `4` length is\n// enforced at compile time by the ECS schema-vocab keyword\n// `'array<T, N>'` (D-6: prefer compile-time enforcement over runtime\n// fail-fast for length-bound contracts).\n//\n// Why an entity-side override component instead of a render parameter on\n// MaterialRenderer? Plan-strategy section 1 / requirements section 5\n// constraint #1 (Pipeline Isolation R1, M1 ssot): `AssetRegistry` stays\n// append-only / read-only and `MaterialRenderer` schema is frozen.\n// Per-entity render-parameter overrides ride the same rail as Layer /\n// SortKey — one ECS column per entity, read at extract time, never\n// flowing back to the asset.\n//\n// Sprite-only consumption (requirements section 5 constraint #2 + section\n// 7 boundary line 1): `render-system-extract` reads this component ONLY\n// inside the sprite bucket branch (`pipelineTag === 'sprite'` plus the\n// asset-side sprite discriminant). Opaque (`unlit` / `standard`) buckets\n// ignore the column even when the entity happens to carry it; the M3\n// T-15 grep gate\n// (`packages/runtime/src/__tests__/sprite-only-isolation-grep-gate.test.ts`)\n// asserts this file contains zero substring matches against the asset\n// discriminant identifier as a structural lock (charter P5 producer /\n// consumer separation: the component owner never names the asset\n// discriminant directly).\n//\n// Naming: bare `SpriteRegionOverride` (no `Component` suffix per\n// AGENTS.md section Component naming \"Single-semantic components drop\n// the Component suffix\"). The `Sprite` prefix is intentional — 3D UV\n// region animation lands in a separate component (e.g. future\n// `MaterialRegionOverride`) per OOS-01 to avoid premature 3D\n// generalisation. Plan-strategy section 8 naming convention pins the\n// prefix to make the AC-11 grep gate trivially decidable.\n//\n// @derives `defineComponent` factory (packages/ecs/src/component.ts) —\n// `'array<f32, 4>'` is on the `SchemaVocabKeyword` whitelist (line ~94\n// `array<${ManagedArrayElementType}, ${number}>`).\n// @consumes M3 T-16 (`render-system-extract.ts` sprite bucket branch\n// reads override into `paramSnapshot.region`, post-M3 feat-20260625\n// ablation -- the pre-ablation per-entity hop through the snapshot\n// POD layer collapsed into the generic paramSchema-driven path).\n// @produces M4 T-23 (`spriteAnimationTickSystem` writes per-frame UV\n// slice into `region`).\n//\n// charter mapping: F1 (single-import barrel discovery — joins Layer /\n// SortKey / Transform / SpriteAnimation under a single\n// `from '@forgeax/engine-render'`); P3 (compile-time length=4 lock\n// surfaces mismatched payloads at the TS edge before the column write\n// path observes them); P4 (consistent abstraction — same per-entity\n// override shape AI users already learned for Layer / SortKey).\n//\n// Anchors: plan-strategy section 2 D-6 + section 3.1 SRO + section 4\n// risk R-SCHEMA-2 reaction; plan-tasks.json T-11; research F-5;\n// requirements section AC-01 + section 2.4 + section 5 constraint #2.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity sprite UV region override (sprite-only).\n *\n * Carries a fixed-length `Float32Array(4)` of `[uMin, vMin, uW, vH]` that\n * `render-system-extract` reads in the sprite bucket branch and writes\n * into `paramSnapshot.region`, replacing the asset-side region for\n * this entity only (feat-20260625 M3 ablation: the prior per-entity POD\n * indirection collapsed into the generic paramSchema-driven snapshot).\n * Opaque buckets ignore this component; the AC-11 grep gate keeps the\n * producer / consumer separation structural (this file never names the\n * asset-side sprite discriminant identifier).\n *\n * Pair with `SpriteAnimation` to drive the override per frame\n * (sprite-animation-tick system, M4 T-23). Standalone use (manual region\n * override without animation) is also supported — set the column once and\n * the next extract picks up the new value.\n *\n * Schema-vocab keyword `'array<f32, 4>'` (D-6) — fixed-length 4 is the\n * compile-time enforcement axis. `Float32Array` payloads with length !== 4\n * round-trip fewer / more bytes per the underlying BufferPool slot, but\n * the slot is sized at schema registration time; AI users keep the\n * payload exactly four-floats wide.\n *\n * @example Spawn a sprite entity that displays the right half of an atlas:\n * import { MeshFilter, MeshRenderer } from '@forgeax/engine-render';\n * import { SpriteRegionOverride } from '@forgeax/engine-render/authoring';\n * import { Transform } from '@forgeax/engine-scene';\n * import { HANDLE_QUAD } from '@forgeax/engine-assets-runtime';\n *\n * world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: MeshFilter, data: { assetHandle: HANDLE_QUAD } },\n * { component: MeshRenderer, data: { materials: [spriteMaterial] } },\n * { component: SpriteRegionOverride,\n * data: { region: new Float32Array([0.5, 0, 0.5, 1]) } },\n * );\n *\n * @example Update the override at runtime (e.g. flip-frame test):\n * world.set(entity, SpriteRegionOverride,\n * { region: new Float32Array([0, 0, 1, 1]) }).unwrap();\n */\nexport const SpriteRegionOverride = defineComponent('SpriteRegionOverride', {\n region: { type: 'array<f32, 4>' },\n});\n","// @forgeax/engine-runtime - TileLayer (one render layer of a Tilemap).\n//\n// Schema (4 fields):\n// tiles array<u32> per-cell tile id (packed Tiled .tmj wire form);\n// length == parent.Tilemap.cols * rows.\n// layerOrder i32 render-order key (higher = drawn on top).\n// dirty u8 0 means clean, non-zero means dirty - the next\n// tilemap-chunk-extract-system pass rebuilds derived\n// per-cell entities for this layer.\n// sortScope u8 (TS: 0 = 'layer' (default) - terrain semantics:\n// closed every derived entity in this\n// 'layer' | layer shares one Layer.value\n// 'per-cell' (layerOrder << 20), so the\n// union) whole layer Y-sorts as a single\n// bucket. AI users grep\n// `sortScope: 'layer'` to confirm.\n// 1 = 'per-cell' - object semantics: each derived\n// entity carries its own foot-Y\n// key; preserves per-cell entity\n// derivation for Y-interleave\n// with sprite entities sharing\n// the same Layer.value.\n//\n// Storage rationale (D-V-3 R-NEW-1 fallback / round-2): ECS schema does not\n// yet support `values: ['layer', 'per-cell']` literal-union constraints\n// on a `'string'` column, so the on-disk shape is `u8` (0/1) but every\n// AI-facing TS surface (`TileLayerData.sortScope`) is the closed\n// `'layer' | 'per-cell'` string union. The bridge functions\n// `encodeSortScope` / `decodeSortScope` are the SSOT for the two-way\n// mapping (charter F1 — single grep target).\n//\n// Each TileLayer entity attaches to a Tilemap entity via ChildOf (the parent\n// field carries the Tilemap entity). M0 supports multiple TileLayer entities\n// per Tilemap (each rendered as an independent z-ordered layer).\n//\n// charter mapping: F1 (single-import barrel + single grep target for\n// `sortScope`), P1 (progressive disclosure — `'layer'` / `'per-cell'`\n// reads directly without a magic-number table), P3 (dirty flag is\n// explicit - silent re-extraction is forbidden), P4 (handle-free row\n// schema mirrors MeshFilter / MeshRenderer conventions).\n\nimport { defineComponent, type EcsError, type EntityHandle, type World } from '@forgeax/engine-ecs';\nimport type { Result } from '@forgeax/engine-types';\n\n/**\n * Closed string-literal union for the TileLayer.sortScope field. AI users\n * grep `sortScope` and land on this single SSOT type alias; switch\n * statements over this type are exhaustive without a default arm.\n *\n * - 'layer' - terrain semantics; whole layer shares one Layer.value\n * bucket and Y-sorts together (chunkIndex is folded into 0).\n * - 'per-cell' - object semantics; each derived entity gets its own\n * chunkIndex tiebreak so it can Y-interleave with\n * sprite entities carrying the same Layer.value (e.g. a\n * player sprite riding the same SPRITE_LAYER_VALUE).\n */\nexport type SortScope = 'layer' | 'per-cell';\n\n/** Compact authoring values for the stored u8 sort-scope field. */\nexport const TilemapSort = Object.freeze({\n layer: 0 as const,\n perCell: 1 as const,\n});\n\n/**\n * Bridge: `SortScope` -> on-disk u8. SSOT for the encoding (`'layer'` -> 0,\n * `'per-cell'` -> 1). The compile-time exhaustive switch guards against\n * silent drift if the union ever grows; adding a new literal here without\n * adding its arm fails typecheck (charter P3 — closed unions never default).\n */\nexport function encodeSortScope(scope: SortScope): 0 | 1 {\n switch (scope) {\n case 'layer':\n return TilemapSort.layer;\n case 'per-cell':\n return TilemapSort.perCell;\n }\n}\n\n/**\n * Bridge: on-disk u8 -> `SortScope`. Defaults to `'layer'` for any value\n * outside `{0, 1}` (defensive — the column is typed `u8` so out-of-range\n * values can only appear if a future schema migration loosens the bound;\n * the default preserves terrain semantics which is the safer of the two).\n */\nexport function decodeSortScope(raw: number | undefined): SortScope {\n return raw === 1 ? 'per-cell' : 'layer';\n}\n\n/**\n * Public TileLayer field shape (`world.spawn({ component: TileLayer, data:\n * { ... } })` payload). `sortScope` is the closed string union surfaced to\n * AI users; the runtime row encodes it as `u8` via `encodeSortScope` at\n * spawn time so on-disk storage stays compact.\n *\n * Treat as the `TileLayer` data SSOT — `defineComponent` schema below\n * mirrors it field-for-field with the bridge `sortScope: u8` in place of\n * the union literal.\n */\nexport interface TileLayerData {\n readonly tiles: Uint32Array;\n readonly layerOrder?: number;\n readonly dirty?: number;\n readonly sortScope?: SortScope;\n}\n\n/**\n * TileLayer component (M0 baseline rebuild + round-2 sortScope rename).\n *\n * AI users typically spawn a TileLayer + ChildOf pair pointing at an\n * existing Tilemap entity:\n *\n * @example\n * const tilesArray = new Uint32Array(cols * rows);\n * tilesArray[5 * cols + 7] = 1; // tile id 1 at cell (7, 5)\n * world.spawn(\n * { component: TileLayer, data: { tiles: tilesArray, layerOrder: 0 } },\n * { component: ChildOf, data: { parent: tilemapEntity } },\n * );\n *\n * Object-layer variant (Y-interleave with sprite entities):\n *\n * > NOTE: schema storage is `u8` (ECS schema does not support\n * > string-literal-union column constraints; see R-NEW-2). The\n * > AI-user surface is the closed `SortScope` string union, but\n * > `world.spawn` requires the numeric encoding — pass through\n * > `encodeSortScope('per-cell')` rather than the literal string.\n *\n * @example\n * world.spawn(\n * { component: TileLayer, data: {\n * tiles: objectTiles,\n * layerOrder: 1000,\n * sortScope: encodeSortScope('per-cell'),\n * } },\n * { component: ChildOf, data: { parent: tilemapEntity } },\n * );\n *\n * Defaults: `layerOrder = 0`, `dirty = 0`, `sortScope = 'layer'` (stored\n * as `u8 = 0`, i.e. `encodeSortScope('layer')`). `tiles` has no default -\n * AI users supply the per-cell array at spawn time. To trigger a re-build\n * after mutating tiles in place, call `markTileLayerDirty(world, layer)`.\n */\nexport const TileLayer = defineComponent('TileLayer', {\n tiles: { type: 'array<u32>' },\n layerOrder: { type: 'i32', default: 0 },\n dirty: { type: 'u8', default: 0 },\n sortScope: { type: 'u8', default: 0 },\n});\n\n/**\n * Mark a TileLayer entity dirty so the next `tilemapChunkExtractSystem`\n * pass purges and re-spawns its derived per-cell entities. Use this after\n * mutating `TileLayer.tiles` (e.g. an in-place patch via a column view).\n *\n * Returns the underlying ECS write result - on `err` branch the caller\n * can read `.code` to recover (`'stale-entity'` if the layer was\n * despawned, `'component-not-present'` if the entity is missing the\n * TileLayer column; both kebab-case literals are members of the closed\n * `EcsErrorCode` union).\n */\nexport function markTileLayerDirty(\n world: World,\n layerEntity: EntityHandle,\n): Result<void, EcsError> {\n return world.set(layerEntity, TileLayer, { dirty: 1 });\n}\n","// @forgeax/engine-runtime - Tilemap (grid + tileset reference).\n//\n// Schema (5 fields):\n// cols u32 total grid columns\n// rows u32 total grid rows\n// tileSize array<f32, 2> per-cell world [width, height] (default [1, 1];\n// feat-20260709 M3: collapsed from the tileSizeX\n// / tileSizeY scalar pair into one inline column)\n// chunkSize u32 per-chunk axis-length in cells (default 16)\n// tileset string durable TilesetAsset GUID\n//\n// Naming: single-semantic Tilemap (AGENTS.md §Component naming drops\n// `Component` suffix). One Tilemap entity per grid; TileLayer entities\n// attach via ChildOf relationship and supply the per-cell tile id array\n// for a single render-layer.\n//\n// charter mapping: F1 (single-import barrel from `@forgeax/engine-runtime`),\n// P1 (progressive disclosure - defaults cover the common case), P4 (durable\n// asset identity stays separate from World-local handles).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Tilemap component (M0 baseline rebuild).\n *\n * A Tilemap entity carries grid metadata + a single durable `tileset` GUID. The\n * actual per-cell tile id array lives on attached `TileLayer` entities\n * (one per render layer; ChildOf points back to the Tilemap entity).\n *\n * Defaults:\n * - `tileSize = [1, 1]` (unit-cell world coordinates).\n * - `chunkSize = 16` (tilemap-chunk-extract-system chunks 16x16 cells).\n *\n * @example Spawn a 32x32 unit-cell Tilemap referencing a TilesetAsset:\n * const tilemap = world.spawn(\n * { component: Tilemap, data: { cols: 32, rows: 32, tileset } },\n * { component: Transform, data: {} },\n * ).unwrap();\n */\nexport const Tilemap = defineComponent('Tilemap', {\n cols: { type: 'u32', default: 0 },\n rows: { type: 'u32', default: 0 },\n // tileSize carries an explicit layer-2 default [1,1] (unit cell); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n tileSize: { type: 'array<f32, 2>', default: new Float32Array([1, 1]) },\n chunkSize: { type: 'u32', default: 16 },\n tileset: { type: 'string' },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/points-lines/admission.ts","../src/point-shadow-inspection.ts","../src/volume/inspection.ts","../src/capture/cube-views.ts","../src/reflection/filter.ts","../src/reflection/gpu-table.ts","../src/reflection/inspection.ts","../src/reflection/projection.ts","../src/scene/visibility/inspection.ts","../src/ssr/admission.ts"],"names":["pass","primitiveKey","failure"],"mappings":"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","file":"chunk-KM2NOX2I.mjs","sourcesContent":["import { err, type MaterialAsset, type MeshAsset, ok, type Result } from '@forgeax/engine-types';\nimport { type PointShape, PointShapeValue, pointShapeFromU32 } from '../components/points';\nimport type {\n PointsLinesBudgetExceededError,\n PointsLinesInvalidStyleError,\n PointsLinesMaterialUnsupportedError,\n PointsLinesStyleUnsupportedError,\n PointsLinesTopologyMismatchError,\n} from '../errors/render';\nimport {\n PointsLinesBudgetExceededError as BudgetError,\n PointsLinesInvalidStyleError as InvalidStyleError,\n PointsLinesMaterialUnsupportedError as MaterialError,\n PointsLinesStyleUnsupportedError as StyleError,\n PointsLinesTopologyMismatchError as TopologyError,\n} from '../errors/render';\n\nexport interface PointsStyleInput {\n readonly sizePx?: number;\n readonly shape?: number;\n}\n\nexport interface LinesStyleInput {\n readonly widthPx?: number;\n}\n\nexport interface PointsLinesAdmissionLimits {\n readonly maxPoints?: number;\n readonly maxSegments?: number;\n}\n\nexport interface PointsLinesAdmissionInput {\n readonly entity: number;\n readonly points?: PointsStyleInput;\n readonly lines?: LinesStyleInput;\n readonly mesh: MeshAsset;\n readonly material: MaterialAsset;\n readonly limits?: PointsLinesAdmissionLimits;\n readonly materialId?: string;\n}\n\nexport interface PointsLinesAdmission {\n readonly component: 'Points' | 'Lines';\n readonly shape?: PointShape;\n readonly sizePx?: number;\n readonly widthPx?: number;\n readonly pointCount: number;\n readonly segmentCount: number;\n readonly submeshes: readonly number[];\n}\n\nexport type PointsLinesAdmissionError =\n | PointsLinesInvalidStyleError\n | PointsLinesTopologyMismatchError\n | PointsLinesStyleUnsupportedError\n | PointsLinesMaterialUnsupportedError\n | PointsLinesBudgetExceededError;\n\nfunction invalidStyle(\n input: PointsLinesAdmissionInput,\n component: 'Points' | 'Lines' | 'Points/Lines',\n field: string,\n value: number | string | undefined,\n expected: string,\n): Result<never, PointsLinesAdmissionError> {\n return err(new InvalidStyleError({ entity: input.entity, component, field, value, expected }));\n}\n\nfunction topologyMismatch(\n input: PointsLinesAdmissionInput,\n submesh: number,\n expected: string,\n actual: string,\n): Result<never, PointsLinesAdmissionError> {\n return err(new TopologyError({ entity: input.entity, submesh, expected, actual }));\n}\n\nfunction checkStyle(\n input: PointsLinesAdmissionInput,\n): Result<\n { component: 'Points' | 'Lines'; shape?: PointShape; sizePx?: number; widthPx?: number },\n PointsLinesAdmissionError\n> {\n const hasPoints = input.points !== undefined;\n const hasLines = input.lines !== undefined;\n if (hasPoints && hasLines) {\n return invalidStyle(\n input,\n 'Points/Lines',\n 'components',\n 'Points + Lines',\n 'exactly one style component',\n );\n }\n if (!hasPoints && !hasLines) {\n return invalidStyle(input, 'Points/Lines', 'components', undefined, 'one style component');\n }\n\n if (hasPoints) {\n const sizePx = input.points?.sizePx ?? 4;\n const shapeValue = input.points?.shape ?? PointShapeValue.square;\n const shape = pointShapeFromU32(shapeValue);\n if (!Number.isFinite(sizePx) || sizePx <= 0) {\n return invalidStyle(input, 'Points', 'sizePx', sizePx, 'finite sizePx > 0');\n }\n if (shape === undefined) {\n return invalidStyle(input, 'Points', 'shape', shapeValue, \"shape is 'square' or 'circle'\");\n }\n return ok({ component: 'Points', shape, sizePx });\n }\n\n const widthPx = input.lines?.widthPx ?? 1;\n if (!Number.isFinite(widthPx) || widthPx <= 0) {\n return invalidStyle(input, 'Lines', 'widthPx', widthPx, 'finite widthPx > 0');\n }\n return ok({ component: 'Lines', widthPx });\n}\n\nfunction checkTopology(\n input: PointsLinesAdmissionInput,\n component: 'Points' | 'Lines',\n): Result<\n { pointCount: number; segmentCount: number; submeshes: readonly number[] },\n PointsLinesAdmissionError\n> {\n const expected = component === 'Points' ? 'point-list' : 'line-list';\n let pointCount = 0;\n let segmentCount = 0;\n const acceptedSubmeshes: number[] = [];\n let sawNonEmpty = false;\n\n for (const [submeshIndex, submesh] of input.mesh.submeshes.entries()) {\n const indexed = input.mesh.indices !== undefined && submesh.indexCount > 0;\n const elementCount = indexed ? submesh.indexCount : submesh.vertexCount;\n if (elementCount === 0) continue;\n sawNonEmpty = true;\n\n if (component === 'Lines' && submesh.topology === 'line-strip') {\n return err(\n new StyleError({\n lane: 'admission',\n field: 'topology',\n member: 'line-strip',\n supported: ['line-list'],\n }),\n );\n }\n if (submesh.topology !== expected) {\n return topologyMismatch(input, submeshIndex, expected, submesh.topology);\n }\n if (component === 'Lines' && elementCount % 2 !== 0) {\n return topologyMismatch(input, submeshIndex, 'line-list pairs', 'line-list odd tail');\n }\n acceptedSubmeshes.push(submeshIndex);\n if (component === 'Points') pointCount += elementCount;\n else segmentCount += elementCount / 2;\n }\n\n if (!sawNonEmpty) return topologyMismatch(input, 0, expected, 'empty-range');\n return ok({ pointCount, segmentCount, submeshes: acceptedSubmeshes });\n}\n\nfunction checkMaterial(input: PointsLinesAdmissionInput): Result<void, PointsLinesAdmissionError> {\n const passes = input.material.passes ?? [];\n const unlitModules = new Set(['forgeax_material::unlit', 'forgeax::default-unlit']);\n if (passes.length !== 1 || passes[0] === undefined) {\n const pass =\n passes.find(\n (candidate) => candidate.name === 'deferred' || candidate.name === 'shadow-caster',\n ) ?? passes[0];\n return err(\n new MaterialError({\n entity: input.entity,\n material: input.materialId ?? '<anonymous>',\n pass: pass?.name ?? '<empty>',\n module: pass?.program.module ?? '<empty>',\n reason: 'points-lines admission requires one unlit forward pass',\n }),\n );\n }\n const pass = passes[0];\n const lightMode = (pass.renderState?.tags as Record<string, unknown> | undefined)?.LightMode;\n if (\n !unlitModules.has(pass.program.module) ||\n pass.name !== 'forward' ||\n lightMode === 'ShadowCaster'\n ) {\n return err(\n new MaterialError({\n entity: input.entity,\n material: input.materialId ?? '<anonymous>',\n pass: pass.name,\n module: pass.program.module,\n reason: 'points-lines admission requires an engine-owned unlit forward pass',\n }),\n );\n }\n return ok(undefined);\n}\n\n/** Validate one complete Points/Lines candidate before any renderer publication. */\nexport function admitPointsLines(\n input: PointsLinesAdmissionInput,\n): Result<PointsLinesAdmission, PointsLinesAdmissionError> {\n const style = checkStyle(input);\n if (!style.ok) return style;\n const topology = checkTopology(input, style.value.component);\n if (!topology.ok) return topology;\n const material = checkMaterial(input);\n if (!material.ok) return material;\n\n if (style.value.component === 'Points' && input.limits?.maxPoints !== undefined) {\n if (topology.value.pointCount > input.limits.maxPoints) {\n return err(\n new BudgetError({\n lane: 'admission',\n requested: topology.value.pointCount,\n limit: input.limits.maxPoints,\n unit: 'points',\n }),\n );\n }\n }\n if (style.value.component === 'Lines' && input.limits?.maxSegments !== undefined) {\n if (topology.value.segmentCount > input.limits.maxSegments) {\n return err(\n new BudgetError({\n lane: 'admission',\n requested: topology.value.segmentCount,\n limit: input.limits.maxSegments,\n unit: 'segments',\n }),\n );\n }\n }\n\n return ok({ ...style.value, ...topology.value });\n}\n","import type { PointShadowSnapshot } from './render-system-extract';\n\n/**\n * Detached point-shadow budget facts from one completed extract/record frame.\n *\n * `requested` is the number of PointLight + PointLightShadow pairs. The\n * renderer owns the bounded cube-array atlas, so `admitted`, `shadowed`, and\n * `shadowAtlasOccupancy` are all derived from the layer sentinel emitted by\n * the same extract owner. No consumer needs to maintain a second budget\n * ledger.\n */\nexport interface PointShadowInspection {\n readonly status: 'inactive' | 'ready' | 'over-budget';\n readonly requested: number;\n readonly admitted: number;\n readonly shadowed: number;\n readonly shadowAtlasOccupancy: number;\n readonly shadowAtlasCapacity: number;\n}\n\n/** Project point-shadow snapshots to the public, JSON-safe inspection shape. */\nexport function inspectPointShadow(\n snapshots: readonly PointShadowSnapshot[],\n shadowAtlasCapacity: number,\n): PointShadowInspection {\n const requested = snapshots.length;\n const admitted = snapshots.reduce(\n (count, snapshot) =>\n snapshot.shadowAtlasLayer >= 0 && snapshot.shadowAtlasLayer < shadowAtlasCapacity\n ? count + 1\n : count,\n 0,\n );\n // Never publish a misleading `ready` state when any requested shadow owns\n // no atlas layer. The extract sentinel is the single admission projection;\n // a partial or all-sentinel frame is therefore a failed/over-budget\n // admission, not an active shadow path with incomplete output.\n const status =\n requested === 0\n ? ('inactive' as const)\n : requested > shadowAtlasCapacity || admitted !== requested\n ? ('over-budget' as const)\n : ('ready' as const);\n return Object.freeze({\n status,\n requested,\n admitted,\n // A point shadow only samples an atlas after it owns an atlas layer. Keep\n // these names explicit for AI diagnostics while deriving both from the\n // one layer projection above.\n shadowed: admitted,\n shadowAtlasOccupancy: admitted,\n shadowAtlasCapacity,\n });\n}\n","import type { TextureFormat } from '@forgeax/engine-rhi';\nimport type { VolumeRecoveryState, VolumeSelectedLightFacts } from './recovery';\nimport type { VolumetricFogResourceFacts } from './resources';\n\nexport type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable' | 'degraded';\n\nexport type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';\n\nexport interface VolumetricFogInspection {\n readonly status: VolumetricFogInspectionStatus;\n readonly resourceStage: VolumetricFogResourceStage;\n readonly guid: string | undefined;\n readonly generation: number | undefined;\n readonly digest: string | undefined;\n readonly candidateGeneration: number | undefined;\n readonly candidateDigest: string | undefined;\n readonly lkgGeneration: number | undefined;\n readonly candidateFailure: VolumeRecoveryState['candidateFailure'];\n readonly deviceEpoch: number;\n readonly format: TextureFormat | undefined;\n readonly passCount: number;\n readonly sampleCount: number;\n readonly memoryBytes: number;\n readonly resourceFacts: VolumetricFogResourceFacts | undefined;\n readonly selectedLight: VolumeSelectedLightFacts | undefined;\n readonly candidateSelectedLight: VolumeSelectedLightFacts | undefined;\n}\n\nexport interface VolumetricFogInspectionInput {\n readonly authored: boolean;\n readonly capability: 'available' | 'unavailable';\n readonly degraded?: boolean;\n readonly recovery?: VolumeRecoveryState;\n readonly acceptedDigest?: string;\n readonly format?: TextureFormat;\n readonly passCount?: number;\n readonly sampleCount?: number;\n readonly memoryBytes?: number;\n readonly resourceFacts?: VolumetricFogResourceFacts;\n}\n\nfunction resourceStage(input: VolumetricFogInspectionInput): VolumetricFogResourceStage {\n if (!input.authored || input.recovery === undefined) return 'none';\n if (input.recovery.status === 'candidate') return 'candidate';\n if (input.recovery.status === 'recovering') return 'recovering';\n if (input.recovery.status === 'degraded') return 'lkg';\n return 'accepted';\n}\n\nexport function inspectVolumetricFog(input: VolumetricFogInspectionInput): VolumetricFogInspection {\n const recovery = input.recovery;\n const status: VolumetricFogInspectionStatus = !input.authored\n ? 'off'\n : input.capability === 'unavailable'\n ? 'unavailable'\n : input.degraded === true || recovery?.status === 'degraded'\n ? 'degraded'\n : 'available';\n return Object.freeze({\n status,\n resourceStage: resourceStage(input),\n guid: recovery?.guid,\n generation: recovery?.generation,\n digest: input.acceptedDigest,\n candidateGeneration: recovery?.candidateGeneration,\n candidateDigest: recovery?.candidateDigest,\n lkgGeneration: recovery?.lkgGeneration,\n candidateFailure: recovery?.candidateFailure,\n deviceEpoch: recovery?.deviceEpoch ?? 0,\n format: input.format,\n passCount: input.passCount ?? 0,\n sampleCount: input.sampleCount ?? 0,\n memoryBytes: input.memoryBytes ?? 0,\n resourceFacts: input.resourceFacts,\n selectedLight: recovery?.selectedLight,\n candidateSelectedLight: recovery?.candidateSelectedLight,\n });\n}\n","import { type Mat4, mat4, type Vec3Like } from '@forgeax/engine-math';\nimport { CUBE_CAMERA_FACE_ORDER, type CubeCameraFace } from '../components/cube-camera';\n\nexport interface CubeCameraFaceView {\n readonly position: Vec3Like;\n readonly face: CubeCameraFace;\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n readonly near: number;\n readonly far: number;\n readonly view: Mat4;\n readonly projection: Mat4;\n readonly viewProjection: Mat4;\n}\n\nexport interface CubeCameraFaceViewInput {\n readonly position: Vec3Like;\n readonly near: number;\n readonly far: number;\n}\n\nconst FACE_ORIENTATION: ReadonlyArray<{\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n}> = [\n { direction: [1, 0, 0], up: [0, 1, 0] },\n { direction: [-1, 0, 0], up: [0, 1, 0] },\n { direction: [0, 1, 0], up: [0, 0, -1] },\n { direction: [0, -1, 0], up: [0, 0, 1] },\n { direction: [0, 0, 1], up: [0, 1, 0] },\n { direction: [0, 0, -1], up: [0, 1, 0] },\n];\n\nfunction assertRange(near: number, far: number): void {\n if (!Number.isFinite(near) || near <= 0 || !Number.isFinite(far) || far <= near) {\n throw new RangeError('CubeCamera requires finite near > 0 and far > near.');\n }\n}\n\n/** Build the only supported +X,-X,+Y,-Y,+Z,-Z cube orientation. */\nexport function buildCubeCameraFaceViews(input: CubeCameraFaceViewInput): CubeCameraFaceView[] {\n assertRange(input.near, input.far);\n const views: CubeCameraFaceView[] = [];\n for (const [index, face] of CUBE_CAMERA_FACE_ORDER.entries()) {\n const orientation = FACE_ORIENTATION[index];\n if (orientation === undefined)\n throw new Error(`CubeCamera face orientation missing at ${index}`);\n const target: Vec3Like = [\n (input.position[0] ?? 0) + orientation.direction[0],\n (input.position[1] ?? 0) + orientation.direction[1],\n (input.position[2] ?? 0) + orientation.direction[2],\n ];\n const view = mat4.lookAt(mat4.create(), input.position, target, orientation.up);\n const projection = mat4.perspective(mat4.create(), Math.PI / 2, 1, input.near, input.far);\n const viewProjection = mat4.multiply(mat4.create(), projection, view);\n views.push({\n position: input.position,\n face,\n direction: orientation.direction,\n up: orientation.up,\n near: input.near,\n far: input.far,\n view,\n projection,\n viewProjection,\n });\n }\n return views;\n}\n","export interface ProbeFilterState {\n readonly probeIndex: number;\n readonly faceCount: number;\n readonly mipCount: number;\n readonly cursor: number;\n readonly activeGeneration: number;\n}\n\nexport function createProbeFilterState(input: {\n readonly probeIndex: number;\n readonly faceCount?: number;\n readonly mipCount: number;\n readonly activeGeneration?: number;\n}): ProbeFilterState {\n return {\n probeIndex: input.probeIndex,\n faceCount: input.faceCount ?? 6,\n mipCount: input.mipCount,\n cursor: 0,\n activeGeneration: input.activeGeneration ?? 0,\n };\n}\n\nexport function advanceProbeFilter(\n state: ProbeFilterState,\n):\n | { readonly probeIndex: number; readonly faceIndex: number; readonly mipLevel: number }\n | undefined {\n const total = state.faceCount * state.mipCount;\n if (state.cursor >= total) return undefined;\n return {\n probeIndex: state.probeIndex,\n faceIndex: state.cursor % state.faceCount,\n mipLevel: Math.floor(state.cursor / state.faceCount),\n };\n}\n\nexport function commitProbeFilterStep(state: ProbeFilterState, success: boolean): ProbeFilterState {\n if (!success) return state;\n const nextCursor = state.cursor + 1;\n const complete = nextCursor >= state.faceCount * state.mipCount;\n return {\n ...state,\n cursor: nextCursor,\n activeGeneration: complete ? state.activeGeneration + 1 : state.activeGeneration,\n };\n}\n\nexport function probeFilterIsSteady(state: ProbeFilterState): boolean {\n return state.cursor >= state.faceCount * state.mipCount;\n}\n\nfunction normalize(vector: readonly [number, number, number]): [number, number, number] {\n const length = Math.hypot(vector[0], vector[1], vector[2]);\n if (length === 0) return [0, 0, 1];\n return [vector[0] / length, vector[1] / length, vector[2] / length];\n}\n\nexport function boxProjectReflectionDirection(\n direction: readonly [number, number, number],\n boxCenter: readonly [number, number, number],\n halfExtents: readonly [number, number, number],\n point: readonly [number, number, number],\n): [number, number, number] {\n const ray = normalize(direction);\n let distance = Number.POSITIVE_INFINITY;\n for (let axis = 0; axis < 3; axis += 1) {\n const component = ray[axis] ?? 0;\n if (component === 0) continue;\n const extent = halfExtents[axis] ?? 0;\n const edge = component > 0 ? (boxCenter[axis] ?? 0) + extent : (boxCenter[axis] ?? 0) - extent;\n const candidate = (edge - (point[axis] ?? 0)) / component;\n if (candidate > 0) distance = Math.min(distance, candidate);\n }\n if (!Number.isFinite(distance)) return ray;\n return normalize([\n (point[0] ?? 0) + ray[0] * distance - (boxCenter[0] ?? 0),\n (point[1] ?? 0) + ray[1] * distance - (boxCenter[1] ?? 0),\n (point[2] ?? 0) + ray[2] * distance - (boxCenter[2] ?? 0),\n ]);\n}\n","import type { Buffer, Sampler, TextureView } from '@forgeax/engine-rhi';\n\nexport interface ReflectionProbeTableRow {\n readonly primitiveKey?: string;\n readonly index: number;\n readonly worldId: number;\n readonly entityKey: number;\n readonly center: readonly [number, number, number];\n readonly halfExtents: readonly [number, number, number];\n readonly intensity: number;\n readonly generation: number;\n /** Renderer-owned filtered cube used by the Standard material lane. */\n readonly filteredView?: TextureView;\n /** Renderer-owned sampler paired with filteredView. */\n readonly sampler?: Sampler;\n /** Per-probe uniform payload; keeps MaterialAsset ABI unchanged. */\n readonly uniformBuffer?: Buffer;\n}\n\nexport interface ReflectionProbeTable {\n readonly rows: readonly ReflectionProbeTableRow[];\n readonly cpuIndexByPrimitive: (primitiveKey: string) => number | undefined;\n readonly gpuIndexByPrimitive: (primitiveKey: string) => number | undefined;\n}\n\nexport function buildReflectionProbeTable(\n rows: readonly ReflectionProbeTableRow[],\n): ReflectionProbeTable {\n const ordered = rows.slice().sort((a, b) => a.index - b.index);\n const indices = new Map<string, number>();\n for (const row of ordered) {\n if (row.primitiveKey !== undefined) indices.set(row.primitiveKey, row.index);\n }\n const indexFor = (primitiveKey: string): number | undefined => indices.get(primitiveKey);\n return {\n rows: Object.freeze(ordered),\n cpuIndexByPrimitive: indexFor,\n gpuIndexByPrimitive: indexFor,\n };\n}\n\nexport function reflectionProbeTableBytes(table: ReflectionProbeTable): number {\n return table.rows.length * 48;\n}\n","import type {\n ReflectionFallbackFailureStage,\n ReflectionFallbackInspection,\n ReflectionFallbackReceipt,\n ReflectionFallbackRecoveryAction,\n} from '../inspection-types';\n\nexport interface ReflectionFallbackFailureInput {\n readonly stage: ReflectionFallbackFailureStage;\n readonly code: string;\n readonly expected: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nfunction recoveryFor(\n receipt: ReflectionFallbackReceipt,\n failure?: ReflectionFallbackFailureInput,\n): ReflectionFallbackRecoveryAction {\n if (failure !== undefined) {\n const code = failure.code.toLowerCase();\n if (code.includes('device') || code.includes('format') || code.includes('capability')) {\n return 'rebuild';\n }\n if (failure.stage === 'prepare' || failure.stage === 'filter') return 'recapture';\n if (failure.stage === 'build' || failure.stage === 'encode') return 'rebuild';\n if (failure.stage === 'finish' || failure.stage === 'submit') return 'retry';\n // Completion failures may still retain a source-identical committed row;\n // use it as LKG, otherwise retry the producer completion.\n if (failure.stage === 'completion') {\n if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {\n return 'use-LKG';\n }\n if (\n receipt.source === 'skylight' &&\n (receipt.state === 'active' || receipt.state === 'lkg')\n ) {\n return 'use-Skylight';\n }\n if (receipt.source === 'neutral' && receipt.state === 'neutral') return 'use-neutral';\n return 'retry';\n }\n }\n if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {\n return 'use-LKG';\n }\n if (receipt.source === 'skylight' || receipt.state === 'lkg') return 'use-Skylight';\n return 'use-neutral';\n}\n\n/** Projects producer state and the latest closed failure into detached facts. */\nexport function inspectReflectionFallback(\n receipt: ReflectionFallbackReceipt,\n failure?: ReflectionFallbackFailureInput,\n): ReflectionFallbackInspection {\n return {\n receipt,\n recoveryAction: recoveryFor(receipt, failure),\n ...(failure === undefined\n ? {}\n : {\n failureStage: failure.stage,\n failureCode: failure.code,\n expected: failure.expected,\n ...(failure.detail === undefined ? {} : { detail: failure.detail }),\n }),\n };\n}\n","import type { ReflectionProbeUpdateIntent } from '../components/reflection-probe';\n\nexport const REFLECTION_PROBE_BYTES_PER_TEXEL = 8;\nexport const DEFAULT_REFLECTION_PROBE_LIMITS = Object.freeze({\n maxProbes: 16,\n maxResolution: 256,\n maxBytes: 64 * 1024 * 1024,\n});\n\nexport interface ReflectionProbeInput {\n readonly halfExtents: readonly [number, number, number];\n readonly priority: number;\n readonly intensity: number;\n readonly resolution: number;\n}\n\nexport interface ReflectionProbeFact extends ReflectionProbeInput {\n readonly worldId: number;\n readonly entityKey: number;\n readonly center: readonly [number, number, number];\n readonly revision: number;\n readonly updateIntent?: ReflectionProbeUpdateIntent;\n readonly invalidationVersion?: number;\n}\n\nexport interface ReflectionProbeAdmissionLimits {\n readonly maxProbes?: number;\n readonly maxResolution?: number;\n readonly maxBytes?: number;\n}\n\nexport interface ReflectionProbeInvalidInput {\n readonly code: 'reflection-probe-input-invalid';\n readonly field: string;\n readonly value: unknown;\n readonly expected: string;\n}\n\nexport interface ReflectionProbeBudgetFailure {\n readonly code: 'reflection-probe-budget-exceeded';\n readonly requested: number;\n readonly activeCount: number;\n readonly activeBytes: number;\n readonly maxProbes: number;\n readonly maxBytes: number;\n}\n\nexport type ReflectionProbeAdmission =\n | { readonly ok: true; readonly acceptedBytes: number }\n | { readonly ok: false; readonly error: ReflectionProbeBudgetFailure };\n\nexport function validateReflectionProbeInput(\n input: ReflectionProbeInput,\n): { readonly ok: true } | { readonly ok: false; readonly error: ReflectionProbeInvalidInput } {\n for (let index = 0; index < input.halfExtents.length; index += 1) {\n const value = input.halfExtents[index];\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: `halfExtents[${index}]`,\n value,\n expected: 'a finite number greater than zero',\n },\n };\n }\n }\n if (!Number.isFinite(input.priority)) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'priority',\n value: input.priority,\n expected: 'a finite number',\n },\n };\n }\n if (!Number.isFinite(input.intensity) || input.intensity < 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'intensity',\n value: input.intensity,\n expected: 'a finite number greater than or equal to zero',\n },\n };\n }\n if (!Number.isInteger(input.resolution) || input.resolution <= 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'resolution',\n value: input.resolution,\n expected: 'a positive integer',\n },\n };\n }\n return { ok: true };\n}\n\nexport function estimateReflectionProbeBytes(\n resolution: number,\n limits: ReflectionProbeAdmissionLimits = DEFAULT_REFLECTION_PROBE_LIMITS,\n): number {\n const maxResolution = limits.maxResolution ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxResolution;\n const clamped = Math.min(resolution, maxResolution);\n let mipTexels = 0;\n for (let size = clamped; size >= 1; size = Math.floor(size / 2)) {\n mipTexels += size * size;\n }\n return mipTexels * 6 * REFLECTION_PROBE_BYTES_PER_TEXEL;\n}\n\nexport function admitReflectionProbe(\n input: ReflectionProbeInput,\n current: { readonly acceptedCount: number; readonly acceptedBytes: number },\n limits: ReflectionProbeAdmissionLimits = DEFAULT_REFLECTION_PROBE_LIMITS,\n): ReflectionProbeAdmission {\n const maxProbes = limits.maxProbes ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxProbes;\n const maxBytes = limits.maxBytes ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxBytes;\n const maxResolution = limits.maxResolution ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxResolution;\n const requested = estimateReflectionProbeBytes(input.resolution, { maxResolution });\n if (\n input.resolution > maxResolution ||\n current.acceptedCount >= maxProbes ||\n current.acceptedBytes + requested > maxBytes\n ) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-budget-exceeded',\n requested,\n activeCount: current.acceptedCount,\n activeBytes: current.acceptedBytes,\n maxProbes,\n maxBytes,\n },\n };\n }\n return { ok: true, acceptedBytes: current.acceptedBytes + requested };\n}\n\nexport interface ReflectionProbeSelection {\n readonly kind: 'probe';\n readonly worldId: number;\n readonly entityKey: number;\n readonly normalizedDistance: number;\n}\n\nexport interface SkylightSelection {\n readonly kind: 'skylight';\n}\n\nexport type ReflectionProbeSelectionResult = ReflectionProbeSelection | SkylightSelection;\n\nexport type ReflectionFallbackSource = 'probe' | 'skylight' | 'neutral';\n\nexport interface ReflectionFallbackProjectionInput {\n /** Stable renderable identity used to join the main-pass projection. */\n readonly renderableKey?: string;\n /** Stable producer source identity; never a live GPU handle. */\n readonly sourceKey?: string;\n readonly source: ReflectionFallbackSource;\n readonly coverage: number;\n readonly extent?: readonly [number, number, number];\n readonly linearHdr: readonly [number, number, number, number];\n readonly brdfSignature: string;\n}\n\nexport interface ReflectionFallbackProjection extends ReflectionFallbackProjectionInput {\n readonly source: ReflectionFallbackSource;\n}\n\nexport type ReflectionFallbackMismatchKind = 'source' | 'coverage' | 'extent' | 'brdf';\n\nexport interface ReflectionFallbackMismatch {\n readonly code:\n | 'reflection-fallback-source-mismatch'\n | 'reflection-fallback-coverage-mismatch'\n | 'reflection-fallback-extent-mismatch'\n | 'reflection-fallback-brdf-mismatch';\n readonly expected: string;\n readonly actual: string;\n}\n\nexport interface ReflectionFallbackInputInvalid {\n readonly code: 'reflection-fallback-input-invalid';\n readonly field: string;\n readonly expected: string;\n}\n\nexport type ReflectionFallbackProjectionResult =\n | { readonly ok: true; readonly value: ReflectionFallbackProjection }\n | { readonly ok: false; readonly error: ReflectionFallbackInputInvalid };\n\nexport function resolveReflectionFallbackSource(\n selection: ReflectionProbeSelectionResult,\n probeReady: boolean,\n skylightAvailable = true,\n): ReflectionFallbackSource {\n if (selection.kind === 'probe' && probeReady) return 'probe';\n // An unavailable probe follows the producer recovery order: use the active\n // Skylight when one exists, then the producer-owned neutral zero. Returning\n // neutral directly here would make the main Standard lighting lane and the\n // detached fallback projection disagree.\n if (skylightAvailable) return 'skylight';\n return 'neutral';\n}\n\nexport function reflectionFallbackCoverage(\n source: ReflectionFallbackSource,\n fact: ReflectionProbeFact | undefined,\n selection: ReflectionProbeSelectionResult,\n): number {\n if (source === 'neutral') return 0;\n if (source === 'skylight') return 1;\n if (fact === undefined || selection.kind !== 'probe') return 0;\n const normalized = Math.sqrt(Math.max(0, selection.normalizedDistance));\n return Math.max(0, Math.min(1, 1 - normalized / Math.sqrt(3)));\n}\n\nexport function reflectionFallbackSourceKey(\n source: ReflectionFallbackSource,\n selection: ReflectionProbeSelectionResult,\n skylight?: { readonly entityHandle: number; readonly equirectHandle: number },\n): string {\n if (source === 'probe' && selection.kind === 'probe') {\n return `probe:${selection.worldId}:${selection.entityKey}`;\n }\n if (source === 'skylight' && skylight !== undefined) {\n return `skylight:${skylight.entityHandle}:${skylight.equirectHandle}`;\n }\n return source;\n}\n\nexport function reflectionFallbackProjectionSignature(\n input: ReflectionFallbackProjectionInput,\n): string {\n return JSON.stringify({\n renderableKey: input.renderableKey,\n sourceKey: input.sourceKey,\n source: input.source,\n coverage: input.coverage,\n extent: input.extent,\n brdfSignature: input.brdfSignature,\n });\n}\n\nexport function deriveReflectionFallbackProjection(\n input: ReflectionFallbackProjectionInput,\n): ReflectionFallbackProjectionResult {\n if (!Number.isFinite(input.coverage) || input.coverage < 0 || input.coverage > 1) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'coverage',\n expected: 'a finite number between zero and one',\n },\n };\n }\n if (input.extent?.some((value) => !Number.isFinite(value) || value <= 0)) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'extent',\n expected: 'three finite numbers greater than zero',\n },\n };\n }\n if (input.linearHdr.some((value) => !Number.isFinite(value))) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'linearHdr',\n expected: 'four finite linear HDR values',\n },\n };\n }\n if (input.brdfSignature.length === 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'brdfSignature',\n expected: 'a non-empty BRDF signature',\n },\n };\n }\n const linearHdr = input.source === 'neutral' ? ([0, 0, 0, 0] as const) : [...input.linearHdr];\n return {\n ok: true,\n value: Object.freeze({\n ...(input.renderableKey === undefined ? {} : { renderableKey: input.renderableKey }),\n ...(input.sourceKey === undefined ? {} : { sourceKey: input.sourceKey }),\n source: input.source,\n coverage: input.coverage,\n ...(input.extent === undefined\n ? {}\n : {\n extent: Object.freeze([...input.extent]) as readonly [number, number, number],\n }),\n linearHdr: Object.freeze(linearHdr) as ReflectionFallbackProjection['linearHdr'],\n brdfSignature: input.brdfSignature,\n }),\n };\n}\n\nexport function validateReflectionFallbackCompatibility(\n expected: ReflectionFallbackProjectionInput,\n actual: ReflectionFallbackProjectionInput,\n): { readonly ok: true } | { readonly ok: false; readonly error: ReflectionFallbackMismatch } {\n const mismatch = (\n kind: ReflectionFallbackMismatchKind,\n expectedValue: string,\n actualValue: string,\n ): { readonly ok: false; readonly error: ReflectionFallbackMismatch } => ({\n ok: false,\n error: {\n code: `reflection-fallback-${kind}-mismatch` as ReflectionFallbackMismatch['code'],\n expected: expectedValue,\n actual: actualValue,\n },\n });\n if (expected.source !== actual.source) {\n return mismatch('source', expected.source, actual.source);\n }\n if (expected.coverage !== actual.coverage) {\n return mismatch('coverage', String(expected.coverage), String(actual.coverage));\n }\n const expectedExtent = expected.extent;\n const actualExtent = actual.extent;\n if (\n (expectedExtent === undefined && actualExtent !== undefined) ||\n (expectedExtent !== undefined &&\n (actualExtent === undefined ||\n expectedExtent.some((value, index) => value !== actualExtent[index])))\n ) {\n return mismatch('extent', JSON.stringify(expectedExtent), JSON.stringify(actualExtent));\n }\n if (expected.brdfSignature !== actual.brdfSignature) {\n return mismatch('brdf', expected.brdfSignature, actual.brdfSignature);\n }\n return { ok: true };\n}\n\nfunction contains(fact: ReflectionProbeFact, point: readonly [number, number, number]): boolean {\n return fact.halfExtents.every((extent, axis) => {\n const center = fact.center[axis] ?? 0;\n const coordinate = point[axis] ?? 0;\n return Math.abs(coordinate - center) <= extent;\n });\n}\n\nfunction normalizedDistance(\n fact: ReflectionProbeFact,\n point: readonly [number, number, number],\n): number {\n let squared = 0;\n for (let axis = 0; axis < 3; axis += 1) {\n const delta = (point[axis] ?? 0) - (fact.center[axis] ?? 0);\n const extent = fact.halfExtents[axis] ?? 1;\n squared += (delta / extent) ** 2;\n }\n return squared;\n}\n\nfunction isBetter(\n candidate: ReflectionProbeSelection,\n current: ReflectionProbeSelection,\n facts: readonly ReflectionProbeFact[],\n): boolean {\n const candidateFact = facts.find(\n (fact) => fact.worldId === candidate.worldId && fact.entityKey === candidate.entityKey,\n );\n const currentFact = facts.find(\n (fact) => fact.worldId === current.worldId && fact.entityKey === current.entityKey,\n );\n if (candidateFact === undefined || currentFact === undefined) return false;\n if (candidateFact.priority !== currentFact.priority)\n return candidateFact.priority > currentFact.priority;\n if (candidate.normalizedDistance !== current.normalizedDistance) {\n return candidate.normalizedDistance < current.normalizedDistance;\n }\n return (\n candidate.worldId < current.worldId ||\n (candidate.worldId === current.worldId && candidate.entityKey < current.entityKey)\n );\n}\n\nexport function selectReflectionProbe(\n facts: readonly ReflectionProbeFact[],\n primitiveCenter: readonly [number, number, number],\n): ReflectionProbeSelectionResult {\n let selected: ReflectionProbeSelection | undefined;\n for (const fact of facts) {\n if (!contains(fact, primitiveCenter)) continue;\n const candidate: ReflectionProbeSelection = {\n kind: 'probe',\n worldId: fact.worldId,\n entityKey: fact.entityKey,\n normalizedDistance: normalizedDistance(fact, primitiveCenter),\n };\n if (selected === undefined || isBetter(candidate, selected, facts)) selected = candidate;\n }\n return selected ?? { kind: 'skylight' };\n}\n\nexport interface ReflectionProbePrimitive {\n readonly worldId: number;\n readonly entityKey: number;\n /** Main-pass renderable key; world/entity is retained as the compatibility fallback. */\n readonly renderableKey?: string;\n readonly center: readonly [number, number, number];\n}\n\nexport interface ReflectionProbeProjectionSnapshot {\n readonly revision: number;\n readonly facts: readonly ReflectionProbeFact[];\n readonly selected: ReadonlyMap<string, ReflectionProbeSelectionResult>;\n readonly scannedPrimitives: number;\n}\n\nfunction primitiveKey(worldId: number, entityKey: number): string {\n return `${worldId}:${entityKey}`;\n}\n\nexport class ReflectionProbeProjection {\n private revision = 0;\n private facts: readonly ReflectionProbeFact[] = [];\n private selected = new Map<string, ReflectionProbeSelectionResult>();\n private signature = '';\n private scannedPrimitives = 0;\n\n update(\n facts: readonly ReflectionProbeFact[],\n primitives: readonly ReflectionProbePrimitive[],\n ): ReflectionProbeProjectionSnapshot {\n const nextFacts = facts\n .slice()\n .sort((a, b) => a.worldId - b.worldId || a.entityKey - b.entityKey);\n const signature = JSON.stringify({ facts: nextFacts, primitives });\n if (signature === this.signature) return this.snapshot();\n this.signature = signature;\n this.facts = nextFacts;\n this.selected = new Map();\n for (const primitive of primitives) {\n this.selected.set(\n primitive.renderableKey ?? primitiveKey(primitive.worldId, primitive.entityKey),\n selectReflectionProbe(nextFacts, primitive.center),\n );\n }\n this.scannedPrimitives = primitives.length;\n this.revision += 1;\n return this.snapshot();\n }\n\n snapshot(): ReflectionProbeProjectionSnapshot {\n return {\n revision: this.revision,\n facts: this.facts,\n selected: this.selected,\n scannedPrimitives: this.scannedPrimitives,\n };\n }\n\n selection(worldId: number, entityKey: number): ReflectionProbeSelectionResult {\n return this.selected.get(primitiveKey(worldId, entityKey)) ?? { kind: 'skylight' };\n }\n}\n","import { createVisibilityBudget } from './budget';\n\n/** Detached, bounded LOD/occlusion facts for renderer inspection consumers. */\n\nexport const LOD_OCCLUSION_INSPECTION_SCHEMA = 'forgeax::lod-occlusion-inspection::v2' as const;\nexport const LOD_OCCLUSION_INSPECTION_MAX_BYTES = 16 * 1024;\nconst MAX_INSPECTION_SAMPLES = 64;\n\nexport type LodOcclusionInspectionError = {\n readonly code: string;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, string | number | boolean>>;\n};\n\nexport type LodOcclusionFallback =\n | { readonly active: false }\n | {\n readonly active: true;\n readonly reason: 'producer-failed' | 'page-exhausted' | 'query-failed' | 'device-loss';\n readonly error: LodOcclusionInspectionError;\n };\n\nexport type LodOcclusionDegradation =\n | { readonly active: false }\n | { readonly active: true; readonly reason: 'all-visible' | 'query-unavailable' };\n\nexport interface LodOcclusionInspectionSample {\n readonly primitiveSlot: number;\n readonly level: number;\n readonly visible: boolean;\n}\n\nexport interface LodOcclusionInspectionRow {\n readonly root: { readonly guid: string; readonly sourceKey: string };\n readonly view: {\n readonly attachmentId: string;\n readonly cameraEntity: number;\n readonly viewRole: 'main' | 'shadow' | 'reflection' | 'probe';\n readonly viewGeneration: number;\n };\n readonly slot: { readonly primitiveSlot: number; readonly slotGeneration: number };\n readonly generation: number;\n readonly count: {\n readonly candidates: number;\n readonly visible: number;\n readonly occluded: number;\n };\n readonly lodHistogram: readonly { readonly level: number; readonly count: number }[];\n /** Map latency for the most recently completed query page (bounded POD). */\n readonly queryLatencyUs: {\n readonly median: number;\n readonly p95: number;\n readonly last: number;\n };\n readonly pagePressure: { readonly used: number; readonly capacity: number };\n readonly fallback: LodOcclusionFallback;\n readonly degradation: LodOcclusionDegradation;\n readonly samples: readonly LodOcclusionInspectionSample[];\n}\n\nexport interface LodOcclusionInspectionSubmit {\n readonly frameId: number;\n readonly build: string;\n readonly deviceGeneration: number;\n}\n\n/**\n * Per-World attribution is only authoritative when the renderer publishes\n * the GPU facts from the same submit that owns the parent inspection. The\n * normal projection path remains useful diagnostics, but it must not be used\n * as evidence for a World-reorder or per-World LOD claim.\n */\nexport type LodOcclusionWorldAttribution =\n | { readonly status: 'unavailable'; readonly reason: 'projection-only' }\n | { readonly status: 'same-submit'; readonly submit: LodOcclusionInspectionSubmit };\n\nexport interface LodOcclusionWorldInspection {\n readonly attachmentId: string;\n readonly rows: readonly LodOcclusionInspectionRow[];\n readonly attribution: LodOcclusionWorldAttribution;\n}\n\nexport interface LodOcclusionInspectionBudget {\n readonly configuredQueryBudget: number;\n readonly effectiveQueryBudget: number;\n readonly settleSubmits: number;\n readonly retestSubmits: number;\n readonly expirySubmits: number;\n}\n\nexport interface LodOcclusionInspection extends LodOcclusionInspectionRow {\n readonly schema: typeof LOD_OCCLUSION_INSPECTION_SCHEMA;\n /** Atomic identity for the submit that produced every row below. */\n readonly submit: LodOcclusionInspectionSubmit;\n /** Immutable budget values used by the query and confidence owners. */\n readonly budget: LodOcclusionInspectionBudget;\n /** Stable attachment identity; array order is never an attribution key. */\n readonly worlds: readonly LodOcclusionWorldInspection[];\n}\n\nexport type LodOcclusionInspectionInput = Omit<\n LodOcclusionInspection,\n 'schema' | 'submit' | 'budget' | 'worlds'\n> & {\n readonly submit?: LodOcclusionInspectionSubmit;\n readonly budget?: LodOcclusionInspectionBudget;\n readonly worlds?: readonly LodOcclusionWorldInspectionInput[];\n};\n\nexport type LodOcclusionWorldInspectionInput = Omit<LodOcclusionWorldInspection, 'attribution'> & {\n readonly attribution?: LodOcclusionWorldAttribution;\n};\n\nexport type LodOcclusionInspectionAction =\n | { readonly action: 'none' }\n | { readonly action: 'rebuild'; readonly sourceKey: string; readonly reason: string }\n | { readonly action: 'cold-cook'; readonly sourceKey: string; readonly reason: string }\n | { readonly action: 'retry'; readonly sourceKey: string; readonly reason: string };\n\nfunction nonNegativeInteger(name: string, value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new Error(`${name} must be a non-negative integer`);\n return value;\n}\n\nfunction copyError(error: LodOcclusionInspectionError): LodOcclusionInspectionError {\n return Object.freeze({\n code: error.code,\n expected: error.expected,\n hint: error.hint,\n ...(error.detail === undefined ? {} : { detail: Object.freeze({ ...error.detail }) }),\n });\n}\n\nfunction copyFallback(fallback: LodOcclusionFallback): LodOcclusionFallback {\n return fallback.active\n ? Object.freeze({ ...fallback, error: copyError(fallback.error) })\n : Object.freeze({ active: false });\n}\n\nfunction copySamples(\n samples: readonly LodOcclusionInspectionSample[],\n): readonly LodOcclusionInspectionSample[] {\n return Object.freeze(\n [...samples]\n .sort((left, right) => left.primitiveSlot - right.primitiveSlot)\n .slice(0, MAX_INSPECTION_SAMPLES)\n .map((sample) =>\n Object.freeze({\n primitiveSlot: nonNegativeInteger('sample.primitiveSlot', sample.primitiveSlot),\n level: nonNegativeInteger('sample.level', sample.level),\n visible: sample.visible,\n }),\n ),\n );\n}\n\nfunction copyWorldAttribution(\n attribution: LodOcclusionWorldAttribution | undefined,\n): LodOcclusionWorldAttribution {\n if (attribution === undefined) {\n return Object.freeze({ status: 'unavailable', reason: 'projection-only' });\n }\n if (attribution.status === 'same-submit') {\n if (typeof attribution.submit.build !== 'string' || attribution.submit.build.length === 0) {\n throw new Error('world.attribution.submit.build must be a non-empty string');\n }\n nonNegativeInteger('world.attribution.submit.frameId', attribution.submit.frameId);\n nonNegativeInteger(\n 'world.attribution.submit.deviceGeneration',\n attribution.submit.deviceGeneration,\n );\n return Object.freeze({\n status: 'same-submit',\n submit: Object.freeze({ ...attribution.submit }),\n });\n }\n if (attribution.status !== 'unavailable' || attribution.reason !== 'projection-only') {\n throw new Error('world.attribution must declare same-submit or projection-only');\n }\n return Object.freeze({ status: 'unavailable', reason: 'projection-only' });\n}\n\nfunction copyRow(row: LodOcclusionInspectionRow): LodOcclusionInspectionRow {\n for (const [name, value] of Object.entries({\n generation: row.generation,\n candidates: row.count.candidates,\n visible: row.count.visible,\n occluded: row.count.occluded,\n median: row.queryLatencyUs.median,\n p95: row.queryLatencyUs.p95,\n last: row.queryLatencyUs.last,\n pageUsed: row.pagePressure.used,\n pageCapacity: row.pagePressure.capacity,\n }))\n nonNegativeInteger(`inspection.${name}`, value);\n if (\n row.view.cameraEntity < 0 ||\n row.view.viewGeneration < 0 ||\n row.slot.primitiveSlot < 0 ||\n row.slot.slotGeneration < 0\n ) {\n throw new Error('inspection identity values must be non-negative');\n }\n if (row.pagePressure.used > row.pagePressure.capacity) {\n throw new Error('inspection page pressure exceeds capacity');\n }\n return Object.freeze({\n root: Object.freeze({ ...row.root }),\n view: Object.freeze({ ...row.view }),\n slot: Object.freeze({ ...row.slot }),\n generation: row.generation,\n count: Object.freeze({ ...row.count }),\n lodHistogram: Object.freeze(\n row.lodHistogram.map((histogram) =>\n Object.freeze({\n level: nonNegativeInteger('histogram.level', histogram.level),\n count: nonNegativeInteger('histogram.count', histogram.count),\n }),\n ),\n ),\n queryLatencyUs: Object.freeze({ ...row.queryLatencyUs }),\n pagePressure: Object.freeze({ ...row.pagePressure }),\n fallback: copyFallback(row.fallback),\n degradation: Object.freeze({ ...row.degradation }),\n samples: copySamples(row.samples),\n });\n}\n\nfunction copyWorlds(\n worlds: readonly LodOcclusionWorldInspectionInput[] | undefined,\n fallback: LodOcclusionInspectionRow,\n): readonly LodOcclusionWorldInspection[] {\n const source = worlds ?? [{ attachmentId: fallback.view.attachmentId, rows: [fallback] }];\n return Object.freeze(\n source.map((world) =>\n Object.freeze({\n attachmentId: world.attachmentId,\n rows: Object.freeze(world.rows.map((row) => copyRow(row))),\n attribution: copyWorldAttribution(world.attribution),\n }),\n ),\n );\n}\n\nexport function inspectLodOcclusion(input: LodOcclusionInspectionInput): LodOcclusionInspection {\n const row = copyRow(input);\n const defaultBudget = createVisibilityBudget();\n const budget = input.budget ?? {\n configuredQueryBudget: defaultBudget.configuredQueryBudget,\n effectiveQueryBudget: defaultBudget.effectiveQueryBudget,\n settleSubmits: defaultBudget.settleSubmits,\n retestSubmits: defaultBudget.retestSubmits,\n expirySubmits: defaultBudget.expirySubmits,\n };\n for (const [name, value] of Object.entries(budget))\n nonNegativeInteger(`inspection.budget.${name}`, value);\n const submit = input.submit ?? {\n frameId: input.generation,\n build: 'unknown',\n deviceGeneration: 0,\n };\n nonNegativeInteger('inspection.submit.frameId', submit.frameId);\n nonNegativeInteger('inspection.submit.deviceGeneration', submit.deviceGeneration);\n if (typeof submit.build !== 'string' || submit.build.length === 0) {\n throw new Error('inspection.submit.build must be a non-empty string');\n }\n const worlds = copyWorlds(input.worlds, row);\n for (const world of worlds) {\n if (\n world.attribution.status === 'same-submit' &&\n (world.attribution.submit.frameId !== submit.frameId ||\n world.attribution.submit.build !== submit.build ||\n world.attribution.submit.deviceGeneration !== submit.deviceGeneration)\n ) {\n throw new Error('world attribution must reference the parent inspection submit');\n }\n }\n const inspection: LodOcclusionInspection = Object.freeze({\n schema: LOD_OCCLUSION_INSPECTION_SCHEMA,\n ...row,\n submit: Object.freeze({ ...submit }),\n budget: Object.freeze({ ...budget }),\n worlds,\n });\n if (JSON.stringify(inspection).length > LOD_OCCLUSION_INSPECTION_MAX_BYTES) {\n throw new Error(`LOD occlusion inspection exceeds ${LOD_OCCLUSION_INSPECTION_MAX_BYTES} bytes`);\n }\n return inspection;\n}\n\nexport function serializeLodOcclusionInspection(inspection: LodOcclusionInspection): string {\n const serialized = JSON.stringify(inspection);\n if (serialized.length > LOD_OCCLUSION_INSPECTION_MAX_BYTES) {\n throw new Error(`LOD occlusion inspection exceeds ${LOD_OCCLUSION_INSPECTION_MAX_BYTES} bytes`);\n }\n return serialized;\n}\n\nexport function consumeLodOcclusionInspection(\n inspection: LodOcclusionInspection,\n): LodOcclusionInspectionAction {\n if (!inspection.fallback.active) return { action: 'none' };\n const { reason, error } = inspection.fallback;\n const action =\n error.code.startsWith('asset-') || reason === 'producer-failed'\n ? 'rebuild'\n : reason === 'query-failed' || reason === 'page-exhausted' || reason === 'device-loss'\n ? 'retry'\n : 'cold-cook';\n return { action, sourceKey: inspection.root.sourceKey, reason };\n}\n","/**\n * Consumer-only SSR M0 admission.\n *\n * This module consumes detached producer receipts. It owns no capture,\n * device, graph, or recovery handle and therefore cannot repair a missing\n * producer. A complete receipt set is the only route to an admitted result.\n */\n\nimport {\n type RhiTextureFormatCapabilityReceipt,\n validateR32FloatReceipt,\n} from '@forgeax/engine-rhi';\nimport type { ReflectionFallbackReceipt } from '../inspection-types';\nimport type { SsrOwnerRecoveryAction } from './errors';\nimport type { SsrAdmissionIdentity } from './identity';\n\nexport const SSR_FORMAT_PROFILE = 'r32float-mip-sampled-storage' as const;\n\nexport const SSR_FORMAT_STAGES = Object.freeze([\n 'texture-create',\n 'mip-view',\n 'sampled-storage-bind-group',\n 'pipeline-bind',\n 'finish',\n 'submit',\n 'completion',\n 'readback',\n] as const);\n\nexport type { SsrAdmissionIdentity } from './identity';\n\nexport type SsrFormatStage = (typeof SSR_FORMAT_STAGES)[number];\n\n/**\n * The admission input is the real renderer owner receipt plus the one\n * integration identity supplied by the host. It deliberately does not\n * recreate submitted/source/LKG boolean flags.\n */\nexport type SsrReflectionFallbackReceipt = ReflectionFallbackReceipt & {\n readonly identity: SsrAdmissionIdentity;\n};\n\n/** RHI capability receipt with the same host-supplied integration identity. */\nexport type SsrFormatReceipt = RhiTextureFormatCapabilityReceipt & {\n readonly identity: SsrAdmissionIdentity;\n};\n\nexport interface SsrTemporalReceipt {\n readonly identity: SsrAdmissionIdentity;\n readonly successfulSubmit: true;\n readonly generation: number;\n}\n\nexport interface SsrAdmissionWork {\n readonly attachmentCount: number;\n readonly passCount: number;\n readonly bindingCount: number;\n readonly resourceCount: number;\n readonly historyCount: 0;\n readonly temporalDemand: 0;\n}\n\nexport interface SsrAdmissionBudget {\n readonly probeExecutions: 0 | 1;\n readonly resetCount: 0;\n readonly rebuildCount: 0;\n}\n\nexport interface SsrAdmissionFailure {\n readonly code:\n | 'ssr-not-requested'\n | 'ssr-reflection-fallback-unavailable'\n | 'ssr-format-unavailable'\n | 'ssr-temporal-unavailable'\n | 'ssr-receipt-identity-mismatch'\n | 'ssr-receipt-stale';\n readonly expected: string;\n readonly hint: string;\n readonly detail: Readonly<{\n readonly owner: 'producer' | 'format' | 'temporal' | 'consumer';\n /** Owner-directed action an AI consumer can take without parsing hint text. */\n readonly action: SsrOwnerRecoveryAction;\n readonly generation?: number;\n readonly identityField?: keyof SsrAdmissionIdentity;\n }>;\n}\n\nexport type SsrAdmissionResult =\n | {\n readonly status: 'admitted';\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly generation: number;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure?: undefined;\n }\n | {\n readonly status: 'fallback-only';\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly generation: number;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure: SsrAdmissionFailure;\n };\n\nexport interface SsrAdmissionInput {\n readonly requested: boolean;\n readonly identity: SsrAdmissionIdentity;\n readonly reflectionFallback?: SsrReflectionFallbackReceipt;\n readonly format?: SsrFormatReceipt;\n readonly temporal?: SsrTemporalReceipt;\n readonly previousGeneration?: number;\n}\n\n/** Public renderer projection consumed by the parent SSR feature. */\nexport interface SsrDependenciesInspection {\n readonly status: 'admitted' | 'fallback-only';\n /** Absent until the host binds an exact source/tree/lock/build identity. */\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly requested: boolean;\n readonly reflectionFallback: ReflectionFallbackReceipt | undefined;\n readonly format: SsrFormatReceipt | undefined;\n readonly temporal: SsrTemporalReceipt | undefined;\n readonly admission: SsrAdmissionResult;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure: SsrAdmissionFailure | undefined;\n}\n\nconst ZERO_WORK: SsrAdmissionWork = Object.freeze({\n attachmentCount: 0,\n passCount: 0,\n bindingCount: 0,\n resourceCount: 0,\n historyCount: 0,\n temporalDemand: 0,\n});\n\nconst ADMITTED_WORK: SsrAdmissionWork = Object.freeze({\n attachmentCount: 1,\n passCount: 1,\n bindingCount: 1,\n resourceCount: 1,\n historyCount: 0,\n temporalDemand: 0,\n});\n\nconst ZERO_BUDGET: SsrAdmissionBudget = Object.freeze({\n probeExecutions: 0,\n resetCount: 0,\n rebuildCount: 0,\n});\n\nconst ADMITTED_BUDGET: SsrAdmissionBudget = Object.freeze({\n probeExecutions: 1,\n resetCount: 0,\n rebuildCount: 0,\n});\n\nfunction identityFieldMismatch(\n expected: SsrAdmissionIdentity,\n actual: SsrAdmissionIdentity,\n): keyof SsrAdmissionIdentity | undefined {\n for (const field of ['sourceHead', 'sourceTree', 'lockSha256', 'buildSha256'] as const) {\n if (expected[field] !== actual[field]) return field;\n }\n return undefined;\n}\n\nfunction blocked(\n identity: SsrAdmissionIdentity | undefined,\n failure: SsrAdmissionFailure,\n generation = 0,\n): SsrAdmissionResult {\n return Object.freeze({\n status: 'fallback-only',\n identity,\n generation,\n work: ZERO_WORK,\n budget: ZERO_BUDGET,\n failure,\n });\n}\n\nfunction failure(\n code: SsrAdmissionFailure['code'],\n owner: SsrAdmissionFailure['detail']['owner'],\n hint: string,\n detail: Omit<SsrAdmissionFailure['detail'], 'owner' | 'action'> = {},\n): SsrAdmissionFailure {\n const action: SsrOwnerRecoveryAction = recoveryActionFor(code);\n return Object.freeze({\n code,\n expected: 'all producer, format, and temporal receipts share one admitted identity',\n hint,\n detail: Object.freeze({ owner, action, ...detail }),\n });\n}\n\nfunction recoveryActionFor(code: SsrAdmissionFailure['code']): SsrOwnerRecoveryAction {\n switch (code) {\n case 'ssr-reflection-fallback-unavailable':\n case 'ssr-receipt-identity-mismatch':\n return 'rebuild';\n case 'ssr-not-requested':\n case 'ssr-format-unavailable':\n case 'ssr-temporal-unavailable':\n case 'ssr-receipt-stale':\n return 'retry';\n }\n}\n\nfunction receiptFailure(\n input: SsrAdmissionInput,\n receipt: { readonly identity: SsrAdmissionIdentity },\n owner: SsrAdmissionFailure['detail']['owner'],\n): SsrAdmissionResult | undefined {\n const field = identityFieldMismatch(input.identity, receipt.identity);\n if (field === undefined) return undefined;\n return blocked(\n input.identity,\n failure('ssr-receipt-identity-mismatch', owner, 'rebuild the owner receipt for this identity', {\n identityField: field,\n }),\n );\n}\n\nfunction validFallback(receipt: SsrReflectionFallbackReceipt | undefined): boolean {\n return (\n receipt !== undefined &&\n receipt.candidateVisible === false &&\n Number.isFinite(receipt.coverage) &&\n receipt.coverage >= 0 &&\n receipt.coverage <= 1 &&\n (receipt.sourceKey === undefined || receipt.sourceKey.length > 0) &&\n (receipt.extent === undefined ||\n (receipt.extent.length === 3 &&\n receipt.extent.every((value) => Number.isFinite(value) && value > 0))) &&\n Number.isInteger(receipt.sourceGeneration) &&\n receipt.sourceGeneration >= 0 &&\n Number.isInteger(receipt.projectionGeneration) &&\n receipt.projectionGeneration >= 0 &&\n Number.isInteger(receipt.deviceGeneration) &&\n receipt.deviceGeneration >= 0 &&\n receipt.brdfSignature === 'standard-pbr-ibl-v1' &&\n ((receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) ||\n (receipt.source === 'skylight' && (receipt.state === 'active' || receipt.state === 'lkg')) ||\n (receipt.source === 'neutral' && receipt.state === 'neutral'))\n );\n}\n\nfunction validFormat(receipt: SsrFormatReceipt | undefined): boolean {\n if (\n receipt?.profile !== SSR_FORMAT_PROFILE ||\n receipt.verdict !== 'admitted' ||\n receipt.evidence !== 'real' ||\n !Number.isInteger(receipt.deviceGeneration) ||\n receipt.deviceGeneration < 0\n ) {\n return false;\n }\n if (\n !SSR_FORMAT_STAGES.every((stage) =>\n receipt.stages.some((entry) => entry.stage === stage && entry.verdict === 'admitted'),\n )\n ) {\n return false;\n }\n return validateR32FloatReceipt(receipt).ok;\n}\n\nfunction validTemporal(receipt: SsrTemporalReceipt | undefined): boolean {\n return (\n receipt?.successfulSubmit === true &&\n Number.isInteger(receipt.generation) &&\n receipt.generation >= 0\n );\n}\n\nexport function admitSsrM0(input: SsrAdmissionInput): SsrAdmissionResult {\n if (!input.requested) {\n return blocked(\n input.identity,\n failure('ssr-not-requested', 'consumer', 'request SSR before evaluating M0 admission'),\n );\n }\n if (input.reflectionFallback === undefined) {\n return blocked(\n input.identity,\n failure('ssr-reflection-fallback-unavailable', 'producer', 'use LKG, Skylight, or neutral'),\n );\n }\n const fallbackIdentityFailure = receiptFailure(input, input.reflectionFallback, 'producer');\n if (fallbackIdentityFailure !== undefined) return fallbackIdentityFailure;\n if (!validFallback(input.reflectionFallback)) {\n return blocked(\n input.identity,\n failure(\n 'ssr-reflection-fallback-unavailable',\n 'producer',\n 'inspect and rebuild the producer receipt',\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (input.format === undefined) {\n return blocked(\n input.identity,\n failure('ssr-format-unavailable', 'format', 'probe the exact format profile for this device'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n const formatIdentityFailure = receiptFailure(input, input.format, 'format');\n if (formatIdentityFailure !== undefined) return formatIdentityFailure;\n if (!validFormat(input.format)) {\n return blocked(\n input.identity,\n failure('ssr-format-unavailable', 'format', 'complete the full r32float profile probe'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (input.temporal === undefined) {\n return blocked(\n input.identity,\n failure(\n 'ssr-temporal-unavailable',\n 'temporal',\n 'submit the matching temporal producer receipt',\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n const temporalIdentityFailure = receiptFailure(input, input.temporal, 'temporal');\n if (temporalIdentityFailure !== undefined) return temporalIdentityFailure;\n if (!validTemporal(input.temporal)) {\n return blocked(\n input.identity,\n failure('ssr-temporal-unavailable', 'temporal', 'inspect and rebuild the temporal receipt'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (\n input.previousGeneration !== undefined &&\n input.previousGeneration !== input.reflectionFallback.projectionGeneration\n ) {\n return blocked(\n input.identity,\n failure(\n 'ssr-receipt-stale',\n 'consumer',\n 'discard stale completion and reinspect the owners',\n {\n generation: input.reflectionFallback.projectionGeneration,\n },\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n return Object.freeze({\n status: 'admitted',\n identity: input.identity,\n generation: input.reflectionFallback.projectionGeneration,\n work: ADMITTED_WORK,\n budget: ADMITTED_BUDGET,\n });\n}\n\n/**\n * Joins the live owner projections at the renderer boundary. The only casts\n * here add the host identity to receipts that otherwise remain canonical RHI\n * or ReflectionProbe PODs; no producer fact is copied or renamed.\n */\nexport function projectSsrDependencies(input: {\n readonly requested: boolean;\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly reflectionFallback: ReflectionFallbackReceipt | undefined;\n readonly format: RhiTextureFormatCapabilityReceipt | undefined;\n readonly temporal: { readonly successfulSubmit: true; readonly generation: number } | undefined;\n readonly previousGeneration?: number;\n}): SsrDependenciesInspection {\n const identity = input.identity;\n const reflectionFallback =\n identity === undefined || input.reflectionFallback?.identity === undefined\n ? undefined\n : (input.reflectionFallback as SsrReflectionFallbackReceipt);\n const format =\n identity === undefined || input.format === undefined\n ? undefined\n : ({ ...input.format, identity } satisfies SsrFormatReceipt);\n const temporal =\n identity === undefined || input.temporal === undefined\n ? undefined\n : ({ identity, ...input.temporal } satisfies SsrTemporalReceipt);\n const admission =\n identity === undefined\n ? blocked(\n undefined,\n failure(\n input.requested ? 'ssr-receipt-identity-mismatch' : 'ssr-not-requested',\n 'consumer',\n input.requested\n ? 'bind the exact source, tree, lock, and build identity before admission'\n : 'request SSR before evaluating M0 admission',\n input.requested ? { identityField: 'sourceHead' } : {},\n ),\n )\n : admitSsrM0({\n requested: input.requested,\n identity,\n ...(reflectionFallback === undefined ? {} : { reflectionFallback }),\n ...(format === undefined ? {} : { format }),\n ...(temporal === undefined ? {} : { temporal }),\n ...(input.previousGeneration === undefined\n ? {}\n : { previousGeneration: input.previousGeneration }),\n });\n return Object.freeze({\n status: admission.status,\n identity,\n requested: input.requested,\n reflectionFallback: input.reflectionFallback,\n format,\n temporal,\n admission,\n work: admission.work,\n budget: admission.budget,\n failure: admission.failure,\n });\n}\n\nexport function zeroSsrAdmissionWork(): SsrAdmissionWork {\n return ZERO_WORK;\n}\n\n/**\n * Projects the admission decision into the existing temporal reset seam.\n * Admission never creates temporal history; only a changed committed\n * producer generation can request a reset through the coordinator.\n */\nexport function resolveSsrAdmissionGeneration(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): { readonly changed: boolean; readonly generation: number | undefined } {\n return {\n changed:\n previousGeneration !== undefined &&\n nextGeneration !== undefined &&\n previousGeneration !== nextGeneration,\n generation: nextGeneration,\n };\n}\n"]}
|