@vgai/engine 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/adapter-surface.d.ts +30 -0
- package/dist/adapter/adapter-surface.d.ts.map +1 -0
- package/dist/adapter/adapter-surface.js +18 -0
- package/dist/adapter/authoring.d.ts +597 -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 +77 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
- package/dist/adapter/colyseus-networking-adapter.js +76 -0
- package/dist/adapter/first-party-systems.d.ts +23 -0
- package/dist/adapter/first-party-systems.d.ts.map +1 -0
- package/dist/adapter/first-party-systems.js +196 -0
- package/dist/adapter/host-context.d.ts +194 -0
- package/dist/adapter/host-context.d.ts.map +1 -0
- package/dist/adapter/host-context.js +80 -0
- package/dist/adapter/index.d.ts +33 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +25 -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/scene-capture.d.ts +121 -0
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
- package/dist/adapter/ingest/scene-capture.js +270 -0
- package/dist/adapter/ingest/structural-ids.d.ts +64 -0
- package/dist/adapter/ingest/structural-ids.d.ts.map +1 -0
- package/dist/adapter/ingest/structural-ids.js +110 -0
- package/dist/adapter/ingest/upstream-pin.d.ts +44 -0
- package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
- package/dist/adapter/ingest/upstream-pin.js +47 -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 +69 -0
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
- package/dist/adapter/rapier-physics-adapter.js +135 -0
- package/dist/adapter/root-adapter.d.ts +195 -0
- package/dist/adapter/root-adapter.d.ts.map +1 -0
- package/dist/adapter/root-adapter.js +25 -0
- package/dist/adapter/setup-three-root-adapter.d.ts +87 -0
- package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -0
- package/dist/adapter/setup-three-root-adapter.js +791 -0
- package/dist/adapter/system-adapter.d.ts +453 -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/ai/navigation.d.ts +78 -0
- package/dist/ai/navigation.d.ts.map +1 -0
- package/dist/ai/navigation.js +152 -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 +249 -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 +31 -0
- package/dist/animation/cubic-spline-interpolant.d.ts +54 -0
- package/dist/animation/cubic-spline-interpolant.d.ts.map +1 -0
- package/dist/animation/cubic-spline-interpolant.js +111 -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 +277 -0
- package/dist/animation/theatre-director.d.ts.map +1 -0
- package/dist/animation/theatre-director.js +248 -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 +119 -0
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
- package/dist/animation/xstate-animation-binding.js +349 -0
- package/dist/animation/xstate-animation-meta.d.ts +266 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
- package/dist/animation/xstate-animation-meta.js +252 -0
- package/dist/asset-formats/camera.d.ts +15 -0
- package/dist/asset-formats/camera.d.ts.map +1 -0
- package/dist/asset-formats/camera.js +15 -0
- package/dist/asset-formats/collider.d.ts +21 -0
- package/dist/asset-formats/collider.d.ts.map +1 -0
- package/dist/asset-formats/collider.js +53 -0
- package/dist/asset-formats/index.d.ts +46 -0
- package/dist/asset-formats/index.d.ts.map +1 -0
- package/dist/asset-formats/index.js +36 -0
- package/dist/asset-formats/instances.d.ts +17 -0
- package/dist/asset-formats/instances.d.ts.map +1 -0
- package/dist/asset-formats/instances.js +31 -0
- package/dist/asset-formats/light.d.ts +21 -0
- package/dist/asset-formats/light.d.ts.map +1 -0
- package/dist/asset-formats/light.js +35 -0
- package/dist/asset-formats/material.d.ts +129 -0
- package/dist/asset-formats/material.d.ts.map +1 -0
- package/dist/asset-formats/material.js +88 -0
- package/dist/asset-formats/mesh.d.ts +22 -0
- package/dist/asset-formats/mesh.d.ts.map +1 -0
- package/dist/asset-formats/mesh.js +64 -0
- package/dist/asset-formats/parse.d.ts +20 -0
- package/dist/asset-formats/parse.d.ts.map +1 -0
- package/dist/asset-formats/parse.js +34 -0
- package/dist/asset-formats/particles.d.ts +1390 -0
- package/dist/asset-formats/particles.d.ts.map +1 -0
- package/dist/asset-formats/particles.js +319 -0
- package/dist/asset-formats/render-env.d.ts +387 -0
- package/dist/asset-formats/render-env.d.ts.map +1 -0
- package/dist/asset-formats/render-env.js +300 -0
- package/dist/asset-formats/tuples.d.ts +12 -0
- package/dist/asset-formats/tuples.d.ts.map +1 -0
- package/dist/asset-formats/tuples.js +14 -0
- package/dist/asset-loaders.d.ts +97 -0
- package/dist/asset-loaders.d.ts.map +1 -0
- package/dist/asset-loaders.js +209 -0
- package/dist/asset-parse-error.d.ts +24 -0
- package/dist/asset-parse-error.d.ts.map +1 -0
- package/dist/asset-parse-error.js +29 -0
- package/dist/asset-registry.d.ts +38 -0
- package/dist/asset-registry.d.ts.map +1 -0
- package/dist/asset-registry.js +66 -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/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/canvas-react/engine-bridge.d.ts +45 -0
- package/dist/canvas-react/engine-bridge.d.ts.map +1 -0
- package/dist/canvas-react/engine-bridge.js +45 -0
- package/dist/canvas-react/index.d.ts +42 -0
- package/dist/canvas-react/index.d.ts.map +1 -0
- package/dist/canvas-react/index.js +41 -0
- package/dist/canvas-react/pixi-primitive.d.ts +85 -0
- package/dist/canvas-react/pixi-primitive.d.ts.map +1 -0
- package/dist/canvas-react/pixi-primitive.js +181 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts +71 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-adapter.js +229 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts +56 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-root-factory.js +73 -0
- package/dist/canvas-react/world-context.d.ts +88 -0
- package/dist/canvas-react/world-context.d.ts.map +1 -0
- package/dist/canvas-react/world-context.js +212 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +8 -0
- package/dist/core/frame-pacing.d.ts +90 -0
- package/dist/core/frame-pacing.d.ts.map +1 -0
- package/dist/core/frame-pacing.js +89 -0
- package/dist/core/game-loop.d.ts +62 -0
- package/dist/core/game-loop.d.ts.map +1 -0
- package/dist/core/game-loop.js +189 -0
- package/dist/core/seeded-random.d.ts +69 -0
- package/dist/core/seeded-random.d.ts.map +1 -0
- package/dist/core/seeded-random.js +121 -0
- package/dist/core/sim-clock.d.ts +199 -0
- package/dist/core/sim-clock.d.ts.map +1 -0
- package/dist/core/sim-clock.js +291 -0
- package/dist/core/system-runner.d.ts +96 -0
- package/dist/core/system-runner.d.ts.map +1 -0
- package/dist/core/system-runner.js +253 -0
- package/dist/core/types.d.ts +111 -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 +109 -0
- package/dist/data/data-check-core.d.ts.map +1 -0
- package/dist/data/data-check-core.js +177 -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/defaults.d.ts +233 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +137 -0
- package/dist/dev/chrome-trace.d.ts +45 -0
- package/dist/dev/chrome-trace.d.ts.map +1 -0
- package/dist/dev/chrome-trace.js +114 -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/instruments.d.ts +133 -0
- package/dist/dev/instruments.d.ts.map +1 -0
- package/dist/dev/instruments.js +231 -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/dev/performance-profiler.d.ts +111 -0
- package/dist/dev/performance-profiler.d.ts.map +1 -0
- package/dist/dev/performance-profiler.js +215 -0
- package/dist/dev/render-debug-adapter.d.ts +57 -0
- package/dist/dev/render-debug-adapter.d.ts.map +1 -0
- package/dist/dev/render-debug-adapter.js +141 -0
- package/dist/dev/render-memory.d.ts +53 -0
- package/dist/dev/render-memory.d.ts.map +1 -0
- package/dist/dev/render-memory.js +190 -0
- package/dist/dev/webgl-frame-capture.d.ts +134 -0
- package/dist/dev/webgl-frame-capture.d.ts.map +1 -0
- package/dist/dev/webgl-frame-capture.js +270 -0
- package/dist/dev/webgl-gpu-timer.d.ts +8 -0
- package/dist/dev/webgl-gpu-timer.d.ts.map +1 -0
- package/dist/dev/webgl-gpu-timer.js +52 -0
- package/dist/ecs/scene-index.d.ts +179 -0
- package/dist/ecs/scene-index.d.ts.map +1 -0
- package/dist/ecs/scene-index.js +331 -0
- package/dist/ecs/scene-query.d.ts +6 -0
- package/dist/ecs/scene-query.d.ts.map +1 -0
- package/dist/ecs/scene-query.js +40 -0
- package/dist/ecs/user-data.d.ts +193 -0
- package/dist/ecs/user-data.d.ts.map +1 -0
- package/dist/ecs/user-data.js +145 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/input/input-manager.d.ts +944 -0
- package/dist/input/input-manager.d.ts.map +1 -0
- package/dist/input/input-manager.js +2209 -0
- package/dist/input/input-types.d.ts +174 -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 +76 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +114 -0
- package/dist/manifest/editor-port.d.ts +53 -0
- package/dist/manifest/editor-port.d.ts.map +1 -0
- package/dist/manifest/editor-port.js +67 -0
- package/dist/manifest/filename.d.ts +14 -0
- package/dist/manifest/filename.d.ts.map +1 -0
- package/dist/manifest/filename.js +43 -0
- package/dist/manifest/index.d.ts +6 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +9 -0
- package/dist/manifest/load-file.d.ts +7 -0
- package/dist/manifest/load-file.d.ts.map +1 -0
- package/dist/manifest/load-file.js +23 -0
- package/dist/manifest/load.d.ts +161 -0
- package/dist/manifest/load.d.ts.map +1 -0
- package/dist/manifest/load.js +269 -0
- package/dist/manifest/locate.d.ts +24 -0
- package/dist/manifest/locate.d.ts.map +1 -0
- package/dist/manifest/locate.js +48 -0
- package/dist/manifest/schema.d.ts +293 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +633 -0
- package/dist/physics/collider-dimensions.d.ts +63 -0
- package/dist/physics/collider-dimensions.d.ts.map +1 -0
- package/dist/physics/collider-dimensions.js +98 -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/pixi/authoring.d.ts +93 -0
- package/dist/pixi/authoring.d.ts.map +1 -0
- package/dist/pixi/authoring.js +207 -0
- package/dist/pixi/index.d.ts +16 -0
- package/dist/pixi/index.d.ts.map +1 -0
- package/dist/pixi/index.js +15 -0
- package/dist/pixi/ingest-iframe.d.ts +82 -0
- package/dist/pixi/ingest-iframe.d.ts.map +1 -0
- package/dist/pixi/ingest-iframe.js +166 -0
- package/dist/pixi/ingest.d.ts +97 -0
- package/dist/pixi/ingest.d.ts.map +1 -0
- package/dist/pixi/ingest.js +40 -0
- package/dist/pixi/physics-registry.d.ts +24 -0
- package/dist/pixi/physics-registry.d.ts.map +1 -0
- package/dist/pixi/physics-registry.js +38 -0
- package/dist/pixi/scene-capture.d.ts +43 -0
- package/dist/pixi/scene-capture.d.ts.map +1 -0
- package/dist/pixi/scene-capture.js +92 -0
- package/dist/pixi/system-adapters.d.ts +16 -0
- package/dist/pixi/system-adapters.d.ts.map +1 -0
- package/dist/pixi/system-adapters.js +37 -0
- package/dist/react/unmanaged-root-detector.d.ts +18 -0
- package/dist/react/unmanaged-root-detector.d.ts.map +1 -0
- package/dist/react/unmanaged-root-detector.js +70 -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 +101 -0
- package/dist/react/use-selection.d.ts +54 -0
- package/dist/react/use-selection.d.ts.map +1 -0
- package/dist/react/use-selection.js +71 -0
- package/dist/react/world-state.d.ts +154 -0
- package/dist/react/world-state.d.ts.map +1 -0
- package/dist/react/world-state.js +220 -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/instance-mesh.d.ts +5 -0
- package/dist/render/instance-mesh.d.ts.map +1 -0
- package/dist/render/instance-mesh.js +19 -0
- package/dist/render/light-camera-factory.d.ts +24 -0
- package/dist/render/light-camera-factory.d.ts.map +1 -0
- package/dist/render/light-camera-factory.js +71 -0
- package/dist/render/lod.d.ts +13 -0
- package/dist/render/lod.d.ts.map +1 -0
- package/dist/render/lod.js +16 -0
- package/dist/render/material-factory.d.ts +15 -0
- package/dist/render/material-factory.d.ts.map +1 -0
- package/dist/render/material-factory.js +186 -0
- package/dist/render/mesh-shadow.d.ts +11 -0
- package/dist/render/mesh-shadow.d.ts.map +1 -0
- package/dist/render/mesh-shadow.js +19 -0
- package/dist/render/particles-factory.d.ts +99 -0
- package/dist/render/particles-factory.d.ts.map +1 -0
- package/dist/render/particles-factory.js +361 -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 +223 -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 +35 -0
- package/dist/render/render-settings.d.ts.map +1 -0
- package/dist/render/render-settings.js +51 -0
- package/dist/render/spark-renderer-lifecycle.d.ts +18 -0
- package/dist/render/spark-renderer-lifecycle.d.ts.map +1 -0
- package/dist/render/spark-renderer-lifecycle.js +57 -0
- package/dist/render/viewport-shading.d.ts +17 -0
- package/dist/render/viewport-shading.d.ts.map +1 -0
- package/dist/render/viewport-shading.js +87 -0
- package/dist/runtime/create-runtime.d.ts +259 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -0
- package/dist/runtime/create-runtime.js +666 -0
- package/dist/runtime/debug-bridge.d.ts +288 -0
- package/dist/runtime/debug-bridge.d.ts.map +1 -0
- package/dist/runtime/debug-bridge.js +277 -0
- package/dist/runtime/debug-registry.d.ts +287 -0
- package/dist/runtime/debug-registry.d.ts.map +1 -0
- package/dist/runtime/debug-registry.js +528 -0
- package/dist/runtime/dev-layers.d.ts +34 -0
- package/dist/runtime/dev-layers.d.ts.map +1 -0
- package/dist/runtime/dev-layers.js +40 -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 +576 -0
- package/dist/runtime/game.d.ts.map +1 -0
- package/dist/runtime/game.js +1003 -0
- package/dist/runtime/gameplay-rng-trap.d.ts +47 -0
- package/dist/runtime/gameplay-rng-trap.d.ts.map +1 -0
- package/dist/runtime/gameplay-rng-trap.js +95 -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 +126 -0
- package/dist/runtime/mount-game.d.ts.map +1 -0
- package/dist/runtime/mount-game.js +159 -0
- package/dist/runtime/mount-manifest.d.ts +174 -0
- package/dist/runtime/mount-manifest.d.ts.map +1 -0
- package/dist/runtime/mount-manifest.js +304 -0
- package/dist/runtime/presentation.d.ts +85 -0
- package/dist/runtime/presentation.d.ts.map +1 -0
- package/dist/runtime/presentation.js +92 -0
- package/dist/runtime/render-audio-control.d.ts +126 -0
- package/dist/runtime/render-audio-control.d.ts.map +1 -0
- package/dist/runtime/render-audio-control.js +116 -0
- package/dist/runtime/render-control.d.ts +347 -0
- package/dist/runtime/render-control.d.ts.map +1 -0
- package/dist/runtime/render-control.js +317 -0
- package/dist/runtime/render-seed.d.ts +56 -0
- package/dist/runtime/render-seed.d.ts.map +1 -0
- package/dist/runtime/render-seed.js +73 -0
- package/dist/runtime/state-bridge.d.ts +60 -0
- package/dist/runtime/state-bridge.d.ts.map +1 -0
- package/dist/runtime/state-bridge.js +62 -0
- package/dist/runtime/types.d.ts +285 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/unexported-game-trap.d.ts +36 -0
- package/dist/runtime/unexported-game-trap.d.ts.map +1 -0
- package/dist/runtime/unexported-game-trap.js +80 -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 +82 -0
- package/dist/setup/setup-renderer.d.ts.map +1 -0
- package/dist/setup/setup-renderer.js +381 -0
- package/dist/world3d-react/engine-bridge.d.ts +47 -0
- package/dist/world3d-react/engine-bridge.d.ts.map +1 -0
- package/dist/world3d-react/engine-bridge.js +48 -0
- package/dist/world3d-react/index.d.ts +47 -0
- package/dist/world3d-react/index.d.ts.map +1 -0
- package/dist/world3d-react/index.js +46 -0
- package/dist/world3d-react/r3f-adapter.d.ts +51 -0
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -0
- package/dist/world3d-react/r3f-adapter.js +368 -0
- package/dist/world3d-react/r3f-root-factory.d.ts +62 -0
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -0
- package/dist/world3d-react/r3f-root-factory.js +79 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts +76 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -0
- package/dist/world3d-react/rapier-physics-bridge.js +120 -0
- package/dist/world3d-react/renderer-config.d.ts +58 -0
- package/dist/world3d-react/renderer-config.d.ts.map +1 -0
- package/dist/world3d-react/renderer-config.js +96 -0
- package/dist/world3d-react/world-context.d.ts +123 -0
- package/dist/world3d-react/world-context.d.ts.map +1 -0
- package/dist/world3d-react/world-context.js +204 -0
- package/dist-config/config.js +303 -0
- package/dist-config/config.js.map +7 -0
- package/package.json +14 -3
- package/src/adapter/rapier-physics-adapter.ts +77 -34
- package/src/config.ts +8 -0
- package/src/core/frame-pacing.ts +26 -0
- package/src/core/game-loop.ts +4 -3
- package/src/dev/instruments.ts +302 -0
- package/src/runtime/mount-game.ts +6 -0
- package/src/runtime/unexported-game-trap.ts +82 -0
- package/src/setup/setup-renderer.ts +2 -0
- package/src/world3d-react/index.ts +9 -0
- package/src/world3d-react/rapier-physics-bridge.tsx +137 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host contexts — what the host hands a root when it mounts it, PER SURFACE.
|
|
3
|
+
*
|
|
4
|
+
* This generalizes the old `GameContext`, which baked in first-party system
|
|
5
|
+
* choices (a Rapier world, the postprocessing composer, the InputManager, …).
|
|
6
|
+
* The host never assumes Rapier/Colyseus; those live behind `SystemAdapters`
|
|
7
|
+
* owned by the first-party implementer.
|
|
8
|
+
*
|
|
9
|
+
* ## Why this file is a family, not one interface (P-8)
|
|
10
|
+
*
|
|
11
|
+
* There used to be a single "neutral" `HostContext` interface handed to EVERY
|
|
12
|
+
* root, with a NON-OPTIONAL `three: typeof THREE` and `renderer:
|
|
13
|
+
* THREE.WebGLRenderer` on it. That made the neutral layer three-LOCKED rather
|
|
14
|
+
* than merely three-named: a Pixi or React root would have been handed a WebGL
|
|
15
|
+
* renderer it cannot use. In practice nobody did hand it one — the production
|
|
16
|
+
* Pixi and React hosts have always built their own canvas/dom-shaped contexts
|
|
17
|
+
* instead — so the "one context for every surface"
|
|
18
|
+
* claim was already false in the tree; it just wasn't expressed in the types,
|
|
19
|
+
* which is why `RootAdapter<K>` could only parameterize its RETURN type and
|
|
20
|
+
* the Pixi/React adapters lived outside `RootAdapter` entirely.
|
|
21
|
+
*
|
|
22
|
+
* The split (ratified, docs/ARCHITECTURE-CORE.md "Seam"):
|
|
23
|
+
*
|
|
24
|
+
* {@link HostContextBase} what EVERY surface genuinely gets
|
|
25
|
+
* ├─ {@link ThreeHostContext} + `three` · `renderer` · `surface` · `assets`
|
|
26
|
+
* ├─ {@link CanvasHostContext} + `canvas`/`width`/`height` (+ dpr/compositing hints)
|
|
27
|
+
* └─ {@link DomHostContext} + `container`
|
|
28
|
+
*
|
|
29
|
+
* and {@link HostContextFor} maps an `AdapterSurface` to its context, so
|
|
30
|
+
* `RootAdapter<K>.mount`'s PARAMETER is K-typed too — the surface tag now
|
|
31
|
+
* picks the context type, which is the whole point of the tag.
|
|
32
|
+
*
|
|
33
|
+
* ### Where the line was drawn, and why
|
|
34
|
+
*
|
|
35
|
+
* The base holds exactly the members all three surfaces ALREADY carry today —
|
|
36
|
+
* nothing was invented to make the base look richer:
|
|
37
|
+
*
|
|
38
|
+
* - `game` — the root handle. Every surface has one (three: `ThreeHostContext.game`,
|
|
39
|
+
* canvas: `CanvasHostContext.game`, dom: `DomHostContext.game`), and it is the one
|
|
40
|
+
* genuinely surface-independent thing a host can hand any root.
|
|
41
|
+
* - `headless` — a property of the ENVIRONMENT (no GPU/DOM/audio), not of the
|
|
42
|
+
* render surface.
|
|
43
|
+
*
|
|
44
|
+
* Deliberately NOT in the base:
|
|
45
|
+
*
|
|
46
|
+
* - `renderer`/`three` — three's own objects; the defect this split exists to
|
|
47
|
+
* fix.
|
|
48
|
+
* - the render surface — its SHAPE is surface-specific and there is no honest
|
|
49
|
+
* common denominator: three nests `{canvas,width,height}` under `surface`,
|
|
50
|
+
* canvas passes those three flat (plus its own compositing hints), and a DOM
|
|
51
|
+
* root gets an `HTMLElement` container and no canvas at all. A shared
|
|
52
|
+
* `surface` field would have to be a union nobody can consume without
|
|
53
|
+
* re-branching on kind — i.e. the same three-shaped promise, one level down.
|
|
54
|
+
* - `assets` — `AssetCache`'s SIGNATURE reads neutral (`load<T>(url)`), but its
|
|
55
|
+
* one implementation is a GLTF/texture loader (`assets.ts` branches on
|
|
56
|
+
* `.glb`/`.gltf` and resolves THREE objects), and neither the canvas nor the
|
|
57
|
+
* dom host has ever been handed one: a canvas adapter builds its own
|
|
58
|
+
* cache inside `mount`. Promoting it to the base would be the anti-shim rule
|
|
59
|
+
* in miniature — a host promise nothing keeps. It stays on
|
|
60
|
+
* {@link ThreeHostContext} until a second surface genuinely receives one.
|
|
61
|
+
*
|
|
62
|
+
* These three names are the ONLY names for these shapes. The transitional
|
|
63
|
+
* aliases that carried the pre-split spellings were deleted; every implementer
|
|
64
|
+
* and call site names the surface it actually mounts on.
|
|
65
|
+
*
|
|
66
|
+
* It also used to carry `requestSystem<T extends keyof SystemRegistry>()` — an
|
|
67
|
+
* "ask the host for a first-party subsystem" hook — over an EMPTY
|
|
68
|
+
* `SystemRegistry`. That made `keyof SystemRegistry` = `never`, so no argument
|
|
69
|
+
* could legally be passed and the method was uncallable by construction. In
|
|
70
|
+
* practice it existed as 28 copies of `requestSystem: () => null` in tests and
|
|
71
|
+
* hosts, with no caller anywhere, and its only real effect would have been to
|
|
72
|
+
* re-open the door this interface exists to close: the host handing a game a
|
|
73
|
+
* subsystem it did not build. Deleted rather than kept as a promise.
|
|
74
|
+
*
|
|
75
|
+
* Migration note: `SetupThreeRootAdapter.mount` builds today's `GameContext`
|
|
76
|
+
* (Rapier world, composer, …) internally from a `ThreeHostContext`. New code
|
|
77
|
+
* targets these contexts; `GameContext` is now a first-party implementation
|
|
78
|
+
* detail.
|
|
79
|
+
*/
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter interfaces — the seams the engine host and the editor DEPEND ON.
|
|
3
|
+
*
|
|
4
|
+
* host → RootAdapter ← { SetupThreeRootAdapter, IngestRootAdapter, … }
|
|
5
|
+
* editor → AuthoringAdapter ← { LiveThreeAuthoringAdapter, ReactRootAuthoringAdapter, … }
|
|
6
|
+
* game → SystemAdapters (physics/networking/navigation/audio/debug)
|
|
7
|
+
*
|
|
8
|
+
* The first-party Rapier/Colyseus stack is ONE implementer of these
|
|
9
|
+
* interfaces, not the engine's vocabulary..
|
|
10
|
+
*
|
|
11
|
+
* **This module is TYPE-ONLY, and must stay that way (P-6).** It used to
|
|
12
|
+
* value-export its own implementers — `SetupThreeRootAdapter`/`fromSetup`,
|
|
13
|
+
* `createRapierPhysicsAdapter`, `createColyseusNetworkingAdapter`,
|
|
14
|
+
* `createNavigationAdapter` — so `import type { AuthoringAdapter } from
|
|
15
|
+
* '@engine/adapter'` was the only thing keeping the three/Rapier/Colyseus/
|
|
16
|
+
* `.vscn` stack out of a Pixi or React consumer's module graph. A seam that
|
|
17
|
+
* ships its implementers is not a seam. Import an implementer from its OWN
|
|
18
|
+
* path instead:
|
|
19
|
+
*
|
|
20
|
+
* `@engine/adapter/setup-three-root-adapter` SetupThreeRootAdapter, fromSetup
|
|
21
|
+
* `@engine/adapter/rapier-physics-adapter` createRapierPhysicsAdapter
|
|
22
|
+
* `@engine/adapter/colyseus-networking-adapter` createColyseusNetworkingAdapter
|
|
23
|
+
* `@engine/adapter/first-party-systems` createNavigationAdapter
|
|
24
|
+
*/
|
|
25
|
+
export type { AdapterSurface } from './adapter-surface';
|
|
26
|
+
export type { AssetDropContext, AssetDropProvider, AssetSubjectProvider, AuthoringAdapter, AuthoringAssetSubject, AuthoringCapabilities, AuthoringProvenance, BoxEditProvider, BoxEditReferencePoint, ColorSampleProvider, CreationSiteProvider, DOMRectLike, EditorNode, EditorNodeRole, FileMapProvider, HierarchyProvider, InspectorProvider, NodeCreationSite, PersistenceProvider, PickProvider, PropertyDescriptor, RectProvider, RootGroup, RootGroupsProvider, SelectionProvider, SelectionResolution, StoriesProvider, StoryRef, StructureProvider, TextProvider, TransformChannel, TransformEditability, TransformObservation, TransformProvider, } from './authoring';
|
|
27
|
+
export type { ColyseusNetworkingConfig } from './colyseus-networking-adapter';
|
|
28
|
+
export type { CanvasHostContext, DomHostContext, HostContextBase, HostContextFor, HostSurface, ThreeHostContext, } from './host-context';
|
|
29
|
+
export type { MountedPixiRoot, MountedReactRoot, MountedRoot, MountedRootBase, MountedThreeRoot, RootAdapter, RootStateObserver, SurfaceAdapter, SurfaceAdapterFor, } from './root-adapter';
|
|
30
|
+
export type { MountedSetupThreeRoot, SetupThreeRootConfig } from './setup-three-root-adapter';
|
|
31
|
+
export type { AudioAdapter, AudioDebugEvent, AudioGraphNode, AudioMeterFrame, AudioMeterHandle, AudioTransportState, ConnectionState, NavCrowdAgentState, NavigationAdapter, NavPoint, NetConditioning, NetMessageEvent, NetPeer, NetPlayerIdentity, NetRates, NetServerConfig, NetworkingAdapter, PhysicsAdapter, RenderDebugAdapter, ReplicationStats, RoomInfo, SystemAdapters, Unsubscribe, } from './system-adapter';
|
|
32
|
+
export type { Transform, TransformOwner } from './transform';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,cAAc,EACd,WAAW,EACX,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC9F,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,eAAe,EACf,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter interfaces — the seams the engine host and the editor DEPEND ON.
|
|
3
|
+
*
|
|
4
|
+
* host → RootAdapter ← { SetupThreeRootAdapter, IngestRootAdapter, … }
|
|
5
|
+
* editor → AuthoringAdapter ← { LiveThreeAuthoringAdapter, ReactRootAuthoringAdapter, … }
|
|
6
|
+
* game → SystemAdapters (physics/networking/navigation/audio/debug)
|
|
7
|
+
*
|
|
8
|
+
* The first-party Rapier/Colyseus stack is ONE implementer of these
|
|
9
|
+
* interfaces, not the engine's vocabulary..
|
|
10
|
+
*
|
|
11
|
+
* **This module is TYPE-ONLY, and must stay that way (P-6).** It used to
|
|
12
|
+
* value-export its own implementers — `SetupThreeRootAdapter`/`fromSetup`,
|
|
13
|
+
* `createRapierPhysicsAdapter`, `createColyseusNetworkingAdapter`,
|
|
14
|
+
* `createNavigationAdapter` — so `import type { AuthoringAdapter } from
|
|
15
|
+
* '@engine/adapter'` was the only thing keeping the three/Rapier/Colyseus/
|
|
16
|
+
* `.vscn` stack out of a Pixi or React consumer's module graph. A seam that
|
|
17
|
+
* ships its implementers is not a seam. Import an implementer from its OWN
|
|
18
|
+
* path instead:
|
|
19
|
+
*
|
|
20
|
+
* `@engine/adapter/setup-three-root-adapter` SetupThreeRootAdapter, fromSetup
|
|
21
|
+
* `@engine/adapter/rapier-physics-adapter` createRapierPhysicsAdapter
|
|
22
|
+
* `@engine/adapter/colyseus-networking-adapter` createColyseusNetworkingAdapter
|
|
23
|
+
* `@engine/adapter/first-party-systems` createNavigationAdapter
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The game→host contract: ONE pre-defined interface an external game may
|
|
3
|
+
* declare on `window.vgaiGame` to let the editor work with it like native
|
|
4
|
+
* content. Capabilities are by PRESENCE — every field is optional, and a game
|
|
5
|
+
* that declares nothing runs exactly as before (doctrine: adaptation enables
|
|
6
|
+
* editor features; it never bends a game around host internals). This file is
|
|
7
|
+
* the single source of truth for the contract's shape — host code reads it
|
|
8
|
+
* through {@link readGameContract} instead of ad-hoc `window` casts, so the
|
|
9
|
+
* spec and the implementation cannot drift apart.
|
|
10
|
+
*
|
|
11
|
+
* Relationship to the native engine: first-party content implements the SAME
|
|
12
|
+
* conceptual surface (mount root, lifecycle, loop gating) through
|
|
13
|
+
* `RootAdapter`/`MountedThreeRoot` — the native engine is the premade 100%
|
|
14
|
+
* implementation of this contract. An ingested game climbs the same ladder
|
|
15
|
+
* endpoint by endpoint: capture infers what it can (the scene), the game
|
|
16
|
+
* declares what inference can't reach (its DOM root, its session lifecycle).
|
|
17
|
+
*
|
|
18
|
+
* Origin (root), F17+F21 (lifecycle).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Session lifecycle endpoints. Declaring `start` means "I support cold
|
|
22
|
+
* mount": when the host sets `window.__vgaiMountCold` before the game's entry
|
|
23
|
+
* executes, the game may defer its session side-effects (backend connections,
|
|
24
|
+
* narrative, audio) and render a quiet, inspectable scene; the host calls
|
|
25
|
+
* `start()` — at most once per mount — when the user presses ▶. Declaring
|
|
26
|
+
* `pause`/`resume` means the game can genuinely freeze/unfreeze itself; the
|
|
27
|
+
* host prefers these over its outside-in loop gate (which cannot gate a raw
|
|
28
|
+
* requestAnimationFrame loop at all — R3F games, notably).
|
|
29
|
+
*/
|
|
30
|
+
export interface VgaiGameLifecycle {
|
|
31
|
+
start?(): void;
|
|
32
|
+
pause?(): void;
|
|
33
|
+
resume?(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface VgaiGameContract {
|
|
36
|
+
/** Bump only on breaking shape changes; additive endpoints keep version 1. */
|
|
37
|
+
contractVersion: 1;
|
|
38
|
+
/**
|
|
39
|
+
* The element that OWNS the game's whole DOM (canvas + HUD + overlay
|
|
40
|
+
* portals). The host adopts it wholesale into the game pane, so DOM-hybrid
|
|
41
|
+
* games keep their UI instead of stranding it at page level. The host
|
|
42
|
+
* verifies it actually contains the captured canvas before adopting.
|
|
43
|
+
*/
|
|
44
|
+
root?: HTMLElement;
|
|
45
|
+
lifecycle?: VgaiGameLifecycle;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Read the declared contract, if any. The `contractVersion` gate is the
|
|
49
|
+
* forward-compatibility hinge: a future v2 game on a v1 host is ignored
|
|
50
|
+
* (pre-contract fallbacks apply) rather than half-interpreted.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readGameContract(): VgaiGameContract | null;
|
|
53
|
+
//# sourceMappingURL=game-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,eAAe,EAAE,CAAC,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,GAAG,IAAI,CAI1D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The game→host contract: ONE pre-defined interface an external game may
|
|
3
|
+
* declare on `window.vgaiGame` to let the editor work with it like native
|
|
4
|
+
* content. Capabilities are by PRESENCE — every field is optional, and a game
|
|
5
|
+
* that declares nothing runs exactly as before (doctrine: adaptation enables
|
|
6
|
+
* editor features; it never bends a game around host internals). This file is
|
|
7
|
+
* the single source of truth for the contract's shape — host code reads it
|
|
8
|
+
* through {@link readGameContract} instead of ad-hoc `window` casts, so the
|
|
9
|
+
* spec and the implementation cannot drift apart.
|
|
10
|
+
*
|
|
11
|
+
* Relationship to the native engine: first-party content implements the SAME
|
|
12
|
+
* conceptual surface (mount root, lifecycle, loop gating) through
|
|
13
|
+
* `RootAdapter`/`MountedThreeRoot` — the native engine is the premade 100%
|
|
14
|
+
* implementation of this contract. An ingested game climbs the same ladder
|
|
15
|
+
* endpoint by endpoint: capture infers what it can (the scene), the game
|
|
16
|
+
* declares what inference can't reach (its DOM root, its session lifecycle).
|
|
17
|
+
*
|
|
18
|
+
* Origin (root), F17+F21 (lifecycle).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Read the declared contract, if any. The `contractVersion` gate is the
|
|
22
|
+
* forward-compatibility hinge: a future v2 game on a v1 host is ignored
|
|
23
|
+
* (pre-contract fallbacks apply) rather than half-interpreted.
|
|
24
|
+
*/
|
|
25
|
+
export function readGameContract() {
|
|
26
|
+
const declared = window.vgaiGame;
|
|
27
|
+
if (!declared || declared.contractVersion !== 1)
|
|
28
|
+
return null;
|
|
29
|
+
return declared;
|
|
30
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene capture — the core primitive of unmodified-game ingestion.
|
|
3
|
+
*
|
|
4
|
+
* An external three.js game owns its own `WebGLRenderer`, `Scene`, camera, and
|
|
5
|
+
* render loop. To let the editor inspect/edit that live scene WITHOUT touching
|
|
6
|
+
* the game's code, we need a handle to the game's `Scene`+camera the moment it
|
|
7
|
+
* first renders. The robust way to obtain it is an **accessor trap** on
|
|
8
|
+
* `WebGLRenderer.prototype.render`:
|
|
9
|
+
*
|
|
10
|
+
* - `WebGLRenderer` assigns `this.render` as an OWN instance property inside
|
|
11
|
+
* its constructor (not on the prototype), and `THREE.WebGLRenderer` is a
|
|
12
|
+
* read-only module export (can't subclass-swap it). A naive "wrap render"
|
|
13
|
+
* hook therefore captures nothing.
|
|
14
|
+
* - Installing a getter/setter for `render` on the PROTOTYPE means the
|
|
15
|
+
* constructor's `this.render = realFn` hits our setter (the instance has no
|
|
16
|
+
* own `render` yet), we stash the real fn, and our getter returns a wrapper
|
|
17
|
+
* that captures `(scene, camera, renderer)` on the first real frame.
|
|
18
|
+
*
|
|
19
|
+
* This is the hardened, typed form of the `ingest-study` spike
|
|
20
|
+
* (`docs/ingest-study-spike/vgai-ingest-adapter.js`), proven against an
|
|
21
|
+
* unmodified `three.js/examples/games_fps` game.
|
|
22
|
+
*
|
|
23
|
+
* CRITICAL: the trap must be installed on the SAME `three` module instance the
|
|
24
|
+
* game uses. In a bundler/dev-server that dedupes `three` (one `node_modules/
|
|
25
|
+
* three`), an external ESM game's `import 'three'` resolves to that one instance,
|
|
26
|
+
* so passing the host's `THREE` here traps the game's renderer too. A game that
|
|
27
|
+
* bundles its own copy of `three` cannot be captured this way (the module-identity
|
|
28
|
+
* gatekeeper).
|
|
29
|
+
*
|
|
30
|
+
* Wave 17 adds an OPTIONAL, ADDITIVE composer capture: a game rendering through
|
|
31
|
+
* its own three.js addon `EffectComposer`
|
|
32
|
+
* (`three/examples/jsm/postprocessing/EffectComposer.js`) still trips the `render`
|
|
33
|
+
* trap above (its `RenderPass` calls `renderer.render(scene,camera)` internally),
|
|
34
|
+
* but the renderer holds no reference back to the composer, so the host previously
|
|
35
|
+
* could not resize the composer's own (intentionally non-1:1,
|
|
36
|
+
* progressively-downsampled — see `UnrealBloomPass`) render targets when the host
|
|
37
|
+
* resizes the game's pane. Unlike `WebGLRenderer`, `EffectComposer` is a plain ES
|
|
38
|
+
* class whose methods (including `render`) live on the PROTOTYPE, not assigned as
|
|
39
|
+
* own instance properties in the constructor — so a direct method-wrapper (no
|
|
40
|
+
* getter/ setter indirection) on `EffectComposer.prototype.render` is sufficient:
|
|
41
|
+
* it calls through to the real `render`, then — AFTER that call, so any nested
|
|
42
|
+
* `renderer.render()` the pass makes has already hit the trap above and set
|
|
43
|
+
* `captured` — records `this` (the composer instance) if its `.renderer` is the
|
|
44
|
+
* captured one. This is deduped/shared-trappable for the same reason
|
|
45
|
+
* `WebGLRenderer` is: `EffectComposer.js` is a FILE inside the same `three`
|
|
46
|
+
* package tree Vite's `resolve.dedupe: ['three', …]` already collapses to one
|
|
47
|
+
* instance — not a separate package with its own dedupe question. Proven live
|
|
48
|
+
* against the `bloom-composer` fixture
|
|
49
|
+
* (`docs/f13-bloom-composer-proof/record-fixed.mjs`).
|
|
50
|
+
*/
|
|
51
|
+
import type * as THREE from 'three';
|
|
52
|
+
/** A live runtime captured from an external game on its first rendered frame. */
|
|
53
|
+
export interface CapturedRuntime {
|
|
54
|
+
scene: THREE.Scene;
|
|
55
|
+
camera: THREE.Camera;
|
|
56
|
+
renderer: THREE.WebGLRenderer;
|
|
57
|
+
}
|
|
58
|
+
/** Options for {@link installSceneCapture}. */
|
|
59
|
+
export interface SceneCaptureOptions {
|
|
60
|
+
/**
|
|
61
|
+
* True when `renderer` is one the HOST constructed for its own drawing.
|
|
62
|
+
*
|
|
63
|
+
* The trap lives on the shared `WebGLRenderer.prototype` — that sharing is
|
|
64
|
+
* the whole mechanism — so the host's renders arrive here too, and the trap
|
|
65
|
+
* captures the first scene it sees. Any host renderer built after the trap
|
|
66
|
+
* installs (the editor bakes model thumbnails and asset previews on demand,
|
|
67
|
+
* each with its own offscreen renderer and its own little light rig) is a
|
|
68
|
+
* candidate to be captured AS THE GAME.
|
|
69
|
+
*
|
|
70
|
+
* That is what made `cov-mismatched-three` — the spec for "a game bundling
|
|
71
|
+
* its own three is DETECTED and degrades to embed-only, never silently" —
|
|
72
|
+
* pass or fail on timing alone: whether a thumbnail happened to bake inside
|
|
73
|
+
* the game's 2.5s capture window. When it did, the editor adopted its own
|
|
74
|
+
* preview scene as the game and `captureFailed` never fired.
|
|
75
|
+
*
|
|
76
|
+
* Identity, not shape, is the discriminator: a host renderer and a game
|
|
77
|
+
* renderer are the same class, both built after install, both drawing real
|
|
78
|
+
* scenes. The host is the only party that knows which is which, so it says
|
|
79
|
+
* so (`packages/editor/src/host-renderers.ts`).
|
|
80
|
+
*/
|
|
81
|
+
isHostRenderer?: (renderer: unknown) => boolean;
|
|
82
|
+
}
|
|
83
|
+
/** Handle returned by {@link installSceneCapture}. */
|
|
84
|
+
export interface SceneCaptureHandle {
|
|
85
|
+
/** The captured runtime, or null until the game renders its first frame. */
|
|
86
|
+
readonly captured: CapturedRuntime | null;
|
|
87
|
+
/** Resolve once a scene+camera is captured (rejects on timeout). */
|
|
88
|
+
waitForCapture(timeoutMs?: number): Promise<CapturedRuntime>;
|
|
89
|
+
/** Total `render()` calls observed through the trap (a liveness signal). */
|
|
90
|
+
getDrawCount(): number;
|
|
91
|
+
/** The game's last (non-null) `setAnimationLoop` callback for a renderer, so the
|
|
92
|
+
* host can pause (set null) and resume (re-set it) the game's own loop. */
|
|
93
|
+
getAnimationLoop(renderer: THREE.WebGLRenderer): ((time: number) => void) | null;
|
|
94
|
+
/**
|
|
95
|
+
* Wave 17 (D-C3): resize every captured `EffectComposer` that renders
|
|
96
|
+
* through the captured renderer to `w`×`h`, matching its pixel ratio to
|
|
97
|
+
* `renderer.getPixelRatio()` — the composer tracks whatever DPR policy the
|
|
98
|
+
* host already applies to the renderer; no separate knob. A no-op when no
|
|
99
|
+
* `effectComposerCtor` was passed to {@link installSceneCapture} (or no
|
|
100
|
+
* composer of that ctor has rendered through the captured renderer yet) —
|
|
101
|
+
* a non-composer game is unaffected.
|
|
102
|
+
*/
|
|
103
|
+
resizeComposers(w: number, h: number): void;
|
|
104
|
+
/** Remove the trap and restore the captured renderer's real `render`. */
|
|
105
|
+
uninstall(): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Install the render accessor trap on `threeNamespace.WebGLRenderer.prototype`.
|
|
109
|
+
* Pass the host's `three` module so the game (which shares it) is trapped.
|
|
110
|
+
*
|
|
111
|
+
* `effectComposerCtor` is OPTIONAL (Wave 17, D-C2): pass the host's
|
|
112
|
+
* `EffectComposer` class (`three/examples/jsm/postprocessing/EffectComposer.js`)
|
|
113
|
+
* to also trap composer construction/rendering on that shared addon, so
|
|
114
|
+
* `resizeComposers()` can reach it. Omitting it (or a game never constructing
|
|
115
|
+
* one) leaves capture byte-identical to before this wave.
|
|
116
|
+
*
|
|
117
|
+
* Idempotent per call site is NOT guaranteed — install once per ingest session
|
|
118
|
+
* and `uninstall()` on teardown.
|
|
119
|
+
*/
|
|
120
|
+
export declare function installSceneCapture(threeNamespace: unknown, effectComposerCtor?: unknown, opts?: SceneCaptureOptions): SceneCaptureHandle;
|
|
121
|
+
//# sourceMappingURL=scene-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-capture.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/scene-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;CAC/B;AAED,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC;CACjD;AAED,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,oEAAoE;IACpE,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC7D,4EAA4E;IAC5E,YAAY,IAAI,MAAM,CAAC;IACvB;gFAC4E;IAC5E,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACjF;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,yEAAyE;IACzE,SAAS,IAAI,IAAI,CAAC;CACnB;AAsBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,OAAO,EACvB,kBAAkB,CAAC,EAAE,OAAO,EAC5B,IAAI,CAAC,EAAE,mBAAmB,GACzB,kBAAkB,CA8MpB"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene capture — the core primitive of unmodified-game ingestion.
|
|
3
|
+
*
|
|
4
|
+
* An external three.js game owns its own `WebGLRenderer`, `Scene`, camera, and
|
|
5
|
+
* render loop. To let the editor inspect/edit that live scene WITHOUT touching
|
|
6
|
+
* the game's code, we need a handle to the game's `Scene`+camera the moment it
|
|
7
|
+
* first renders. The robust way to obtain it is an **accessor trap** on
|
|
8
|
+
* `WebGLRenderer.prototype.render`:
|
|
9
|
+
*
|
|
10
|
+
* - `WebGLRenderer` assigns `this.render` as an OWN instance property inside
|
|
11
|
+
* its constructor (not on the prototype), and `THREE.WebGLRenderer` is a
|
|
12
|
+
* read-only module export (can't subclass-swap it). A naive "wrap render"
|
|
13
|
+
* hook therefore captures nothing.
|
|
14
|
+
* - Installing a getter/setter for `render` on the PROTOTYPE means the
|
|
15
|
+
* constructor's `this.render = realFn` hits our setter (the instance has no
|
|
16
|
+
* own `render` yet), we stash the real fn, and our getter returns a wrapper
|
|
17
|
+
* that captures `(scene, camera, renderer)` on the first real frame.
|
|
18
|
+
*
|
|
19
|
+
* This is the hardened, typed form of the `ingest-study` spike
|
|
20
|
+
* (`docs/ingest-study-spike/vgai-ingest-adapter.js`), proven against an
|
|
21
|
+
* unmodified `three.js/examples/games_fps` game.
|
|
22
|
+
*
|
|
23
|
+
* CRITICAL: the trap must be installed on the SAME `three` module instance the
|
|
24
|
+
* game uses. In a bundler/dev-server that dedupes `three` (one `node_modules/
|
|
25
|
+
* three`), an external ESM game's `import 'three'` resolves to that one instance,
|
|
26
|
+
* so passing the host's `THREE` here traps the game's renderer too. A game that
|
|
27
|
+
* bundles its own copy of `three` cannot be captured this way (the module-identity
|
|
28
|
+
* gatekeeper).
|
|
29
|
+
*
|
|
30
|
+
* Wave 17 adds an OPTIONAL, ADDITIVE composer capture: a game rendering through
|
|
31
|
+
* its own three.js addon `EffectComposer`
|
|
32
|
+
* (`three/examples/jsm/postprocessing/EffectComposer.js`) still trips the `render`
|
|
33
|
+
* trap above (its `RenderPass` calls `renderer.render(scene,camera)` internally),
|
|
34
|
+
* but the renderer holds no reference back to the composer, so the host previously
|
|
35
|
+
* could not resize the composer's own (intentionally non-1:1,
|
|
36
|
+
* progressively-downsampled — see `UnrealBloomPass`) render targets when the host
|
|
37
|
+
* resizes the game's pane. Unlike `WebGLRenderer`, `EffectComposer` is a plain ES
|
|
38
|
+
* class whose methods (including `render`) live on the PROTOTYPE, not assigned as
|
|
39
|
+
* own instance properties in the constructor — so a direct method-wrapper (no
|
|
40
|
+
* getter/ setter indirection) on `EffectComposer.prototype.render` is sufficient:
|
|
41
|
+
* it calls through to the real `render`, then — AFTER that call, so any nested
|
|
42
|
+
* `renderer.render()` the pass makes has already hit the trap above and set
|
|
43
|
+
* `captured` — records `this` (the composer instance) if its `.renderer` is the
|
|
44
|
+
* captured one. This is deduped/shared-trappable for the same reason
|
|
45
|
+
* `WebGLRenderer` is: `EffectComposer.js` is a FILE inside the same `three`
|
|
46
|
+
* package tree Vite's `resolve.dedupe: ['three', …]` already collapses to one
|
|
47
|
+
* instance — not a separate package with its own dedupe question. Proven live
|
|
48
|
+
* against the `bloom-composer` fixture
|
|
49
|
+
* (`docs/f13-bloom-composer-proof/record-fixed.mjs`).
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* Install the render accessor trap on `threeNamespace.WebGLRenderer.prototype`.
|
|
53
|
+
* Pass the host's `three` module so the game (which shares it) is trapped.
|
|
54
|
+
*
|
|
55
|
+
* `effectComposerCtor` is OPTIONAL (Wave 17, D-C2): pass the host's
|
|
56
|
+
* `EffectComposer` class (`three/examples/jsm/postprocessing/EffectComposer.js`)
|
|
57
|
+
* to also trap composer construction/rendering on that shared addon, so
|
|
58
|
+
* `resizeComposers()` can reach it. Omitting it (or a game never constructing
|
|
59
|
+
* one) leaves capture byte-identical to before this wave.
|
|
60
|
+
*
|
|
61
|
+
* Idempotent per call site is NOT guaranteed — install once per ingest session
|
|
62
|
+
* and `uninstall()` on teardown.
|
|
63
|
+
*/
|
|
64
|
+
export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
65
|
+
const THREE_NS = threeNamespace;
|
|
66
|
+
const proto = THREE_NS.WebGLRenderer.prototype;
|
|
67
|
+
// Stash the real render fn per-instance under a unique symbol so multiple
|
|
68
|
+
// renderers (editor's + game's) never collide.
|
|
69
|
+
const REAL = Symbol('vgai.realRender');
|
|
70
|
+
let captured = null;
|
|
71
|
+
let drawCount = 0;
|
|
72
|
+
const waiters = [];
|
|
73
|
+
// Preserve any descriptor already on the prototype so uninstall can restore it.
|
|
74
|
+
const priorDescriptor = Object.getOwnPropertyDescriptor(proto, 'render');
|
|
75
|
+
// Trap setAnimationLoop to record each renderer's game loop callback, so the host
|
|
76
|
+
// can freeze (set null) and resume (re-set) the game's own rAF for stable editing.
|
|
77
|
+
// CRITICAL: like `render`, WebGLRenderer assigns `this.setAnimationLoop` as an OWN
|
|
78
|
+
// instance property in its constructor — NOT on the prototype. A naive value-wrapper
|
|
79
|
+
// on the prototype is therefore shadowed by the instance's own property and never
|
|
80
|
+
// runs (resume could never recover the callback). So we mirror the `render` trap: a
|
|
81
|
+
// prototype getter/setter. The constructor's `this.setAnimationLoop = realFn` hits
|
|
82
|
+
// our SETTER (the instance has no own property yet) and we stash realFn per-instance;
|
|
83
|
+
// the GETTER returns a wrapper that records each non-null callback before forwarding.
|
|
84
|
+
const REAL_SAL = Symbol('vgai.realSetAnimationLoop');
|
|
85
|
+
const loopCallbacks = new WeakMap();
|
|
86
|
+
const priorSAL = Object.getOwnPropertyDescriptor(proto, 'setAnimationLoop');
|
|
87
|
+
Object.defineProperty(proto, 'setAnimationLoop', {
|
|
88
|
+
configurable: true,
|
|
89
|
+
set(fn) {
|
|
90
|
+
this[REAL_SAL] = fn;
|
|
91
|
+
},
|
|
92
|
+
get() {
|
|
93
|
+
const self = this;
|
|
94
|
+
return function setAnimationLoop(cb) {
|
|
95
|
+
if (cb)
|
|
96
|
+
loopCallbacks.set(self, cb);
|
|
97
|
+
const real = self[REAL_SAL];
|
|
98
|
+
return typeof real === 'function'
|
|
99
|
+
? real.call(self, cb)
|
|
100
|
+
: undefined;
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(proto, 'render', {
|
|
105
|
+
configurable: true,
|
|
106
|
+
set(fn) {
|
|
107
|
+
this[REAL] = fn;
|
|
108
|
+
},
|
|
109
|
+
get() {
|
|
110
|
+
const self = this;
|
|
111
|
+
return function render(...args) {
|
|
112
|
+
const [scene, camera] = args;
|
|
113
|
+
// Attribute the draw to the GAME, not to whoever shares this prototype.
|
|
114
|
+
// The trap patches `WebGLRenderer.prototype.render` on the editor's own
|
|
115
|
+
// three, so the EDITOR viewport's renders land here too. Counting them
|
|
116
|
+
// made `getDrawCount()` climb while the ingested game was paused, which
|
|
117
|
+
// is what the pause assertions in `14-ingest-feature-matrix` were
|
|
118
|
+
// measuring — the loop gate was doing its job (both games use
|
|
119
|
+
// `setAnimationLoop`, so they ARE gateable) and the instrument was
|
|
120
|
+
// reporting someone else's frames. Before capture every render still
|
|
121
|
+
// counts: that is how the first game frame is detected at all.
|
|
122
|
+
if (!captured || self === captured.renderer)
|
|
123
|
+
drawCount++;
|
|
124
|
+
// Never capture a scene the HOST owns. The trap sits on the shared
|
|
125
|
+
// `WebGLRenderer.prototype`, so the editor's own viewport renders
|
|
126
|
+
// arrive here too — and when a game bundles its own MISMATCHED three
|
|
127
|
+
// (the case this whole degrade-to-embed-only path exists for), the
|
|
128
|
+
// editor's scene is then the only thing that ever reaches the trap.
|
|
129
|
+
// It was duly "captured" as the game: the editor got a hierarchy of
|
|
130
|
+
// its own GridHelper, BatchedRenderer and viewport lights presented as
|
|
131
|
+
// the ingested game's content, and `captureFailed` — the signal the
|
|
132
|
+
// whole graceful-degradation contract is built on — never fired.
|
|
133
|
+
// Whether that happened at all came down to whether the editor
|
|
134
|
+
// rendered a frame inside the game's capture window, so the same
|
|
135
|
+
// session could pass or fail on timing alone.
|
|
136
|
+
const isHostRender = opts?.isHostRenderer?.(self) === true;
|
|
137
|
+
if (!captured && !isHostRender && scene && scene.isScene) {
|
|
138
|
+
captured = {
|
|
139
|
+
scene: scene,
|
|
140
|
+
camera: camera,
|
|
141
|
+
renderer: self,
|
|
142
|
+
};
|
|
143
|
+
for (const resolve of waiters.splice(0))
|
|
144
|
+
resolve(captured);
|
|
145
|
+
}
|
|
146
|
+
// Forward to the renderer's real render with the original args.
|
|
147
|
+
return self[REAL].apply(self, args);
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
// ---- Wave 17 (D-C2): additive composer capture, only when a composer ctor
|
|
152
|
+
// was passed. `EffectComposer` methods (including `render`) live on the
|
|
153
|
+
// PROTOTYPE (a plain ES class — the constructor never does `this.render =
|
|
154
|
+
// …`), so a direct method-wrapper suffices — no getter/setter indirection
|
|
155
|
+
// like the `render`/`setAnimationLoop` traps above need. ----
|
|
156
|
+
const composers = new Set();
|
|
157
|
+
let composerProto;
|
|
158
|
+
let priorComposerRender;
|
|
159
|
+
if (effectComposerCtor) {
|
|
160
|
+
const EC = effectComposerCtor;
|
|
161
|
+
composerProto = EC.prototype;
|
|
162
|
+
priorComposerRender = composerProto['render'];
|
|
163
|
+
composerProto['render'] = function (...args) {
|
|
164
|
+
// Call the real render FIRST: a composer's RenderPass calls
|
|
165
|
+
// `renderer.render(scene,camera)` internally, which is what actually
|
|
166
|
+
// sets `captured` (above) on the game's first frame. Checking after
|
|
167
|
+
// ensures a composer's very first render is still collected.
|
|
168
|
+
const result = priorComposerRender?.apply(this, args);
|
|
169
|
+
if (captured && this.renderer === captured.renderer) {
|
|
170
|
+
composers.add(this);
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Extracted so `uninstall()`'s own cognitive complexity doesn't grow with
|
|
176
|
+
// this additive Wave-17 restore step (biome's noExcessiveCognitiveComplexity).
|
|
177
|
+
function restoreComposerTrap() {
|
|
178
|
+
if (!composerProto)
|
|
179
|
+
return;
|
|
180
|
+
if (priorComposerRender)
|
|
181
|
+
composerProto['render'] = priorComposerRender;
|
|
182
|
+
else
|
|
183
|
+
delete composerProto['render'];
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
get captured() {
|
|
187
|
+
return captured;
|
|
188
|
+
},
|
|
189
|
+
getDrawCount() {
|
|
190
|
+
return drawCount;
|
|
191
|
+
},
|
|
192
|
+
getAnimationLoop(renderer) {
|
|
193
|
+
return loopCallbacks.get(renderer) ?? null;
|
|
194
|
+
},
|
|
195
|
+
resizeComposers(w, h) {
|
|
196
|
+
// No composer ctor passed (or none constructed yet) → no-op, and never
|
|
197
|
+
// touches `renderer.getPixelRatio()` — a non-composer game's captured
|
|
198
|
+
// renderer need not even expose that method for this to stay a no-op.
|
|
199
|
+
if (!captured || composers.size === 0)
|
|
200
|
+
return;
|
|
201
|
+
const pixelRatio = captured.renderer.getPixelRatio();
|
|
202
|
+
for (const composer of composers) {
|
|
203
|
+
composer.setSize(w, h);
|
|
204
|
+
composer.setPixelRatio(pixelRatio);
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
waitForCapture(timeoutMs = 10_000) {
|
|
208
|
+
if (captured)
|
|
209
|
+
return Promise.resolve(captured);
|
|
210
|
+
return new Promise((resolve, reject) => {
|
|
211
|
+
const timer = setTimeout(() => {
|
|
212
|
+
const i = waiters.indexOf(wrapped);
|
|
213
|
+
if (i >= 0)
|
|
214
|
+
waiters.splice(i, 1);
|
|
215
|
+
reject(new Error(`Scene capture timed out after ${timeoutMs}ms — the game never rendered, ` +
|
|
216
|
+
`or it bundles its own (un-shared) copy of three.`));
|
|
217
|
+
}, timeoutMs);
|
|
218
|
+
const wrapped = (rt) => {
|
|
219
|
+
clearTimeout(timer);
|
|
220
|
+
resolve(rt);
|
|
221
|
+
};
|
|
222
|
+
waiters.push(wrapped);
|
|
223
|
+
});
|
|
224
|
+
},
|
|
225
|
+
uninstall() {
|
|
226
|
+
// Restore the captured renderer's real render as an OWN property so its
|
|
227
|
+
// loop keeps working after the prototype trap is removed.
|
|
228
|
+
if (captured) {
|
|
229
|
+
const r = captured.renderer;
|
|
230
|
+
const real = r[REAL];
|
|
231
|
+
if (typeof real === 'function') {
|
|
232
|
+
Object.defineProperty(captured.renderer, 'render', {
|
|
233
|
+
configurable: true,
|
|
234
|
+
writable: true,
|
|
235
|
+
value: real,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (priorDescriptor) {
|
|
240
|
+
Object.defineProperty(proto, 'render', priorDescriptor);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
delete proto['render'];
|
|
244
|
+
}
|
|
245
|
+
// Restore the captured renderer's real setAnimationLoop as an OWN property (the
|
|
246
|
+
// prototype getter/setter intercepted the constructor's assignment, so the
|
|
247
|
+
// instance has none) — else removing the prototype trap would leave it without
|
|
248
|
+
// setAnimationLoop and freeze its loop.
|
|
249
|
+
if (captured) {
|
|
250
|
+
const r = captured.renderer;
|
|
251
|
+
const realSal = r[REAL_SAL];
|
|
252
|
+
if (typeof realSal === 'function') {
|
|
253
|
+
Object.defineProperty(captured.renderer, 'setAnimationLoop', {
|
|
254
|
+
configurable: true,
|
|
255
|
+
writable: true,
|
|
256
|
+
value: realSal,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (priorSAL)
|
|
261
|
+
Object.defineProperty(proto, 'setAnimationLoop', priorSAL);
|
|
262
|
+
else
|
|
263
|
+
delete proto['setAnimationLoop'];
|
|
264
|
+
// Wave 17: fully restore the composer addon's `render` (a plain
|
|
265
|
+
// prototype method — no per-instance own-property to restore, unlike
|
|
266
|
+
// the renderer/loop traps above).
|
|
267
|
+
restoreComposerTrap();
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
}
|