@forgeax/engine-render 0.1.28 → 0.1.30
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 +856 -126
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +4 -3
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- 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 +14 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +31 -1
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
- 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/device-loss-fanout.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/recovery-attempt.d.ts +1 -6
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +7 -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 +7 -1
- 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 +2 -2
- package/dist/capture/scene-projection.d.ts +41 -0
- package/dist/capture/scene-projection.d.ts.map +1 -0
- package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
- package/dist/chunk-7MQ3XBSP.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-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
- package/dist/chunk-C3DDSXYK.mjs.map +1 -0
- package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
- package/dist/chunk-FUUO4UND.mjs.map +1 -0
- package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
- package/dist/chunk-JRBDO2KB.mjs.map +1 -0
- package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
- package/dist/chunk-MDQJPY3T.mjs.map +1 -0
- package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
- package/dist/chunk-NO4WZCAH.mjs.map +1 -0
- package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
- package/dist/chunk-PA5DRJNI.mjs.map +1 -0
- package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
- package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
- package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
- package/dist/chunk-S5UE2T5P.mjs.map +1 -0
- package/dist/components/camera.d.ts +62 -2
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/directional-light.d.ts +2 -2
- package/dist/components/dynamic-resolution.d.ts +15 -0
- package/dist/components/dynamic-resolution.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -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/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +1 -0
- package/dist/components/reflection-probe.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/components/skylight.d.ts +4 -1
- package/dist/components/skylight.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +14809 -7570
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +3 -14
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/background.d.ts +7 -0
- package/dist/environment/background.d.ts.map +1 -0
- package/dist/environment/ibl.d.ts +11 -0
- package/dist/environment/ibl.d.ts.map +1 -0
- package/dist/environment/storage.d.ts +14 -0
- package/dist/environment/storage.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 +41 -4
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +7 -0
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +50 -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/material-artifacts.d.ts +24 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
- package/dist/gpu-driven/material-bindings.d.ts +7 -0
- package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
- 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 +2 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +169 -27
- 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-resource.d.ts +5 -2
- package/dist/gpu-resource.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 +9 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +2 -0
- package/dist/ibl/IblPipelineCache.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 +3 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +87 -75
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +10 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +180 -1
- 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 +117 -9
- 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 +15 -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 +23 -5
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/render-extent.d.ts +51 -0
- package/dist/pipeline/render-extent.d.ts.map +1 -0
- package/dist/pipeline/standard-build-context.d.ts +7 -0
- package/dist/pipeline/standard-build-context.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts +3 -2
- 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/standard-profile.d.ts +2 -1
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +5 -2
- 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/plugin.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/post-process-errors.d.ts +9 -2
- package/dist/post-process-errors.d.ts.map +1 -1
- package/dist/prepare/extended-lighting/resources.d.ts +3 -3
- 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 +109 -13
- 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 +41 -5
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +13 -9
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +43 -3
- 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 +14 -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 +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +101 -22
- 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 +39 -8
- 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/background.d.ts +14 -0
- package/dist/reflection/background.d.ts.map +1 -0
- package/dist/reflection/filter.d.ts.map +1 -1
- package/dist/reflection/projection.d.ts +1 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts +4 -4
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +211 -53
- 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 +81 -6
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +15 -6
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +128 -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 +27 -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 +31 -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/ssao-config.d.ts +8 -6
- package/dist/ssao-config.d.ts.map +1 -1
- 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 +4 -2
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts +15 -0
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
- package/dist/temporal/temporal-view.d.ts +6 -0
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +41 -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/component.d.ts +1 -0
- package/dist/volume/component.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__/capture-scene-projection.unit.test.ts +24 -0
- package/src/__tests__/detached-inspection.integration.test.ts +5 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
- package/src/__tests__/device-loss-fanout.unit.test.ts +43 -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-batch.unit.test.ts +157 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
- package/src/__tests__/factory-contract.integration.test.ts +231 -9
- 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-observation.contract.test.ts +21 -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 +307 -7
- 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 +261 -0
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -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 +1076 -106
- 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 +160 -52
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
- package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
- 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 +613 -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 +57 -3
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
- package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -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 +42 -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__/post-process-error-policy-owner.unit.test.ts +6 -5
- 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 +251 -9
- 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 +171 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
- package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
- package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
- package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
- package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
- package/src/__tests__/render-extent.unit.test.ts +63 -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 +915 -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 +233 -9
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
- package/src/__tests__/shader-manifest-fixture.ts +45 -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 +125 -14
- package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
- package/src/__tests__/ssao-config.unit.test.ts +7 -0
- package/src/__tests__/ssao-surface.dawn.test.ts +252 -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-cube-silhouette.dawn.test.ts +270 -0
- package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +951 -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 +84 -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 +275 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
- package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -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 +199 -0
- package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -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 +342 -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__/temporal-view.unit.test.ts +17 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
- package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
- 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/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
- package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
- package/src/assembly/device-feature-admission.ts +9 -4
- package/src/assembly/dynamic-geometry-host.ts +284 -163
- 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 +19 -0
- package/src/assembly/material/assembly.ts +383 -1
- package/src/assembly/material/pipeline-helpers.ts +100 -0
- package/src/assembly/material-shader-policy.ts +110 -46
- package/src/assembly/recovery/device-loss-fanout.ts +5 -0
- package/src/assembly/recovery/failure-location.ts +62 -0
- package/src/assembly/recovery/recovery-attempt.ts +2 -29
- package/src/assembly/recovery/renderer-recover.ts +16 -17
- package/src/assembly/renderer-facade.ts +34 -1
- 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 +46 -1
- 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 +161 -131
- 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 +744 -730
- package/src/assembly/webgpu-vertex-layouts.ts +233 -87
- package/src/capture/scene-projection.ts +37 -0
- package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
- package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
- package/src/components/__tests__/light-radius.integration.test.ts +59 -0
- package/src/components/camera.ts +287 -7
- package/src/components/directional-light.ts +3 -3
- package/src/components/dynamic-resolution.ts +67 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +45 -18
- package/src/components/light-helpers.ts +6 -1
- package/src/components/reflection-probe.ts +1 -0
- package/src/components/scene-instance.ts +2 -1
- package/src/components/screen-space-reflection.ts +21 -0
- package/src/components/skylight.ts +4 -1
- package/src/components/sprite-animation.ts +2 -2
- package/src/components/sprite-instances.ts +1 -1
- package/src/device/device-scope.ts +13 -7
- package/src/device/gpu-residency.ts +45 -42
- package/src/dynamic-geometry.ts +13 -8
- package/src/environment/background.ts +281 -0
- package/src/environment/ibl.ts +211 -0
- package/src/environment/storage.ts +63 -0
- package/src/errors/gpu-driven.ts +49 -8
- package/src/errors/render.ts +91 -3
- package/src/extract/camera.ts +37 -1
- package/src/extract/contracts.ts +10 -0
- package/src/extract/gpu-driven.ts +240 -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 +452 -108
- package/src/gpu-driven/material-artifacts.ts +179 -0
- package/src/gpu-driven/material-bindings.ts +41 -0
- package/src/gpu-driven/pbr-program.ts +31 -0
- package/src/gpu-driven/prepared-draw.ts +42 -6
- package/src/gpu-driven/production-raster.ts +2806 -716
- package/src/gpu-driven/shadow-views.ts +539 -0
- package/src/gpu-driven/view-gpu.ts +188 -41
- package/src/gpu-resource.ts +21 -2
- package/src/gpu-scene-schema.ts +61 -11
- package/src/gpu-scene.ts +197 -99
- package/src/gpu-texture-usage.ts +1 -0
- package/src/hdrp-buffers.ts +141 -36
- package/src/ibl/IblPipelineCache.ts +5 -0
- package/src/ibl/frame-resources.ts +38 -0
- package/src/ibl/skylight-bind-group.ts +32 -21
- package/src/index.ts +194 -75
- package/src/inspection-types.ts +207 -1
- 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 +194 -0
- package/src/materials.ts +44 -8
- package/src/pbr-pipeline.ts +172 -19
- package/src/pipeline/render-extent.ts +111 -0
- package/src/pipeline/standard-build-context.ts +7 -0
- package/src/pipeline/standard-forward-lane.ts +74 -29
- 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 +232 -70
- package/src/pipeline/standard-post.ts +190 -27
- package/src/pipeline/standard-profile.ts +2 -1
- package/src/pipeline-builder.ts +28 -9
- package/src/pipeline-spec-types.ts +4 -0
- package/src/pipeline-spec.ts +37 -29
- package/src/plugin.ts +4 -0
- package/src/points-lines/standard-owner.ts +6 -14
- package/src/post-process-errors.ts +26 -18
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
- package/src/prepare/extended-lighting/resources.ts +3 -3
- package/src/prepare/prepared-graphics-resolver.ts +9 -2
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
- package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
- 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 +15 -12
- package/src/record/frame-snapshot.ts +146 -34
- package/src/record/frame-targets.ts +9 -0
- package/src/record/frame.ts +838 -170
- package/src/record/main-pass-geometry.ts +209 -103
- package/src/record/main-pass-material.ts +157 -40
- package/src/record/main-pass-sprite-draws.ts +16 -107
- package/src/record/main-pass.ts +141 -12
- package/src/record/material-uniforms.ts +1 -1
- package/src/record/mesh-ssbo.ts +59 -15
- package/src/record/prepared-material-bindings.ts +238 -0
- package/src/record/recovery-pipeline.ts +69 -90
- package/src/record/render-context.ts +123 -24
- package/src/record/shadow-pass.ts +1389 -230
- package/src/record/skybox-post-pass.ts +14 -3
- package/src/record/typed-frame-graph.ts +1064 -47
- package/src/record/view-ubo.ts +12 -1
- package/src/recovery/render-system-candidate.ts +135 -68
- package/src/recovery/render-system-roots.ts +113 -0
- package/src/recovery/types.ts +77 -0
- package/src/reflection/background.ts +151 -0
- package/src/reflection/filter.ts +3 -0
- package/src/reflection/projection.ts +16 -6
- package/src/reflection/record-owner.ts +308 -140
- package/src/render-contract.ts +237 -49
- package/src/render-graph-primitives.ts +34 -5
- package/src/render-pipeline.ts +90 -2
- package/src/render-system-extract-tail.ts +431 -162
- package/src/render-system-extract.ts +478 -119
- package/src/render-system-projections.ts +241 -0
- package/src/render-system.ts +715 -828
- package/src/scene/render-scene-types.ts +13 -4
- package/src/scene/render-scene.ts +577 -355
- package/src/scene/shadow-visibility.ts +21 -0
- package/src/ssao-config.ts +25 -8
- 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 +797 -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 +79 -12
- package/src/temporal/history.ts +3 -1
- package/src/temporal/inspection.ts +2 -1
- package/src/temporal/standard-scene-data.ts +10 -2
- package/src/temporal/target-coverage-attachment.ts +72 -0
- package/src/temporal/temporal-view.ts +11 -2
- package/src/temporal/view.ts +12 -2
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
- package/src/typed-render-graph-primitives.ts +304 -74
- package/src/typed-shadow-passes.ts +122 -12
- package/src/volume/component.ts +1 -0
- package/src/volume/passes.ts +3 -3
- package/src/volume/temporal.ts +10 -0
- package/dist/chunk-GE3SDD72.mjs.map +0 -1
- package/dist/chunk-GF523LHF.mjs.map +0 -1
- package/dist/chunk-IQMKJLNU.mjs.map +0 -1
- package/dist/chunk-J52NMQKR.mjs.map +0 -1
- package/dist/chunk-J6KACNOH.mjs.map +0 -1
- package/dist/chunk-JAASCMXA.mjs.map +0 -1
- package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
- package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
- package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
- package/dist/chunk-VSL23LZE.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,40 +1,9 @@
|
|
|
1
|
+
import { classifySceneDataCoverage } from './chunk-FUUO4UND.mjs';
|
|
1
2
|
import { mat4 } from '@forgeax/engine-math';
|
|
2
3
|
import { ok, err } from '@forgeax/engine-types';
|
|
3
4
|
|
|
4
|
-
// src/temporal/coverage.ts
|
|
5
|
-
function createTemporalCoverage(width, height) {
|
|
6
|
-
if (!Number.isSafeInteger(width) || width <= 0) throw new RangeError("width must be positive.");
|
|
7
|
-
if (!Number.isSafeInteger(height) || height <= 0)
|
|
8
|
-
throw new RangeError("height must be positive.");
|
|
9
|
-
return Object.freeze({ width, height, bytes: 32 * width * height, fullScreen: true });
|
|
10
|
-
}
|
|
11
|
-
function classifySceneDataCoverage(input) {
|
|
12
|
-
const exactContributorIds = input.contributors.filter((c) => c.kind === "exact").map((c) => c.id);
|
|
13
|
-
const reactiveContributorIds = input.contributors.filter((c) => c.kind === "reactive").map((c) => c.id);
|
|
14
|
-
const available = new Set(input.contributors.map((c) => c.id));
|
|
15
|
-
const missing = input.requiredContributorIds.filter((id) => !available.has(id));
|
|
16
|
-
return {
|
|
17
|
-
exactContributorIds: Object.freeze(exactContributorIds),
|
|
18
|
-
reactiveContributorIds: Object.freeze(reactiveContributorIds),
|
|
19
|
-
missingContributorIds: Object.freeze(missing.slice(0, 32)),
|
|
20
|
-
omittedMissingContributorCount: Math.max(0, missing.length - 32),
|
|
21
|
-
complete: missing.length === 0
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function scanSceneDataCoverage(input) {
|
|
25
|
-
const classification = classifySceneDataCoverage({
|
|
26
|
-
contributors: input.contributorIds.map((id) => ({ id, kind: "exact" })),
|
|
27
|
-
requiredContributorIds: input.requiredContributorIds
|
|
28
|
-
});
|
|
29
|
-
return Object.freeze({
|
|
30
|
-
schema: input.schema,
|
|
31
|
-
lane: input.lane,
|
|
32
|
-
producerId: input.producerId,
|
|
33
|
-
...classification,
|
|
34
|
-
contributorIds: Object.freeze([...input.contributorIds])
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
5
|
var TEMPORAL_JITTER_SAMPLE_COUNT = 8;
|
|
6
|
+
var TEMPORAL_TAAU_DEPENDENCY_STATUS = "available";
|
|
38
7
|
function temporalViewId(worldId, entityKey) {
|
|
39
8
|
const raw = entityKey >>> 0;
|
|
40
9
|
const index = raw & 16777215;
|
|
@@ -95,8 +64,8 @@ function projectTemporalView(input) {
|
|
|
95
64
|
const viewId = temporalViewId(camera.worldId ?? 0, camera.entityKey ?? 0);
|
|
96
65
|
const currentJitterUv = temporalJitterUv(
|
|
97
66
|
input.temporalFrameIndex,
|
|
98
|
-
input.surfaceWidth,
|
|
99
|
-
input.surfaceHeight
|
|
67
|
+
input.internalWidth ?? input.surfaceWidth,
|
|
68
|
+
input.internalHeight ?? input.surfaceHeight
|
|
100
69
|
);
|
|
101
70
|
const view = mat4.invert(mat4.create(), camera.world);
|
|
102
71
|
const projection = cameraProjection(camera);
|
|
@@ -115,6 +84,8 @@ function projectTemporalView(input) {
|
|
|
115
84
|
historyValid,
|
|
116
85
|
resetReason: reason,
|
|
117
86
|
currentJitterUv,
|
|
87
|
+
internalWidth: input.internalWidth ?? input.surfaceWidth,
|
|
88
|
+
internalHeight: input.internalHeight ?? input.surfaceHeight,
|
|
118
89
|
previousJitterUv: historyValid ? input.lastSubmitted?.jitterUv ?? currentJitterUv : currentJitterUv,
|
|
119
90
|
currentJitteredViewProjection,
|
|
120
91
|
currentUnjitteredViewProjection,
|
|
@@ -231,6 +202,7 @@ var TemporalFrameCoordinator = class {
|
|
|
231
202
|
historyStore;
|
|
232
203
|
epoch;
|
|
233
204
|
previous;
|
|
205
|
+
consumerIds = [];
|
|
234
206
|
active;
|
|
235
207
|
attempt = "none";
|
|
236
208
|
historyAttempt = "none";
|
|
@@ -251,7 +223,8 @@ var TemporalFrameCoordinator = class {
|
|
|
251
223
|
this.previous = initial.previous;
|
|
252
224
|
}
|
|
253
225
|
begin(input) {
|
|
254
|
-
const
|
|
226
|
+
const consumerIds = Object.freeze([...input.consumerIds ?? []]);
|
|
227
|
+
const demanded = input.antialias === "taa" || input.temporalDemand === true || consumerIds.length > 0;
|
|
255
228
|
if (!demanded) {
|
|
256
229
|
return ok({
|
|
257
230
|
epoch: this.epoch,
|
|
@@ -260,6 +233,7 @@ var TemporalFrameCoordinator = class {
|
|
|
260
233
|
history: { direction: this.historyDirection, valid: false },
|
|
261
234
|
contributors: Object.freeze([...input.contributors ?? []]),
|
|
262
235
|
requiredContributorIds: Object.freeze([...input.requiredContributorIds ?? []]),
|
|
236
|
+
consumerIds,
|
|
263
237
|
...input.temporalView === void 0 ? {} : { temporalView: input.temporalView }
|
|
264
238
|
});
|
|
265
239
|
}
|
|
@@ -283,6 +257,7 @@ var TemporalFrameCoordinator = class {
|
|
|
283
257
|
history: { direction: this.historyDirection, valid: this.previous !== void 0 },
|
|
284
258
|
contributors: Object.freeze([...input.contributors ?? []]),
|
|
285
259
|
requiredContributorIds: Object.freeze([...input.requiredContributorIds ?? []]),
|
|
260
|
+
consumerIds,
|
|
286
261
|
...input.temporalView === void 0 ? {} : { temporalView: input.temporalView }
|
|
287
262
|
};
|
|
288
263
|
if (input.antialias === "taa") {
|
|
@@ -305,6 +280,7 @@ var TemporalFrameCoordinator = class {
|
|
|
305
280
|
this.temporalFrameIndex += 1;
|
|
306
281
|
}
|
|
307
282
|
this.historyDirection = candidate.history.direction === "a-to-b" ? "b-to-a" : "a-to-b";
|
|
283
|
+
this.consumerIds = candidate.consumerIds;
|
|
308
284
|
const historyAttempt = this.historyAttempts.get(candidate);
|
|
309
285
|
historyAttempt?.commit({
|
|
310
286
|
deviceGeneration: this.historyStore.inspect().deviceGeneration,
|
|
@@ -338,7 +314,9 @@ var TemporalFrameCoordinator = class {
|
|
|
338
314
|
const started = this.begin(input);
|
|
339
315
|
if (!started.ok) return started;
|
|
340
316
|
const candidate = started.value;
|
|
341
|
-
if (input.antialias !== "taa" && input.temporalDemand !== true
|
|
317
|
+
if (input.antialias !== "taa" && input.temporalDemand !== true && (input.consumerIds?.length ?? 0) === 0) {
|
|
318
|
+
return ok(void 0);
|
|
319
|
+
}
|
|
342
320
|
try {
|
|
343
321
|
const built = phases.build();
|
|
344
322
|
phases.encode(built);
|
|
@@ -360,6 +338,7 @@ var TemporalFrameCoordinator = class {
|
|
|
360
338
|
return {
|
|
361
339
|
epoch: this.epoch,
|
|
362
340
|
previous: this.previous,
|
|
341
|
+
consumerIds: this.consumerIds,
|
|
363
342
|
historyAttempt: this.historyAttempt,
|
|
364
343
|
attempt: this.attempt,
|
|
365
344
|
lastFailure: this.lastFailure,
|
|
@@ -401,6 +380,7 @@ var TemporalFrameCoordinator = class {
|
|
|
401
380
|
missingContributorIds: [],
|
|
402
381
|
omittedMissingContributorCount: 0
|
|
403
382
|
};
|
|
383
|
+
this.consumerIds = [];
|
|
404
384
|
}
|
|
405
385
|
stageFromError(cause) {
|
|
406
386
|
if (typeof cause === "object" && cause !== null && "stage" in cause) {
|
|
@@ -412,6 +392,6 @@ var TemporalFrameCoordinator = class {
|
|
|
412
392
|
}
|
|
413
393
|
};
|
|
414
394
|
|
|
415
|
-
export { TEMPORAL_JITTER_SAMPLE_COUNT,
|
|
416
|
-
//# sourceMappingURL=chunk-
|
|
417
|
-
//# sourceMappingURL=chunk-
|
|
395
|
+
export { TEMPORAL_JITTER_SAMPLE_COUNT, TEMPORAL_TAAU_DEPENDENCY_STATUS, TemporalFrameCoordinator, projectTemporalView, snapshotSubmittedTemporalView, temporalJitterSample, temporalViewId };
|
|
396
|
+
//# sourceMappingURL=chunk-MDQJPY3T.mjs.map
|
|
397
|
+
//# sourceMappingURL=chunk-MDQJPY3T.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/temporal/temporal-view.ts","../src/temporal/taa-history-store.ts","../src/temporal/frame-coordinator.ts"],"names":[],"mappings":"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","file":"chunk-MDQJPY3T.mjs","sourcesContent":["import { mat4 } from '@forgeax/engine-math';\nimport type { CameraProjection } from '../components/camera';\nimport type { CameraSnapshot } from '../render-contract';\n\nexport const TEMPORAL_JITTER_SAMPLE_COUNT = 8;\n\n/** TAAU shares the temporal view owner; its internal dimensions are optional. */\nexport const TEMPORAL_TAAU_DEPENDENCY_STATUS = 'available' as const;\n\nexport type TemporalViewResetReason =\n | 'first-frame'\n | 'camera-switch'\n | 'history-version-changed'\n | 'projection-kind-changed'\n | 'projection-range-changed';\n\nexport interface SubmittedTemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n readonly jitterUv: readonly [number, number];\n readonly unjitteredViewProjection: Float32Array;\n}\n\nexport interface TemporalView {\n readonly viewId: string;\n readonly historyVersion: number;\n readonly temporalFrameIndex: number;\n readonly historyValid: boolean;\n readonly resetReason: TemporalViewResetReason | undefined;\n readonly currentJitterUv: readonly [number, number];\n readonly internalWidth: number;\n readonly internalHeight: number;\n readonly previousJitterUv: readonly [number, number];\n readonly currentJitteredViewProjection: Float32Array;\n readonly currentUnjitteredViewProjection: Float32Array;\n readonly previousUnjitteredViewProjection: Float32Array;\n readonly projection: CameraProjection;\n readonly near: number;\n readonly far: number;\n}\n\nexport interface TemporalViewInput {\n readonly camera: CameraSnapshot;\n readonly temporalFrameIndex: number;\n readonly surfaceWidth: number;\n readonly surfaceHeight: number;\n readonly internalWidth?: number;\n readonly internalHeight?: number;\n readonly lastSubmitted?: SubmittedTemporalView;\n}\n\nexport function temporalViewId(worldId: number, entityKey: number): string {\n const raw = entityKey >>> 0;\n const index = raw & 0x00ffffff;\n const generation = (raw >>> 24) & 0xff;\n return `${worldId}:${index}:${generation}`;\n}\n\nfunction halton(index: number, base: number): number {\n let result = 0;\n let fraction = 1 / base;\n let value = index;\n while (value > 0) {\n result += fraction * (value % base);\n value = Math.floor(value / base);\n fraction /= base;\n }\n return result;\n}\n\nexport function temporalJitterSample(temporalFrameIndex: number): readonly [number, number] {\n const sampleIndex =\n ((Math.trunc(temporalFrameIndex) % TEMPORAL_JITTER_SAMPLE_COUNT) +\n TEMPORAL_JITTER_SAMPLE_COUNT) %\n TEMPORAL_JITTER_SAMPLE_COUNT;\n const haltonIndex = sampleIndex + 1;\n return [halton(haltonIndex, 2) - 0.5, halton(haltonIndex, 3) - 0.5];\n}\n\nfunction temporalJitterUv(\n temporalFrameIndex: number,\n surfaceWidth: number,\n surfaceHeight: number,\n): readonly [number, number] {\n const sample = temporalJitterSample(temporalFrameIndex);\n return [sample[0] / Math.max(1, surfaceWidth), sample[1] / Math.max(1, surfaceHeight)];\n}\n\nfunction cameraProjection(camera: CameraSnapshot): Float32Array {\n const projection = mat4.create();\n if (camera.projection === 'orthographic') {\n mat4.orthographic(\n projection,\n camera.orthoLeft,\n camera.orthoRight,\n camera.orthoTop,\n camera.orthoBottom,\n camera.near,\n camera.far,\n );\n } else {\n mat4.perspective(projection, camera.fov, camera.aspect, camera.near, camera.far);\n }\n return projection;\n}\n\nfunction resetReason(\n current: CameraSnapshot,\n viewId: string,\n previous: SubmittedTemporalView | undefined,\n): TemporalViewResetReason | undefined {\n if (previous === undefined) return 'first-frame';\n if (previous.viewId !== viewId) return 'camera-switch';\n if (previous.historyVersion !== (current.historyVersion ?? 0)) {\n return 'history-version-changed';\n }\n if (previous.projection !== current.projection) return 'projection-kind-changed';\n if (!Object.is(previous.near, current.near) || !Object.is(previous.far, current.far)) {\n return 'projection-range-changed';\n }\n return undefined;\n}\n\nexport function projectTemporalView(input: TemporalViewInput): TemporalView {\n const { camera } = input;\n const viewId = temporalViewId(camera.worldId ?? 0, camera.entityKey ?? 0);\n const currentJitterUv = temporalJitterUv(\n input.temporalFrameIndex,\n input.internalWidth ?? input.surfaceWidth,\n input.internalHeight ?? input.surfaceHeight,\n );\n const view = mat4.invert(mat4.create(), camera.world);\n const projection = cameraProjection(camera);\n const currentUnjitteredViewProjection = mat4.multiply(mat4.create(), projection, view);\n const clipJitter = mat4.identity(mat4.create());\n clipJitter[12] = currentJitterUv[0] * 2;\n clipJitter[13] = currentJitterUv[1] * -2;\n const jitteredProjection = mat4.multiply(mat4.create(), clipJitter, projection);\n const currentJitteredViewProjection = mat4.multiply(mat4.create(), jitteredProjection, view);\n const reason = resetReason(camera, viewId, input.lastSubmitted);\n const historyValid = reason === undefined;\n return {\n viewId,\n historyVersion: camera.historyVersion ?? 0,\n temporalFrameIndex: input.temporalFrameIndex,\n historyValid,\n resetReason: reason,\n currentJitterUv,\n internalWidth: input.internalWidth ?? input.surfaceWidth,\n internalHeight: input.internalHeight ?? input.surfaceHeight,\n previousJitterUv: historyValid\n ? (input.lastSubmitted?.jitterUv ?? currentJitterUv)\n : currentJitterUv,\n currentJitteredViewProjection,\n currentUnjitteredViewProjection,\n previousUnjitteredViewProjection: historyValid\n ? (input.lastSubmitted?.unjitteredViewProjection ?? currentUnjitteredViewProjection)\n : currentUnjitteredViewProjection,\n projection: camera.projection,\n near: camera.near,\n far: camera.far,\n };\n}\n\nexport function snapshotSubmittedTemporalView(view: TemporalView): SubmittedTemporalView {\n return {\n viewId: view.viewId,\n historyVersion: view.historyVersion,\n projection: view.projection,\n near: view.near,\n far: view.far,\n jitterUv: [view.currentJitterUv[0], view.currentJitterUv[1]],\n unjitteredViewProjection: new Float32Array(view.currentUnjitteredViewProjection),\n };\n}\n","export type TaaHistoryResetReason =\n | 'first-frame'\n | 'camera-cut'\n | 'resize'\n | 'recover'\n | 'device-generation';\n\nexport interface TaaHistoryInspection {\n readonly token: number;\n readonly deviceGeneration: number;\n readonly content: 'uninitialized' | 'active';\n readonly fallback: 'neutral-texture';\n readonly requestVersion: number;\n readonly generation: number;\n readonly seed: number;\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly valid: boolean;\n readonly resetReason: TaaHistoryResetReason | undefined;\n}\n\nexport interface TaaHistoryReceipt {\n readonly deviceGeneration: number;\n readonly completed: boolean;\n}\n\nexport interface TaaHistoryAttempt {\n readonly generation: number;\n readonly seed: number;\n commit(receipt?: TaaHistoryReceipt): void;\n abort(): void;\n}\n\nlet nextHistoryToken = 1;\n\n/** TAA-only history owner. No global registry or backend handle crosses this boundary. */\nexport class TaaHistoryStore {\n private readonly token = nextHistoryToken++;\n private deviceGeneration = 0;\n private content: TaaHistoryInspection['content'] = 'uninitialized';\n private requestVersion = 0;\n private generation = 0;\n private seed = 0;\n private valid = false;\n private attempt: TaaHistoryInspection['attempt'] = 'none';\n private resetReason: TaaHistoryResetReason | undefined;\n\n begin(reason: TaaHistoryResetReason | undefined = undefined): TaaHistoryAttempt {\n const generation = this.generation;\n const seed = this.seed;\n this.attempt = 'active';\n let state: 'active' | 'committed' | 'aborted' = 'active';\n return {\n generation,\n seed,\n commit: (receipt) => {\n if (state !== 'active') return;\n if (\n receipt !== undefined &&\n (!receipt.completed || receipt.deviceGeneration !== this.deviceGeneration)\n ) {\n state = 'aborted';\n this.attempt = 'aborted';\n return;\n }\n state = 'committed';\n this.attempt = 'committed';\n this.valid = true;\n this.content = 'active';\n this.requestVersion += 1;\n this.generation += 1;\n this.seed += 1;\n this.resetReason = reason;\n },\n abort: () => {\n if (state !== 'active') return;\n state = 'aborted';\n this.attempt = 'aborted';\n },\n };\n }\n\n seedHistory(reason: TaaHistoryResetReason = 'first-frame'): void {\n this.valid = false;\n this.content = 'uninitialized';\n this.resetReason = reason;\n this.attempt = 'none';\n }\n\n reset(reason: TaaHistoryResetReason): void {\n this.generation = 0;\n this.seed = 0;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = reason;\n }\n\n recoverForGeneration(deviceGeneration: number): void {\n if (!Number.isSafeInteger(deviceGeneration) || deviceGeneration < 0) {\n throw new RangeError('deviceGeneration must be a non-negative safe integer.');\n }\n this.deviceGeneration = deviceGeneration;\n this.valid = false;\n this.content = 'uninitialized';\n this.attempt = 'none';\n this.resetReason = 'device-generation';\n }\n\n inspect(): TaaHistoryInspection {\n return {\n token: this.token,\n deviceGeneration: this.deviceGeneration,\n content: this.content,\n fallback: 'neutral-texture',\n requestVersion: this.requestVersion,\n generation: this.generation,\n seed: this.seed,\n attempt: this.attempt,\n valid: this.valid,\n resetReason: this.resetReason,\n };\n }\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport type { CameraSnapshot } from '../render-contract';\nimport { classifySceneDataCoverage, type SceneDataContributor } from './coverage';\nimport { type TaaHistoryAttempt, TaaHistoryStore } from './taa-history-store';\nimport {\n projectTemporalView,\n type SubmittedTemporalView,\n snapshotSubmittedTemporalView,\n type TemporalView,\n} from './temporal-view';\n\n/** The only stages that may publish a temporal frame. */\nexport type TemporalFrameStage = 'build' | 'encode' | 'finish' | 'submit';\n\n/** Closed list of consumers that share the renderer temporal transaction. */\nexport type TemporalFrameConsumerId = 'taa' | 'motion-blur' | 'ssr';\n\nexport type TemporalFrameErrorCode = 'taa-unavailable' | 'temporal-active' | 'temporal-not-active';\n\nexport interface TemporalFrameError {\n readonly code: TemporalFrameErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nexport interface TemporalFrameSnapshot<T = unknown> {\n readonly epoch: number;\n readonly previous: T | undefined;\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly historyAttempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly attempt: 'none' | 'active' | 'committed' | 'aborted';\n readonly lastFailure: TemporalFrameStage | undefined;\n readonly coverage: {\n readonly exactContributorIds: readonly string[];\n readonly reactiveContributorIds: readonly string[];\n readonly missingContributorIds: readonly string[];\n readonly omittedMissingContributorCount: number;\n };\n}\n\nexport interface TemporalFrameBeginInput<T = unknown> {\n readonly current: T;\n readonly antialias: 'none' | 'fxaa' | 'msaa' | 'taa';\n /** Enables the shared transaction for a temporal feature without TAA. */\n readonly temporalDemand?: boolean;\n /** Consumers registered on this one renderer-owned frame transaction. */\n readonly consumerIds?: readonly TemporalFrameConsumerId[];\n readonly available?: boolean;\n readonly contributors?: readonly SceneDataContributor[];\n readonly requiredContributorIds?: readonly string[];\n /** Projection produced before record uploads; it commits with the frame. */\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFrameCandidate<T = unknown> {\n readonly epoch: number;\n readonly current: T;\n readonly previous: T | undefined;\n readonly history: { readonly direction: 'a-to-b' | 'b-to-a'; readonly valid: boolean };\n readonly contributors: readonly SceneDataContributor[];\n readonly requiredContributorIds: readonly string[];\n readonly consumerIds: readonly TemporalFrameConsumerId[];\n readonly temporalView?: TemporalView;\n}\n\nexport interface TemporalFramePhases<T = unknown> {\n readonly build: () => T;\n readonly encode: (built: T) => void;\n readonly finish: () => void;\n readonly submit: () => void;\n}\n\nexport interface TemporalFrameReceipt<T = unknown> {\n readonly epoch: number;\n readonly previous: T;\n readonly historyDirection: 'a-to-b' | 'b-to-a';\n}\n\nexport type ReflectionFallbackTemporalReset =\n | { readonly reset: false }\n | { readonly reset: true; readonly reason: 'reflection-fallback-generation' };\n\n/** Maps committed producer generations into the existing temporal reset seam. */\nexport function resolveReflectionFallbackTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n if (previousGeneration === undefined || nextGeneration === undefined) return { reset: false };\n return previousGeneration === nextGeneration\n ? { reset: false }\n : { reset: true, reason: 'reflection-fallback-generation' };\n}\n\n/**\n * Keeps SSR admission on the existing producer-generation reset seam. The\n * admission path never allocates or resolves temporal history itself.\n */\nexport function resolveSsrAdmissionTemporalReset(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): ReflectionFallbackTemporalReset {\n return resolveReflectionFallbackTemporalReset(previousGeneration, nextGeneration);\n}\n\nfunction failure(code: TemporalFrameErrorCode, hint: string): TemporalFrameError {\n return {\n code,\n expected:\n code === 'taa-unavailable'\n ? 'TAA resources and capability are available'\n : 'one temporal frame is active',\n hint,\n };\n}\n\n/**\n * Renderer-owned temporal transaction. It has no graph or backend dependency:\n * graph assembly supplies the four phase callbacks and only submit publishes\n * the candidate snapshot.\n */\nexport class TemporalFrameCoordinator<T = unknown> {\n readonly historyStore: TaaHistoryStore;\n private epoch: number;\n private previous: T | undefined;\n private consumerIds: readonly TemporalFrameConsumerId[] = [];\n private active: TemporalFrameCandidate<T> | undefined;\n private attempt: TemporalFrameSnapshot<T>['attempt'] = 'none';\n private historyAttempt: TemporalFrameSnapshot<T>['historyAttempt'] = 'none';\n private lastFailure: TemporalFrameStage | undefined;\n private historyDirection: 'a-to-b' | 'b-to-a' = 'a-to-b';\n private temporalFrameIndex = 0;\n private lastSubmittedView: SubmittedTemporalView | undefined;\n private coverage: TemporalFrameSnapshot<T>['coverage'] = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n private readonly historyAttempts = new WeakMap<object, TaaHistoryAttempt>();\n\n constructor(\n initial: {\n readonly epoch?: number;\n readonly previous?: T;\n readonly historyStore?: TaaHistoryStore;\n } = {},\n ) {\n this.historyStore = initial.historyStore ?? new TaaHistoryStore();\n this.epoch = initial.epoch ?? 0;\n this.previous = initial.previous;\n }\n\n begin(input: TemporalFrameBeginInput<T>): Result<TemporalFrameCandidate<T>, TemporalFrameError> {\n const consumerIds = Object.freeze([...(input.consumerIds ?? [])]);\n const demanded =\n input.antialias === 'taa' || input.temporalDemand === true || consumerIds.length > 0;\n if (!demanded) {\n return ok({\n epoch: this.epoch,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: false },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n });\n }\n if (input.available === false) {\n return err(\n failure('taa-unavailable', 'enable rgba16float temporal targets and retry the frame'),\n );\n }\n if (this.active !== undefined) {\n return err(\n failure(\n 'temporal-active',\n 'commit or abort the active temporal frame before beginning another',\n ),\n );\n }\n const candidate: TemporalFrameCandidate<T> = {\n epoch: this.epoch + 1,\n current: input.current,\n previous: this.previous,\n history: { direction: this.historyDirection, valid: this.previous !== undefined },\n contributors: Object.freeze([...(input.contributors ?? [])]),\n requiredContributorIds: Object.freeze([...(input.requiredContributorIds ?? [])]),\n consumerIds,\n ...(input.temporalView === undefined ? {} : { temporalView: input.temporalView }),\n };\n if (input.antialias === 'taa') {\n this.historyAttempts.set(candidate, this.historyStore.begin());\n }\n this.active = candidate;\n this.attempt = 'active';\n this.historyAttempt = input.antialias === 'taa' ? 'active' : 'none';\n this.lastFailure = undefined;\n return ok(candidate);\n }\n\n commit(\n candidate: TemporalFrameCandidate<T>,\n ): Result<TemporalFrameReceipt<T>, TemporalFrameError> {\n if (this.active !== candidate) {\n return err(failure('temporal-not-active', 'commit the candidate returned by begin'));\n }\n this.epoch = candidate.epoch;\n this.previous = candidate.current;\n if (candidate.temporalView !== undefined) {\n this.lastSubmittedView = snapshotSubmittedTemporalView(candidate.temporalView);\n this.temporalFrameIndex += 1;\n }\n this.historyDirection = candidate.history.direction === 'a-to-b' ? 'b-to-a' : 'a-to-b';\n this.consumerIds = candidate.consumerIds;\n const historyAttempt = this.historyAttempts.get(candidate);\n historyAttempt?.commit({\n deviceGeneration: this.historyStore.inspect().deviceGeneration,\n completed: true,\n });\n this.coverage = classifySceneDataCoverage({\n contributors: candidate.contributors,\n requiredContributorIds: candidate.requiredContributorIds,\n });\n this.active = undefined;\n historyAttempt?.abort();\n this.historyAttempts.delete(candidate);\n this.attempt = 'committed';\n this.historyAttempt = historyAttempt === undefined ? 'none' : 'committed';\n return ok({\n epoch: this.epoch,\n previous: candidate.current,\n historyDirection: candidate.history.direction,\n });\n }\n\n abort(candidate: TemporalFrameCandidate<T>, stage: TemporalFrameStage = 'submit'): void {\n if (this.active !== candidate) return;\n this.historyAttempts.get(candidate)?.abort();\n this.historyAttempts.delete(candidate);\n this.active = undefined;\n this.attempt = 'aborted';\n this.historyAttempt = 'aborted';\n this.lastFailure = stage;\n }\n\n run(\n input: TemporalFrameBeginInput<T>,\n phases: TemporalFramePhases<T>,\n ): Result<TemporalFrameReceipt<T> | undefined, TemporalFrameError> {\n const started = this.begin(input);\n if (!started.ok) return started;\n const candidate = started.value;\n if (\n input.antialias !== 'taa' &&\n input.temporalDemand !== true &&\n (input.consumerIds?.length ?? 0) === 0\n ) {\n return ok(undefined);\n }\n try {\n const built = phases.build();\n phases.encode(built);\n phases.finish();\n phases.submit();\n } catch (cause) {\n const stage = this.stageFromError(cause);\n this.abort(candidate, stage);\n return err({\n code: 'temporal-not-active',\n expected: `temporal ${stage} succeeds before commit`,\n hint: 'inspect the underlying stage failure and retry the frame',\n detail: { stage, cause },\n });\n }\n return this.commit(candidate);\n }\n\n inspect(): TemporalFrameSnapshot<T> {\n return {\n epoch: this.epoch,\n previous: this.previous,\n consumerIds: this.consumerIds,\n historyAttempt: this.historyAttempt,\n attempt: this.attempt,\n lastFailure: this.lastFailure,\n coverage: this.coverage,\n };\n }\n\n /**\n * Derive the current/previous camera matrices without mutating history.\n * `commit()` is the only operation that publishes the returned view, so a\n * graph/finish/submit failure leaves the last successful view intact.\n */\n prepareTemporalView(\n camera: CameraSnapshot,\n surfaceWidth: number,\n surfaceHeight: number,\n ): TemporalView | undefined {\n const demanded =\n camera.antialias === 'taa' ||\n (camera.motionBlur?.shutterAngle !== undefined && camera.motionBlur.shutterAngle > 0);\n if (!demanded) return undefined;\n return projectTemporalView({\n camera,\n temporalFrameIndex: this.temporalFrameIndex,\n surfaceWidth,\n surfaceHeight,\n ...(this.lastSubmittedView === undefined ? {} : { lastSubmitted: this.lastSubmittedView }),\n });\n }\n\n reset(\n reason:\n | 'cut'\n | 'resize'\n | 'camera-switch'\n | 'detach'\n | 'recover'\n | 'device-loss'\n | 'device-generation' = 'recover',\n ): void {\n void reason;\n this.active = undefined;\n this.epoch = 0;\n this.previous = undefined;\n this.temporalFrameIndex = 0;\n this.lastSubmittedView = undefined;\n this.historyDirection = 'a-to-b';\n this.historyStore.reset(\n reason === 'cut' || reason === 'camera-switch'\n ? 'camera-cut'\n : reason === 'resize'\n ? 'resize'\n : reason === 'device-generation' || reason === 'device-loss'\n ? 'device-generation'\n : 'recover',\n );\n this.attempt = 'none';\n this.historyAttempt = 'none';\n this.lastFailure = undefined;\n this.coverage = {\n exactContributorIds: [],\n reactiveContributorIds: [],\n missingContributorIds: [],\n omittedMissingContributorCount: 0,\n };\n this.consumerIds = [];\n }\n\n private stageFromError(cause: unknown): TemporalFrameStage {\n if (typeof cause === 'object' && cause !== null && 'stage' in cause) {\n const stage = (cause as { stage?: unknown }).stage;\n if (stage === 'build' || stage === 'encode' || stage === 'finish' || stage === 'submit')\n return stage;\n }\n return 'submit';\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RenderFeaturePreparedStateMismatchError, SceneDataUnavailableError } from './chunk-
|
|
1
|
+
import { RenderFeaturePreparedStateMismatchError, SceneDataUnavailableError } from './chunk-JRBDO2KB.mjs';
|
|
2
2
|
import { err, ok } from '@forgeax/engine-types';
|
|
3
3
|
|
|
4
4
|
// src/pipeline/standard-lighting/layout.ts
|
|
@@ -292,5 +292,5 @@ function createSceneDataCatalog(options) {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
export { CLUSTER_GRID_STRIDE_U32, DEFAULT_CLUSTER_GRID, DEFAULT_STANDARD_PROFILE, LIGHT_INDEX_LIST_CAPACITY, MAX_LIGHTS, REFLECTION_PROBE_IBL_STAGES, SCENE_DATA_TEMPORAL_V1_DESCRIPTOR, SCENE_DATA_TEMPORAL_V1_SCHEMA, STANDARD_LIGHT_COUNTS, STANDARD_PIPELINE_ID, STANDARD_POST_STAGE_NAMES, beginProbeIblUpdate, createIblKernelCache, createProbeIblOutput, createSceneDataCatalog, createStandardClusterLayout, isSceneDataTarget, publishProbeIblOutput, registerSceneDataTarget, resetIblKernelCaches, resolveVolumetricFogProfile, sceneDataError, sceneDataTargetAsAttachment, sceneDataTargetOwner, sceneDataTokenMismatch };
|
|
295
|
-
//# sourceMappingURL=chunk-
|
|
296
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-NO4WZCAH.mjs.map
|
|
296
|
+
//# sourceMappingURL=chunk-NO4WZCAH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pipeline/standard-lighting/layout.ts","../src/pipeline/standard-profile.ts","../src/ibl/kernel-cache.ts","../src/temporal/scene-data.ts","../src/temporal/scene-data-catalog.ts"],"names":[],"mappings":"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","file":"chunk-NO4WZCAH.mjs","sourcesContent":["export const DEFAULT_CLUSTER_GRID = { x: 16, y: 9, z: 24 } as const;\nexport const CLUSTER_GRID_STRIDE_U32 = 2 as const;\nexport const LIGHT_INDEX_LIST_CAPACITY = 1048576 as const;\nexport const MAX_LIGHTS = 256 as const;\n\nexport interface StandardClusterLayout {\n readonly grid: { readonly x: number; readonly y: number; readonly z: number };\n readonly clusterCount: number;\n readonly clusterGridStrideU32: typeof CLUSTER_GRID_STRIDE_U32;\n readonly clusterGridU32Length: number;\n readonly lightIndexListCapacity: typeof LIGHT_INDEX_LIST_CAPACITY;\n readonly lightDataSlotCount: typeof MAX_LIGHTS;\n readonly lightBoundsInt32Length: number;\n}\n\nexport function createStandardClusterLayout(\n grid: { readonly x: number; readonly y: number; readonly z: number } = DEFAULT_CLUSTER_GRID,\n): StandardClusterLayout {\n const clusterCount = grid.x * grid.y * grid.z;\n return Object.freeze({\n grid,\n clusterCount,\n clusterGridStrideU32: CLUSTER_GRID_STRIDE_U32,\n clusterGridU32Length: clusterCount * CLUSTER_GRID_STRIDE_U32,\n lightIndexListCapacity: LIGHT_INDEX_LIST_CAPACITY,\n lightDataSlotCount: MAX_LIGHTS,\n lightBoundsInt32Length: MAX_LIGHTS * 6,\n });\n}\n\nexport const STANDARD_CLUSTER_LAYOUT = createStandardClusterLayout();\n","import type { SsaoParameterConfig } from '../ssao-config';\nexport const STANDARD_PIPELINE_ID = 'forgeax::standard' as const;\nexport const STANDARD_LIGHT_COUNTS = [1, 32, 256] as const;\nexport {\n CLUSTER_GRID_STRIDE_U32,\n DEFAULT_CLUSTER_GRID,\n LIGHT_INDEX_LIST_CAPACITY,\n MAX_LIGHTS,\n} from './standard-lighting/layout';\n\nexport type StandardLightCount = (typeof STANDARD_LIGHT_COUNTS)[number];\nexport type StandardShadowMode = 'off' | 'hard' | 'filtered';\nexport type StandardVolumetricFogQuality = 'low' | 'high';\n\nexport interface StandardVolumetricFogProfile {\n readonly quality: StandardVolumetricFogQuality;\n readonly depth: 48 | 64;\n readonly tileSize: 4 | 16;\n}\n\nexport const STANDARD_POST_STAGE_NAMES = [\n 'transparent-blend',\n 'bloom',\n 'output-transform',\n 'fxaa',\n 'post-effect',\n 'present',\n] as const;\nexport type StandardPostStage = (typeof STANDARD_POST_STAGE_NAMES)[number];\nexport interface StandardProfile {\n readonly pipelineId: typeof STANDARD_PIPELINE_ID;\n readonly lightCount: StandardLightCount;\n /** Graph topology selector; all local lights use the shared Cluster path. */\n readonly renderPath: 'forward' | 'deferred';\n readonly shadows: StandardShadowMode;\n readonly pbr: boolean;\n readonly ibl: boolean;\n readonly ssao: boolean | SsaoParameterConfig;\n /** Renderer-owned 1080p volume profile; tile width/height remain surface-derived. */\n readonly volumetricFog?: StandardVolumetricFogProfile | undefined;\n readonly postStages: typeof STANDARD_POST_STAGE_NAMES;\n}\n\nexport const DEFAULT_STANDARD_PROFILE: StandardProfile = Object.freeze({\n pipelineId: STANDARD_PIPELINE_ID,\n lightCount: 32,\n renderPath: 'forward',\n shadows: 'filtered',\n pbr: true,\n ibl: true,\n ssao: false,\n postStages: STANDARD_POST_STAGE_NAMES,\n});\n\nexport function resolveVolumetricFogProfile(\n profile: Pick<StandardProfile, 'volumetricFog'>,\n): StandardVolumetricFogProfile {\n return profile.volumetricFog ?? { quality: 'high', depth: 64, tileSize: 4 };\n}\n","export const REFLECTION_PROBE_IBL_STAGES = ['raw', 'filtered', 'publish'] as const;\nexport type ReflectionProbeIblStage = (typeof REFLECTION_PROBE_IBL_STAGES)[number];\n\nexport interface IblKernelCache {\n readonly generation: number;\n readonly pipelineIdentity: object;\n readonly samplerIdentity: object;\n readonly brdfLutIdentity: object;\n}\n\nconst kernelCaches = new Map<number, IblKernelCache>();\n\nexport function createIblKernelCache(generation: number): IblKernelCache {\n const existing = kernelCaches.get(generation);\n if (existing !== undefined) return existing;\n const created: IblKernelCache = {\n generation,\n pipelineIdentity: {},\n samplerIdentity: {},\n brdfLutIdentity: {},\n };\n kernelCaches.set(generation, created);\n return created;\n}\n\nexport interface ProbeIblOutput {\n readonly entityKey: number;\n readonly resolution: number;\n readonly deviceGeneration: number;\n readonly raw: object;\n readonly filtered: object;\n readonly rawGeneration: number;\n readonly filteredGeneration: number;\n readonly lkg: boolean;\n}\n\nexport interface ProbeIblUpdate extends ProbeIblOutput {\n readonly stages: typeof REFLECTION_PROBE_IBL_STAGES;\n readonly nextStage: ReflectionProbeIblStage;\n readonly candidateGeneration: number;\n}\n\nexport function createProbeIblOutput(input: {\n readonly entityKey: number;\n readonly resolution: number;\n readonly deviceGeneration: number;\n}): ProbeIblOutput {\n return {\n ...input,\n raw: {},\n filtered: {},\n rawGeneration: 0,\n filteredGeneration: 0,\n lkg: true,\n };\n}\n\nexport function beginProbeIblUpdate(output: ProbeIblOutput): ProbeIblUpdate {\n return {\n ...output,\n stages: REFLECTION_PROBE_IBL_STAGES,\n nextStage: 'raw',\n candidateGeneration: output.filteredGeneration + 1,\n };\n}\n\nexport function publishProbeIblOutput(\n update: ProbeIblUpdate,\n result: { readonly stage: ReflectionProbeIblStage; readonly ok: boolean },\n): ProbeIblOutput {\n if (!result.ok || result.stage !== update.nextStage) return update;\n if (result.stage === 'raw') {\n return {\n ...update,\n rawGeneration: update.candidateGeneration,\n };\n }\n if (result.stage === 'filtered') return update;\n return {\n ...update,\n filteredGeneration: update.candidateGeneration,\n lkg: true,\n };\n}\n\nexport function resetIblKernelCaches(): void {\n kernelCaches.clear();\n}\n","import { type RenderError, RenderFeaturePreparedStateMismatchError } from '../errors/render';\nimport type { RenderFeatureTargetHandle } from '../features/targets';\n\n/** The closed semantic schema namespace published by the render owner. */\nexport const SCENE_DATA_TEMPORAL_V1_SCHEMA = 'forgeax::scene-data::temporal-v1' as const;\nexport type SceneDataSchemaId = typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n\nexport type SceneDataLane = 'direct' | 'clustered' | 'cpu-webgl2';\n\nexport interface SceneDataTemporalV1Descriptor {\n readonly schema: typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly format: 'rgba16float';\n readonly sampleCount: 1;\n readonly extent: 'render-resolution';\n readonly clearValue: readonly [0, 0, -1, 1];\n readonly channels: Readonly<{\n readonly motionUv: 'rg';\n readonly viewDepth: 'b-log2-1-plus-depth';\n readonly reactive: 'a';\n }>;\n}\n\nexport const SCENE_DATA_TEMPORAL_V1_DESCRIPTOR: SceneDataTemporalV1Descriptor = Object.freeze({\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n format: 'rgba16float',\n sampleCount: 1,\n extent: 'render-resolution',\n clearValue: [0, 0, -1, 1] as const,\n channels: Object.freeze({\n motionUv: 'rg',\n viewDepth: 'b-log2-1-plus-depth',\n reactive: 'a',\n }),\n});\n\n/** Opaque, sampled-read-only semantic data token. */\nexport interface SceneDataTarget<Schema extends SceneDataSchemaId = SceneDataSchemaId> {\n readonly kind: 'scene-data';\n readonly schema: Schema;\n readonly access: 'sampled-read';\n readonly format: 'rgba16float';\n readonly sampleCount: 1;\n readonly extent: 'render-resolution';\n readonly __sceneDataTarget: unique symbol;\n}\n\nexport type SceneDataTokenMismatch = RenderFeaturePreparedStateMismatchError;\n\nconst targetOwners = new WeakMap<object, SceneDataCatalogIdentity>();\n\nexport interface SceneDataCatalogIdentity {\n readonly featureIdentity: string;\n readonly planIdentity: string;\n readonly generation: number;\n}\n\nexport function registerSceneDataTarget(\n target: SceneDataTarget,\n owner: SceneDataCatalogIdentity,\n): void {\n targetOwners.set(target, owner);\n}\n\nexport function sceneDataTargetOwner(\n target: SceneDataTarget,\n): SceneDataCatalogIdentity | undefined {\n return typeof target === 'object' && target !== null ? targetOwners.get(target) : undefined;\n}\n\nexport function sceneDataTokenMismatch(\n operation: string,\n reason: 'foreign-feature' | 'foreign-kind' | 'generation-mismatch' | 'layout-mismatch',\n owner: SceneDataCatalogIdentity,\n target: Partial<SceneDataTarget> | undefined,\n): SceneDataTokenMismatch {\n const detail =\n reason === 'generation-mismatch'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedGeneration: owner.generation,\n actualGeneration: targetOwners.get(target as object)?.generation ?? -1,\n recovery: 'renderer-recover' as const,\n }\n : reason === 'foreign-feature'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedFeatureIdentity: owner.featureIdentity,\n actualFeatureIdentity: targetOwners.get(target as object)?.featureIdentity ?? 'unknown',\n recovery: 'next-frame' as const,\n }\n : reason === 'foreign-kind'\n ? {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedKind: 'attachment' as const,\n actualKind: 'pipeline' as const,\n recovery: 'next-frame' as const,\n }\n : {\n featureIdentity: owner.featureIdentity,\n order: -1,\n stage: 'contribute' as const,\n operation,\n resourceKind: 'attachment' as const,\n reason,\n expectedLayout: 'sampled-read-temporal-v1',\n actualLayout: target?.access ?? 'unknown',\n recovery: 'next-frame' as const,\n };\n return new RenderFeaturePreparedStateMismatchError(detail);\n}\n\nexport function isSceneDataTarget(value: unknown): value is SceneDataTarget {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as Partial<SceneDataTarget>;\n return (\n candidate.kind === 'scene-data' &&\n candidate.schema === SCENE_DATA_TEMPORAL_V1_SCHEMA &&\n candidate.access === 'sampled-read' &&\n candidate.format === 'rgba16float' &&\n candidate.sampleCount === 1 &&\n candidate.extent === 'render-resolution' &&\n targetOwners.has(value)\n );\n}\n\nexport function sceneDataTargetAsAttachment(_target: SceneDataTarget): never {\n throw new TypeError('SceneDataTarget is sampled-read-only and cannot be used as an attachment');\n}\n\nexport type SceneDataTargetInput = RenderFeatureTargetHandle | SceneDataTarget;\n\nexport function sceneDataError(error: SceneDataTokenMismatch): RenderError {\n return error;\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport type { RenderError } from '../errors/render';\nimport { SceneDataUnavailableError } from '../errors/render';\nimport {\n registerSceneDataTarget,\n SCENE_DATA_TEMPORAL_V1_DESCRIPTOR,\n SCENE_DATA_TEMPORAL_V1_SCHEMA,\n type SceneDataLane,\n type SceneDataSchemaId,\n type SceneDataTarget,\n sceneDataTargetOwner,\n sceneDataTokenMismatch,\n} from './scene-data';\n\nexport type SceneDataAvailability =\n | {\n readonly status: 'available';\n readonly completeness: 'exact' | 'exact-with-reactive-fallback';\n }\n | {\n readonly status: 'unavailable';\n readonly reason:\n | 'capability-missing'\n | 'producer-missing'\n | 'coverage-incomplete'\n | 'renderer-recovering';\n };\n\nexport interface SceneDataInspection {\n readonly schema: SceneDataSchemaId;\n readonly status: SceneDataAvailability['status'];\n readonly generation: number;\n readonly planIdentity: string;\n readonly lane: SceneDataLane;\n readonly completeness?: 'exact' | 'exact-with-reactive-fallback';\n readonly reason?: Exclude<SceneDataAvailability, { status: 'available' }>['reason'];\n readonly missingContributorIds: readonly string[];\n readonly omittedMissingContributorCount: number;\n}\n\nexport interface SceneDataCatalogOptions {\n readonly featureIdentity: string;\n readonly generation: number;\n readonly planIdentity: string;\n readonly lane?: SceneDataLane;\n readonly rgba16floatRenderable: boolean;\n readonly producerPresent?: boolean;\n readonly coverageComplete?: boolean;\n readonly recovering?: boolean;\n readonly reactiveFallback?: boolean;\n readonly missingContributorIds?: readonly string[];\n}\n\nexport interface SceneDataCatalog {\n readonly schema: typeof SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly generation: number;\n readonly planIdentity: string;\n readonly availability: SceneDataAvailability;\n require<Schema extends SceneDataSchemaId>(schema: Schema): SceneDataTarget<Schema>;\n validate(target: SceneDataTarget, generation?: number): Result<SceneDataTarget, RenderError>;\n inspect(): SceneDataInspection;\n}\n\nfunction availability(options: SceneDataCatalogOptions): SceneDataAvailability {\n if (options.recovering) return { status: 'unavailable', reason: 'renderer-recovering' };\n if (!options.rgba16floatRenderable)\n return { status: 'unavailable', reason: 'capability-missing' };\n if (options.producerPresent === false)\n return { status: 'unavailable', reason: 'producer-missing' };\n if (options.coverageComplete === false)\n return { status: 'unavailable', reason: 'coverage-incomplete' };\n return {\n status: 'available',\n completeness: options.reactiveFallback ? 'exact-with-reactive-fallback' : 'exact',\n };\n}\n\nfunction createTarget(owner: SceneDataCatalogOptions): SceneDataTarget {\n const target = Object.freeze({\n kind: 'scene-data' as const,\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n access: 'sampled-read' as const,\n format: 'rgba16float' as const,\n sampleCount: 1 as const,\n extent: 'render-resolution' as const,\n }) as SceneDataTarget;\n registerSceneDataTarget(target, {\n featureIdentity: owner.featureIdentity,\n planIdentity: owner.planIdentity,\n generation: owner.generation,\n });\n return target;\n}\n\nfunction tokenError(catalog: SceneDataCatalogOptions, operation: string): RenderError {\n return sceneDataTokenMismatch(\n operation,\n 'foreign-kind',\n {\n featureIdentity: catalog.featureIdentity,\n planIdentity: catalog.planIdentity,\n generation: catalog.generation,\n },\n undefined,\n );\n}\n\nfunction unavailableError(\n options: SceneDataCatalogOptions,\n reason: Exclude<SceneDataAvailability, { status: 'available' }>['reason'],\n): RenderError {\n const recovery =\n reason === 'capability-missing'\n ? 'enable-capability'\n : reason === 'renderer-recovering'\n ? 'renderer-recover'\n : 'next-frame';\n return new SceneDataUnavailableError({\n featureIdentity: options.featureIdentity,\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n lane: options.lane ?? 'direct',\n reason,\n missingContributorIds: options.missingContributorIds ?? [],\n omittedMissingContributorCount: 0,\n recovery,\n });\n}\n\nexport function createSceneDataCatalog(options: SceneDataCatalogOptions): SceneDataCatalog {\n const state = availability(options);\n const owner = {\n featureIdentity: options.featureIdentity,\n planIdentity: options.planIdentity,\n generation: options.generation,\n };\n const missing = [...(options.missingContributorIds ?? [])];\n const inspectionBase = {\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n generation: options.generation,\n planIdentity: options.planIdentity,\n lane: options.lane ?? 'direct',\n missingContributorIds: Object.freeze(missing.slice(0, 32)),\n omittedMissingContributorCount: Math.max(0, missing.length - 32),\n };\n return {\n schema: SCENE_DATA_TEMPORAL_V1_SCHEMA,\n generation: options.generation,\n planIdentity: options.planIdentity,\n availability: state,\n require(schema) {\n if (schema !== SCENE_DATA_TEMPORAL_V1_SCHEMA || state.status !== 'available') {\n if (state.status === 'unavailable') throw unavailableError(options, state.reason);\n throw tokenError(options, 'require scene-data target');\n }\n return createTarget(options) as SceneDataTarget<typeof schema>;\n },\n validate(target, generation = options.generation) {\n const targetOwner = sceneDataTargetOwner(target);\n if (targetOwner === undefined) {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'foreign-feature', owner, target),\n );\n }\n if (\n targetOwner.planIdentity !== owner.planIdentity ||\n targetOwner.featureIdentity !== owner.featureIdentity\n ) {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'foreign-feature', owner, target),\n );\n }\n if (generation !== owner.generation || targetOwner.generation !== owner.generation) {\n return err(\n sceneDataTokenMismatch(\n 'validate scene-data target',\n 'generation-mismatch',\n owner,\n target,\n ),\n );\n }\n if (target.access !== 'sampled-read') {\n return err(\n sceneDataTokenMismatch('validate scene-data target', 'layout-mismatch', owner, target),\n );\n }\n return ok(target);\n },\n inspect() {\n return Object.freeze(\n state.status === 'available'\n ? { ...inspectionBase, status: state.status, completeness: state.completeness }\n : { ...inspectionBase, status: state.status, reason: state.reason },\n );\n },\n };\n}\n\nexport { SCENE_DATA_TEMPORAL_V1_SCHEMA } from './scene-data';\nexport { SCENE_DATA_TEMPORAL_V1_DESCRIPTOR };\n"]}
|
|
@@ -54,5 +54,5 @@ function selectActiveCameraIndex(cameraEntities, activeEntity) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export { SpriteAnimation, SpriteInstances, SpriteRegionOverride, TileLayer, Tilemap, TilemapSort, decodeSortScope, getActiveCamera, selectActiveCameraIndex, setActiveCamera };
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-PA5DRJNI.mjs.map
|
|
58
|
+
//# sourceMappingURL=chunk-PA5DRJNI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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","../src/systems/active-camera.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;;;ACYM,IAAM,iBAAA,GAAoB,cAAA;AAkB1B,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,IAAI,CAAC,KAAA,CAAM,WAAA,CAAY,iBAAiB,GAAG,OAAO,MAAA;AAClD,EAAA,OAAO,KAAA,CAAM,YAA0B,iBAAiB,CAAA;AAC1D;AAUO,SAAS,eAAA,CAAgB,OAAc,MAAA,EAAsB;AAClE,EAAA,KAAA,CAAM,cAAA,CAA6B,iBAAA,EAAmB,EAAE,MAAA,EAAQ,CAAA;AAClE;AAiBO,SAAS,uBAAA,CACd,gBACA,YAAA,EACQ;AACR,EAAA,IAAI,YAAA,KAAiB,QAAW,OAAO,EAAA;AACvC,EAAA,OAAO,cAAA,CAAe,QAAQ,YAAY,CAAA;AAC5C","file":"chunk-PA5DRJNI.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 the renderer-owned 3D instance collection snapshot whose length\n// depends on the live instance count; the owners remain separate.\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 asset atlas --input <glob> --name <prefix> --output <dir> --root <project>`\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, matching the 3D collection projection.\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","// @forgeax/engine-runtime - ActiveCamera KV resource + selection helper.\n//\n// feat-20260630-viewport-2x2-run-x-display-redesign M2 w12 / plan-strategy D-2.\n//\n// PROBLEM (research Finding 4): the render extract stage selects the camera by\n// archetype-query FIRST-HIT (`cameras[0]`) and fires `render-system-multi-camera`\n// when more than one [Camera, Transform, Entity] entity exists. A single engine\n// world that carries BOTH an editor orbit camera AND a game camera therefore\n// cannot pick which one renders. This module adds the minimum neutral mechanism:\n// an `ActiveCamera { entity }` resource naming the entity to render through.\n//\n// ENGINE-NEUTRAL (requirements OOS-4 / AC-16): the engine knows only entity IDs.\n// It does NOT know which entity is \"editor\" or \"game\" -- the caller (editor side)\n// decides what `ActiveCamera.entity` points at. No editor concept enters this\n// file or the engine layer.\n//\n// BACKWARD COMPATIBLE (plan-strategy D-2): when the resource is ABSENT, or the\n// named entity is not among the queried cameras, selection falls back to the\n// existing first-hit behavior unchanged. Single-camera scenes are unaffected.\n//\n// Surface:\n// - interface ActiveCamera { entity: number }\n// - constant ACTIVE_CAMERA_KEY = 'ActiveCamera'\n// - helper getActiveCamera(world): ActiveCamera | undefined\n// - helper setActiveCamera(world, entity): void\n// - pure selectActiveCameraIndex(cameraEntities, activeEntity): number\n//\n// @new-surface KV resource: ECS has no defineResource factory; the TS POD\n// interface + string KV key form is the minimum-new-surface route, mirroring\n// TransparentSortConfig. The world resource store\n// (insertResource / getResource / hasResource) is reused unchanged.\n// @derives world.hasResource / world.insertResource / world.getResource KV API.\n// @fallback getActiveCamera KV missing returns undefined; no warn; no throw\n// (absent ActiveCamera is a legal state -> first-hit fallback in extract).\n//\n// charter mapping: F1 (single-import barrel + single entity pointer, smallest\n// concept face vs a multi-field priority/enabled scheme) + P4 (consistent\n// abstraction -- same world.{has,get,insert}Resource KV API as every other\n// engine resource consumer).\n\nimport type { World } from '@forgeax/engine-ecs';\n\n// ────────────────────────────────────────────────────────────────────────────\n// POD interface + KV key\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Active-camera pointer (plain-data POD). Lives as a world-level resource keyed\n * by `ACTIVE_CAMERA_KEY`. `entity` is the packed entity id (engine `EntityHandle`\n * is a branded number) of the camera the renderer should use.\n *\n * The engine treats `entity` as an opaque id; whether it names an editor camera\n * or a game camera is a caller-side decision (OOS-4 — engine stays neutral).\n */\nexport interface ActiveCamera {\n readonly entity: number;\n}\n\n/** World resource key for the `ActiveCamera` KV entry. */\nexport const ACTIVE_CAMERA_KEY = 'ActiveCamera' as const;\n\n// ────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Read the world's `ActiveCamera` resource.\n *\n * @fallback KV missing returns `undefined` — absent ActiveCamera is a legal\n * state (the renderer falls back to archetype first-hit). NO warn, NO throw.\n * The `hasResource` guard precedes the read so this helper never trips\n * `ResourceNotFoundError` from `world.getResource`.\n *\n * @example\n * const a = getActiveCamera(world); // undefined when not set\n * if (a) { ... a.entity ... }\n */\nexport function getActiveCamera(world: World): ActiveCamera | undefined {\n if (!world.hasResource(ACTIVE_CAMERA_KEY)) return undefined;\n return world.getResource<ActiveCamera>(ACTIVE_CAMERA_KEY);\n}\n\n/**\n * Write the world's `ActiveCamera` resource (idempotent last-write-wins via\n * `world.insertResource`). The renderer will use the camera whose entity id\n * equals `entity`, or fall back to first-hit if that id is not a queried camera.\n *\n * @example\n * setActiveCamera(world, gameCameraEntity); // render through the game camera\n */\nexport function setActiveCamera(world: World, entity: number): void {\n world.insertResource<ActiveCamera>(ACTIVE_CAMERA_KEY, { entity });\n}\n\n/**\n * Pure selection: given the entity ids of every camera surfaced by the extract\n * archetype query (in query order) and the optional active-camera entity id,\n * return the index of the active camera in `cameraEntities`, or `-1` to signal\n * \"no selection — use first-hit fallback\".\n *\n * `-1` is returned when `activeEntity` is `undefined` (resource absent) OR when\n * the id is not present among `cameraEntities` (stale / non-camera entity).\n * Both cases preserve the existing first-hit behavior (plan-strategy D-2).\n *\n * @example\n * selectActiveCameraIndex([10, 20, 30], 20) === 1 // pick the 2nd camera\n * selectActiveCameraIndex([10, 20, 30], undefined) === -1 // first-hit\n * selectActiveCameraIndex([10, 20, 30], 999) === -1 // first-hit\n */\nexport function selectActiveCameraIndex(\n cameraEntities: readonly number[],\n activeEntity: number | undefined,\n): number {\n if (activeEntity === undefined) return -1;\n return cameraEntities.indexOf(activeEntity);\n}\n"]}
|