@vgai/engine 0.2.0 → 0.3.0
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 +3 -1
- package/dist/adapter/authoring.d.ts +404 -0
- package/dist/adapter/authoring.d.ts.map +1 -0
- package/dist/adapter/authoring.js +22 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts +43 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
- package/dist/adapter/colyseus-networking-adapter.js +38 -0
- package/dist/adapter/first-party-systems.d.ts +38 -0
- package/dist/adapter/first-party-systems.d.ts.map +1 -0
- package/dist/adapter/first-party-systems.js +77 -0
- package/dist/adapter/game-adapter.d.ts +133 -0
- package/dist/adapter/game-adapter.d.ts.map +1 -0
- package/dist/adapter/game-adapter.js +10 -0
- package/dist/adapter/host-context.d.ts +73 -0
- package/dist/adapter/host-context.d.ts.map +1 -0
- package/dist/adapter/host-context.js +16 -0
- package/dist/adapter/index.d.ts +22 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +15 -0
- package/dist/adapter/ingest/game-contract.d.ts +53 -0
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
- package/dist/adapter/ingest/game-contract.js +30 -0
- package/dist/adapter/ingest/overlay-applier.d.ts +118 -0
- package/dist/adapter/ingest/overlay-applier.d.ts.map +1 -0
- package/dist/adapter/ingest/overlay-applier.js +132 -0
- package/dist/adapter/ingest/overlay-apply.d.ts +60 -0
- package/dist/adapter/ingest/overlay-apply.d.ts.map +1 -0
- package/dist/adapter/ingest/overlay-apply.js +101 -0
- package/dist/adapter/ingest/overlay-file.d.ts +79 -0
- package/dist/adapter/ingest/overlay-file.d.ts.map +1 -0
- package/dist/adapter/ingest/overlay-file.js +66 -0
- package/dist/adapter/ingest/overlay-report.d.ts +113 -0
- package/dist/adapter/ingest/overlay-report.d.ts.map +1 -0
- package/dist/adapter/ingest/overlay-report.js +103 -0
- package/dist/adapter/ingest/scene-capture.d.ts +97 -0
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
- package/dist/adapter/ingest/scene-capture.js +248 -0
- package/dist/adapter/ingest/upstream-pin.d.ts +47 -0
- package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
- package/dist/adapter/ingest/upstream-pin.js +50 -0
- package/dist/adapter/loop-gate-report.d.ts +34 -0
- package/dist/adapter/loop-gate-report.d.ts.map +1 -0
- package/dist/adapter/loop-gate-report.js +37 -0
- package/dist/adapter/rapier-physics-adapter.d.ts +12 -0
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
- package/dist/adapter/rapier-physics-adapter.js +46 -0
- package/dist/adapter/system-adapter.d.ts +133 -0
- package/dist/adapter/system-adapter.d.ts.map +1 -0
- package/dist/adapter/system-adapter.js +13 -0
- package/dist/adapter/transform.d.ts +18 -0
- package/dist/adapter/transform.d.ts.map +1 -0
- package/dist/adapter/transform.js +1 -0
- package/dist/adapter/vgai-scene-game-adapter.d.ts +116 -0
- package/dist/adapter/vgai-scene-game-adapter.d.ts.map +1 -0
- package/dist/adapter/vgai-scene-game-adapter.js +714 -0
- package/dist/adapter/world-kind.d.ts +30 -0
- package/dist/adapter/world-kind.d.ts.map +1 -0
- package/dist/adapter/world-kind.js +18 -0
- package/dist/ai/navigation.d.ts +64 -0
- package/dist/ai/navigation.d.ts.map +1 -0
- package/dist/ai/navigation.js +133 -0
- package/dist/animation/anim-graph-types.d.ts +25 -0
- package/dist/animation/anim-graph-types.d.ts.map +1 -0
- package/dist/animation/anim-graph-types.js +1 -0
- package/dist/animation/animation-clock.d.ts +213 -0
- package/dist/animation/animation-clock.d.ts.map +1 -0
- package/dist/animation/animation-clock.js +301 -0
- package/dist/animation/blend-node.d.ts +22 -0
- package/dist/animation/blend-node.d.ts.map +1 -0
- package/dist/animation/blend-node.js +97 -0
- package/dist/animation/camera-ownership.d.ts +250 -0
- package/dist/animation/camera-ownership.d.ts.map +1 -0
- package/dist/animation/camera-ownership.js +169 -0
- package/dist/animation/cinematic-cues.d.ts +200 -0
- package/dist/animation/cinematic-cues.d.ts.map +1 -0
- package/dist/animation/cinematic-cues.js +213 -0
- package/dist/animation/clip-map.d.ts +12 -0
- package/dist/animation/clip-map.d.ts.map +1 -0
- package/dist/animation/clip-map.js +37 -0
- package/dist/animation/gsap-registration.d.ts +119 -0
- package/dist/animation/gsap-registration.d.ts.map +1 -0
- package/dist/animation/gsap-registration.js +92 -0
- package/dist/animation/theatre-clock-binding.d.ts +89 -0
- package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
- package/dist/animation/theatre-clock-binding.js +29 -0
- package/dist/animation/theatre-director.d.ts +242 -0
- package/dist/animation/theatre-director.d.ts.map +1 -0
- package/dist/animation/theatre-director.js +235 -0
- package/dist/animation/theatre-object-binding.d.ts +305 -0
- package/dist/animation/theatre-object-binding.d.ts.map +1 -0
- package/dist/animation/theatre-object-binding.js +351 -0
- package/dist/animation/xstate-animation-binding.d.ts +111 -0
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
- package/dist/animation/xstate-animation-binding.js +307 -0
- package/dist/animation/xstate-animation-meta.d.ts +228 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
- package/dist/animation/xstate-animation-meta.js +221 -0
- package/dist/assets.d.ts +26 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +55 -0
- package/dist/audio/index.d.ts +4 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +24 -0
- package/dist/audio/tone-clock-binding.d.ts +75 -0
- package/dist/audio/tone-clock-binding.d.ts.map +1 -0
- package/dist/audio/tone-clock-binding.js +29 -0
- package/dist/audio/tone-context.d.ts +114 -0
- package/dist/audio/tone-context.d.ts.map +1 -0
- package/dist/audio/tone-context.js +39 -0
- package/dist/audio/tone-offline-render.d.ts +90 -0
- package/dist/audio/tone-offline-render.d.ts.map +1 -0
- package/dist/audio/tone-offline-render.js +56 -0
- package/dist/audio/wav-encode.d.ts +38 -0
- package/dist/audio/wav-encode.d.ts.map +1 -0
- package/dist/audio/wav-encode.js +97 -0
- package/dist/core/game-loop.d.ts +21 -0
- package/dist/core/game-loop.d.ts.map +1 -0
- package/dist/core/game-loop.js +130 -0
- package/dist/core/system-runner.d.ts +120 -0
- package/dist/core/system-runner.d.ts.map +1 -0
- package/dist/core/system-runner.js +286 -0
- package/dist/core/types.d.ts +58 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +25 -0
- package/dist/data/data-asset.d.ts +101 -0
- package/dist/data/data-asset.d.ts.map +1 -0
- package/dist/data/data-asset.js +122 -0
- package/dist/data/data-check-core.d.ts +110 -0
- package/dist/data/data-check-core.d.ts.map +1 -0
- package/dist/data/data-check-core.js +178 -0
- package/dist/data/data-ref.d.ts +79 -0
- package/dist/data/data-ref.d.ts.map +1 -0
- package/dist/data/data-ref.js +130 -0
- package/dist/data/vite-plugin-data.d.ts +79 -0
- package/dist/data/vite-plugin-data.d.ts.map +1 -0
- package/dist/data/vite-plugin-data.js +217 -0
- package/dist/dev/console-bridge.d.ts +22 -0
- package/dist/dev/console-bridge.d.ts.map +1 -0
- package/dist/dev/console-bridge.js +71 -0
- package/dist/dev/debug-draw.d.ts +24 -0
- package/dist/dev/debug-draw.d.ts.map +1 -0
- package/dist/dev/debug-draw.js +73 -0
- package/dist/dev/logger.d.ts +30 -0
- package/dist/dev/logger.d.ts.map +1 -0
- package/dist/dev/logger.js +90 -0
- package/dist/ecs/component-manager.d.ts +189 -0
- package/dist/ecs/component-manager.d.ts.map +1 -0
- package/dist/ecs/component-manager.js +676 -0
- package/dist/ecs/game-component.d.ts +97 -0
- package/dist/ecs/game-component.d.ts.map +1 -0
- package/dist/ecs/game-component.js +80 -0
- package/dist/ecs/hmr-swap-report.d.ts +53 -0
- package/dist/ecs/hmr-swap-report.d.ts.map +1 -0
- package/dist/ecs/hmr-swap-report.js +55 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/input/input-manager.d.ts +596 -0
- package/dist/input/input-manager.d.ts.map +1 -0
- package/dist/input/input-manager.js +1564 -0
- package/dist/input/input-types.d.ts +171 -0
- package/dist/input/input-types.d.ts.map +1 -0
- package/dist/input/input-types.js +1 -0
- package/dist/input/prompt-labels.d.ts +21 -0
- package/dist/input/prompt-labels.d.ts.map +1 -0
- package/dist/input/prompt-labels.js +121 -0
- package/dist/input/rebind-controller.d.ts +59 -0
- package/dist/input/rebind-controller.d.ts.map +1 -0
- package/dist/input/rebind-controller.js +85 -0
- package/dist/input/schema.d.ts +16 -0
- package/dist/input/schema.d.ts.map +1 -0
- package/dist/input/schema.js +228 -0
- package/dist/loader.d.ts +43 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +59 -0
- package/dist/manifest/index.d.ts +5 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +8 -0
- package/dist/manifest/load-file.d.ts +4 -0
- package/dist/manifest/load-file.d.ts.map +1 -0
- package/dist/manifest/load-file.js +14 -0
- package/dist/manifest/load.d.ts +117 -0
- package/dist/manifest/load.d.ts.map +1 -0
- package/dist/manifest/load.js +255 -0
- package/dist/manifest/schema.d.ts +173 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +302 -0
- package/dist/physics/collision-system.d.ts +41 -0
- package/dist/physics/collision-system.d.ts.map +1 -0
- package/dist/physics/collision-system.js +64 -0
- package/dist/physics/physics-registry.d.ts +45 -0
- package/dist/physics/physics-registry.d.ts.map +1 -0
- package/dist/physics/physics-registry.js +65 -0
- package/dist/physics/transform-writer.d.ts +16 -0
- package/dist/physics/transform-writer.d.ts.map +1 -0
- package/dist/physics/transform-writer.js +38 -0
- package/dist/physics/trigger-dispatch.d.ts +24 -0
- package/dist/physics/trigger-dispatch.d.ts.map +1 -0
- package/dist/physics/trigger-dispatch.js +80 -0
- package/dist/react/game-state.d.ts +105 -0
- package/dist/react/game-state.d.ts.map +1 -0
- package/dist/react/game-state.js +144 -0
- package/dist/react/use-data.d.ts +60 -0
- package/dist/react/use-data.d.ts.map +1 -0
- package/dist/react/use-data.js +96 -0
- package/dist/react/use-selection.d.ts +75 -0
- package/dist/react/use-selection.d.ts.map +1 -0
- package/dist/react/use-selection.js +90 -0
- package/dist/render/auto-batcher.d.ts +34 -0
- package/dist/render/auto-batcher.d.ts.map +1 -0
- package/dist/render/auto-batcher.js +140 -0
- package/dist/render/render-batch-system.d.ts +33 -0
- package/dist/render/render-batch-system.d.ts.map +1 -0
- package/dist/render/render-batch-system.js +230 -0
- package/dist/render/render-features.d.ts +47 -0
- package/dist/render/render-features.d.ts.map +1 -0
- package/dist/render/render-features.js +105 -0
- package/dist/render/render-settings.d.ts +36 -0
- package/dist/render/render-settings.d.ts.map +1 -0
- package/dist/render/render-settings.js +51 -0
- package/dist/runtime/create-runtime.d.ts +280 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -0
- package/dist/runtime/create-runtime.js +795 -0
- package/dist/runtime/frame-selector-cache.d.ts +41 -0
- package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
- package/dist/runtime/frame-selector-cache.js +65 -0
- package/dist/runtime/game.d.ts +433 -0
- package/dist/runtime/game.d.ts.map +1 -0
- package/dist/runtime/game.js +569 -0
- package/dist/runtime/input-router.d.ts +78 -0
- package/dist/runtime/input-router.d.ts.map +1 -0
- package/dist/runtime/input-router.js +171 -0
- package/dist/runtime/mount-game.d.ts +129 -0
- package/dist/runtime/mount-game.d.ts.map +1 -0
- package/dist/runtime/mount-game.js +152 -0
- package/dist/runtime/mount-manifest.d.ts +119 -0
- package/dist/runtime/mount-manifest.d.ts.map +1 -0
- package/dist/runtime/mount-manifest.js +204 -0
- package/dist/runtime/render-audio-control.d.ts +110 -0
- package/dist/runtime/render-audio-control.d.ts.map +1 -0
- package/dist/runtime/render-audio-control.js +111 -0
- package/dist/runtime/render-control.d.ts +291 -0
- package/dist/runtime/render-control.d.ts.map +1 -0
- package/dist/runtime/render-control.js +264 -0
- package/dist/runtime/render-seed.d.ts +57 -0
- package/dist/runtime/render-seed.d.ts.map +1 -0
- package/dist/runtime/render-seed.js +74 -0
- package/dist/runtime/scene-ui-bridge.d.ts +69 -0
- package/dist/runtime/scene-ui-bridge.d.ts.map +1 -0
- package/dist/runtime/scene-ui-bridge.js +23 -0
- package/dist/runtime/scene-ui-data.d.ts +13 -0
- package/dist/runtime/scene-ui-data.d.ts.map +1 -0
- package/dist/runtime/scene-ui-data.js +92 -0
- package/dist/runtime/state-bridge.d.ts +47 -0
- package/dist/runtime/state-bridge.d.ts.map +1 -0
- package/dist/runtime/state-bridge.js +53 -0
- package/dist/runtime/types.d.ts +179 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +1 -0
- package/dist/scene/asset-loaders.d.ts +79 -0
- package/dist/scene/asset-loaders.d.ts.map +1 -0
- package/dist/scene/asset-loaders.js +141 -0
- package/dist/scene/asset-paths.d.ts +11 -0
- package/dist/scene/asset-paths.d.ts.map +1 -0
- package/dist/scene/asset-paths.js +108 -0
- package/dist/scene/asset-ref-check.d.ts +88 -0
- package/dist/scene/asset-ref-check.d.ts.map +1 -0
- package/dist/scene/asset-ref-check.js +214 -0
- package/dist/scene/asset-registry.d.ts +30 -0
- package/dist/scene/asset-registry.d.ts.map +1 -0
- package/dist/scene/asset-registry.js +50 -0
- package/dist/scene/collider-dimensions.d.ts +63 -0
- package/dist/scene/collider-dimensions.d.ts.map +1 -0
- package/dist/scene/collider-dimensions.js +98 -0
- package/dist/scene/component-registry.d.ts +17 -0
- package/dist/scene/component-registry.d.ts.map +1 -0
- package/dist/scene/component-registry.js +28 -0
- package/dist/scene/defaults.d.ts +252 -0
- package/dist/scene/defaults.d.ts.map +1 -0
- package/dist/scene/defaults.js +151 -0
- package/dist/scene/geometries/index.d.ts +8 -0
- package/dist/scene/geometries/index.d.ts.map +1 -0
- package/dist/scene/geometries/index.js +7 -0
- package/dist/scene/geometries/terrain.d.ts +2 -0
- package/dist/scene/geometries/terrain.d.ts.map +1 -0
- package/dist/scene/geometries/terrain.js +37 -0
- package/dist/scene/geometry-registry.d.ts +24 -0
- package/dist/scene/geometry-registry.d.ts.map +1 -0
- package/dist/scene/geometry-registry.js +20 -0
- package/dist/scene/instance-registry.d.ts +36 -0
- package/dist/scene/instance-registry.d.ts.map +1 -0
- package/dist/scene/instance-registry.js +55 -0
- package/dist/scene/instancers/grid.d.ts +2 -0
- package/dist/scene/instancers/grid.d.ts.map +1 -0
- package/dist/scene/instancers/grid.js +36 -0
- package/dist/scene/instancers/index.d.ts +8 -0
- package/dist/scene/instancers/index.d.ts.map +1 -0
- package/dist/scene/instancers/index.js +7 -0
- package/dist/scene/light-camera-factory.d.ts +23 -0
- package/dist/scene/light-camera-factory.d.ts.map +1 -0
- package/dist/scene/light-camera-factory.js +68 -0
- package/dist/scene/material-factory.d.ts +17 -0
- package/dist/scene/material-factory.d.ts.map +1 -0
- package/dist/scene/material-factory.js +197 -0
- package/dist/scene/material-registry.d.ts +40 -0
- package/dist/scene/material-registry.d.ts.map +1 -0
- package/dist/scene/material-registry.js +44 -0
- package/dist/scene/materials/index.d.ts +8 -0
- package/dist/scene/materials/index.d.ts.map +1 -0
- package/dist/scene/materials/index.js +7 -0
- package/dist/scene/materials/water.d.ts +2 -0
- package/dist/scene/materials/water.d.ts.map +1 -0
- package/dist/scene/materials/water.js +54 -0
- package/dist/scene/parse.d.ts +23 -0
- package/dist/scene/parse.d.ts.map +1 -0
- package/dist/scene/parse.js +179 -0
- package/dist/scene/particles-factory.d.ts +33 -0
- package/dist/scene/particles-factory.d.ts.map +1 -0
- package/dist/scene/particles-factory.js +282 -0
- package/dist/scene/scene-apply.d.ts +109 -0
- package/dist/scene/scene-apply.d.ts.map +1 -0
- package/dist/scene/scene-apply.js +326 -0
- package/dist/scene/scene-diff-schema.d.ts +285 -0
- package/dist/scene/scene-diff-schema.d.ts.map +1 -0
- package/dist/scene/scene-diff-schema.js +92 -0
- package/dist/scene/scene-diff-types.d.ts +40 -0
- package/dist/scene/scene-diff-types.d.ts.map +1 -0
- package/dist/scene/scene-diff-types.js +14 -0
- package/dist/scene/scene-loader.d.ts +177 -0
- package/dist/scene/scene-loader.d.ts.map +1 -0
- package/dist/scene/scene-loader.js +1213 -0
- package/dist/scene/scene-query.d.ts +11 -0
- package/dist/scene/scene-query.d.ts.map +1 -0
- package/dist/scene/scene-query.js +63 -0
- package/dist/scene/scene-types.d.ts +10 -0
- package/dist/scene/scene-types.d.ts.map +1 -0
- package/dist/scene/scene-types.js +8 -0
- package/dist/scene/scene-version.d.ts +26 -0
- package/dist/scene/scene-version.d.ts.map +1 -0
- package/dist/scene/scene-version.js +34 -0
- package/dist/scene/schema/animation.d.ts +8 -0
- package/dist/scene/schema/animation.d.ts.map +1 -0
- package/dist/scene/schema/animation.js +42 -0
- package/dist/scene/schema/audio.d.ts +13 -0
- package/dist/scene/schema/audio.d.ts.map +1 -0
- package/dist/scene/schema/audio.js +22 -0
- package/dist/scene/schema/camera.d.ts +28 -0
- package/dist/scene/schema/camera.d.ts.map +1 -0
- package/dist/scene/schema/camera.js +17 -0
- package/dist/scene/schema/collider.d.ts +40 -0
- package/dist/scene/schema/collider.d.ts.map +1 -0
- package/dist/scene/schema/collider.js +55 -0
- package/dist/scene/schema/entity-ref.d.ts +31 -0
- package/dist/scene/schema/entity-ref.d.ts.map +1 -0
- package/dist/scene/schema/entity-ref.js +61 -0
- package/dist/scene/schema/entity.d.ts +1036 -0
- package/dist/scene/schema/entity.d.ts.map +1 -0
- package/dist/scene/schema/entity.js +153 -0
- package/dist/scene/schema/environment.d.ts +425 -0
- package/dist/scene/schema/environment.d.ts.map +1 -0
- package/dist/scene/schema/environment.js +357 -0
- package/dist/scene/schema/index.d.ts +39 -0
- package/dist/scene/schema/index.d.ts.map +1 -0
- package/dist/scene/schema/index.js +20 -0
- package/dist/scene/schema/instances.d.ts +14 -0
- package/dist/scene/schema/instances.d.ts.map +1 -0
- package/dist/scene/schema/instances.js +28 -0
- package/dist/scene/schema/joint.d.ts +23 -0
- package/dist/scene/schema/joint.d.ts.map +1 -0
- package/dist/scene/schema/joint.js +23 -0
- package/dist/scene/schema/light.d.ts +38 -0
- package/dist/scene/schema/light.d.ts.map +1 -0
- package/dist/scene/schema/light.js +26 -0
- package/dist/scene/schema/material.d.ts +199 -0
- package/dist/scene/schema/material.d.ts.map +1 -0
- package/dist/scene/schema/material.js +99 -0
- package/dist/scene/schema/mesh.d.ts +48 -0
- package/dist/scene/schema/mesh.d.ts.map +1 -0
- package/dist/scene/schema/mesh.js +82 -0
- package/dist/scene/schema/particles.d.ts +2178 -0
- package/dist/scene/schema/particles.d.ts.map +1 -0
- package/dist/scene/schema/particles.js +321 -0
- package/dist/scene/schema/physics.d.ts +56 -0
- package/dist/scene/schema/physics.d.ts.map +1 -0
- package/dist/scene/schema/physics.js +37 -0
- package/dist/scene/schema/scene-file.d.ts +304 -0
- package/dist/scene/schema/scene-file.d.ts.map +1 -0
- package/dist/scene/schema/scene-file.js +262 -0
- package/dist/scene/schema/shadow.d.ts +28 -0
- package/dist/scene/schema/shadow.d.ts.map +1 -0
- package/dist/scene/schema/shadow.js +20 -0
- package/dist/scene/schema/spline.d.ts +25 -0
- package/dist/scene/schema/spline.d.ts.map +1 -0
- package/dist/scene/schema/spline.js +15 -0
- package/dist/scene/schema/tuples.d.ts +12 -0
- package/dist/scene/schema/tuples.d.ts.map +1 -0
- package/dist/scene/schema/tuples.js +14 -0
- package/dist/scene/schema/ui.d.ts +880 -0
- package/dist/scene/schema/ui.d.ts.map +1 -0
- package/dist/scene/schema/ui.js +506 -0
- package/dist/scene/user-data.d.ts +171 -0
- package/dist/scene/user-data.d.ts.map +1 -0
- package/dist/scene/user-data.js +137 -0
- package/dist/setup/setup-audio.d.ts +20 -0
- package/dist/setup/setup-audio.d.ts.map +1 -0
- package/dist/setup/setup-audio.js +41 -0
- package/dist/setup/setup-particles.d.ts +17 -0
- package/dist/setup/setup-particles.d.ts.map +1 -0
- package/dist/setup/setup-particles.js +16 -0
- package/dist/setup/setup-physics.d.ts +25 -0
- package/dist/setup/setup-physics.d.ts.map +1 -0
- package/dist/setup/setup-physics.js +51 -0
- package/dist/setup/setup-renderer.d.ts +69 -0
- package/dist/setup/setup-renderer.d.ts.map +1 -0
- package/dist/setup/setup-renderer.js +363 -0
- package/dist/tools/define-tool.d.ts +105 -0
- package/dist/tools/define-tool.d.ts.map +1 -0
- package/dist/tools/define-tool.js +82 -0
- package/dist/world2d/authoring-2d.d.ts +76 -0
- package/dist/world2d/authoring-2d.d.ts.map +1 -0
- package/dist/world2d/authoring-2d.js +176 -0
- package/dist/world2d/capture-to-scene2d.d.ts +5 -0
- package/dist/world2d/capture-to-scene2d.d.ts.map +1 -0
- package/dist/world2d/capture-to-scene2d.js +49 -0
- package/dist/world2d/collision-2d.d.ts +52 -0
- package/dist/world2d/collision-2d.d.ts.map +1 -0
- package/dist/world2d/collision-2d.js +70 -0
- package/dist/world2d/components-2d.d.ts +47 -0
- package/dist/world2d/components-2d.d.ts.map +1 -0
- package/dist/world2d/components-2d.js +77 -0
- package/dist/world2d/index.d.ts +34 -0
- package/dist/world2d/index.d.ts.map +1 -0
- package/dist/world2d/index.js +32 -0
- package/dist/world2d/ingest-iframe-2d.d.ts +82 -0
- package/dist/world2d/ingest-iframe-2d.d.ts.map +1 -0
- package/dist/world2d/ingest-iframe-2d.js +166 -0
- package/dist/world2d/ingest2d.d.ts +97 -0
- package/dist/world2d/ingest2d.d.ts.map +1 -0
- package/dist/world2d/ingest2d.js +40 -0
- package/dist/world2d/physics2d-registry.d.ts +24 -0
- package/dist/world2d/physics2d-registry.d.ts.map +1 -0
- package/dist/world2d/physics2d-registry.js +38 -0
- package/dist/world2d/pixi-game-adapter.d.ts +107 -0
- package/dist/world2d/pixi-game-adapter.d.ts.map +1 -0
- package/dist/world2d/pixi-game-adapter.js +211 -0
- package/dist/world2d/pixi-surface.d.ts +39 -0
- package/dist/world2d/pixi-surface.d.ts.map +1 -0
- package/dist/world2d/pixi-surface.js +47 -0
- package/dist/world2d/scene-capture-2d.d.ts +43 -0
- package/dist/world2d/scene-capture-2d.d.ts.map +1 -0
- package/dist/world2d/scene-capture-2d.js +92 -0
- package/dist/world2d/scene2d-loader.d.ts +27 -0
- package/dist/world2d/scene2d-loader.d.ts.map +1 -0
- package/dist/world2d/scene2d-loader.js +274 -0
- package/dist/world2d/schema/entity2d.d.ts +102 -0
- package/dist/world2d/schema/entity2d.d.ts.map +1 -0
- package/dist/world2d/schema/entity2d.js +119 -0
- package/dist/world2d/schema/physics2d.d.ts +46 -0
- package/dist/world2d/schema/physics2d.d.ts.map +1 -0
- package/dist/world2d/schema/physics2d.js +45 -0
- package/dist/world2d/schema/sprite.d.ts +42 -0
- package/dist/world2d/schema/sprite.d.ts.map +1 -0
- package/dist/world2d/schema/sprite.js +63 -0
- package/dist/world2d/schema/tilemap.d.ts +15 -0
- package/dist/world2d/schema/tilemap.d.ts.map +1 -0
- package/dist/world2d/schema/tilemap.js +19 -0
- package/dist/world2d/schema/tuples2d.d.ts +20 -0
- package/dist/world2d/schema/tuples2d.d.ts.map +1 -0
- package/dist/world2d/schema/tuples2d.js +19 -0
- package/dist/world2d/system-adapters-2d.d.ts +16 -0
- package/dist/world2d/system-adapters-2d.d.ts.map +1 -0
- package/dist/world2d/system-adapters-2d.js +37 -0
- package/dist/world2d/transform-writer-2d.d.ts +16 -0
- package/dist/world2d/transform-writer-2d.d.ts.map +1 -0
- package/dist/world2d/transform-writer-2d.js +22 -0
- package/dist/world2d/types.d.ts +53 -0
- package/dist/world2d/types.d.ts.map +1 -0
- package/dist/world2d/types.js +1 -0
- package/package.json +18 -4
- package/src/adapter/authoring.ts +10 -0
- package/src/adapter/first-party-systems.ts +23 -34
- package/src/adapter/index.ts +1 -3
- package/src/adapter/system-adapter.ts +15 -22
- package/src/adapter/vgai-scene-game-adapter.ts +5 -14
- package/src/animation/anim-graph-types.ts +12 -43
- package/src/animation/animation-clock.ts +479 -0
- package/src/animation/camera-ownership.ts +467 -0
- package/src/animation/cinematic-cues.ts +451 -0
- package/src/animation/clip-map.ts +41 -0
- package/src/animation/gsap-registration.ts +184 -0
- package/src/animation/theatre-clock-binding.ts +111 -0
- package/src/animation/theatre-director.ts +347 -0
- package/src/animation/theatre-object-binding.ts +661 -0
- package/src/animation/xstate-animation-binding.ts +398 -0
- package/src/animation/xstate-animation-meta.ts +282 -0
- package/src/audio/index.ts +39 -7
- package/src/audio/tone-clock-binding.ts +98 -0
- package/src/audio/tone-context.ts +129 -0
- package/src/audio/tone-offline-render.ts +167 -0
- package/src/audio/wav-encode.ts +119 -0
- package/src/core/game-loop.ts +17 -0
- package/src/core/types.ts +13 -0
- package/src/data/data-asset.ts +167 -0
- package/src/data/data-check-core.ts +242 -0
- package/src/data/data-ref.ts +145 -0
- package/src/data/vite-plugin-data.ts +290 -0
- package/src/index.ts +48 -0
- package/src/input/input-manager.ts +1206 -32
- package/src/input/input-types.ts +155 -3
- package/src/input/prompt-labels.ts +122 -0
- package/src/input/rebind-controller.ts +105 -0
- package/src/input/schema.ts +206 -52
- package/src/react/use-data.ts +114 -0
- package/src/react/use-selection.tsx +135 -0
- package/src/runtime/create-runtime.ts +30 -9
- package/src/runtime/render-audio-control.ts +168 -0
- package/src/runtime/render-control.ts +522 -0
- package/src/runtime/render-seed.ts +79 -0
- package/src/runtime/types.ts +0 -5
- package/src/scene/asset-loaders.ts +10 -36
- package/src/scene/asset-paths.ts +0 -2
- package/src/scene/asset-ref-check.ts +248 -0
- package/src/scene/parse.ts +133 -0
- package/src/scene/scene-loader.ts +81 -96
- package/src/scene/schema/animation.ts +30 -79
- package/src/scene/schema/entity.ts +20 -0
- package/src/scene/schema/index.ts +2 -12
- package/src/scene/user-data.ts +8 -9
- package/src/setup/setup-renderer.ts +9 -2
- package/src/tools/define-tool.ts +152 -0
- package/src/animation/anim-graph.ts +0 -406
- package/src/animation/anim-system.ts +0 -28
- package/src/animation/property-track.ts +0 -178
- package/src/animation/schema.ts +0 -204
- package/src/audio/ambient.ts +0 -300
- package/src/audio/impacts.ts +0 -212
- package/src/audio/movement.ts +0 -140
- package/src/audio/musical.ts +0 -200
- package/src/audio/ui-sounds.ts +0 -171
- package/src/audio/vehicle.ts +0 -235
- package/src/audio/weapons.ts +0 -152
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical GLTF / texture load + cache layer (A2). (Formerly also hosted the
|
|
3
|
+
* `.animgraph.json` loader — removed by E5; see
|
|
4
|
+
* packages/engine/src/animation/xstate-animation-binding.ts.)
|
|
5
|
+
*
|
|
6
|
+
* ONE place that owns the URL-keyed caches and the clone-safety contract, shared
|
|
7
|
+
* by BOTH the engine runtime (scene-loader, create-runtime) AND the editor
|
|
8
|
+
* (entity-factory, scene-sync). Previously this logic was duplicated across six
|
|
9
|
+
* sites with three separate GLTF caches and four GLTFLoader instances, so fixes
|
|
10
|
+
* (DRACO wiring, the `__sharedGeometry` clone-safety tag, skybox handling) did
|
|
11
|
+
* not propagate. Everything funnels through the shared loaders in `../loader`
|
|
12
|
+
* (`gltfLoader` is DRACO-wired — CB2 — and `textureLoader` shares the engine
|
|
13
|
+
* LoadingManager / asset-prefix rewrite).
|
|
14
|
+
*
|
|
15
|
+
* Cache lifetime / P1.8: these caches are intentionally module-level and persist
|
|
16
|
+
* ACROSS hot-reloads / scene switches (they are NOT cleared on every scene load).
|
|
17
|
+
* This is deliberate: (1) it makes repeated Play→Stop→Play cheap, and (2) it
|
|
18
|
+
* underpins the `__sharedGeometry` contract from P0.2 — GLTF clones share the
|
|
19
|
+
* cached source geometry, so clearing mid-session would orphan live clones. The
|
|
20
|
+
* caches are keyed by URL, so loading the SAME asset N times is bounded (one
|
|
21
|
+
* entry per distinct URL, not per load). They are released only on full runtime
|
|
22
|
+
* teardown via {@link clearAssetCaches}.
|
|
23
|
+
*/
|
|
24
|
+
import * as THREE from 'three';
|
|
25
|
+
/** Load (and cache) a texture via the shared, prefix-aware TextureLoader. */
|
|
26
|
+
export declare function loadTexture(url: string): THREE.Texture;
|
|
27
|
+
/**
|
|
28
|
+
* Load a GLTF/GLB and return a fresh, disposal-safe clone (+ the source's
|
|
29
|
+
* animation clips). DRACO decoding is handled by the shared `gltfLoader`.
|
|
30
|
+
*
|
|
31
|
+
* Clone-safety contract (P0.2 — load-bearing, tested):
|
|
32
|
+
* `SkeletonUtils.clone` shares geometry AND materials with the cached source.
|
|
33
|
+
* We give each clone its OWN materials (so scene cleanup can dispose them
|
|
34
|
+
* without corrupting the cache) and tag every mesh `userData.__sharedGeometry`
|
|
35
|
+
* so cleanup (engine create-runtime fullCleanup + editor scene-sync
|
|
36
|
+
* disposeObject3D) skips disposing the shared geometry buffers.
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadGLTF(url: string): Promise<{
|
|
39
|
+
scene: THREE.Group;
|
|
40
|
+
animations: THREE.AnimationClip[];
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a single named node inside an already-loaded glTF scene graph (F4,
|
|
44
|
+
* docs/VSCN-STRUCTURAL-GAPS-DESIGN.md `mesh.node`). Pure and headlessly
|
|
45
|
+
* testable — no fetch, no cache lookups; callers pass the `scene` they already
|
|
46
|
+
* got from {@link loadGLTF}.
|
|
47
|
+
*
|
|
48
|
+
* The returned node is the SAME object (and shares the SAME geometry) as
|
|
49
|
+
* found in `scene` — nothing is cloned or copied out. `scene` is already a
|
|
50
|
+
* fresh `SkeletonUtils.clone()` per {@link loadGLTF}'s clone-safety contract,
|
|
51
|
+
* so mutating/detaching the returned node is safe.
|
|
52
|
+
*
|
|
53
|
+
* Atomic-subtree guard: a `SkinnedMesh` cannot be lifted out of its armature
|
|
54
|
+
* (its skeleton/bind matrices reference sibling bone nodes elsewhere in the
|
|
55
|
+
* hierarchy), so resolving a node that IS a SkinnedMesh, or that CONTAINS one,
|
|
56
|
+
* throws a loud `SceneParseError` instead of silently producing broken skinning.
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveGltfNode(scene: THREE.Object3D, nodeName: string, src: string): THREE.Object3D;
|
|
59
|
+
/**
|
|
60
|
+
* Clear the module-level GLTF / texture caches. Call on full runtime teardown
|
|
61
|
+
* (create-runtime fullCleanup / hot-reload) to release cached GPU resources
|
|
62
|
+
* and avoid leaking across editor Play sessions. See the lifetime note at the
|
|
63
|
+
* top of this file for why these are NOT cleared per scene load.
|
|
64
|
+
*
|
|
65
|
+
* NOTE: the IBL/skybox env-map cache lives in scene-loader (it needs a
|
|
66
|
+
* WebGLRenderer for PMREM); scene-loader's `clearAssetCaches` wraps this and
|
|
67
|
+
* also clears that env cache.
|
|
68
|
+
*/
|
|
69
|
+
export declare function clearAssetCaches(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Test-only: current sizes of the module-level caches. Used by the P1.8 headless
|
|
72
|
+
* test to assert caches stay bounded (one entry per distinct asset URL) across
|
|
73
|
+
* repeated loads of the same scene, rather than growing per load.
|
|
74
|
+
*/
|
|
75
|
+
export declare function assetCacheSizes(): {
|
|
76
|
+
textures: number;
|
|
77
|
+
gltf: number;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=asset-loaders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-loaders.d.ts","sourceRoot":"","sources":["../../src/scene/asset-loaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,OAAO,CAMtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IAAC,UAAU,EAAE,KAAK,CAAC,aAAa,EAAE,CAAA;CAAE,CAAC,CAyBpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,KAAK,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,GACV,KAAK,CAAC,QAAQ,CAuChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAEpE"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical GLTF / texture load + cache layer (A2). (Formerly also hosted the
|
|
3
|
+
* `.animgraph.json` loader — removed by E5; see
|
|
4
|
+
* packages/engine/src/animation/xstate-animation-binding.ts.)
|
|
5
|
+
*
|
|
6
|
+
* ONE place that owns the URL-keyed caches and the clone-safety contract, shared
|
|
7
|
+
* by BOTH the engine runtime (scene-loader, create-runtime) AND the editor
|
|
8
|
+
* (entity-factory, scene-sync). Previously this logic was duplicated across six
|
|
9
|
+
* sites with three separate GLTF caches and four GLTFLoader instances, so fixes
|
|
10
|
+
* (DRACO wiring, the `__sharedGeometry` clone-safety tag, skybox handling) did
|
|
11
|
+
* not propagate. Everything funnels through the shared loaders in `../loader`
|
|
12
|
+
* (`gltfLoader` is DRACO-wired — CB2 — and `textureLoader` shares the engine
|
|
13
|
+
* LoadingManager / asset-prefix rewrite).
|
|
14
|
+
*
|
|
15
|
+
* Cache lifetime / P1.8: these caches are intentionally module-level and persist
|
|
16
|
+
* ACROSS hot-reloads / scene switches (they are NOT cleared on every scene load).
|
|
17
|
+
* This is deliberate: (1) it makes repeated Play→Stop→Play cheap, and (2) it
|
|
18
|
+
* underpins the `__sharedGeometry` contract from P0.2 — GLTF clones share the
|
|
19
|
+
* cached source geometry, so clearing mid-session would orphan live clones. The
|
|
20
|
+
* caches are keyed by URL, so loading the SAME asset N times is bounded (one
|
|
21
|
+
* entry per distinct URL, not per load). They are released only on full runtime
|
|
22
|
+
* teardown via {@link clearAssetCaches}.
|
|
23
|
+
*/
|
|
24
|
+
import * as THREE from 'three';
|
|
25
|
+
import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';
|
|
26
|
+
import { gltfLoader, textureLoader } from '../loader';
|
|
27
|
+
import { SceneParseError } from './parse';
|
|
28
|
+
import { setUserData } from './user-data';
|
|
29
|
+
const textureCache = new Map();
|
|
30
|
+
const gltfCache = new Map();
|
|
31
|
+
/** Load (and cache) a texture via the shared, prefix-aware TextureLoader. */
|
|
32
|
+
export function loadTexture(url) {
|
|
33
|
+
const cached = textureCache.get(url);
|
|
34
|
+
if (cached)
|
|
35
|
+
return cached;
|
|
36
|
+
const tex = textureLoader.load(url);
|
|
37
|
+
textureCache.set(url, tex);
|
|
38
|
+
return tex;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load a GLTF/GLB and return a fresh, disposal-safe clone (+ the source's
|
|
42
|
+
* animation clips). DRACO decoding is handled by the shared `gltfLoader`.
|
|
43
|
+
*
|
|
44
|
+
* Clone-safety contract (P0.2 — load-bearing, tested):
|
|
45
|
+
* `SkeletonUtils.clone` shares geometry AND materials with the cached source.
|
|
46
|
+
* We give each clone its OWN materials (so scene cleanup can dispose them
|
|
47
|
+
* without corrupting the cache) and tag every mesh `userData.__sharedGeometry`
|
|
48
|
+
* so cleanup (engine create-runtime fullCleanup + editor scene-sync
|
|
49
|
+
* disposeObject3D) skips disposing the shared geometry buffers.
|
|
50
|
+
*/
|
|
51
|
+
export function loadGLTF(url) {
|
|
52
|
+
let cached = gltfCache.get(url);
|
|
53
|
+
if (!cached) {
|
|
54
|
+
cached = new Promise((resolve, reject) => {
|
|
55
|
+
gltfLoader.load(url, (gltf) => resolve({ scene: gltf.scene, animations: gltf.animations }), undefined, (err) => reject(err));
|
|
56
|
+
});
|
|
57
|
+
gltfCache.set(url, cached);
|
|
58
|
+
}
|
|
59
|
+
return cached.then((entry) => {
|
|
60
|
+
const scene = SkeletonUtils.clone(entry.scene);
|
|
61
|
+
scene.traverse((child) => {
|
|
62
|
+
if (child instanceof THREE.Mesh) {
|
|
63
|
+
child.material = Array.isArray(child.material)
|
|
64
|
+
? child.material.map((m) => m.clone())
|
|
65
|
+
: child.material.clone();
|
|
66
|
+
setUserData(child, '__sharedGeometry', true);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return { scene, animations: entry.animations };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve a single named node inside an already-loaded glTF scene graph (F4,
|
|
74
|
+
* docs/VSCN-STRUCTURAL-GAPS-DESIGN.md `mesh.node`). Pure and headlessly
|
|
75
|
+
* testable — no fetch, no cache lookups; callers pass the `scene` they already
|
|
76
|
+
* got from {@link loadGLTF}.
|
|
77
|
+
*
|
|
78
|
+
* The returned node is the SAME object (and shares the SAME geometry) as
|
|
79
|
+
* found in `scene` — nothing is cloned or copied out. `scene` is already a
|
|
80
|
+
* fresh `SkeletonUtils.clone()` per {@link loadGLTF}'s clone-safety contract,
|
|
81
|
+
* so mutating/detaching the returned node is safe.
|
|
82
|
+
*
|
|
83
|
+
* Atomic-subtree guard: a `SkinnedMesh` cannot be lifted out of its armature
|
|
84
|
+
* (its skeleton/bind matrices reference sibling bone nodes elsewhere in the
|
|
85
|
+
* hierarchy), so resolving a node that IS a SkinnedMesh, or that CONTAINS one,
|
|
86
|
+
* throws a loud `SceneParseError` instead of silently producing broken skinning.
|
|
87
|
+
*/
|
|
88
|
+
export function resolveGltfNode(scene, nodeName, src) {
|
|
89
|
+
const node = scene.getObjectByName(nodeName);
|
|
90
|
+
if (!node) {
|
|
91
|
+
throw new SceneParseError([
|
|
92
|
+
{
|
|
93
|
+
code: 'custom',
|
|
94
|
+
path: ['mesh', 'node'],
|
|
95
|
+
message: `glTF "${src}" has no node named "${nodeName}" (getObjectByName found nothing)`,
|
|
96
|
+
},
|
|
97
|
+
], src);
|
|
98
|
+
}
|
|
99
|
+
const isSkinned = (o) => o.isSkinnedMesh;
|
|
100
|
+
let containsSkinned = isSkinned(node);
|
|
101
|
+
if (!containsSkinned) {
|
|
102
|
+
node.traverse((child) => {
|
|
103
|
+
if (isSkinned(child))
|
|
104
|
+
containsSkinned = true;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (containsSkinned) {
|
|
108
|
+
throw new SceneParseError([
|
|
109
|
+
{
|
|
110
|
+
code: 'custom',
|
|
111
|
+
path: ['mesh', 'node'],
|
|
112
|
+
message: `glTF "${src}" node "${nodeName}" is (or contains) a SkinnedMesh — a skinned mesh ` +
|
|
113
|
+
'cannot be lifted out of its armature (atomic-subtree rule). Reference the whole ' +
|
|
114
|
+
'file instead of a `node`, or bake/export a non-skinned sub-asset.',
|
|
115
|
+
},
|
|
116
|
+
], src);
|
|
117
|
+
}
|
|
118
|
+
return node;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear the module-level GLTF / texture caches. Call on full runtime teardown
|
|
122
|
+
* (create-runtime fullCleanup / hot-reload) to release cached GPU resources
|
|
123
|
+
* and avoid leaking across editor Play sessions. See the lifetime note at the
|
|
124
|
+
* top of this file for why these are NOT cleared per scene load.
|
|
125
|
+
*
|
|
126
|
+
* NOTE: the IBL/skybox env-map cache lives in scene-loader (it needs a
|
|
127
|
+
* WebGLRenderer for PMREM); scene-loader's `clearAssetCaches` wraps this and
|
|
128
|
+
* also clears that env cache.
|
|
129
|
+
*/
|
|
130
|
+
export function clearAssetCaches() {
|
|
131
|
+
textureCache.clear();
|
|
132
|
+
gltfCache.clear();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Test-only: current sizes of the module-level caches. Used by the P1.8 headless
|
|
136
|
+
* test to assert caches stay bounded (one entry per distinct asset URL) across
|
|
137
|
+
* repeated loads of the same scene, rather than growing per load.
|
|
138
|
+
*/
|
|
139
|
+
export function assetCacheSizes() {
|
|
140
|
+
return { textures: textureCache.size, gltf: gltfCache.size };
|
|
141
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SceneEntity, SceneEnvironment, SceneFile } from './scene-types';
|
|
2
|
+
/**
|
|
3
|
+
* Collect all external asset paths referenced by a scene's entities and environment.
|
|
4
|
+
*/
|
|
5
|
+
export declare function collectAssetPaths(entities: SceneEntity[], environment?: SceneEnvironment): Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Deep-clone a scene document and replace all occurrences of oldPath with newPath
|
|
8
|
+
* in asset reference fields. Returns the new document.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyAssetRename(doc: SceneFile, oldPath: string, newPath: string): SceneFile;
|
|
11
|
+
//# sourceMappingURL=asset-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-paths.d.ts","sourceRoot":"","sources":["../../src/scene/asset-paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAuD9E;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,EAAE,EACvB,WAAW,CAAC,EAAE,gBAAgB,GAC7B,GAAG,CAAC,MAAM,CAAC,CAsBb;AAuBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAU5F"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every material field that holds a texture-file path, as [group, key] pairs —
|
|
3
|
+
* group `null` for top-level fields, otherwise the physical feature group
|
|
4
|
+
* (clearcoat/transmission/sheen/iridescence) the key nests under. One table
|
|
5
|
+
* drives both collect and rename so the two can never disagree;
|
|
6
|
+
* `asset-paths.test.ts` derives the expected set from SceneMaterialSchema's
|
|
7
|
+
* `.describe()` strings so this list can't silently fall behind the schema.
|
|
8
|
+
*/
|
|
9
|
+
const MATERIAL_TEXTURE_FIELDS = [
|
|
10
|
+
[null, 'map'],
|
|
11
|
+
[null, 'normalMap'],
|
|
12
|
+
[null, 'emissiveMap'],
|
|
13
|
+
[null, 'aoMap'],
|
|
14
|
+
[null, 'lightMap'],
|
|
15
|
+
[null, 'roughnessMap'],
|
|
16
|
+
[null, 'metalnessMap'],
|
|
17
|
+
[null, 'displacementMap'],
|
|
18
|
+
['clearcoat', 'clearcoatMap'],
|
|
19
|
+
['clearcoat', 'clearcoatRoughnessMap'],
|
|
20
|
+
['transmission', 'transmissionMap'],
|
|
21
|
+
['sheen', 'sheenColorMap'],
|
|
22
|
+
['sheen', 'sheenRoughnessMap'],
|
|
23
|
+
['iridescence', 'iridescenceMap'],
|
|
24
|
+
['iridescence', 'iridescenceThicknessMap'],
|
|
25
|
+
];
|
|
26
|
+
/** Visit every authored texture path on a material (inline or override). */
|
|
27
|
+
function forEachMaterialTexturePath(material, fn) {
|
|
28
|
+
for (const [group, key] of MATERIAL_TEXTURE_FIELDS) {
|
|
29
|
+
const holder = group
|
|
30
|
+
? material[group]
|
|
31
|
+
: material;
|
|
32
|
+
if (!holder || typeof holder !== 'object')
|
|
33
|
+
continue;
|
|
34
|
+
const value = holder[key];
|
|
35
|
+
if (typeof value === 'string')
|
|
36
|
+
fn(holder, key, value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function isFilePrefab(value) {
|
|
40
|
+
return value.includes('/');
|
|
41
|
+
}
|
|
42
|
+
function walkEntities(entities, fn) {
|
|
43
|
+
for (const e of entities) {
|
|
44
|
+
fn(e);
|
|
45
|
+
if (e.children)
|
|
46
|
+
walkEntities(e.children, fn);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Collect all external asset paths referenced by a scene's entities and environment.
|
|
51
|
+
*/
|
|
52
|
+
export function collectAssetPaths(entities, environment) {
|
|
53
|
+
const paths = new Set();
|
|
54
|
+
walkEntities(entities, (e) => {
|
|
55
|
+
if (e.mesh?.type === 'gltf' && e.mesh.src)
|
|
56
|
+
paths.add(e.mesh.src);
|
|
57
|
+
if (e.mesh?.instances)
|
|
58
|
+
paths.add(e.mesh.instances);
|
|
59
|
+
if (e.material) {
|
|
60
|
+
forEachMaterialTexturePath(e.material, (_holder, _key, value) => paths.add(value));
|
|
61
|
+
}
|
|
62
|
+
if (e.materialRef)
|
|
63
|
+
paths.add(e.materialRef);
|
|
64
|
+
if (e.particles?.material?.map)
|
|
65
|
+
paths.add(e.particles.material.map);
|
|
66
|
+
if (e.audio?.src)
|
|
67
|
+
paths.add(e.audio.src);
|
|
68
|
+
if (e.prefab && isFilePrefab(e.prefab))
|
|
69
|
+
paths.add(e.prefab);
|
|
70
|
+
});
|
|
71
|
+
if (environment?.skybox)
|
|
72
|
+
paths.add(environment.skybox);
|
|
73
|
+
return paths;
|
|
74
|
+
}
|
|
75
|
+
/** Replace oldPath with newPath in a single entity's asset fields. Mutates in place. */
|
|
76
|
+
function renameInEntity(e, oldPath, newPath) {
|
|
77
|
+
if (e.mesh?.type === 'gltf' && e.mesh.src === oldPath) {
|
|
78
|
+
e.mesh.src = newPath;
|
|
79
|
+
}
|
|
80
|
+
if (e.mesh?.instances === oldPath)
|
|
81
|
+
e.mesh.instances = newPath;
|
|
82
|
+
if (e.material) {
|
|
83
|
+
forEachMaterialTexturePath(e.material, (holder, key, value) => {
|
|
84
|
+
if (value === oldPath)
|
|
85
|
+
holder[key] = newPath;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (e.materialRef === oldPath)
|
|
89
|
+
e.materialRef = newPath;
|
|
90
|
+
if (e.particles?.material?.map === oldPath)
|
|
91
|
+
e.particles.material.map = newPath;
|
|
92
|
+
if (e.audio?.src === oldPath)
|
|
93
|
+
e.audio.src = newPath;
|
|
94
|
+
if (e.prefab === oldPath)
|
|
95
|
+
e.prefab = newPath;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Deep-clone a scene document and replace all occurrences of oldPath with newPath
|
|
99
|
+
* in asset reference fields. Returns the new document.
|
|
100
|
+
*/
|
|
101
|
+
export function applyAssetRename(doc, oldPath, newPath) {
|
|
102
|
+
const cloned = JSON.parse(JSON.stringify(doc));
|
|
103
|
+
walkEntities(cloned.entities, (e) => renameInEntity(e, oldPath, newPath));
|
|
104
|
+
if (cloned.environment?.skybox === oldPath) {
|
|
105
|
+
cloned.environment.skybox = newPath;
|
|
106
|
+
}
|
|
107
|
+
return cloned;
|
|
108
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared asset-reference integrity check (B6 follow-up to B2 item #20,
|
|
3
|
+
* docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md §8 B6).
|
|
4
|
+
*
|
|
5
|
+
* RELOCATED HERE (from `packages/vgai-cli/src/apply-diff.ts`, where it was
|
|
6
|
+
* originally built as `dereferenceNewAssetRefs`) so it can be shared by BOTH
|
|
7
|
+
* `vgai apply-diff` (the file-mode CLI verb) and the SDK's
|
|
8
|
+
* `project.scene.apply` operation (`packages/vgai-sdk/src/project/scene-operations.ts`)
|
|
9
|
+
* WITHOUT the SDK importing from the CLI — that would invert the intended
|
|
10
|
+
* dependency direction (CLI -> SDK -> engine, §3.4). The engine's scene layer
|
|
11
|
+
* is the correct shared home: both the CLI and the SDK already depend
|
|
12
|
+
* directly on `@vgai/engine/scene/*` for scene parsing/patching, so this
|
|
13
|
+
* module sits alongside `parse.ts`/`scene-apply.ts` as one more piece of
|
|
14
|
+
* scene-layer machinery neither caller re-implements.
|
|
15
|
+
*
|
|
16
|
+
* WHAT THIS CATCHES that schema validation alone does not: the Zod scene
|
|
17
|
+
* schema only checks that e.g. `materialRef` is a STRING — never that the
|
|
18
|
+
* string points at anything real. A diff introducing
|
|
19
|
+
* `materialRef: "materials/typo.mat.json"` (nonexistent, or present but
|
|
20
|
+
* malformed) passes ordinary scene/patch validation and would be written;
|
|
21
|
+
* the failure would otherwise only surface later, at runtime asset fetch.
|
|
22
|
+
* `dereferenceNewAssetRefs` closes that gap by re-resolving every asset
|
|
23
|
+
* reference the diff INTRODUCED (present in `result`, absent from
|
|
24
|
+
* `inputScene` — deliberately not pre-existing refs, so a scene with
|
|
25
|
+
* unrelated prior breakage can still receive an unrelated repair;
|
|
26
|
+
* `validate-scenes` remains the whole-project content gate) against disk,
|
|
27
|
+
* refusing the write if anything is missing or fails its own schema.
|
|
28
|
+
*
|
|
29
|
+
* Reference kinds and their treatment (unchanged from the original CLI-only
|
|
30
|
+
* implementation):
|
|
31
|
+
* - Zod-validated (JSON formats with engine Zod schemas): `materialRef`
|
|
32
|
+
* (.mat.json -> parseMaterialFile), `prefab` in its file-path form
|
|
33
|
+
* (.prefab.json -> parsePrefabFile). Prefabs are validated ONE level
|
|
34
|
+
* deep — the referenced prefab file itself must exist and parse; assets
|
|
35
|
+
* IT references are that file's own concern. (`animation.animGraph` ->
|
|
36
|
+
* AnimGraphFileSchema was removed by E5 — AnimGraph no longer exists.)
|
|
37
|
+
* - Existence-checked only (binary formats with no Zod schema to parse
|
|
38
|
+
* them through): gltf `mesh.src`, every material texture-map path
|
|
39
|
+
* (including the nested clearcoat/transmission/sheen/iridescence groups),
|
|
40
|
+
* `particles.material.map`, `audio.src`, `environment.skybox`.
|
|
41
|
+
* - `.inputmap.json` is structurally out of scope: no `.vscn.json`/
|
|
42
|
+
* `.prefab.json` field references an input map.
|
|
43
|
+
*/
|
|
44
|
+
import type { SceneFile } from './scene-types';
|
|
45
|
+
/** One asset reference found in a scene document: where it is + what it points at. */
|
|
46
|
+
export interface AssetRef {
|
|
47
|
+
/** The authored path string (web-root-relative, optionally /-prefixed). */
|
|
48
|
+
path: string;
|
|
49
|
+
/** Human-readable field location for error messages, e.g. `entity "crate" field materialRef`. */
|
|
50
|
+
field: string;
|
|
51
|
+
kind: 'material' | 'prefab' | 'binary';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* One asset reference that failed to dereference. `reason` is a one-line-or-
|
|
55
|
+
* more human-readable explanation (schema-validation failures may be
|
|
56
|
+
* multi-line); `field`/`path` mirror `AssetRef` and `diskPath` is the
|
|
57
|
+
* resolved absolute path that was checked, so every caller (CLI text report,
|
|
58
|
+
* SDK structured error data) can build its own presentation from the same
|
|
59
|
+
* facts without re-deriving them.
|
|
60
|
+
*/
|
|
61
|
+
export interface AssetRefError {
|
|
62
|
+
field: string;
|
|
63
|
+
path: string;
|
|
64
|
+
diskPath: string;
|
|
65
|
+
reason: string;
|
|
66
|
+
}
|
|
67
|
+
/** Collect every asset reference in a scene document (entities walked recursively + environment), labeled for error messages. */
|
|
68
|
+
export declare function collectAssetRefs(doc: SceneFile): AssetRef[];
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the asset root the scene's references are relative to. Asset paths
|
|
71
|
+
* are web-root-relative (the runtime fetches them from the served `public/`
|
|
72
|
+
* directory), and scene files conventionally live INSIDE `public/`
|
|
73
|
+
* (`public/scenes/*.vscn.json`) — so the nearest ancestor directory literally
|
|
74
|
+
* named `public` is the root. Fallback for scenes not under a `public/`
|
|
75
|
+
* ancestor: the scene's own directory.
|
|
76
|
+
*/
|
|
77
|
+
export declare function findAssetRoot(scenePath: string): string;
|
|
78
|
+
/**
|
|
79
|
+
* Dereference every asset reference `result` introduces relative to
|
|
80
|
+
* `inputScene` (present in the result, absent from the input) against disk,
|
|
81
|
+
* relative to `scenePath`'s asset root (see `findAssetRoot`). Returns
|
|
82
|
+
* structured errors (empty = every new reference resolved and validated) —
|
|
83
|
+
* never throws; callers decide how to present/escalate a non-empty result
|
|
84
|
+
* (the CLI folds these into one `ApplyDiffCliError` message, the SDK raises
|
|
85
|
+
* a declared `ASSET_REF_INVALID` `OperationError`).
|
|
86
|
+
*/
|
|
87
|
+
export declare function dereferenceNewAssetRefs(inputScene: SceneFile, result: SceneFile, scenePath: string): AssetRefError[];
|
|
88
|
+
//# sourceMappingURL=asset-ref-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-ref-check.d.ts","sourceRoot":"","sources":["../../src/scene/asset-ref-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAKH,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,eAAe,CAAC;AAE5D,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACvB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,iGAAiG;IACjG,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AA4BD,iIAAiI;AACjI,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,QAAQ,EAAE,CA0D3D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASvD;AAOD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,SAAS,EACrB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,GAChB,aAAa,EAAE,CAkDjB"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared asset-reference integrity check (B6 follow-up to B2 item #20,
|
|
3
|
+
* docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md §8 B6).
|
|
4
|
+
*
|
|
5
|
+
* RELOCATED HERE (from `packages/vgai-cli/src/apply-diff.ts`, where it was
|
|
6
|
+
* originally built as `dereferenceNewAssetRefs`) so it can be shared by BOTH
|
|
7
|
+
* `vgai apply-diff` (the file-mode CLI verb) and the SDK's
|
|
8
|
+
* `project.scene.apply` operation (`packages/vgai-sdk/src/project/scene-operations.ts`)
|
|
9
|
+
* WITHOUT the SDK importing from the CLI — that would invert the intended
|
|
10
|
+
* dependency direction (CLI -> SDK -> engine, §3.4). The engine's scene layer
|
|
11
|
+
* is the correct shared home: both the CLI and the SDK already depend
|
|
12
|
+
* directly on `@vgai/engine/scene/*` for scene parsing/patching, so this
|
|
13
|
+
* module sits alongside `parse.ts`/`scene-apply.ts` as one more piece of
|
|
14
|
+
* scene-layer machinery neither caller re-implements.
|
|
15
|
+
*
|
|
16
|
+
* WHAT THIS CATCHES that schema validation alone does not: the Zod scene
|
|
17
|
+
* schema only checks that e.g. `materialRef` is a STRING — never that the
|
|
18
|
+
* string points at anything real. A diff introducing
|
|
19
|
+
* `materialRef: "materials/typo.mat.json"` (nonexistent, or present but
|
|
20
|
+
* malformed) passes ordinary scene/patch validation and would be written;
|
|
21
|
+
* the failure would otherwise only surface later, at runtime asset fetch.
|
|
22
|
+
* `dereferenceNewAssetRefs` closes that gap by re-resolving every asset
|
|
23
|
+
* reference the diff INTRODUCED (present in `result`, absent from
|
|
24
|
+
* `inputScene` — deliberately not pre-existing refs, so a scene with
|
|
25
|
+
* unrelated prior breakage can still receive an unrelated repair;
|
|
26
|
+
* `validate-scenes` remains the whole-project content gate) against disk,
|
|
27
|
+
* refusing the write if anything is missing or fails its own schema.
|
|
28
|
+
*
|
|
29
|
+
* Reference kinds and their treatment (unchanged from the original CLI-only
|
|
30
|
+
* implementation):
|
|
31
|
+
* - Zod-validated (JSON formats with engine Zod schemas): `materialRef`
|
|
32
|
+
* (.mat.json -> parseMaterialFile), `prefab` in its file-path form
|
|
33
|
+
* (.prefab.json -> parsePrefabFile). Prefabs are validated ONE level
|
|
34
|
+
* deep — the referenced prefab file itself must exist and parse; assets
|
|
35
|
+
* IT references are that file's own concern. (`animation.animGraph` ->
|
|
36
|
+
* AnimGraphFileSchema was removed by E5 — AnimGraph no longer exists.)
|
|
37
|
+
* - Existence-checked only (binary formats with no Zod schema to parse
|
|
38
|
+
* them through): gltf `mesh.src`, every material texture-map path
|
|
39
|
+
* (including the nested clearcoat/transmission/sheen/iridescence groups),
|
|
40
|
+
* `particles.material.map`, `audio.src`, `environment.skybox`.
|
|
41
|
+
* - `.inputmap.json` is structurally out of scope: no `.vscn.json`/
|
|
42
|
+
* `.prefab.json` field references an input map.
|
|
43
|
+
*/
|
|
44
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
45
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
46
|
+
import { parseMaterialFile, parsePrefabFile, SceneParseError } from './parse';
|
|
47
|
+
/** Material texture-map fields that hold image paths — top-level and nested feature groups. */
|
|
48
|
+
const MATERIAL_MAP_KEYS = [
|
|
49
|
+
'map',
|
|
50
|
+
'normalMap',
|
|
51
|
+
'emissiveMap',
|
|
52
|
+
'aoMap',
|
|
53
|
+
'roughnessMap',
|
|
54
|
+
'metalnessMap',
|
|
55
|
+
'displacementMap',
|
|
56
|
+
];
|
|
57
|
+
const MATERIAL_GROUP_MAP_KEYS = {
|
|
58
|
+
clearcoat: ['clearcoatMap', 'clearcoatRoughnessMap'],
|
|
59
|
+
transmission: ['transmissionMap'],
|
|
60
|
+
sheen: ['sheenColorMap', 'sheenRoughnessMap'],
|
|
61
|
+
iridescence: ['iridescenceMap', 'iridescenceThicknessMap'],
|
|
62
|
+
};
|
|
63
|
+
/** Same file-path-vs-registry-id heuristic as `asset-paths.ts`. */
|
|
64
|
+
function isFilePrefab(value) {
|
|
65
|
+
return value.includes('/');
|
|
66
|
+
}
|
|
67
|
+
function entityLabel(e) {
|
|
68
|
+
return e.id ? `entity "${e.name}" (id ${e.id})` : `entity "${e.name}"`;
|
|
69
|
+
}
|
|
70
|
+
/** Collect every asset reference in a scene document (entities walked recursively + environment), labeled for error messages. */
|
|
71
|
+
export function collectAssetRefs(doc) {
|
|
72
|
+
const refs = [];
|
|
73
|
+
function walk(entities) {
|
|
74
|
+
for (const e of entities) {
|
|
75
|
+
const label = entityLabel(e);
|
|
76
|
+
if (e.mesh?.type === 'gltf' && e.mesh.src) {
|
|
77
|
+
refs.push({ path: e.mesh.src, field: `${label} field mesh.src`, kind: 'binary' });
|
|
78
|
+
}
|
|
79
|
+
if (e.material) {
|
|
80
|
+
const mat = e.material;
|
|
81
|
+
for (const key of MATERIAL_MAP_KEYS) {
|
|
82
|
+
const val = mat[key];
|
|
83
|
+
if (typeof val === 'string') {
|
|
84
|
+
refs.push({ path: val, field: `${label} field material.${key}`, kind: 'binary' });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const [group, keys] of Object.entries(MATERIAL_GROUP_MAP_KEYS)) {
|
|
88
|
+
const groupVal = mat[group];
|
|
89
|
+
if (groupVal && typeof groupVal === 'object') {
|
|
90
|
+
for (const key of keys) {
|
|
91
|
+
const val = groupVal[key];
|
|
92
|
+
if (typeof val === 'string') {
|
|
93
|
+
refs.push({
|
|
94
|
+
path: val,
|
|
95
|
+
field: `${label} field material.${group}.${key}`,
|
|
96
|
+
kind: 'binary',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (e.materialRef) {
|
|
104
|
+
refs.push({ path: e.materialRef, field: `${label} field materialRef`, kind: 'material' });
|
|
105
|
+
}
|
|
106
|
+
if (e.particles?.material?.map) {
|
|
107
|
+
refs.push({
|
|
108
|
+
path: e.particles.material.map,
|
|
109
|
+
field: `${label} field particles.material.map`,
|
|
110
|
+
kind: 'binary',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (e.audio?.src) {
|
|
114
|
+
refs.push({ path: e.audio.src, field: `${label} field audio.src`, kind: 'binary' });
|
|
115
|
+
}
|
|
116
|
+
if (e.prefab && isFilePrefab(e.prefab)) {
|
|
117
|
+
refs.push({ path: e.prefab, field: `${label} field prefab`, kind: 'prefab' });
|
|
118
|
+
}
|
|
119
|
+
if (e.children)
|
|
120
|
+
walk(e.children);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
walk(doc.entities);
|
|
124
|
+
if (doc.environment?.skybox) {
|
|
125
|
+
refs.push({ path: doc.environment.skybox, field: 'environment.skybox', kind: 'binary' });
|
|
126
|
+
}
|
|
127
|
+
return refs;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Resolve the asset root the scene's references are relative to. Asset paths
|
|
131
|
+
* are web-root-relative (the runtime fetches them from the served `public/`
|
|
132
|
+
* directory), and scene files conventionally live INSIDE `public/`
|
|
133
|
+
* (`public/scenes/*.vscn.json`) — so the nearest ancestor directory literally
|
|
134
|
+
* named `public` is the root. Fallback for scenes not under a `public/`
|
|
135
|
+
* ancestor: the scene's own directory.
|
|
136
|
+
*/
|
|
137
|
+
export function findAssetRoot(scenePath) {
|
|
138
|
+
const dir = resolve(dirname(scenePath));
|
|
139
|
+
let cursor = dir;
|
|
140
|
+
for (;;) {
|
|
141
|
+
if (basename(cursor) === 'public')
|
|
142
|
+
return cursor;
|
|
143
|
+
const parent = dirname(cursor);
|
|
144
|
+
if (parent === cursor)
|
|
145
|
+
return dir;
|
|
146
|
+
cursor = parent;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Format Zod/scene-parse issues as `path: message`, one per line. */
|
|
150
|
+
function formatIssues(issues) {
|
|
151
|
+
return issues.map((i) => ` ${i.path.join('.')}: ${i.message}`).join('\n');
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Dereference every asset reference `result` introduces relative to
|
|
155
|
+
* `inputScene` (present in the result, absent from the input) against disk,
|
|
156
|
+
* relative to `scenePath`'s asset root (see `findAssetRoot`). Returns
|
|
157
|
+
* structured errors (empty = every new reference resolved and validated) —
|
|
158
|
+
* never throws; callers decide how to present/escalate a non-empty result
|
|
159
|
+
* (the CLI folds these into one `ApplyDiffCliError` message, the SDK raises
|
|
160
|
+
* a declared `ASSET_REF_INVALID` `OperationError`).
|
|
161
|
+
*/
|
|
162
|
+
export function dereferenceNewAssetRefs(inputScene, result, scenePath) {
|
|
163
|
+
const preexisting = new Set(collectAssetRefs(inputScene).map((r) => r.path));
|
|
164
|
+
const newRefs = collectAssetRefs(result).filter((r) => !preexisting.has(r.path));
|
|
165
|
+
if (newRefs.length === 0)
|
|
166
|
+
return [];
|
|
167
|
+
const assetRoot = findAssetRoot(scenePath);
|
|
168
|
+
const errors = [];
|
|
169
|
+
for (const ref of newRefs) {
|
|
170
|
+
const diskPath = join(assetRoot, ref.path.replace(/^\//, ''));
|
|
171
|
+
if (!existsSync(diskPath)) {
|
|
172
|
+
errors.push({
|
|
173
|
+
field: ref.field,
|
|
174
|
+
path: ref.path,
|
|
175
|
+
diskPath,
|
|
176
|
+
reason: `file not found at ${diskPath} (resolved against ${assetRoot})`,
|
|
177
|
+
});
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (ref.kind === 'binary')
|
|
181
|
+
continue; // existence-only (see the exclusion note above)
|
|
182
|
+
let json;
|
|
183
|
+
try {
|
|
184
|
+
json = JSON.parse(readFileSync(diskPath, 'utf-8'));
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
errors.push({
|
|
188
|
+
field: ref.field,
|
|
189
|
+
path: ref.path,
|
|
190
|
+
diskPath,
|
|
191
|
+
reason: `${diskPath} is not valid JSON: ${err instanceof Error ? err.message : err}`,
|
|
192
|
+
});
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
if (ref.kind === 'material') {
|
|
197
|
+
parseMaterialFile(json, diskPath);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
parsePrefabFile(json, diskPath);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
const detail = err instanceof SceneParseError ? `\n${formatIssues(err.issues)}` : ` ${err}`;
|
|
205
|
+
errors.push({
|
|
206
|
+
field: ref.field,
|
|
207
|
+
path: ref.path,
|
|
208
|
+
diskPath,
|
|
209
|
+
reason: `${diskPath} fails schema validation:${detail}`,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return errors;
|
|
214
|
+
}
|