@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,90 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* W3.1 of docs/DATA-TOOLS-DESIGN.md §3.3 — `useSelection()`, the third
|
|
4
|
+
* tool-hooks contract member (alongside `useData`/`writeData` from
|
|
5
|
+
* `use-data.ts`). Where those two hooks are about DATA ASSETS, this one is
|
|
6
|
+
* about the currently-selected ENTITY and the components authored on it —
|
|
7
|
+
* the gap a real consumer (`critter-types-w3b`'s `critter-type.tool.tsx`,
|
|
8
|
+
* §9.4) hit hard: with no way to read a component's own authored config, it
|
|
9
|
+
* had to recover species from `node.label` (a display string, not data).
|
|
10
|
+
*
|
|
11
|
+
* Scope, v1:
|
|
12
|
+
* - INSPECTOR-placement tools only (`placement: 'inspector'`,
|
|
13
|
+
* `define-tool.ts`). `EditorSelectionProvider` is host plumbing —
|
|
14
|
+
* `InspectorToolSection` wraps every tool render in it; dock tools
|
|
15
|
+
* (`ToolHost`/`BottomPanel`) have no adapter/selection in scope and never
|
|
16
|
+
* get a provider. Calling `useSelection()` there throws a teaching error,
|
|
17
|
+
* contained by the tool's `ToolErrorBoundary` (the editor survives).
|
|
18
|
+
* - READ-only. `config` is a shallow copy of the authored record; write
|
|
19
|
+
* through `InspectorProvider.set('components.<Type>.<field>', v)` /
|
|
20
|
+
* `writeData` (the existing paths), never by mutating what this hook
|
|
21
|
+
* returns. Per-entity WRITE-from-tool is deferred with `useTunable` (§10).
|
|
22
|
+
* - Honest degrades, not errors, when the adapter is thinner than the vgai
|
|
23
|
+
* first-party one: no `components` provider at all ⇒ `components: []`;
|
|
24
|
+
* a `components` provider present but with no optional `config()`
|
|
25
|
+
* accessor ⇒ each entry still appears (from `list()`) but with
|
|
26
|
+
* `config: null`. Both mirror the `AuthoringAdapter` optional-provider
|
|
27
|
+
* doctrine (§4) — an ingest/UI adapter that never implements `components`
|
|
28
|
+
* was already legal, and stays legal.
|
|
29
|
+
*
|
|
30
|
+
* Liveness — two existing paths reused, no new mechanism (§4's "reuse that
|
|
31
|
+
* path" rule):
|
|
32
|
+
* 1. Selection changes: `Inspector.tsx`'s own
|
|
33
|
+
* `useSyncExternalStore(store.subscribe, store.getSnapshot)` re-renders
|
|
34
|
+
* the panel, each matched `Section` gets the new `nodeId` prop, and
|
|
35
|
+
* `InspectorToolSection` re-creates this provider's context value.
|
|
36
|
+
* 2. Config edits while the SAME node stays selected: `adapter.subscribe`
|
|
37
|
+
* fires (the vgai adapter's store notifies on every `updateEntity`,
|
|
38
|
+
* which is what `InspectorProvider.set` goes through) — this hook keeps
|
|
39
|
+
* a local version counter bumped per notification (exactly
|
|
40
|
+
* `game-state.tsx`'s `useWorldObservation` pattern: the adapter has no
|
|
41
|
+
* snapshot/version of its own, `subscribe` is fire-only) and recomputes.
|
|
42
|
+
*/
|
|
43
|
+
import { createContext, useContext, useMemo, useRef, useSyncExternalStore, } from 'react';
|
|
44
|
+
const SelectionContext = createContext(null);
|
|
45
|
+
/**
|
|
46
|
+
* EDITOR-side host plumbing: `InspectorToolSection` wraps a tool's rendered
|
|
47
|
+
* `<Component/>` in this, passing the adapter + nodeId it already holds.
|
|
48
|
+
* Project tools never render this themselves — it exists so `useSelection()`
|
|
49
|
+
* has something to read.
|
|
50
|
+
*/
|
|
51
|
+
export function EditorSelectionProvider({ adapter, nodeId, children, }) {
|
|
52
|
+
const value = useMemo(() => ({ adapter, nodeId }), [adapter, nodeId]);
|
|
53
|
+
return _jsx(SelectionContext.Provider, { value: value, children: children });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The selected entity, live: its node, and every component attached to it
|
|
57
|
+
* with that component's own authored config (read-only — see module doc).
|
|
58
|
+
*
|
|
59
|
+
* Throws outside an `EditorSelectionProvider` — inspector tools always render
|
|
60
|
+
* inside one; a dock tool or game-code caller does not, and the error names
|
|
61
|
+
* the fix rather than failing silently.
|
|
62
|
+
*/
|
|
63
|
+
export function useSelection() {
|
|
64
|
+
const ctx = useContext(SelectionContext);
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new Error('useSelection: no editor selection in context — this hook only works inside an editor-hosted ' +
|
|
67
|
+
"INSPECTOR tool (placement: 'inspector', docs/DATA-TOOLS-DESIGN.md §3.3/§3.2). Dock tools and " +
|
|
68
|
+
'game code have no selection to read.');
|
|
69
|
+
}
|
|
70
|
+
const { adapter, nodeId } = ctx;
|
|
71
|
+
// Local version counter bumped per adapter notification — the adapter has
|
|
72
|
+
// no snapshot/version of its own, `subscribe` is fire-only (same pattern
|
|
73
|
+
// as `useWorldObservation`'s `versionRef`, game-state.tsx).
|
|
74
|
+
const versionRef = useRef(0);
|
|
75
|
+
const version = useSyncExternalStore((onStoreChange) => adapter.subscribe?.(() => {
|
|
76
|
+
versionRef.current++;
|
|
77
|
+
onStoreChange();
|
|
78
|
+
}) ?? (() => { }), () => versionRef.current);
|
|
79
|
+
return useMemo(() => {
|
|
80
|
+
const node = nodeId ? adapter.hierarchy.node(nodeId) : null;
|
|
81
|
+
const types = nodeId ? (adapter.components?.list(nodeId) ?? []) : [];
|
|
82
|
+
const components = types.map(({ type }) => ({
|
|
83
|
+
type,
|
|
84
|
+
config: nodeId ? (adapter.components?.config?.(nodeId, type) ?? null) : null,
|
|
85
|
+
}));
|
|
86
|
+
return { nodeId, node, components };
|
|
87
|
+
// `version` has no value of its own — only its CHANGE matters, as the
|
|
88
|
+
// liveness signal described above.
|
|
89
|
+
}, [adapter, nodeId, version]);
|
|
90
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export declare class AutoBatcher {
|
|
3
|
+
/** Root the batcher owns under the scene (instanced meshes when on, entities when off). */
|
|
4
|
+
readonly root: THREE.Group<THREE.Object3DEventMap>;
|
|
5
|
+
private entities;
|
|
6
|
+
private batches;
|
|
7
|
+
private enabled;
|
|
8
|
+
/** Indices of entities whose transform changed since last sync. */
|
|
9
|
+
private dirty;
|
|
10
|
+
private touchedBatches;
|
|
11
|
+
private indexOf;
|
|
12
|
+
private optOut;
|
|
13
|
+
private batchOf;
|
|
14
|
+
private membersOf;
|
|
15
|
+
constructor(parent: THREE.Object3D, enabled?: boolean);
|
|
16
|
+
/** Register an entity (a Mesh) as the logical handle. Call build() after adding. */
|
|
17
|
+
add(entity: THREE.Mesh, optOut?: boolean): void;
|
|
18
|
+
/** Mark an entity moved this frame (dirty-tracking input). */
|
|
19
|
+
markMoved(entity: THREE.Mesh): void;
|
|
20
|
+
/** (Re)build the render representation for the current enabled state. */
|
|
21
|
+
build(): void;
|
|
22
|
+
/** Apply the dirty set to the instance buffers. Cheap when few moved. */
|
|
23
|
+
sync(): void;
|
|
24
|
+
/** Live toggle: rebuilds the representation (one-time cost, not per-frame). */
|
|
25
|
+
setEnabled(on: boolean): void;
|
|
26
|
+
isEnabled(): boolean;
|
|
27
|
+
/** Map a raycast hit on a batch back to the logical entity (editor/gameplay picking). */
|
|
28
|
+
resolvePick(intersection: THREE.Intersection): THREE.Mesh | null;
|
|
29
|
+
/** Per-frame draw-call count this batcher contributes (for stats). */
|
|
30
|
+
get drawCallCount(): number;
|
|
31
|
+
private get optOutCount();
|
|
32
|
+
private clearRoot;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=auto-batcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-batcher.d.ts","sourceRoot":"","sources":["../../src/render/auto-batcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiC/B,qBAAa,WAAW;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,sCAAqB;IAElC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,mEAAmE;IACnE,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,cAAc,CAAoB;IAG1C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,SAAS,CAAoD;gBAEzD,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,UAAO;IAMlD,oFAAoF;IACpF,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,UAAQ,GAAG,IAAI;IAM7C,8DAA8D;IAC9D,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,GAAG,IAAI;IAKnC,yEAAyE;IACzE,KAAK,IAAI,IAAI;IAuCb,yEAAyE;IACzE,IAAI,IAAI,IAAI;IAmBZ,+EAA+E;IAC/E,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAM7B,SAAS,IAAI,OAAO;IAIpB,yFAAyF;IACzF,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI;IAShE,sEAAsE;IACtE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,OAAO,KAAK,WAAW,GAItB;IAED,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
const SIG = (m) => {
|
|
3
|
+
const mat = Array.isArray(m.material) ? m.material[0] : m.material;
|
|
4
|
+
return `${m.geometry.uuid}|${mat.uuid}`;
|
|
5
|
+
};
|
|
6
|
+
export class AutoBatcher {
|
|
7
|
+
/** Root the batcher owns under the scene (instanced meshes when on, entities when off). */
|
|
8
|
+
root = new THREE.Group();
|
|
9
|
+
entities = [];
|
|
10
|
+
batches = new Map();
|
|
11
|
+
enabled;
|
|
12
|
+
/** Indices of entities whose transform changed since last sync. */
|
|
13
|
+
dirty = new Set();
|
|
14
|
+
touchedBatches = new Set();
|
|
15
|
+
// Per-mesh bookkeeping is kept in WeakMaps, NOT on userData (the typed userData
|
|
16
|
+
// registry is reserved for documented engine keys — see user-data.ts).
|
|
17
|
+
indexOf = new WeakMap();
|
|
18
|
+
optOut = new WeakSet();
|
|
19
|
+
batchOf = new WeakMap();
|
|
20
|
+
membersOf = new WeakMap();
|
|
21
|
+
constructor(parent, enabled = true) {
|
|
22
|
+
this.enabled = enabled;
|
|
23
|
+
this.root.name = 'AutoBatcher';
|
|
24
|
+
parent.add(this.root);
|
|
25
|
+
}
|
|
26
|
+
/** Register an entity (a Mesh) as the logical handle. Call build() after adding. */
|
|
27
|
+
add(entity, optOut = false) {
|
|
28
|
+
this.indexOf.set(entity, this.entities.length);
|
|
29
|
+
if (optOut)
|
|
30
|
+
this.optOut.add(entity);
|
|
31
|
+
this.entities.push(entity);
|
|
32
|
+
}
|
|
33
|
+
/** Mark an entity moved this frame (dirty-tracking input). */
|
|
34
|
+
markMoved(entity) {
|
|
35
|
+
const i = this.indexOf.get(entity);
|
|
36
|
+
if (i !== undefined)
|
|
37
|
+
this.dirty.add(i);
|
|
38
|
+
}
|
|
39
|
+
/** (Re)build the render representation for the current enabled state. */
|
|
40
|
+
build() {
|
|
41
|
+
this.clearRoot();
|
|
42
|
+
this.batches.clear();
|
|
43
|
+
if (!this.enabled) {
|
|
44
|
+
for (const e of this.entities)
|
|
45
|
+
this.root.add(e);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const m = new THREE.Matrix4();
|
|
49
|
+
// group eligible entities; opt-outs render individually
|
|
50
|
+
const groups = new Map();
|
|
51
|
+
for (const e of this.entities) {
|
|
52
|
+
if (this.optOut.has(e)) {
|
|
53
|
+
this.root.add(e);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const key = SIG(e);
|
|
57
|
+
const arr = groups.get(key) ?? [];
|
|
58
|
+
arr.push(e);
|
|
59
|
+
groups.set(key, arr);
|
|
60
|
+
}
|
|
61
|
+
for (const [key, members] of groups) {
|
|
62
|
+
const proto = members[0];
|
|
63
|
+
const mat = Array.isArray(proto.material) ? proto.material[0] : proto.material;
|
|
64
|
+
const inst = new THREE.InstancedMesh(proto.geometry, mat, members.length);
|
|
65
|
+
inst.frustumCulled = false;
|
|
66
|
+
for (let i = 0; i < members.length; i++) {
|
|
67
|
+
const e = members[i];
|
|
68
|
+
e.updateMatrix();
|
|
69
|
+
m.copy(e.matrix);
|
|
70
|
+
inst.setMatrixAt(i, m);
|
|
71
|
+
this.batchOf.set(e, { key, localIndex: i });
|
|
72
|
+
}
|
|
73
|
+
inst.instanceMatrix.needsUpdate = true;
|
|
74
|
+
this.membersOf.set(inst, members); // localIndex → entity (picking)
|
|
75
|
+
this.root.add(inst);
|
|
76
|
+
this.batches.set(key, { key, instanced: inst, members });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Apply the dirty set to the instance buffers. Cheap when few moved. */
|
|
80
|
+
sync() {
|
|
81
|
+
if (!this.enabled)
|
|
82
|
+
return;
|
|
83
|
+
const m = new THREE.Matrix4();
|
|
84
|
+
this.touchedBatches.clear();
|
|
85
|
+
for (const i of this.dirty) {
|
|
86
|
+
const e = this.entities[i];
|
|
87
|
+
const info = this.batchOf.get(e);
|
|
88
|
+
if (!info)
|
|
89
|
+
continue; // opt-out or not batched
|
|
90
|
+
const batch = this.batches.get(info.key);
|
|
91
|
+
if (!batch)
|
|
92
|
+
continue;
|
|
93
|
+
e.updateMatrix();
|
|
94
|
+
m.copy(e.matrix);
|
|
95
|
+
batch.instanced.setMatrixAt(info.localIndex, m);
|
|
96
|
+
this.touchedBatches.add(batch);
|
|
97
|
+
}
|
|
98
|
+
for (const b of this.touchedBatches)
|
|
99
|
+
b.instanced.instanceMatrix.needsUpdate = true;
|
|
100
|
+
this.dirty.clear();
|
|
101
|
+
}
|
|
102
|
+
/** Live toggle: rebuilds the representation (one-time cost, not per-frame). */
|
|
103
|
+
setEnabled(on) {
|
|
104
|
+
if (on === this.enabled)
|
|
105
|
+
return;
|
|
106
|
+
this.enabled = on;
|
|
107
|
+
this.build();
|
|
108
|
+
}
|
|
109
|
+
isEnabled() {
|
|
110
|
+
return this.enabled;
|
|
111
|
+
}
|
|
112
|
+
/** Map a raycast hit on a batch back to the logical entity (editor/gameplay picking). */
|
|
113
|
+
resolvePick(intersection) {
|
|
114
|
+
const obj = intersection.object;
|
|
115
|
+
if (obj.isInstancedMesh && intersection.instanceId != null) {
|
|
116
|
+
const members = this.membersOf.get(obj);
|
|
117
|
+
return members?.[intersection.instanceId] ?? null;
|
|
118
|
+
}
|
|
119
|
+
return obj instanceof THREE.Mesh ? obj : null;
|
|
120
|
+
}
|
|
121
|
+
/** Per-frame draw-call count this batcher contributes (for stats). */
|
|
122
|
+
get drawCallCount() {
|
|
123
|
+
return this.enabled ? this.batches.size + this.optOutCount : this.entities.length;
|
|
124
|
+
}
|
|
125
|
+
get optOutCount() {
|
|
126
|
+
let n = 0;
|
|
127
|
+
for (const e of this.entities)
|
|
128
|
+
if (this.optOut.has(e))
|
|
129
|
+
n++;
|
|
130
|
+
return n;
|
|
131
|
+
}
|
|
132
|
+
clearRoot() {
|
|
133
|
+
for (let i = this.root.children.length - 1; i >= 0; i--) {
|
|
134
|
+
const c = this.root.children[i];
|
|
135
|
+
this.root.remove(c);
|
|
136
|
+
if (c.isInstancedMesh)
|
|
137
|
+
c.dispose();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import type { ResolvedRenderSettings } from './render-settings';
|
|
3
|
+
export declare class RenderBatchSystem {
|
|
4
|
+
private scene;
|
|
5
|
+
private settings;
|
|
6
|
+
private root;
|
|
7
|
+
private groups;
|
|
8
|
+
private dynamicGroups;
|
|
9
|
+
private parentOf;
|
|
10
|
+
private membersOf;
|
|
11
|
+
constructor(scene: THREE.Scene, settings: ResolvedRenderSettings);
|
|
12
|
+
/** Scan the scene and build instanced groups. Idempotent (rebuilds). */
|
|
13
|
+
build(): void;
|
|
14
|
+
private makeGroup;
|
|
15
|
+
/**
|
|
16
|
+
* Per-frame sync for DYNAMIC groups only (static are detached & immutable → free).
|
|
17
|
+
* Called in the preRender phase. Refreshes world matrices once (the engine's movers
|
|
18
|
+
* set matrixWorldNeedsUpdate via physics/animation), then re-writes only the instances
|
|
19
|
+
* whose source moved (element-wise cache compare). No-op when there are no movers.
|
|
20
|
+
*/
|
|
21
|
+
update(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Raycast against the batched instances, mapping a hit back to the logical source
|
|
24
|
+
* Object3D (so editor/gameplay picking still resolves a detached entity).
|
|
25
|
+
*/
|
|
26
|
+
raycast(raycaster: THREE.Raycaster): THREE.Mesh | null;
|
|
27
|
+
/** Number of draw calls the batcher contributes (1 per group). */
|
|
28
|
+
get drawCalls(): number;
|
|
29
|
+
/** How many source meshes were collapsed into instances. */
|
|
30
|
+
get batchedCount(): number;
|
|
31
|
+
teardown(): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=render-batch-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-batch-system.d.ts","sourceRoot":"","sources":["../../src/render/render-batch-system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAoGhE,qBAAa,iBAAiB;IAU1B,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAVlB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAe;IAEpC,OAAO,CAAC,QAAQ,CAA6C;IAE7D,OAAO,CAAC,SAAS,CAAoD;gBAG3D,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,sBAAsB;IAM1C,wEAAwE;IACxE,KAAK,IAAI,IAAI;IAmCb,OAAO,CAAC,SAAS;IAyCjB;;;;;OAKG;IACH,MAAM,IAAI,IAAI;IAyBd;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI;IAStD,kEAAkE;IAClE,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,4DAA4D;IAC5D,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,QAAQ,IAAI,IAAI;CAiBjB"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { getUserData } from '../scene/user-data';
|
|
3
|
+
// Structural signature — groups meshes that are VALUE-identical, not object-identical.
|
|
4
|
+
// The engine scene-loader instantiates a fresh geometry+material per entity (no dedup),
|
|
5
|
+
// so keying on .uuid would never batch a real scene. Keying on geometry type+parameters
|
|
6
|
+
// and material type+key-props groups identical authored primitives (e.g. 10k boxes of
|
|
7
|
+
// the same size+color → one batch). Non-primitive geometry (GLTF, no `.parameters`)
|
|
8
|
+
// falls back to uuid → it simply won't group, which is the safe default.
|
|
9
|
+
const geoKey = (g) => {
|
|
10
|
+
const params = g.parameters;
|
|
11
|
+
return params ? `${g.type}:${JSON.stringify(params)}` : `uuid:${g.uuid}`;
|
|
12
|
+
};
|
|
13
|
+
const matKey = (m) => {
|
|
14
|
+
const s = m;
|
|
15
|
+
const col = s.color?.getHexString?.() ?? '';
|
|
16
|
+
const map = s.map?.uuid ?? '';
|
|
17
|
+
return `${m.type}:${col}:${s.roughness ?? ''}:${s.metalness ?? ''}:${map}:${m.side}:${m.transparent}:${m.vertexColors}`;
|
|
18
|
+
};
|
|
19
|
+
const SIG = (m) =>
|
|
20
|
+
// include shadow flags: meshes with different cast/receive must not share a batch
|
|
21
|
+
// (the InstancedMesh carries one flag for the whole group).
|
|
22
|
+
`${geoKey(m.geometry)}|${matKey(m.material)}|${m.castShadow ? 1 : 0}${m.receiveShadow ? 1 : 0}`;
|
|
23
|
+
/** Nearest self/ancestor entity descriptor, if any. */
|
|
24
|
+
function nearestEntity(obj) {
|
|
25
|
+
let cur = obj;
|
|
26
|
+
while (cur) {
|
|
27
|
+
const entity = getUserData(cur, 'entity');
|
|
28
|
+
if (entity)
|
|
29
|
+
return entity;
|
|
30
|
+
cur = cur.parent;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/** Explicit per-entity opt-out (`render.autoBatch === false`). */
|
|
35
|
+
function entityOptOut(obj) {
|
|
36
|
+
return nearestEntity(obj)?.render?.autoBatch === false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Static-batching eligibility: only entities that won't move are safe to freeze
|
|
40
|
+
* and instance. An entity with physics, behavior components, or its own animation
|
|
41
|
+
* is a likely mover → left as an ordinary draw. Plain scenery (no def, or a def
|
|
42
|
+
* with none of those) is eligible. This is the safe, transparent default; a future
|
|
43
|
+
* dynamic-batch path (markMoved-driven) can include movers.
|
|
44
|
+
*/
|
|
45
|
+
function isLikelyStatic(obj) {
|
|
46
|
+
const e = nearestEntity(obj);
|
|
47
|
+
if (!e)
|
|
48
|
+
return true; // un-tagged scenery
|
|
49
|
+
if (e.physics)
|
|
50
|
+
return false;
|
|
51
|
+
if (e.animation)
|
|
52
|
+
return false;
|
|
53
|
+
if (e.components && Object.keys(e.components).length > 0)
|
|
54
|
+
return false;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
export class RenderBatchSystem {
|
|
58
|
+
scene;
|
|
59
|
+
settings;
|
|
60
|
+
root = new THREE.Group();
|
|
61
|
+
groups = [];
|
|
62
|
+
dynamicGroups = []; // subset needing per-frame sync
|
|
63
|
+
// Original parent of each detached (static) source, to re-attach on teardown.
|
|
64
|
+
parentOf = new WeakMap();
|
|
65
|
+
// instanceId mapping for raycast: which group + slot an InstancedMesh belongs to.
|
|
66
|
+
membersOf = new WeakMap();
|
|
67
|
+
constructor(scene, settings) {
|
|
68
|
+
this.scene = scene;
|
|
69
|
+
this.settings = settings;
|
|
70
|
+
this.root.name = 'RenderBatchSystem';
|
|
71
|
+
this.root.matrixAutoUpdate = false; // instances carry world matrices directly
|
|
72
|
+
}
|
|
73
|
+
/** Scan the scene and build instanced groups. Idempotent (rebuilds). */
|
|
74
|
+
build() {
|
|
75
|
+
this.teardown();
|
|
76
|
+
this.scene.add(this.root);
|
|
77
|
+
this.scene.updateMatrixWorld(true);
|
|
78
|
+
// collect eligible candidates, grouped by (geometry, material)
|
|
79
|
+
const buckets = new Map();
|
|
80
|
+
this.scene.traverse((obj) => {
|
|
81
|
+
const m = obj;
|
|
82
|
+
if (!m.isMesh)
|
|
83
|
+
return;
|
|
84
|
+
if (m.isInstancedMesh)
|
|
85
|
+
return;
|
|
86
|
+
if (m.isSkinnedMesh)
|
|
87
|
+
return;
|
|
88
|
+
if (m.isBatchedMesh)
|
|
89
|
+
return;
|
|
90
|
+
if (!m.visible)
|
|
91
|
+
return;
|
|
92
|
+
if (!m.geometry || !m.material || Array.isArray(m.material))
|
|
93
|
+
return;
|
|
94
|
+
if (m.material.transparent)
|
|
95
|
+
return;
|
|
96
|
+
if (this.root === m.parent)
|
|
97
|
+
return; // our own instances
|
|
98
|
+
if (entityOptOut(m))
|
|
99
|
+
return;
|
|
100
|
+
const key = SIG(m);
|
|
101
|
+
const arr = buckets.get(key) ?? [];
|
|
102
|
+
arr.push(m);
|
|
103
|
+
buckets.set(key, arr);
|
|
104
|
+
});
|
|
105
|
+
// Each signature bucket is partitioned into STATIC (detached, zero-cost) and
|
|
106
|
+
// DYNAMIC (kept in-place, dirty-synced) members, each ≥2 forming its own batch.
|
|
107
|
+
for (const bucket of buckets.values()) {
|
|
108
|
+
const staticMembers = [];
|
|
109
|
+
const dynamicMembers = [];
|
|
110
|
+
for (const m of bucket)
|
|
111
|
+
(isLikelyStatic(m) ? staticMembers : dynamicMembers).push(m);
|
|
112
|
+
if (staticMembers.length >= 2)
|
|
113
|
+
this.makeGroup(staticMembers, false);
|
|
114
|
+
if (dynamicMembers.length >= 2)
|
|
115
|
+
this.makeGroup(dynamicMembers, true);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
makeGroup(sources, dynamic) {
|
|
119
|
+
const frustum = this.settings['frustumCulling'] !== false;
|
|
120
|
+
const tmp = new THREE.Matrix4();
|
|
121
|
+
const proto = sources[0];
|
|
122
|
+
const inst = new THREE.InstancedMesh(proto.geometry, proto.material, sources.length);
|
|
123
|
+
inst.frustumCulled = frustum && !dynamic; // moving batches can leave the padded sphere
|
|
124
|
+
// Inherit shadow flags from the prototype so batched objects still cast/receive
|
|
125
|
+
// shadows (otherwise detaching the sources would silently drop them from shadows).
|
|
126
|
+
inst.castShadow = proto.castShadow;
|
|
127
|
+
inst.receiveShadow = proto.receiveShadow;
|
|
128
|
+
const cache = dynamic ? new Float32Array(sources.length * 16) : undefined;
|
|
129
|
+
for (let i = 0; i < sources.length; i++) {
|
|
130
|
+
const s = sources[i];
|
|
131
|
+
tmp.copy(s.matrixWorld);
|
|
132
|
+
inst.setMatrixAt(i, tmp);
|
|
133
|
+
if (dynamic) {
|
|
134
|
+
// keep the source in the graph (physics/animation still updates its matrixWorld),
|
|
135
|
+
// just hide its own draw; we copy its world matrix into the instance each frame.
|
|
136
|
+
cache.set(tmp.elements, i * 16);
|
|
137
|
+
s.visible = false;
|
|
138
|
+
}
|
|
139
|
+
else if (s.parent) {
|
|
140
|
+
// static: detach entirely so the renderer never walks it (zero per-frame cost)
|
|
141
|
+
this.parentOf.set(s, s.parent);
|
|
142
|
+
s.parent.remove(s);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
inst.instanceMatrix.needsUpdate = true;
|
|
146
|
+
if (frustum && !dynamic)
|
|
147
|
+
inst.computeBoundingSphere();
|
|
148
|
+
this.membersOf.set(inst, sources);
|
|
149
|
+
this.root.add(inst);
|
|
150
|
+
const group = cache
|
|
151
|
+
? { instanced: inst, sources, dynamic, cache }
|
|
152
|
+
: { instanced: inst, sources, dynamic };
|
|
153
|
+
this.groups.push(group);
|
|
154
|
+
if (dynamic)
|
|
155
|
+
this.dynamicGroups.push(group);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Per-frame sync for DYNAMIC groups only (static are detached & immutable → free).
|
|
159
|
+
* Called in the preRender phase. Refreshes world matrices once (the engine's movers
|
|
160
|
+
* set matrixWorldNeedsUpdate via physics/animation), then re-writes only the instances
|
|
161
|
+
* whose source moved (element-wise cache compare). No-op when there are no movers.
|
|
162
|
+
*/
|
|
163
|
+
update() {
|
|
164
|
+
if (this.dynamicGroups.length === 0)
|
|
165
|
+
return;
|
|
166
|
+
this.scene.updateMatrixWorld(false); // refresh moved subtrees (force=false → cheap)
|
|
167
|
+
for (const g of this.dynamicGroups) {
|
|
168
|
+
const cache = g.cache;
|
|
169
|
+
let dirty = false;
|
|
170
|
+
for (let i = 0; i < g.sources.length; i++) {
|
|
171
|
+
const el = g.sources[i].matrixWorld.elements;
|
|
172
|
+
const off = i * 16;
|
|
173
|
+
let changed = false;
|
|
174
|
+
for (let k = 0; k < 16; k++) {
|
|
175
|
+
if (el[k] !== cache[off + k]) {
|
|
176
|
+
changed = true;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!changed)
|
|
181
|
+
continue;
|
|
182
|
+
g.instanced.setMatrixAt(i, g.sources[i].matrixWorld);
|
|
183
|
+
cache.set(el, off);
|
|
184
|
+
dirty = true;
|
|
185
|
+
}
|
|
186
|
+
if (dirty)
|
|
187
|
+
g.instanced.instanceMatrix.needsUpdate = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Raycast against the batched instances, mapping a hit back to the logical source
|
|
192
|
+
* Object3D (so editor/gameplay picking still resolves a detached entity).
|
|
193
|
+
*/
|
|
194
|
+
raycast(raycaster) {
|
|
195
|
+
const hits = raycaster.intersectObject(this.root, true);
|
|
196
|
+
for (const h of hits) {
|
|
197
|
+
const members = this.membersOf.get(h.object);
|
|
198
|
+
if (members && h.instanceId != null)
|
|
199
|
+
return members[h.instanceId] ?? null;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
/** Number of draw calls the batcher contributes (1 per group). */
|
|
204
|
+
get drawCalls() {
|
|
205
|
+
return this.groups.length;
|
|
206
|
+
}
|
|
207
|
+
/** How many source meshes were collapsed into instances. */
|
|
208
|
+
get batchedCount() {
|
|
209
|
+
return this.groups.reduce((n, g) => n + g.sources.length, 0);
|
|
210
|
+
}
|
|
211
|
+
teardown() {
|
|
212
|
+
for (const g of this.groups) {
|
|
213
|
+
for (const s of g.sources) {
|
|
214
|
+
if (g.dynamic)
|
|
215
|
+
s.visible = true; // dynamic sources stayed in-graph, hidden
|
|
216
|
+
else {
|
|
217
|
+
const parent = this.parentOf.get(s); // static sources were detached — re-attach
|
|
218
|
+
if (parent)
|
|
219
|
+
parent.add(s);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
g.instanced.dispose();
|
|
223
|
+
this.root.remove(g.instanced);
|
|
224
|
+
}
|
|
225
|
+
this.groups = [];
|
|
226
|
+
this.dynamicGroups = [];
|
|
227
|
+
if (this.root.parent)
|
|
228
|
+
this.root.parent.remove(this.root);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The render-feature registry — single source of truth for every togglable render
|
|
4
|
+
* setting. The scene schema (`SceneEnvironment.rendering`, `SceneEntity.render`),
|
|
5
|
+
* the cascade resolver (`resolveRenderSettings`), the editor UI, and the stats
|
|
6
|
+
* overlay are all derived from this list, so "everything togglable" stays
|
|
7
|
+
* consistent by construction (same posture as the component/material/instancer
|
|
8
|
+
* registries). Adding a feature here gives it a schema field + cascade entry for
|
|
9
|
+
* free. See docs/research/RENDER-SETTINGS-UX.md.
|
|
10
|
+
*/
|
|
11
|
+
export type RenderFeatureValue = boolean | number | string;
|
|
12
|
+
export interface RenderFeature {
|
|
13
|
+
/** Stable key used in schema, cascade, and UI. */
|
|
14
|
+
key: string;
|
|
15
|
+
/** Editor display label. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** Schema `.describe()` text (powers JSON Schema / inspector docs). */
|
|
18
|
+
description: string;
|
|
19
|
+
/** Control shape. */
|
|
20
|
+
kind: 'toggle' | 'number' | 'enum';
|
|
21
|
+
/** Engine default — the "fast by default" baseline. */
|
|
22
|
+
default: RenderFeatureValue;
|
|
23
|
+
/**
|
|
24
|
+
* `live` re-applies on change; `reload` needs a renderer re-init (e.g. backend,
|
|
25
|
+
* antialias). The editor badges `reload` features and re-inits the viewport.
|
|
26
|
+
*/
|
|
27
|
+
apply: 'live' | 'reload';
|
|
28
|
+
/** Whether this feature may be overridden per-entity (the entity cascade layer). */
|
|
29
|
+
perEntity: boolean;
|
|
30
|
+
/** Allowed values for `enum` kind. */
|
|
31
|
+
options?: readonly string[];
|
|
32
|
+
/** [min, max] for `number` kind. */
|
|
33
|
+
range?: readonly [number, number];
|
|
34
|
+
}
|
|
35
|
+
export declare const RENDER_FEATURES: readonly RenderFeature[];
|
|
36
|
+
/** Map for O(1) lookup by key. */
|
|
37
|
+
export declare const RENDER_FEATURE_BY_KEY: ReadonlyMap<string, RenderFeature>;
|
|
38
|
+
/**
|
|
39
|
+
* Build a Zod object for the render settings, derived from the registry so the
|
|
40
|
+
* schema can never drift from the feature list. All fields optional — absence
|
|
41
|
+
* means "inherit" in the cascade. `perEntityOnly` builds the per-entity override
|
|
42
|
+
* schema (only features whose `perEntity` is true).
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildRenderingZod(opts?: {
|
|
45
|
+
perEntityOnly?: boolean;
|
|
46
|
+
}): z.ZodTypeAny;
|
|
47
|
+
//# sourceMappingURL=render-features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-features.d.ts","sourceRoot":"","sources":["../../src/render/render-features.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AAEH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,uDAAuD;IACvD,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,oFAAoF;IACpF,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,oCAAoC;IACpC,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EA6EnD,CAAC;AAEF,kCAAkC;AAClC,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAEpE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,CAAC,CAAC,UAAU,CAiBtF"}
|