@forgeax/engine-runtime 0.1.4 → 0.1.6
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 +49 -83
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/animation-graph-serialize.unit.test.d.ts +2 -0
- package/dist/__tests__/animation-graph-serialize.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts +2 -0
- package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts.map +1 -0
- package/dist/__tests__/asset-error-exhaustive.test-d.d.ts +11 -0
- package/dist/__tests__/asset-error-exhaustive.test-d.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-guid-reverse.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-guid-reverse.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-mounts.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-mounts.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.browser.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.browser.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.dawn.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.listCatalog.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.listCatalog.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.mesh-bin.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.mesh-bin.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.recursive.spec.d.ts +2 -0
- package/dist/__tests__/asset-registry.recursive.spec.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset.unit.test.d.ts +2 -0
- package/dist/__tests__/asset.unit.test.d.ts.map +1 -0
- package/dist/__tests__/audio-load-by-guid.unit.test.d.ts +2 -0
- package/dist/__tests__/audio-load-by-guid.unit.test.d.ts.map +1 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
- package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts +2 -0
- package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts.map +1 -0
- package/dist/__tests__/builtin-asset-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/builtin-asset-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/collect-scene-asset.test.d.ts +1 -2
- package/dist/__tests__/collect-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/collect-scene-mount-collapse.test.d.ts +2 -0
- package/dist/__tests__/collect-scene-mount-collapse.test.d.ts.map +1 -0
- package/dist/__tests__/collect-transient-roundtrip.test.d.ts +1 -1
- package/dist/__tests__/collect-transient-roundtrip.test.d.ts.map +1 -1
- package/dist/__tests__/collect-transient-skip.test.d.ts +1 -2
- package/dist/__tests__/collect-transient-skip.test.d.ts.map +1 -1
- package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts +2 -0
- package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts.map +1 -0
- package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts +2 -0
- package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts.map +1 -0
- package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts +2 -0
- package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/draw-published.d.ts +2 -2
- package/dist/__tests__/draw-published.d.ts.map +1 -1
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/errors.unit.test.d.ts +2 -0
- package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts +2 -0
- package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts.map +1 -0
- package/dist/__tests__/fetch-binary-decompress.test.d.ts +2 -0
- package/dist/__tests__/fetch-binary-decompress.test.d.ts.map +1 -0
- package/dist/__tests__/four-path-compression.integration.test.d.ts +2 -0
- package/dist/__tests__/four-path-compression.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts +2 -0
- package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/guid-for-asset.unit.test.d.ts +2 -0
- package/dist/__tests__/guid-for-asset.unit.test.d.ts.map +1 -0
- package/dist/__tests__/handle-migration.test.d.ts +2 -0
- package/dist/__tests__/handle-migration.test.d.ts.map +1 -0
- package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
- package/dist/__tests__/host-custom-kind-contract.test-d.d.ts +2 -0
- package/dist/__tests__/host-custom-kind-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/host-custom-kind-contract.test.d.ts +2 -0
- package/dist/__tests__/host-custom-kind-contract.test.d.ts.map +1 -0
- package/dist/__tests__/inspect-name.test.d.ts +2 -0
- package/dist/__tests__/inspect-name.test.d.ts.map +1 -0
- package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts +2 -0
- package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/loadbyguid-payload.unit.test.d.ts +2 -0
- package/dist/__tests__/loadbyguid-payload.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts +2 -0
- package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loader-extract-graceful.test.d.ts +2 -0
- package/dist/__tests__/loader-extract-graceful.test.d.ts.map +1 -0
- package/dist/__tests__/loader-name-survival.test.d.ts +2 -0
- package/dist/__tests__/loader-name-survival.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin-contract.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin-contract.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/new-kind-refs-contract.test.d.ts +2 -0
- package/dist/__tests__/new-kind-refs-contract.test.d.ts.map +1 -0
- package/dist/__tests__/package-promotion.test.d.ts +2 -0
- package/dist/__tests__/package-promotion.test.d.ts.map +1 -0
- package/dist/__tests__/package-rename.test.d.ts +2 -0
- package/dist/__tests__/package-rename.test.d.ts.map +1 -0
- package/dist/__tests__/recover-error-exhaustive.test-d.d.ts +1 -1
- package/dist/__tests__/recover-error-exhaustive.test-d.d.ts.map +1 -1
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts +1 -1
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
- package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts +10 -0
- package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts.map +1 -0
- package/dist/__tests__/render-system-extract.unit.test.d.ts +2 -0
- package/dist/__tests__/render-system-extract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-test-utils.d.ts +10 -0
- package/dist/__tests__/renderer-test-utils.d.ts.map +1 -0
- package/dist/__tests__/renderer.test-d.d.ts +2 -0
- package/dist/__tests__/renderer.test-d.d.ts.map +1 -0
- package/dist/__tests__/resolve-asset-handle-err.test.d.ts +2 -0
- package/dist/__tests__/resolve-asset-handle-err.test.d.ts.map +1 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-fallback.test.d.ts +2 -0
- package/dist/__tests__/resolveName-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-null-package.test.d.ts +2 -0
- package/dist/__tests__/resolveName-null-package.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName-unified-entry.test.d.ts +2 -0
- package/dist/__tests__/resolveName-unified-entry.test.d.ts.map +1 -0
- package/dist/__tests__/resolveName.test.d.ts +2 -0
- package/dist/__tests__/resolveName.test.d.ts.map +1 -0
- package/dist/__tests__/roots-to-scene-asset.test.d.ts +1 -1
- package/dist/__tests__/roots-to-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/roundtrip-primitive.test.d.ts +2 -0
- package/dist/__tests__/roundtrip-primitive.test.d.ts.map +1 -0
- package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts +2 -0
- package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts.map +1 -0
- package/dist/__tests__/scene-instance-authoring.integration.test.d.ts +2 -0
- package/dist/__tests__/scene-instance-authoring.integration.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-fixed-point.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-fixed-point.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/scene-sugar-instantiate.test.d.ts +2 -0
- package/dist/__tests__/scene-sugar-instantiate.test.d.ts.map +1 -0
- package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/serialize-scene-asset.test.d.ts +1 -1
- package/dist/__tests__/serialize-scene-asset.test.d.ts.map +1 -1
- package/dist/__tests__/template-game-default-api-contract.test.d.ts +2 -0
- package/dist/__tests__/template-game-default-api-contract.test.d.ts.map +1 -0
- package/dist/__tests__/tileset-asset-validate.test.d.ts +2 -0
- package/dist/__tests__/tileset-asset-validate.test.d.ts.map +1 -0
- package/dist/__tests__/transcode-fallback.unit.test.d.ts +2 -0
- package/dist/__tests__/transcode-fallback.unit.test.d.ts.map +1 -0
- package/dist/__tests__/transient-runtime-behavior.test.d.ts +2 -0
- package/dist/__tests__/transient-runtime-behavior.test.d.ts.map +1 -0
- package/dist/__tests__/video-loader-consumption.test.d.ts +2 -0
- package/dist/__tests__/video-loader-consumption.test.d.ts.map +1 -0
- package/dist/__tests__/video-loader-smoke.dawn.test.d.ts +2 -0
- package/dist/__tests__/video-loader-smoke.dawn.test.d.ts.map +1 -0
- package/dist/backend-selection.d.ts +13 -0
- package/dist/backend-selection.d.ts.map +1 -0
- package/dist/collect-scene-asset.d.ts +3 -3
- package/dist/collect-scene-asset.d.ts.map +1 -1
- package/dist/createRenderer.d.ts +14 -2
- package/dist/createRenderer.d.ts.map +1 -1
- package/dist/errors/environment.d.ts +1 -1
- package/dist/errors/environment.d.ts.map +1 -1
- package/dist/index.d.ts +19 -81
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +105 -108
- package/dist/index.mjs.map +1 -1
- package/dist/renderer-host.d.ts +9 -0
- package/dist/renderer-host.d.ts.map +1 -0
- package/dist/renderer-host.mjs +62 -0
- package/dist/renderer-host.mjs.map +1 -0
- package/dist/scene-instances/index.d.ts +2 -0
- package/dist/scene-instances/index.d.ts.map +1 -0
- package/dist/scene-utils/mount-override-fold.d.ts +1 -2
- package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
- package/dist/systems/sprite-animation-tick.d.ts +1 -1
- package/dist/systems/sprite-animation-tick.d.ts.map +1 -1
- package/dist/systems/transparent-sort.d.ts +1 -2
- package/dist/systems/transparent-sort.d.ts.map +1 -1
- package/dist/tilemap-register-validate.d.ts.map +1 -1
- package/package.json +34 -33
- package/src/__tests__/active-camera.unit.test.ts +19 -9
- package/src/__tests__/animation-graph-collect-roundtrip.test.ts +213 -0
- package/src/__tests__/animation-graph-serialize.unit.test.ts +171 -0
- package/src/__tests__/append-injection.test.ts +1 -1
- package/src/__tests__/asset-brand-and-name-retirement.test.ts +102 -0
- package/src/__tests__/asset-error-exhaustive.test-d.ts +62 -0
- package/src/__tests__/asset-registry-guid-reverse.test.ts +575 -0
- package/src/__tests__/asset-registry-hdr-equirect.test.ts +78 -0
- package/src/__tests__/asset-registry-mesh-pack-payload.dawn.test.ts +232 -0
- package/src/__tests__/asset-registry-mounts.test.ts +806 -0
- package/src/__tests__/asset-registry.browser.test.ts +81 -0
- package/src/__tests__/asset-registry.dawn.test.ts +94 -0
- package/src/__tests__/asset-registry.listCatalog.test.ts +170 -0
- package/src/__tests__/asset-registry.mesh-bin.test.ts +316 -0
- package/src/__tests__/asset-registry.pack-cache.test.ts +969 -0
- package/src/__tests__/asset-registry.raw-container-failfast.test.ts +225 -0
- package/src/__tests__/asset-registry.recursive.spec.ts +1397 -0
- package/src/__tests__/asset-registry.unit.test.ts +1030 -0
- package/src/__tests__/asset.unit.test.ts +7107 -0
- package/src/__tests__/audio-load-by-guid.unit.test.ts +126 -0
- package/src/__tests__/backend-selection.integration.test.ts +11 -0
- package/src/__tests__/basis-catalog-dispatch.integration.test.ts +320 -0
- package/src/__tests__/bind-group-cache-keying.test.ts +4 -4
- package/src/__tests__/block-upload-math.unit.test.ts +2 -2
- package/src/__tests__/builtin-asset-registry.unit.test.ts +112 -0
- package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
- package/src/__tests__/cache-false-eviction.test.ts +2 -1
- package/src/__tests__/cache-isolation-matrix.test.ts +2 -1
- package/src/__tests__/camera-clear-snapshot-equivalence.unit.test.ts +5 -6
- package/src/__tests__/clamp-to-last.e2e.browser.test.ts +29 -19
- package/src/__tests__/collect-scene-asset.test.ts +49 -52
- package/src/__tests__/collect-scene-mount-collapse.test.ts +391 -0
- package/src/__tests__/collect-subtree.unit.test.ts +1 -2
- package/src/__tests__/collect-transient-children-absent.test.ts +24 -10
- package/src/__tests__/collect-transient-roundtrip.test.ts +44 -20
- package/src/__tests__/collect-transient-skip.test.ts +24 -13
- package/src/__tests__/components.test-d.ts +1 -6
- package/src/__tests__/components.unit.test.ts +20 -19
- package/src/__tests__/composite-skybox-cross-world.browser.test.ts +59 -27
- package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +139 -0
- package/src/__tests__/create-renderer-assembly.integration.test.ts +42 -29
- package/src/__tests__/createRenderer-dispose.test.ts +35 -402
- package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +25 -30
- package/src/__tests__/createRenderer.unit.test.ts +1 -1
- package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +27 -63
- package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +56 -47
- package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +49 -29
- package/src/__tests__/dawn/instances-shadow.dawn.test.ts +26 -15
- package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +13 -14
- package/src/__tests__/dawn/material-alpha.dawn.test.ts +23 -31
- package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +0 -18
- package/src/__tests__/dawn/{mesh-update.dawn.test.ts → mesh-update-dawn.test.ts} +42 -134
- package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +14 -7
- package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +16 -28
- package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +23 -39
- package/src/__tests__/dawn/upload-texture.dawn.test.ts +198 -0
- package/src/__tests__/dawn/user-handle-mesh-render.dawn.test.ts +12 -14
- package/src/__tests__/dawn/user-mesh-upload.dawn.test.ts +27 -22
- package/src/__tests__/dawn/zero-manifest-mesh-fail.dawn.test.ts +25 -28
- package/src/__tests__/dawn/zero-manifest-ready.dawn.test.ts +10 -11
- package/src/__tests__/demo-sortscope-migration.unit.test.ts +5 -5
- package/src/__tests__/derive-bgl-integration.test.ts +34 -44
- package/src/__tests__/derive-render-data-skin.unit.test.ts +1 -1
- package/src/__tests__/draw-published.ts +11 -4
- package/src/__tests__/dynamic-texture-store.unit.test.ts +190 -0
- package/src/__tests__/equirect-bc6h.integration.test.ts +144 -21
- package/src/__tests__/errors.unit.test.ts +1203 -0
- package/src/__tests__/extract-frames-graceful-degradation.test.ts +3 -7
- package/src/__tests__/extract-frames-merge.test.ts +35 -22
- package/src/__tests__/extract-record-no-hardcoded-texture-fields.test.ts +5 -16
- package/src/__tests__/extract-skin-mismatch.unit.test.ts +322 -0
- package/src/__tests__/fetch-binary-decompress.test.ts +356 -0
- package/src/__tests__/four-path-compression.integration.test.ts +395 -0
- package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +1 -1
- package/src/__tests__/fullscreen-feature-host.dawn.test.ts +80 -0
- package/src/__tests__/fullscreen-post-bgl-depth.test.ts +4 -2
- package/src/__tests__/fullscreen-post-depth-params-arity.test.ts +3 -3
- package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +39 -23
- package/src/__tests__/fullscreen-post-process-pass.unit.test.ts +4 -2
- package/src/__tests__/fxaa-pixel-diff.dawn.test.ts +28 -17
- package/src/__tests__/fxaa-validation-and-resize.dawn.test.ts +29 -18
- package/src/__tests__/fxaa-zero-overhead.dawn.test.ts +16 -12
- package/src/__tests__/geometry.unit.test.ts +525 -159
- package/src/__tests__/glyph-tilemap-worldid.test.ts +1 -1
- package/src/__tests__/gpu-resource-cow-survivor.test.ts +6 -4
- package/src/__tests__/guid-for-asset.unit.test.ts +102 -0
- package/src/__tests__/handle-migration.test.ts +136 -0
- package/src/__tests__/helpers/register-runtime-components.ts +4 -2
- package/src/__tests__/helpers/register-scene-components.ts +1 -1
- package/src/__tests__/host-custom-kind-contract.test-d.ts +47 -0
- package/src/__tests__/host-custom-kind-contract.test.ts +578 -0
- package/src/__tests__/inspect-name.test.ts +139 -0
- package/src/__tests__/instances.test-d.ts +1 -1
- package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +112 -0
- package/src/__tests__/light-casters-9-light.browser.test.ts +73 -76
- package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +7 -10
- package/src/__tests__/light-snapshot.test-d.ts +2 -2
- package/src/__tests__/lights-vec-negative.unit.test.ts +1 -1
- package/src/__tests__/lights.unit.test.ts +16 -500
- package/src/__tests__/loadbyguid-payload.unit.test.ts +117 -0
- package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +213 -0
- package/src/__tests__/loader-extract-graceful.test.ts +146 -0
- package/src/__tests__/loader-name-survival.test.ts +213 -0
- package/src/__tests__/m3-vec-negative.unit.test.ts +3 -2
- package/src/__tests__/material-texture-uv-scale.unit.test.ts +101 -31
- package/src/__tests__/materials.unit.test.ts +10 -27
- package/src/__tests__/mesh-bin-contract.test.ts +28 -0
- package/src/__tests__/mesh-bin-skin-roundtrip.unit.test.ts +149 -0
- package/src/__tests__/mesh-bin.test.ts +38 -0
- package/src/__tests__/mesh-loader-skin-contract.unit.test.ts +120 -0
- package/src/__tests__/mesh-ssbo-grow.unit.test.ts +3 -3
- package/src/__tests__/mip-gate.unit.test.ts +1 -1
- package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +29 -68
- package/src/__tests__/new-kind-refs-contract.test.ts +132 -0
- package/src/__tests__/node-shims.d.ts +4 -6
- package/src/__tests__/package-promotion.test.ts +88 -0
- package/src/__tests__/package-rename.test.ts +103 -0
- package/src/__tests__/pass-selector.unit.test.ts +2 -2
- package/src/__tests__/pbr-pipeline.unit.test.ts +14 -21
- package/src/__tests__/pipeline-builder-msaa.unit.test.ts +6 -9
- package/src/__tests__/pipeline-cache-keying.unit.test.ts +6 -9
- package/src/__tests__/pipeline-spec.test.ts +16 -177
- package/src/__tests__/pipeline.unit.test.ts +154 -1693
- package/src/__tests__/point-light-shadow.dawn.test.ts +33 -42
- package/src/__tests__/point-light-shadow.unit.test.ts +19 -60
- package/src/__tests__/post-process-error-codes.unit.test.ts +4 -1
- package/src/__tests__/post-process-params-component.unit.test.ts +1 -1
- package/src/__tests__/post-process-params-extract.unit.test.ts +2 -5
- package/src/__tests__/postprocess-camera-consistency.test.ts +4 -7
- package/src/__tests__/profiler-assembly.integration.test.ts +1 -1
- package/src/__tests__/propagate-transforms.dawn.test.ts +12 -11
- package/src/__tests__/record-worldid-isolation.test.ts +7 -29
- package/src/__tests__/recover-error-exhaustive.test-d.ts +1 -1
- package/src/__tests__/render-error-exhaustive.test-d.ts +81 -71
- package/src/__tests__/render-feature-assembly.test-d.ts +20 -9
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +8 -6
- package/src/__tests__/render-feature-prepared-graphics.browser.test.ts +60 -558
- package/src/__tests__/render-feature-prepared-graphics.dawn.test.ts +57 -544
- package/src/__tests__/render-feature-prepared-graphics.fixture.ts +104 -0
- package/src/__tests__/render-feature-prepared-graphics.integration.test.ts +40 -248
- package/src/__tests__/render-feature-prepared-graphics.regression.integration.test.ts +83 -340
- package/src/__tests__/render-feature-recover.integration.test.ts +9 -49
- package/src/__tests__/render-feature-runtime-surface.test-d.ts +17 -20
- package/src/__tests__/render-schema-consumer.integration.test.ts +20 -13
- package/src/__tests__/render-schema-owner-boundary.unit.test.ts +2 -6
- package/src/__tests__/render-system-cross-world-overlay-queue.test.ts +5 -5
- package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +16 -31
- package/src/__tests__/render-system-extract.test.ts +36 -51
- package/src/__tests__/render-system-extract.unit.test.ts +360 -0
- package/src/__tests__/render-system-fold-bucket.unit.test.ts +3 -5
- package/src/__tests__/render-system-fold-fallback.unit.test.ts +6 -3
- package/src/__tests__/render-system-fold-material.unit.test.ts +3 -5
- package/src/__tests__/render-system-fold-metrics.unit.test.ts +5 -5
- package/src/__tests__/render-system-fold-modegate.unit.test.ts +6 -6
- package/src/__tests__/render-system-fold.dawn.test.ts +7 -5
- package/src/__tests__/render-system-mega.test.ts +292 -190
- package/src/__tests__/render-system-owner-split-contract.test.ts +10 -32
- package/src/__tests__/render-system-record-multi-material-textureview.test.ts +59 -45
- package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +23 -29
- package/src/__tests__/render-system-record.test.ts +398 -235
- package/src/__tests__/render-system-record.unit.test.ts +25 -26
- package/src/__tests__/render-system-skin-bg.unit.test.ts +8 -12
- package/src/__tests__/renderer-consumer.test-d.ts +16 -3
- package/src/__tests__/renderer-health.unit.test.ts +26 -916
- package/src/__tests__/renderer-lifecycle.integration.test.ts +19 -6
- package/src/__tests__/renderer-recover.unit.test.ts +49 -1069
- package/src/__tests__/renderer-result.test-d.ts +19 -9
- package/src/__tests__/renderer-surface.unit.test.ts +3 -5
- package/src/__tests__/renderer-test-utils.ts +56 -0
- package/src/__tests__/renderer.test-d.ts +59 -0
- package/src/__tests__/resolve-asset-handle-err.test.ts +111 -0
- package/src/__tests__/resolve-asset-handle.unit.test.ts +64 -0
- package/src/__tests__/resolve-depth-only-view.test.ts +1 -1
- package/src/__tests__/resolveName-fallback.test.ts +64 -0
- package/src/__tests__/resolveName-null-package.test.ts +38 -0
- package/src/__tests__/resolveName-unified-entry.test.ts +65 -0
- package/src/__tests__/resolveName.test.ts +64 -0
- package/src/__tests__/rhi-null-command-flow.unit.test.ts +43 -261
- package/src/__tests__/rhi-null-renderer-lifecycle.unit.test.ts +41 -169
- package/src/__tests__/roots-to-scene-asset.test.ts +199 -93
- package/src/__tests__/roundtrip-primitive.test.ts +351 -0
- package/src/__tests__/scene-bare-guid-refs-instantiate.test.ts +123 -0
- package/src/__tests__/scene-equirect-roundtrip.test.ts +103 -16
- package/src/__tests__/scene-instance-authoring.integration.test.ts +8 -0
- package/src/__tests__/scene-instance-bridge.integration.test.ts +1 -1
- package/src/__tests__/scene-instance-component.test.ts +1 -1
- package/src/__tests__/scene-mount-fixed-point.test.ts +257 -0
- package/src/__tests__/scene-mount-roundtrip.test.ts +987 -0
- package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +202 -0
- package/src/__tests__/scene-sugar-instantiate.test.ts +324 -0
- package/src/__tests__/serialize-mounts-roundtrip.test.ts +533 -0
- package/src/__tests__/serialize-scene-asset.test.ts +219 -22
- package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -3
- package/src/__tests__/shadow-csm-cascade-loadop.test.ts +37 -17
- package/src/__tests__/shadow-csm-component.test.ts +3 -5
- package/src/__tests__/shadow-csm-extract.test.ts +2 -100
- package/src/__tests__/shadow-csm-orthoz.test.ts +2 -16
- package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +19 -14
- package/src/__tests__/shadow-csm-tile-consistency.test.ts +32 -26
- package/src/__tests__/shadow-csm-ubo.dawn.test.ts +8 -49
- package/src/__tests__/shadow-csm-ubo.test.ts +3 -25
- package/src/__tests__/shadow-csm-viewport.browser.test.ts +1 -1
- package/src/__tests__/shadow-fields-observable.dawn.test.ts +67 -56
- package/src/__tests__/shadow-m1.dawn.test.ts +8 -9
- package/src/__tests__/shadow-mesh-ssbo-order.test.ts +11 -27
- package/src/__tests__/skin-errors.unit.test.ts +1 -1
- package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +7 -5
- package/src/__tests__/skylight-lazy-projection.test.ts +36 -15
- package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +5 -5
- package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +47 -64
- package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +12 -11
- package/src/__tests__/sprite-lit-extract-branch.test.ts +1 -1
- package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
- package/src/__tests__/ssao-bgl.test.ts +16 -9
- package/src/__tests__/ssao-buffers.test.ts +2 -2
- package/src/__tests__/ssao-data.test.ts +2 -2
- package/src/__tests__/ssao-errors.test.ts +1 -1
- package/src/__tests__/ssao-passes.test.ts +64 -392
- package/src/__tests__/ssao-pipelines.test.ts +1 -1
- package/src/__tests__/ssao-uniform-layout.test.ts +8 -6
- package/src/__tests__/stencil-outline-pixel.dawn.test.ts +25 -17
- package/src/__tests__/swap-chain-format.unit.test.ts +5 -7
- package/src/__tests__/systems.unit.test.ts +536 -1326
- package/src/__tests__/template-game-default-api-contract.test.ts +362 -0
- package/src/__tests__/text.unit.test.ts +56 -33
- package/src/__tests__/tilemap-childed-despawn.test.ts +8 -14
- package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +8 -12
- package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +2 -1
- package/src/__tests__/tilemap-chunk-extract.test.ts +13 -17
- package/src/__tests__/tilemap-dirty-rebuild.test.ts +7 -11
- package/src/__tests__/tilemap-material-cache.test.ts +8 -13
- package/src/__tests__/tilemap-multi-atlas.test.ts +12 -32
- package/src/__tests__/tilemap-owner-boundary.unit.test.ts +5 -2
- package/src/__tests__/tilemap-region-pack.test.ts +8 -12
- package/src/__tests__/tilemap-spawn-flip-pivot.test.ts +8 -12
- package/src/__tests__/tilemap-uv-inset.test.ts +11 -14
- package/src/__tests__/tilemap-validate.test.ts +1 -1
- package/src/__tests__/tileset-asset-validate.test.ts +638 -0
- package/src/__tests__/transcode-fallback.unit.test.ts +207 -0
- package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +36 -28
- package/src/__tests__/transient-fields-collect.test.ts +28 -21
- package/src/__tests__/transient-runtime-behavior.test.ts +227 -0
- package/src/__tests__/transparent-sort-tilemap-sprite-interleave.test.ts +4 -4
- package/src/__tests__/variant-selection.unit.test.ts +1 -1
- package/src/__tests__/video-extract-bindgroup.dawn.test.ts +89 -136
- package/src/__tests__/video-loader-consumption.test.ts +86 -0
- package/src/__tests__/video-loader-smoke.dawn.test.ts +60 -0
- package/src/__tests__/view-ubo-layout.browser.test.ts +0 -22
- package/src/__tests__/world-entity-key.test.ts +1 -1
- package/src/__tests__/world-scene-despawn.test.ts +1 -1
- package/src/__tests__/world-scene-instantiate.test.ts +2 -36
- package/src/__tests__/world-scene-nested.test.ts +1 -1
- package/src/__tests__/world-scene-override.test.ts +1 -1
- package/src/backend-selection.ts +69 -0
- package/src/collect-scene-asset.ts +28 -23
- package/src/components/__tests__/camera.test-d.ts +1 -1
- package/src/components/__tests__/camera.test.ts +1 -1
- package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
- package/src/components/__tests__/tile-layer.test-d.ts +1 -1
- package/src/components/__tests__/tile-layer.unit.test.ts +2 -2
- package/src/createRenderer.ts +24 -36
- package/src/errors/environment.ts +1 -1
- package/src/index.ts +47 -113
- package/src/renderer-host.ts +33 -0
- package/src/scene-instances/__tests__/post-spawn-resolve-joints.unit.test.ts +1 -1
- package/src/scene-instances/index.ts +4 -0
- package/src/scene-utils/mount-override-fold.ts +3 -7
- package/src/systems/__tests__/transparent-sort.bench.ts +3 -3
- package/src/systems/sprite-animation-tick.ts +1 -1
- package/src/systems/transparent-sort.ts +38 -38
- package/src/tilemap-register-validate.ts +4 -4
- package/dist/__tests__/bind-group-cache-binding.test.d.ts +0 -2
- package/dist/__tests__/bind-group-cache-binding.test.d.ts.map +0 -1
- package/dist/__tests__/bind-group-cache-frame.test.d.ts +0 -2
- package/dist/__tests__/bind-group-cache-frame.test.d.ts.map +0 -1
- package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts +0 -2
- package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts +0 -2
- package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-manifest.d.ts +0 -131
- package/dist/__tests__/fog-producer-manifest.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel-probe.d.ts +0 -42
- package/dist/__tests__/fog-producer-pixel-probe.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel.browser.test.d.ts +0 -2
- package/dist/__tests__/fog-producer-pixel.browser.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts +0 -2
- package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-real-fixture.d.ts +0 -5
- package/dist/__tests__/fog-producer-real-fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-vfx-effect.d.ts +0 -3
- package/dist/__tests__/fog-producer-vfx-effect.d.ts.map +0 -1
- package/dist/__tests__/fog-scene-asset.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-scene-asset.integration.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts +0 -2
- package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-resource.test.d.ts +0 -2
- package/dist/__tests__/gpu-resource.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts +0 -2
- package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-buffers.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-buffers.unit.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts +0 -2
- package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts +0 -2
- package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts.map +0 -1
- package/dist/__tests__/hdrp-ssao-boundary.test.d.ts +0 -2
- package/dist/__tests__/hdrp-ssao-boundary.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-ssao-falsification.test.d.ts +0 -2
- package/dist/__tests__/hdrp-ssao-falsification.test.d.ts.map +0 -1
- package/dist/__tests__/helpers/primitive-world.d.ts +0 -8
- package/dist/__tests__/helpers/primitive-world.d.ts.map +0 -1
- package/dist/__tests__/helpers/render-asset-port.d.ts +0 -15
- package/dist/__tests__/helpers/render-asset-port.d.ts.map +0 -1
- package/dist/__tests__/helpers/scene-asset-port.d.ts +0 -9
- package/dist/__tests__/helpers/scene-asset-port.d.ts.map +0 -1
- package/dist/__tests__/material-derived-coordinates.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-coordinates.integration.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-layout-selection.test.d.ts +0 -2
- package/dist/__tests__/pipeline-layout-selection.test.d.ts.map +0 -1
- package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts +0 -2
- package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts.map +0 -1
- package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts +0 -2
- package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts +0 -2
- package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts.map +0 -1
- package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts +0 -2
- package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-caster-membership.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-caster-membership.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-pssm.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-pssm.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-csm-viewport.test.d.ts +0 -2
- package/dist/__tests__/shadow-csm-viewport.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m2.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m2.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3-calibrate.d.ts +0 -83
- package/dist/__tests__/shadow-m3-calibrate.d.ts.map +0 -1
- package/dist/__tests__/shadow-m3.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-m3.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts +0 -2
- package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-off-path.unit.test.d.ts +0 -2
- package/dist/__tests__/temporal-off-path.unit.test.d.ts.map +0 -1
- package/dist/__tests__/video-cache-regression.unit.test.d.ts +0 -2
- package/dist/__tests__/video-cache-regression.unit.test.d.ts.map +0 -1
- package/dist/asset-kind.d.ts +0 -4
- package/dist/asset-kind.d.ts.map +0 -1
- package/dist/errors/sprite-animation.d.ts +0 -3
- package/dist/errors/sprite-animation.d.ts.map +0 -1
- package/dist/scene-asset-port.d.ts +0 -17
- package/dist/scene-asset-port.d.ts.map +0 -1
- package/dist/scene-collect-errors.d.ts +0 -22
- package/dist/scene-collect-errors.d.ts.map +0 -1
- package/dist/shadow-m3-calibrate.d.ts +0 -40
- package/dist/shadow-m3-calibrate.d.ts.map +0 -1
- package/src/__tests__/bind-group-cache-binding.test.ts +0 -2513
- package/src/__tests__/bind-group-cache-frame.test.ts +0 -1511
- package/src/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.ts +0 -204
- package/src/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.ts +0 -297
- package/src/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.ts +0 -271
- package/src/__tests__/dispatch-fullscreen-pass-params.unit.test.ts +0 -321
- package/src/__tests__/fog-producer-manifest.ts +0 -162
- package/src/__tests__/fog-producer-pixel-probe.ts +0 -263
- package/src/__tests__/fog-producer-pixel.browser.test.ts +0 -26
- package/src/__tests__/fog-producer-pixel.dawn.test.ts +0 -55
- package/src/__tests__/fog-producer-real-fixture.ts +0 -805
- package/src/__tests__/fog-producer-vfx-effect.ts +0 -272
- package/src/__tests__/fog-scene-asset.integration.test.ts +0 -123
- package/src/__tests__/gpu-resource-store-cubemap-status.test.ts +0 -207
- package/src/__tests__/gpu-resource.test.ts +0 -1206
- package/src/__tests__/hdrp-bgl-slots.browser.test.ts +0 -50
- package/src/__tests__/hdrp-buffers.unit.test.ts +0 -70
- package/src/__tests__/hdrp-execute-filter.unit.test.ts +0 -200
- package/src/__tests__/hdrp-gbuffer-attachments.browser.test.ts +0 -64
- package/src/__tests__/hdrp-pipeline-asset-type.test-d.ts +0 -139
- package/src/__tests__/hdrp-ssao-boundary.test.ts +0 -237
- package/src/__tests__/hdrp-ssao-falsification.test.ts +0 -289
- package/src/__tests__/helpers/primitive-world.ts +0 -91
- package/src/__tests__/helpers/render-asset-port.ts +0 -65
- package/src/__tests__/helpers/scene-asset-port.ts +0 -23
- package/src/__tests__/material-derived-coordinates.integration.test.ts +0 -100
- package/src/__tests__/pipeline-layout-selection.test.ts +0 -298
- package/src/__tests__/post-process-reads-narrowing.test-d.ts +0 -52
- package/src/__tests__/post-process-register-roundtrip.dawn.test.ts +0 -230
- package/src/__tests__/render-feature-zero-feature.browser.test.ts +0 -152
- package/src/__tests__/render-pipeline-trivial.dawn.test.ts +0 -525
- package/src/__tests__/shadow-csm-caster-membership.test.ts +0 -232
- package/src/__tests__/shadow-csm-pssm.test.ts +0 -142
- package/src/__tests__/shadow-csm-temporal.browser.test.ts +0 -145
- package/src/__tests__/shadow-csm-viewport.test.ts +0 -74
- package/src/__tests__/shadow-m2.dawn.test.ts +0 -394
- package/src/__tests__/shadow-m3-calibrate-run.dawn.test.ts +0 -248
- package/src/__tests__/shadow-m3-calibrate.ts +0 -203
- package/src/__tests__/shadow-m3.dawn.test.ts +0 -288
- package/src/__tests__/shadow-probe-control-flow.dawn.test.ts +0 -264
- package/src/__tests__/shadow-quality-metrics.dawn.test.ts +0 -324
- package/src/__tests__/temporal-off-path.unit.test.ts +0 -69
- package/src/__tests__/video-cache-regression.unit.test.ts +0 -186
- package/src/asset-kind.ts +0 -7
- package/src/errors/sprite-animation.ts +0 -5
- package/src/scene-asset-port.ts +0 -32
- package/src/scene-collect-errors.ts +0 -30
- package/src/shadow-m3-calibrate.ts +0 -171
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// w12 - AssetRegistry browser path (loadByGuid + GUID-keyed catalog API)
|
|
2
|
+
//
|
|
3
|
+
// Migration from load(url) to loadByGuid (feat-20260513-guid-asset-package-system w13).
|
|
4
|
+
// feat-20260614 M8 (D-17): the registry catalogues GUID -> payload and
|
|
5
|
+
// `loadByGuid` returns the PAYLOAD (no handle). Column minting moved to
|
|
6
|
+
// `world.allocSharedRef`. Covers catalog + loadByGuid ok path + payload
|
|
7
|
+
// idempotency + AC-11 inspect() shape for a GUID-catalogued asset.
|
|
8
|
+
|
|
9
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
10
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
11
|
+
import type { MeshAsset as TypesMeshAsset } from '@forgeax/engine-types';
|
|
12
|
+
import { describe, expect, it } from 'vitest';
|
|
13
|
+
import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
|
|
14
|
+
|
|
15
|
+
const GUID_BROWSER_A = '00000000-0000-7000-8000-000000000021';
|
|
16
|
+
|
|
17
|
+
function makeMesh(): TypesMeshAsset {
|
|
18
|
+
return {
|
|
19
|
+
kind: 'mesh',
|
|
20
|
+
// 1 vertex * 12F canonical layout (position vec3 + normal vec3 + uv vec2 + tangent vec4)
|
|
21
|
+
vertices: new Float32Array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]),
|
|
22
|
+
indices: new Uint16Array([0]),
|
|
23
|
+
attributes: {},
|
|
24
|
+
submeshes: [
|
|
25
|
+
{
|
|
26
|
+
indexOffset: 0,
|
|
27
|
+
indexCount: 1,
|
|
28
|
+
vertexCount: 12,
|
|
29
|
+
topology: 'triangle-list',
|
|
30
|
+
materialSlot: 0,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
|
|
34
|
+
materialSlots: [{ slotName: 'Default' }],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('w12 - AssetRegistry browser loadByGuid happy path', () => {
|
|
39
|
+
it('loadByGuid() returns Ok(payload) for a catalogued GUID', async () => {
|
|
40
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
41
|
+
const parseResult = AssetGuid.parse(GUID_BROWSER_A);
|
|
42
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
43
|
+
const guid = parseResult.value;
|
|
44
|
+
const mesh = makeMesh();
|
|
45
|
+
reg.catalog<TypesMeshAsset>(guid, mesh);
|
|
46
|
+
const res = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
47
|
+
expect(res.ok).toBe(true);
|
|
48
|
+
if (!res.ok) return;
|
|
49
|
+
expect(res.value.kind).toBe('mesh');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('two loadByGuid(sameGuid) calls return the same payload', async () => {
|
|
53
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
54
|
+
const parseResult = AssetGuid.parse(GUID_BROWSER_A);
|
|
55
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
56
|
+
const guid = parseResult.value;
|
|
57
|
+
reg.catalog<TypesMeshAsset>(guid, makeMesh());
|
|
58
|
+
const a = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
59
|
+
const b = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
60
|
+
expect(a.ok).toBe(true);
|
|
61
|
+
expect(b.ok).toBe(true);
|
|
62
|
+
if (a.ok && b.ok) {
|
|
63
|
+
expect(a.value).toBe(b.value);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('AC-11: inspect() reports MeshAsset brand after catalog()', async () => {
|
|
68
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
69
|
+
const before = reg.inspect().assets.length;
|
|
70
|
+
const parseResult = AssetGuid.parse(GUID_BROWSER_A);
|
|
71
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
72
|
+
const guid = parseResult.value;
|
|
73
|
+
reg.catalog<TypesMeshAsset>(guid, makeMesh());
|
|
74
|
+
const snap = reg.inspect();
|
|
75
|
+
expect(snap.assets.length).toBe(before + 1);
|
|
76
|
+
const last = snap.assets[snap.assets.length - 1];
|
|
77
|
+
expect(last).toBeDefined();
|
|
78
|
+
if (last === undefined) return;
|
|
79
|
+
expect(last.kind).toBe('mesh');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// w13 - AssetRegistry Node path (loadByGuid + GUID-keyed catalog API).
|
|
2
|
+
//
|
|
3
|
+
// Migration from load(url) to loadByGuid (feat-20260513-guid-asset-package-system w13).
|
|
4
|
+
// feat-20260614 M8 (D-17): the registry catalogues GUID -> payload and
|
|
5
|
+
// `loadByGuid` returns the PAYLOAD (no handle); column minting moved to
|
|
6
|
+
// `world.allocSharedRef`, handle->payload resolution to `resolveAssetHandle`.
|
|
7
|
+
// Covers catalog + loadByGuid ok path + payload idempotency + asset-not-found
|
|
8
|
+
// error path on missing GUID + asset-not-found on an unresolvable handle.
|
|
9
|
+
|
|
10
|
+
import { AssetRegistry, resolveAssetHandle } from '@forgeax/engine-assets-runtime';
|
|
11
|
+
import { World } from '@forgeax/engine-ecs';
|
|
12
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
13
|
+
import type { Handle, TextureAsset, MeshAsset as TypesMeshAsset } from '@forgeax/engine-types';
|
|
14
|
+
import { toShared } from '@forgeax/engine-types';
|
|
15
|
+
import { describe, expect, it } from 'vitest';
|
|
16
|
+
import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
|
|
17
|
+
|
|
18
|
+
const GUID_DAWN_A = '00000000-0000-7000-8000-000000000031';
|
|
19
|
+
const GUID_DAWN_B = '00000000-0000-7000-8000-000000000032';
|
|
20
|
+
|
|
21
|
+
function makeMesh(): TypesMeshAsset {
|
|
22
|
+
return {
|
|
23
|
+
kind: 'mesh',
|
|
24
|
+
// 1 vertex * 12F canonical layout (position vec3 + normal vec3 + uv vec2 + tangent vec4)
|
|
25
|
+
vertices: new Float32Array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]),
|
|
26
|
+
indices: new Uint16Array([0]),
|
|
27
|
+
attributes: {},
|
|
28
|
+
submeshes: [
|
|
29
|
+
{
|
|
30
|
+
indexOffset: 0,
|
|
31
|
+
indexCount: 1,
|
|
32
|
+
vertexCount: 12,
|
|
33
|
+
topology: 'triangle-list',
|
|
34
|
+
materialSlot: 0,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
materialSlots: [{ slotName: 'Default' }],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe('w13 - AssetRegistry Node loadByGuid happy path', () => {
|
|
43
|
+
it('loadByGuid() returns Ok(payload) for a catalogued GUID', async () => {
|
|
44
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
45
|
+
const parseResult = AssetGuid.parse(GUID_DAWN_A);
|
|
46
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
47
|
+
const guid = parseResult.value;
|
|
48
|
+
const mesh = makeMesh();
|
|
49
|
+
reg.catalog<TypesMeshAsset>(guid, mesh);
|
|
50
|
+
const res = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
51
|
+
expect(res.ok).toBe(true);
|
|
52
|
+
if (!res.ok) return;
|
|
53
|
+
expect(res.value.kind).toBe('mesh');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('two loadByGuid(sameGuid) calls return same payload (idempotent)', async () => {
|
|
57
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
58
|
+
const parseResult = AssetGuid.parse(GUID_DAWN_A);
|
|
59
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
60
|
+
const guid = parseResult.value;
|
|
61
|
+
reg.catalog<TypesMeshAsset>(guid, makeMesh());
|
|
62
|
+
const a = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
63
|
+
const b = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
64
|
+
expect(a.ok).toBe(true);
|
|
65
|
+
expect(b.ok).toBe(true);
|
|
66
|
+
if (a.ok && b.ok) {
|
|
67
|
+
expect(a.value).toBe(b.value);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('w13 - AssetRegistry Node error paths (AC-03 migration)', () => {
|
|
73
|
+
it('asset-not-found: loadByGuid(unregistered guid)', async () => {
|
|
74
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
75
|
+
const parseResult = AssetGuid.parse(GUID_DAWN_B);
|
|
76
|
+
if (!parseResult.ok) throw new Error('expected ok');
|
|
77
|
+
const guid = parseResult.value;
|
|
78
|
+
const res = await reg.loadByGuid<TypesMeshAsset>(guid);
|
|
79
|
+
expect(res.ok).toBe(false);
|
|
80
|
+
if (!res.ok) expect(res.error.code).toBe('asset-not-found');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('asset-not-found: resolveAssetHandle(unallocated gen-0 handle)', () => {
|
|
84
|
+
const world = new World();
|
|
85
|
+
// gen-0 user-tier handle for a never-allocated slot: passes the generation
|
|
86
|
+
// gate (storeGen defaults to 0) then misses the payload -> asset-not-found.
|
|
87
|
+
// (A gen>0 handle would instead surface 'shared-ref-stale' per D-3/AC-10 —
|
|
88
|
+
// see asset.unit.test.ts "unresolvable handle: stale error forwarded".)
|
|
89
|
+
const fake = toShared<'TextureAsset'>(99999);
|
|
90
|
+
const res = resolveAssetHandle<TextureAsset>(world, fake as Handle<string, 'shared'>);
|
|
91
|
+
expect(res.ok).toBe(false);
|
|
92
|
+
if (!res.ok) expect(res.error.code).toBe('asset-not-found');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// w1 TDD: listCatalog unit test (plan-strategy section 2 D1)
|
|
2
|
+
//
|
|
3
|
+
// Test-first approach — call listCatalog() before it exists on AssetRegistry,
|
|
4
|
+
// confirming the TDD "red" phase via TypeScript compile error (TS2339).
|
|
5
|
+
// w2 will add the implementation and turn these tests green.
|
|
6
|
+
//
|
|
7
|
+
// plan-strategy section 2 D1 (engine export for AC-03 asset panel enumeration);
|
|
8
|
+
// requirements AC-03 (asset panel = engine truth, no parallel discovery);
|
|
9
|
+
// research Finding 5 (AssetRegistry public API is all guid point-lookup;
|
|
10
|
+
// assetCatalog/packIndexCache are private — no enumeration primitive exists yet).
|
|
11
|
+
|
|
12
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
13
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
14
|
+
import type { MeshAsset } from '@forgeax/engine-types';
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
16
|
+
import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
|
|
17
|
+
|
|
18
|
+
function makeReg(): AssetRegistry {
|
|
19
|
+
return new AssetRegistry(makeMockShaderRegistry());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function makeMeshFixture(): MeshAsset {
|
|
23
|
+
return {
|
|
24
|
+
kind: 'mesh',
|
|
25
|
+
vertices: new Float32Array(36),
|
|
26
|
+
indices: new Uint16Array([0, 1, 2]),
|
|
27
|
+
attributes: {},
|
|
28
|
+
materialSlots: [{ slotName: 'Default' }],
|
|
29
|
+
submeshes: [
|
|
30
|
+
{
|
|
31
|
+
indexOffset: 0,
|
|
32
|
+
indexCount: 3,
|
|
33
|
+
vertexCount: 3,
|
|
34
|
+
materialSlot: 0,
|
|
35
|
+
topology: 'triangle-list' as const,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
} as unknown as MeshAsset;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('D-1 listCatalog() (TDD: red before w2 impl)', () => {
|
|
42
|
+
it('returns non-empty array for catalogued assets matching inspect() truth', () => {
|
|
43
|
+
const reg = makeReg();
|
|
44
|
+
const guid = AssetGuid.format(AssetGuid.random());
|
|
45
|
+
const mesh = makeMeshFixture();
|
|
46
|
+
reg.catalog(guid, mesh);
|
|
47
|
+
|
|
48
|
+
const list = reg.listCatalog();
|
|
49
|
+
expect(Array.isArray(list)).toBe(true);
|
|
50
|
+
expect(list.length).toBeGreaterThan(0);
|
|
51
|
+
|
|
52
|
+
const found = list.find(
|
|
53
|
+
(e: { guid: string; kind: string; name?: string; packageUrl: string }) =>
|
|
54
|
+
e.guid === guid.toLowerCase(),
|
|
55
|
+
);
|
|
56
|
+
expect(found).toBeDefined();
|
|
57
|
+
expect(found?.guid).toBe(guid.toLowerCase());
|
|
58
|
+
expect(found?.kind).toBe('mesh');
|
|
59
|
+
// name derived via resolveName (empty for no-package catalogued asset)
|
|
60
|
+
expect(found).toHaveProperty('name');
|
|
61
|
+
expect(found).toHaveProperty('packageUrl');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('returns empty array for a registry with zero catalogued assets (boundary E3)', () => {
|
|
65
|
+
const reg = makeReg();
|
|
66
|
+
// Fresh registry still has builtins. Clear them via invalidateAll.
|
|
67
|
+
reg.invalidateAll();
|
|
68
|
+
const list = reg.listCatalog();
|
|
69
|
+
expect(Array.isArray(list)).toBe(true);
|
|
70
|
+
expect(list.length).toBe(0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('surfaces dev-path refs as flattened GUID edges (Content Browser dependency graph)', () => {
|
|
74
|
+
const reg = makeReg();
|
|
75
|
+
const guid = AssetGuid.format(AssetGuid.random());
|
|
76
|
+
const dep1 = AssetGuid.format(AssetGuid.random());
|
|
77
|
+
const dep2 = AssetGuid.format(AssetGuid.random());
|
|
78
|
+
const mesh = makeMeshFixture();
|
|
79
|
+
// catalog(guid, asset, refs) stores the rich AssetRef[] on the envelope;
|
|
80
|
+
// listCatalog must flatten it to plain GUID strings.
|
|
81
|
+
reg.catalog(guid, mesh, [{ guid: dep1, sourceField: { fieldName: 'a' } }, { guid: dep2 }]);
|
|
82
|
+
|
|
83
|
+
const found = reg.listCatalog().find((e) => e.guid === guid.toLowerCase());
|
|
84
|
+
expect(found?.refs).toEqual([dep1, dep2]);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('omits refs when an asset has no outgoing edges (add-only, undefined not [])', () => {
|
|
88
|
+
const reg = makeReg();
|
|
89
|
+
const guid = AssetGuid.format(AssetGuid.random());
|
|
90
|
+
reg.catalog(guid, makeMeshFixture());
|
|
91
|
+
|
|
92
|
+
const found = reg.listCatalog().find((e) => e.guid === guid.toLowerCase());
|
|
93
|
+
expect(found).toBeDefined();
|
|
94
|
+
expect(found?.refs).toBeUndefined();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('returns a snapshot — two calls return distinct array objects (no internal Map leak, charter P4)', () => {
|
|
98
|
+
const reg = makeReg();
|
|
99
|
+
const guid = AssetGuid.format(AssetGuid.random());
|
|
100
|
+
const mesh = makeMeshFixture();
|
|
101
|
+
reg.catalog(guid, mesh);
|
|
102
|
+
|
|
103
|
+
const first = reg.listCatalog();
|
|
104
|
+
const firstLen = first.length;
|
|
105
|
+
|
|
106
|
+
const second = reg.listCatalog();
|
|
107
|
+
expect(second.length).toBe(firstLen);
|
|
108
|
+
// Snapshot identity: two calls return distinct array objects
|
|
109
|
+
// (no internal Map reference leak — charter P4).
|
|
110
|
+
expect(first).not.toBe(second);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Prod path: sourcePath is only present on the pack-index (fetchPackIndex ->
|
|
115
|
+
// packIndexCache), never on dev-path catalog() envelopes. Editors need it to
|
|
116
|
+
// locate the `.meta.json` sidecar for external-asset CRUD; `packageUrl`
|
|
117
|
+
// points at the Pack v2 package and cannot
|
|
118
|
+
// be reversed to the source path.
|
|
119
|
+
describe('listCatalog() prod-path sourcePath (editor CRUD sidecar lookup)', () => {
|
|
120
|
+
const PACK_INDEX_URL = '/pack-index.json';
|
|
121
|
+
const MESH_GUID = 'a0000000-0000-4000-a000-000000000001';
|
|
122
|
+
const MESH_URL = '/assets/arrow_bow.fbx.a0000000.pack.json';
|
|
123
|
+
const MESH_SOURCE = 'games/marscraft/assets/arrow_bow.fbx';
|
|
124
|
+
// A row that omits sourcePath (legacy / malformed pack-index) must surface as
|
|
125
|
+
// undefined, not '', so consumers can distinguish "no source" from "empty".
|
|
126
|
+
const INLINE_GUID = 'a0000000-0000-4000-a000-000000000002';
|
|
127
|
+
|
|
128
|
+
let originalFetch: typeof globalThis.fetch | undefined;
|
|
129
|
+
|
|
130
|
+
beforeEach(() => {
|
|
131
|
+
originalFetch = globalThis.fetch;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
afterEach(() => {
|
|
135
|
+
if (originalFetch !== undefined) {
|
|
136
|
+
globalThis.fetch = originalFetch;
|
|
137
|
+
} else {
|
|
138
|
+
// biome-ignore lint/suspicious/noExplicitAny: test teardown
|
|
139
|
+
delete (globalThis as any).fetch;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('surfaces sourcePath from the pack-index; omits it for rows that lack one', async () => {
|
|
144
|
+
const reg = makeReg();
|
|
145
|
+
reg.configurePackIndex(PACK_INDEX_URL);
|
|
146
|
+
|
|
147
|
+
const packIndex = [
|
|
148
|
+
{ guid: MESH_GUID, packageUrl: MESH_URL, kind: 'mesh', sourcePath: MESH_SOURCE },
|
|
149
|
+
{ guid: INLINE_GUID, packageUrl: '/assets/other.pack.json', kind: 'mesh' },
|
|
150
|
+
];
|
|
151
|
+
globalThis.fetch = vi.fn().mockImplementation((url: string) => {
|
|
152
|
+
if (url === PACK_INDEX_URL) {
|
|
153
|
+
return Promise.resolve({ ok: true, json: () => Promise.resolve(packIndex) });
|
|
154
|
+
}
|
|
155
|
+
return Promise.resolve({ ok: false, status: 404 });
|
|
156
|
+
}) as typeof globalThis.fetch;
|
|
157
|
+
|
|
158
|
+
// Populate packIndexCache without needing the (missing) pack bodies:
|
|
159
|
+
// refreshCatalog fetches + parses the pack-index into packIndexCache, which
|
|
160
|
+
// is the source listCatalog reads for prod rows.
|
|
161
|
+
await reg.refreshCatalog();
|
|
162
|
+
|
|
163
|
+
const withSource = reg.listCatalog().find((e) => e.guid === MESH_GUID.toLowerCase());
|
|
164
|
+
expect(withSource?.sourcePath).toBe(MESH_SOURCE);
|
|
165
|
+
|
|
166
|
+
const withoutSource = reg.listCatalog().find((e) => e.guid === INLINE_GUID.toLowerCase());
|
|
167
|
+
expect(withoutSource).toBeDefined();
|
|
168
|
+
expect(withoutSource?.sourcePath).toBeUndefined();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// asset-registry.mesh-bin.test.ts -- bug-20260610-pack-mesh-binarize-fetchpackfile-cache
|
|
2
|
+
// M2 / m2-1: regression test for mesh binarize round-trip via .pack.json + .bin
|
|
3
|
+
// sidecar (Fix A). RED at this commit (loader cannot read .bin yet); GREEN
|
|
4
|
+
// after the implementation commit.
|
|
5
|
+
//
|
|
6
|
+
// Cases (plan-decisions D-6):
|
|
7
|
+
// (A) binarized new path -- mesh entry payload is the empty sentinel (vertices=[],
|
|
8
|
+
// indices=[], data=Uint8Array(0)); the runtime resolves vertices/indices from
|
|
9
|
+
// a sibling <guid>.bin URL referenced by the catalog row. Asserts
|
|
10
|
+
// round-tripped vertices and indices are byte-equal to the originals.
|
|
11
|
+
// (B) inline fallback (CON-7) -- mesh entry payload carries inline number arrays
|
|
12
|
+
// (legacy pack shape). meshLoader's existing Array.isArray branch must still
|
|
13
|
+
// work. Asserts handle resolves and registered MeshAsset has the inline
|
|
14
|
+
// vertices/indices.
|
|
15
|
+
// (C) empty mesh -- vertices=[], indices=[] sentinel + 16-byte deterministic
|
|
16
|
+
// header (vlen=0, ilen=0, iwidth=0, jsonlen=0). loader returns a mesh with
|
|
17
|
+
// 0 vertices and 0 indices, no panic.
|
|
18
|
+
//
|
|
19
|
+
// Anchors: requirements AC-04 / AC-05 / CON-1 / CON-7;
|
|
20
|
+
// plan-strategy decisions D-1 / D-2 / D-3 / D-6;
|
|
21
|
+
// plan-decisions D-6 (3-case coverage).
|
|
22
|
+
//
|
|
23
|
+
// The test producer delegates the v4 header and canonical projection to the
|
|
24
|
+
// import owner; the runtime only consumes the resulting bytes.
|
|
25
|
+
|
|
26
|
+
import { AssetRegistry } from '@forgeax/engine-assets-runtime';
|
|
27
|
+
import { packMeshBinV4 } from '@forgeax/engine-import';
|
|
28
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
29
|
+
import type { MeshAsset } from '@forgeax/engine-types';
|
|
30
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
31
|
+
import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
|
|
32
|
+
|
|
33
|
+
// 12 floats per vertex (position vec3 + normal vec3 + uv vec2 + tangent vec4) --
|
|
34
|
+
// matches PROCEDURAL_FLOATS_PER_VERTEX and the meshLoader stride invariant.
|
|
35
|
+
const FLOATS_PER_VERTEX = 12;
|
|
36
|
+
|
|
37
|
+
const MESH_BIN_GUID = '00000000-0000-7000-8000-00006d657368'; // mesh sentinel
|
|
38
|
+
const MESH_INLINE_GUID = '00000000-0000-7000-8000-696e6c696e65'; // inline
|
|
39
|
+
const MESH_EMPTY_GUID = '00000000-0000-7000-8000-656d70747974'; // empty
|
|
40
|
+
|
|
41
|
+
function packMeshBinForTest(
|
|
42
|
+
vertices: Float32Array,
|
|
43
|
+
indices: Uint16Array | Uint32Array,
|
|
44
|
+
metaJson: string,
|
|
45
|
+
): Uint8Array {
|
|
46
|
+
const parsed = JSON.parse(metaJson) as Record<string, unknown>;
|
|
47
|
+
const vertexCount = vertices.length / FLOATS_PER_VERTEX;
|
|
48
|
+
const position = new Float32Array(vertexCount * 3);
|
|
49
|
+
const normal = new Float32Array(vertexCount * 3);
|
|
50
|
+
const uv = new Float32Array(vertexCount * 2);
|
|
51
|
+
const tangent = new Float32Array(vertexCount * 4);
|
|
52
|
+
for (let vertex = 0; vertex < vertexCount; vertex++) {
|
|
53
|
+
const source = vertex * FLOATS_PER_VERTEX;
|
|
54
|
+
position.set(vertices.subarray(source, source + 3), vertex * 3);
|
|
55
|
+
normal.set(vertices.subarray(source + 3, source + 6), vertex * 3);
|
|
56
|
+
uv.set(vertices.subarray(source + 6, source + 8), vertex * 2);
|
|
57
|
+
tangent.set(vertices.subarray(source + 8, source + 12), vertex * 4);
|
|
58
|
+
}
|
|
59
|
+
const packed = packMeshBinV4(
|
|
60
|
+
{
|
|
61
|
+
vertices,
|
|
62
|
+
indices,
|
|
63
|
+
attributes: {
|
|
64
|
+
position,
|
|
65
|
+
normal,
|
|
66
|
+
uv,
|
|
67
|
+
tangent,
|
|
68
|
+
},
|
|
69
|
+
submeshes: parsed.submeshes as MeshAsset['submeshes'],
|
|
70
|
+
aabb: parsed.aabb as MeshAsset['aabb'],
|
|
71
|
+
},
|
|
72
|
+
'runtime://asset-registry',
|
|
73
|
+
);
|
|
74
|
+
if (!packed.ok) throw new Error(packed.error.actual);
|
|
75
|
+
return packed.value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function makePackIndex(rows: Array<{ guid: string; packageUrl: string }>) {
|
|
79
|
+
return rows.map((r) => ({
|
|
80
|
+
guid: r.guid,
|
|
81
|
+
packageUrl: r.packageUrl,
|
|
82
|
+
kind: 'mesh' as const,
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface FetchRoute {
|
|
87
|
+
json?: unknown;
|
|
88
|
+
bytes?: Uint8Array;
|
|
89
|
+
status?: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function installFetchMock(routes: Map<string, FetchRoute>): void {
|
|
93
|
+
globalThis.fetch = (async (input: string | URL | Request) => {
|
|
94
|
+
const url =
|
|
95
|
+
typeof input === 'string'
|
|
96
|
+
? input
|
|
97
|
+
: input instanceof URL
|
|
98
|
+
? input.href
|
|
99
|
+
: (input as Request).url;
|
|
100
|
+
const route = routes.get(url);
|
|
101
|
+
if (route === undefined) {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
status: 404,
|
|
105
|
+
json: async () => null,
|
|
106
|
+
arrayBuffer: async () => new ArrayBuffer(0),
|
|
107
|
+
} as unknown as Response;
|
|
108
|
+
}
|
|
109
|
+
if (route.status !== undefined && route.status >= 400) {
|
|
110
|
+
return { ok: false, status: route.status } as unknown as Response;
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
ok: true,
|
|
114
|
+
status: 200,
|
|
115
|
+
json: async () => route.json,
|
|
116
|
+
arrayBuffer: async () =>
|
|
117
|
+
route.bytes !== undefined
|
|
118
|
+
? route.bytes.buffer.slice(
|
|
119
|
+
route.bytes.byteOffset,
|
|
120
|
+
route.bytes.byteOffset + route.bytes.byteLength,
|
|
121
|
+
)
|
|
122
|
+
: new ArrayBuffer(0),
|
|
123
|
+
} as unknown as Response;
|
|
124
|
+
}) as unknown as typeof globalThis.fetch;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
describe('mesh-bin loader (M2 / m2-1)', () => {
|
|
128
|
+
const originalFetch = globalThis.fetch;
|
|
129
|
+
|
|
130
|
+
beforeEach(() => {
|
|
131
|
+
vi.restoreAllMocks();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
afterEach(() => {
|
|
135
|
+
globalThis.fetch = originalFetch;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('(A) binarized path: vertices/indices reconstructed byte-equal from sibling .bin', async () => {
|
|
139
|
+
// Two-vertex triangle stub (24 floats total = 2 verts * 12F). Vertex count <=
|
|
140
|
+
// 0xffff -> Uint16Array indices.
|
|
141
|
+
const vertices = new Float32Array(FLOATS_PER_VERTEX * 2);
|
|
142
|
+
for (let i = 0; i < vertices.length; i++) vertices[i] = i + 0.5;
|
|
143
|
+
const indices = new Uint16Array([0, 1, 0]);
|
|
144
|
+
const metaJson = JSON.stringify({
|
|
145
|
+
submeshes: [{ indexOffset: 0, indexCount: 3, vertexCount: 2, topology: 'triangle-list' }],
|
|
146
|
+
attributes: {},
|
|
147
|
+
aabb: [0, 0, 0, 1, 1, 1],
|
|
148
|
+
});
|
|
149
|
+
const binBytes = packMeshBinForTest(vertices, indices, metaJson);
|
|
150
|
+
|
|
151
|
+
const packIndexUrl = '/pack-index.json';
|
|
152
|
+
const packUrl = `/assets/${MESH_BIN_GUID.toLowerCase()}.pack.json`;
|
|
153
|
+
const binUrl = `/assets/${MESH_BIN_GUID.toLowerCase()}/body.bin`;
|
|
154
|
+
const routes = new Map<string, FetchRoute>([
|
|
155
|
+
[packIndexUrl, { json: makePackIndex([{ guid: MESH_BIN_GUID, packageUrl: packUrl }]) }],
|
|
156
|
+
[
|
|
157
|
+
packUrl,
|
|
158
|
+
{
|
|
159
|
+
json: {
|
|
160
|
+
schemaVersion: '2.0.0',
|
|
161
|
+
kind: 'internal-text-package',
|
|
162
|
+
assets: [
|
|
163
|
+
{
|
|
164
|
+
guid: MESH_BIN_GUID,
|
|
165
|
+
kind: 'mesh',
|
|
166
|
+
payload: {},
|
|
167
|
+
refs: [],
|
|
168
|
+
artifacts: {
|
|
169
|
+
body: {
|
|
170
|
+
path: `${MESH_BIN_GUID.toLowerCase()}/body.bin`,
|
|
171
|
+
mediaType: 'application/x-forgeax-mesh',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
[binUrl, { bytes: binBytes }],
|
|
180
|
+
]);
|
|
181
|
+
installFetchMock(routes);
|
|
182
|
+
|
|
183
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
184
|
+
reg.configurePackIndex(packIndexUrl);
|
|
185
|
+
|
|
186
|
+
const parsed = AssetGuid.parse(MESH_BIN_GUID);
|
|
187
|
+
expect(parsed.ok).toBe(true);
|
|
188
|
+
if (!parsed.ok) return;
|
|
189
|
+
|
|
190
|
+
const result = await reg.loadByGuid<MeshAsset>(parsed.value);
|
|
191
|
+
expect(result.ok).toBe(true);
|
|
192
|
+
if (!result.ok) return;
|
|
193
|
+
|
|
194
|
+
// D-17: loadByGuid returns the payload directly (registry holds no handles).
|
|
195
|
+
const mesh = result.value;
|
|
196
|
+
expect(mesh.kind).toBe('mesh');
|
|
197
|
+
expect(mesh.vertices.length).toBe(vertices.length);
|
|
198
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
199
|
+
expect(mesh.vertices[i]).toBe(vertices[i]);
|
|
200
|
+
}
|
|
201
|
+
expect(mesh.indices).toBeInstanceOf(Uint16Array);
|
|
202
|
+
expect(mesh.indices?.length).toBe(indices.length);
|
|
203
|
+
if (mesh.indices !== undefined) {
|
|
204
|
+
for (let i = 0; i < indices.length; i++) {
|
|
205
|
+
expect(mesh.indices[i]).toBe(indices[i]);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('(B) inline fallback (CON-7): legacy pack with Array.isArray vertices still loads', async () => {
|
|
211
|
+
// Single triangle, 12 floats per vertex, 3 vertices -> 36 floats, 3 indices.
|
|
212
|
+
const verticesArr: number[] = [];
|
|
213
|
+
for (let i = 0; i < FLOATS_PER_VERTEX * 3; i++) verticesArr.push(i + 0.25);
|
|
214
|
+
const indicesArr: number[] = [0, 1, 2];
|
|
215
|
+
|
|
216
|
+
const packIndexUrl = '/pack-index.json';
|
|
217
|
+
const packUrl = '/assets/inline.pack.json';
|
|
218
|
+
const routes = new Map<string, FetchRoute>([
|
|
219
|
+
[packIndexUrl, { json: makePackIndex([{ guid: MESH_INLINE_GUID, packageUrl: packUrl }]) }],
|
|
220
|
+
[
|
|
221
|
+
packUrl,
|
|
222
|
+
{
|
|
223
|
+
json: {
|
|
224
|
+
schemaVersion: '2.0.0',
|
|
225
|
+
kind: 'internal-text-package',
|
|
226
|
+
assets: [
|
|
227
|
+
{
|
|
228
|
+
guid: MESH_INLINE_GUID,
|
|
229
|
+
kind: 'mesh',
|
|
230
|
+
payload: {
|
|
231
|
+
vertices: verticesArr,
|
|
232
|
+
indices: indicesArr,
|
|
233
|
+
attributes: {},
|
|
234
|
+
},
|
|
235
|
+
refs: [],
|
|
236
|
+
artifacts: {},
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
]);
|
|
243
|
+
installFetchMock(routes);
|
|
244
|
+
|
|
245
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
246
|
+
reg.configurePackIndex(packIndexUrl);
|
|
247
|
+
|
|
248
|
+
const parsed = AssetGuid.parse(MESH_INLINE_GUID);
|
|
249
|
+
expect(parsed.ok).toBe(true);
|
|
250
|
+
if (!parsed.ok) return;
|
|
251
|
+
|
|
252
|
+
const result = await reg.loadByGuid<MeshAsset>(parsed.value);
|
|
253
|
+
expect(result.ok).toBe(true);
|
|
254
|
+
if (!result.ok) return;
|
|
255
|
+
|
|
256
|
+
// D-17: loadByGuid returns the payload directly (registry holds no handles).
|
|
257
|
+
const mesh = result.value;
|
|
258
|
+
expect(mesh.kind).toBe('mesh');
|
|
259
|
+
expect(mesh.vertices.length).toBe(verticesArr.length);
|
|
260
|
+
expect(mesh.vertices[0]).toBe(0.25);
|
|
261
|
+
expect(mesh.indices?.length).toBe(indicesArr.length);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('(C) empty mesh: v4 projection decodes to 0 verts / 0 indices', async () => {
|
|
265
|
+
const binBytes = packMeshBinForTest(
|
|
266
|
+
new Float32Array(0),
|
|
267
|
+
new Uint16Array(0),
|
|
268
|
+
JSON.stringify({
|
|
269
|
+
submeshes: [{ indexOffset: 0, indexCount: 0, vertexCount: 0, materialSlot: 0 }],
|
|
270
|
+
aabb: [0, 0, 0, 0, 0, 0],
|
|
271
|
+
}),
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
const packIndexUrl = '/pack-index.json';
|
|
275
|
+
const packUrl = `/assets/${MESH_EMPTY_GUID.toLowerCase()}.pack.json`;
|
|
276
|
+
const binUrl = `/assets/${MESH_EMPTY_GUID.toLowerCase()}/body.bin`;
|
|
277
|
+
const routes = new Map<string, FetchRoute>([
|
|
278
|
+
[packIndexUrl, { json: makePackIndex([{ guid: MESH_EMPTY_GUID, packageUrl: packUrl }]) }],
|
|
279
|
+
[
|
|
280
|
+
packUrl,
|
|
281
|
+
{
|
|
282
|
+
json: {
|
|
283
|
+
schemaVersion: '2.0.0',
|
|
284
|
+
kind: 'internal-text-package',
|
|
285
|
+
assets: [
|
|
286
|
+
{
|
|
287
|
+
guid: MESH_EMPTY_GUID,
|
|
288
|
+
kind: 'mesh',
|
|
289
|
+
payload: {},
|
|
290
|
+
refs: [],
|
|
291
|
+
artifacts: {
|
|
292
|
+
body: {
|
|
293
|
+
path: `${MESH_EMPTY_GUID.toLowerCase()}/body.bin`,
|
|
294
|
+
mediaType: 'application/x-forgeax-mesh',
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
[binUrl, { bytes: binBytes }],
|
|
303
|
+
]);
|
|
304
|
+
installFetchMock(routes);
|
|
305
|
+
|
|
306
|
+
const reg = new AssetRegistry(makeMockShaderRegistry());
|
|
307
|
+
reg.configurePackIndex(packIndexUrl);
|
|
308
|
+
|
|
309
|
+
const parsed = AssetGuid.parse(MESH_EMPTY_GUID);
|
|
310
|
+
expect(parsed.ok).toBe(true);
|
|
311
|
+
if (!parsed.ok) return;
|
|
312
|
+
|
|
313
|
+
const result = await reg.loadByGuid<MeshAsset>(parsed.value);
|
|
314
|
+
expect(result.ok).toBe(false);
|
|
315
|
+
});
|
|
316
|
+
});
|