@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 @@
|
|
|
1
|
+
{"version":3,"file":"camera-ownership.d.ts","sourceRoot":"","sources":["../../src/animation/camera-ownership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0KG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,QAAQ,GAAG,qBAAqB,CAAC;AAE/E,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,2GAA2G;AAC3G,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,OAAO,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,OAAO,EAAE,MAAM;CAK3B;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,iBAAiB,GAAG,UAAU,CAQvE;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,iBAAiB,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAOjF;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAQhF;AAqBD,MAAM,WAAW,0BAA0B;IACzC,4GAA4G;IAC5G,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,yHAAyH;IACzH,UAAU,EAAE,KAAK,CAAC,iBAAiB,CAAC;IACpC;;;;;OAKG;IACH,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3D,oEAAoE;IACpE,KAAK,EAAE,cAAc,CAAC;IACtB,oGAAoG;IACpG,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,oGAAoG;IACpG,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,yJAAyJ;IACzJ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAClE,kHAAkH;IAClH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,yHAAyH;IACzH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACtE,iHAAiH;IACjH,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC7E,yGAAyG;IACzG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACxE,qEAAqE;IACrE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sHAAsH;IACtH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,qBAAqB,CA6JvB"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
/** Thrown on an ownership-stack rule violation (not-current-owner, unknown camera key, duplicate take). */
|
|
3
|
+
export class CameraOwnershipError extends Error {
|
|
4
|
+
ownerId;
|
|
5
|
+
constructor(message, ownerId) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.ownerId = ownerId;
|
|
8
|
+
this.name = 'CameraOwnershipError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Snapshot a camera's full pose (position/quaternion cloned — never aliases the live object). */
|
|
12
|
+
export function capturePose(camera) {
|
|
13
|
+
return {
|
|
14
|
+
position: camera.position.clone(),
|
|
15
|
+
quaternion: camera.quaternion.clone(),
|
|
16
|
+
fov: camera.fov,
|
|
17
|
+
near: camera.near,
|
|
18
|
+
far: camera.far,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Write a captured pose onto a camera, updating its projection matrix. */
|
|
22
|
+
export function applyPose(camera, pose) {
|
|
23
|
+
camera.position.copy(pose.position);
|
|
24
|
+
camera.quaternion.copy(pose.quaternion);
|
|
25
|
+
camera.fov = pose.fov;
|
|
26
|
+
camera.near = pose.near;
|
|
27
|
+
camera.far = pose.far;
|
|
28
|
+
camera.updateProjectionMatrix();
|
|
29
|
+
}
|
|
30
|
+
/** Position LERP + quaternion SLERP + fov/near/far LERP, `t` in `[0, 1]`. */
|
|
31
|
+
export function lerpPose(from, to, t) {
|
|
32
|
+
return {
|
|
33
|
+
position: from.position.clone().lerp(to.position, t),
|
|
34
|
+
quaternion: from.quaternion.clone().slerp(to.quaternion, t),
|
|
35
|
+
fov: THREE.MathUtils.lerp(from.fov, to.fov, t),
|
|
36
|
+
near: THREE.MathUtils.lerp(from.near, to.near, t),
|
|
37
|
+
far: THREE.MathUtils.lerp(from.far, to.far, t),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build a camera-ownership system bound to `clock`. See the module doc
|
|
42
|
+
* comment for the full ownership-stack, cut/blend, and restore-policy
|
|
43
|
+
* contract.
|
|
44
|
+
*/
|
|
45
|
+
export function createCameraOwnershipSystem(options) {
|
|
46
|
+
const { liveCamera, cameras, clock } = options;
|
|
47
|
+
const defaultPolicy = options.defaultPolicy ?? 'restore';
|
|
48
|
+
const phase = options.phase ?? 'render';
|
|
49
|
+
const stack = [];
|
|
50
|
+
let disposed = false;
|
|
51
|
+
function requireNotDisposed(action) {
|
|
52
|
+
if (disposed) {
|
|
53
|
+
throw new CameraOwnershipError(`[camera-ownership] ${action}: system has been disposed`, '');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function requireSourceCamera(cameraKey, action) {
|
|
57
|
+
const camera = cameras[cameraKey];
|
|
58
|
+
if (!camera) {
|
|
59
|
+
throw new CameraOwnershipError(`[camera-ownership] ${action}: no registered camera for key "${cameraKey}"`, cameraKey);
|
|
60
|
+
}
|
|
61
|
+
return camera;
|
|
62
|
+
}
|
|
63
|
+
function requireTopOwner(ownerId, action) {
|
|
64
|
+
const top = stack[stack.length - 1];
|
|
65
|
+
if (!top) {
|
|
66
|
+
throw new CameraOwnershipError(`[camera-ownership] ${action}: "${ownerId}" is not the current owner (ownership stack is empty)`, ownerId);
|
|
67
|
+
}
|
|
68
|
+
if (top.ownerId !== ownerId) {
|
|
69
|
+
throw new CameraOwnershipError(`[camera-ownership] ${action}: "${ownerId}" is not the current owner (current owner is "${top.ownerId}")`, ownerId);
|
|
70
|
+
}
|
|
71
|
+
return top;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply a frame's CURRENT state to `liveCamera` — a pure function of
|
|
75
|
+
* `clock.time` and the fixed `FrameState` record (see the module doc's
|
|
76
|
+
* "one unified transition model"). Never mutates `frame.state`.
|
|
77
|
+
*/
|
|
78
|
+
function evaluateFrame(frame) {
|
|
79
|
+
const state = frame.state;
|
|
80
|
+
if (!state)
|
|
81
|
+
return;
|
|
82
|
+
const targetPose = capturePose(requireSourceCamera(state.targetKey, 'evaluate'));
|
|
83
|
+
const t = state.durationSeconds <= 0
|
|
84
|
+
? 1
|
|
85
|
+
: Math.min(Math.max((clock.time - state.startTime) / state.durationSeconds, 0), 1);
|
|
86
|
+
applyPose(liveCamera, t >= 1 ? targetPose : lerpPose(state.fromPose, targetPose, t));
|
|
87
|
+
}
|
|
88
|
+
function beginTransition(ownerId, cameraKey, durationSeconds) {
|
|
89
|
+
const frame = requireTopOwner(ownerId, 'cut/blend');
|
|
90
|
+
requireSourceCamera(cameraKey, 'cut/blend'); // validate before mutating frame state
|
|
91
|
+
frame.state = {
|
|
92
|
+
targetKey: cameraKey,
|
|
93
|
+
fromPose: capturePose(liveCamera),
|
|
94
|
+
startTime: clock.time,
|
|
95
|
+
durationSeconds,
|
|
96
|
+
};
|
|
97
|
+
// Apply immediately so direct (non-clock-crossing-sourced) calls are
|
|
98
|
+
// visible right away; the per-crossing evaluator below re-applies the
|
|
99
|
+
// same result on every subsequent crossing (idempotent when called
|
|
100
|
+
// twice within the same crossing — e.g. once here, once from the D4
|
|
101
|
+
// hook's own 'preRender'-phase call site, once more from this module's
|
|
102
|
+
// later 'render'-phase evaluator).
|
|
103
|
+
evaluateFrame(frame);
|
|
104
|
+
}
|
|
105
|
+
function releaseFrame(frame, completed) {
|
|
106
|
+
const shouldRetain = frame.policy === 'retain' || (frame.policy === 'retain-if-completed' && completed);
|
|
107
|
+
if (!shouldRetain) {
|
|
108
|
+
applyPose(liveCamera, frame.restorePose);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const handle = clock.subscribe(phase, () => {
|
|
112
|
+
const top = stack[stack.length - 1];
|
|
113
|
+
if (top)
|
|
114
|
+
evaluateFrame(top);
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
take(ownerId, takeOptions = {}) {
|
|
118
|
+
requireNotDisposed('take');
|
|
119
|
+
if (stack.some((frame) => frame.ownerId === ownerId)) {
|
|
120
|
+
throw new CameraOwnershipError(`[camera-ownership] take: "${ownerId}" is already on the ownership stack`, ownerId);
|
|
121
|
+
}
|
|
122
|
+
stack.push({
|
|
123
|
+
ownerId,
|
|
124
|
+
policy: takeOptions.policy ?? defaultPolicy,
|
|
125
|
+
restorePose: capturePose(liveCamera),
|
|
126
|
+
state: undefined,
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
cut(ownerId, cameraKey) {
|
|
130
|
+
requireNotDisposed('cut');
|
|
131
|
+
beginTransition(ownerId, cameraKey, 0);
|
|
132
|
+
},
|
|
133
|
+
blend(ownerId, cameraKey, blendSeconds) {
|
|
134
|
+
requireNotDisposed('blend');
|
|
135
|
+
if (!Number.isFinite(blendSeconds) || blendSeconds < 0) {
|
|
136
|
+
throw new CameraOwnershipError(`[camera-ownership] blend: blendSeconds must be a finite number >= 0, got ${blendSeconds}`, ownerId);
|
|
137
|
+
}
|
|
138
|
+
beginTransition(ownerId, cameraKey, blendSeconds);
|
|
139
|
+
},
|
|
140
|
+
applyDirectorEvent(ownerId, event) {
|
|
141
|
+
requireNotDisposed('applyDirectorEvent');
|
|
142
|
+
beginTransition(ownerId, event.cameraKey, event.blendSeconds);
|
|
143
|
+
},
|
|
144
|
+
release(ownerId, releaseOptions = {}) {
|
|
145
|
+
requireNotDisposed('release');
|
|
146
|
+
const top = requireTopOwner(ownerId, 'release');
|
|
147
|
+
stack.pop();
|
|
148
|
+
releaseFrame(top, releaseOptions.completed ?? false);
|
|
149
|
+
},
|
|
150
|
+
isOwner(ownerId) {
|
|
151
|
+
const top = stack[stack.length - 1];
|
|
152
|
+
return !!top && top.ownerId === ownerId;
|
|
153
|
+
},
|
|
154
|
+
get depth() {
|
|
155
|
+
return stack.length;
|
|
156
|
+
},
|
|
157
|
+
dispose() {
|
|
158
|
+
if (disposed)
|
|
159
|
+
return;
|
|
160
|
+
disposed = true;
|
|
161
|
+
while (stack.length > 0) {
|
|
162
|
+
const top = stack.pop();
|
|
163
|
+
if (top)
|
|
164
|
+
releaseFrame(top, false);
|
|
165
|
+
}
|
|
166
|
+
handle.dispose();
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type { SystemPhaseName } from '../core/types';
|
|
2
|
+
import type { AnimationClock, ClockCrossing } from './animation-clock';
|
|
3
|
+
/**
|
|
4
|
+
* D5 — Cinematic Cues (spec §10 D5, §5.4, §3.2).
|
|
5
|
+
*
|
|
6
|
+
* `CinematicCue` is the deliberately small VGAI semantic for "gameplay
|
|
7
|
+
* consequences of cinematic time" (spec §3.2: "Theatre carries
|
|
8
|
+
* visual/directorial values; ordinary TypeScript cues carry gameplay
|
|
9
|
+
* consequences"). Cues live ALONGSIDE Theatre (`theatre-clock-binding.ts`,
|
|
10
|
+
* D2) — both are driven by the same canonical `AnimationClock`, but a cue
|
|
11
|
+
* is ordinary TypeScript with a `run`/`reverse` function, never a second
|
|
12
|
+
* property-animation format and never serialized executable code into
|
|
13
|
+
* Theatre state (spec §5.4).
|
|
14
|
+
*
|
|
15
|
+
* ## Fire-once, built on the clock's half-open interval convention
|
|
16
|
+
*
|
|
17
|
+
* The clock documents (see `ClockInterval` in `animation-clock.ts`) that a
|
|
18
|
+
* time `t` is CROSSED by a forward interval iff `t > from && t <= to`, and
|
|
19
|
+
* by a reverse interval iff `t < from && t >= to`. This module uses exactly
|
|
20
|
+
* that test (`crossesForward`/`crossesReverse` below) and nothing else to
|
|
21
|
+
* decide "did this crossing sweep past cue.time" — never a naive comparison
|
|
22
|
+
* of `previousTime`/`currentTime`, which is ambiguous across a loop wrap
|
|
23
|
+
* (one `ClockCrossing` can carry 2+ intervals, one per lap segment; see the
|
|
24
|
+
* clock's loop-wrap tests). Because a repeated `seek()` to the same time
|
|
25
|
+
* re-asserts a ZERO-LENGTH interval (`from === to`), and the half-open test
|
|
26
|
+
* never matches a zero-length interval, a cue naturally does not re-fire on
|
|
27
|
+
* a repeated seek to the same `t` with no extra bookkeeping required.
|
|
28
|
+
*
|
|
29
|
+
* ## Sticky fire-once state + explicit re-arm ("resetsOnLoop"/"restart")
|
|
30
|
+
*
|
|
31
|
+
* Beyond that per-crossing test, each cue additionally tracks whether it
|
|
32
|
+
* has EVER fired forward/reverse ("sticky" state, `CueState` below). Once
|
|
33
|
+
* fired, a cue does not fire again from ordinary play/seek traffic — this
|
|
34
|
+
* is what makes a one-shot story beat like `spawn-enemy` safe to scrub
|
|
35
|
+
* across repeatedly in an editor without re-triggering. Two things
|
|
36
|
+
* explicitly re-arm (clear) that sticky state:
|
|
37
|
+
*
|
|
38
|
+
* - a loop-wrapping crossing (`crossing.looped === true`, which — per the
|
|
39
|
+
* clock's own contract — only `advance()` can ever produce; `seek()`
|
|
40
|
+
* always reports `looped: false`) re-arms only cues with
|
|
41
|
+
* `resetsOnLoop: true`, once per lap boundary actually swept (so a
|
|
42
|
+
* single giant multi-lap `advance()` correctly re-fires a per-lap cue
|
|
43
|
+
* once per lap, not just once for the whole call);
|
|
44
|
+
* - `CueRunner.reset()` unconditionally re-arms EVERY cue — this is the
|
|
45
|
+
* "restart" policy: the intended call when a cinematic explicitly
|
|
46
|
+
* restarts from the top and cues should be able to replay.
|
|
47
|
+
*
|
|
48
|
+
* ## Seek vs. play ("firesDuringSeek")
|
|
49
|
+
*
|
|
50
|
+
* `AnimationClock.seek()` and `AnimationClock.advance()` both funnel
|
|
51
|
+
* through the same `ClockCrossing` shape — the clock does not itself tag a
|
|
52
|
+
* crossing with which method produced it (that distinction is deliberately
|
|
53
|
+
* NOT added to the D1 clock; see the D1 follow-up note in
|
|
54
|
+
* `animation-clock.ts`, which stays scoped to the epsilon-clamp fix only).
|
|
55
|
+
* This module makes the distinction its own responsibility: drive the clock
|
|
56
|
+
* through `CueRunner.seek(t)` / `CueRunner.advance(dt)` (not
|
|
57
|
+
* `clock.seek`/`clock.advance` directly) and the runner tags the resulting
|
|
58
|
+
* crossing with its true source before evaluating cues. A cue with
|
|
59
|
+
* `firesDuringSeek` unset/false is skipped entirely (both directions, and
|
|
60
|
+
* the auto-cleanup/compensation described below) on a seek-sourced
|
|
61
|
+
* crossing — this is what keeps authoring-time scrubbing from spamming
|
|
62
|
+
* `player.lockInput()`/`enemies.spawn()` side effects, matching the spirit
|
|
63
|
+
* of the D4 director AC ("seeking ... without spuriously firing gameplay
|
|
64
|
+
* cues"). Driving the clock directly (bypassing the runner's wrapper
|
|
65
|
+
* methods) is still safe — the crossing is simply treated as `'advance'`
|
|
66
|
+
* sourced by default — but loses seek-vs-play discrimination; this is a
|
|
67
|
+
* documented, deliberate limitation, not a bug.
|
|
68
|
+
*
|
|
69
|
+
* ## Equal-timestamp tiebreak
|
|
70
|
+
*
|
|
71
|
+
* Cues are evaluated in ascending `time` order; cues with an EQUAL `time`
|
|
72
|
+
* are evaluated in REGISTRATION order (the order they appear in the array
|
|
73
|
+
* passed to `createCueRunner`) — the same tiebreak convention
|
|
74
|
+
* `AnimationClock.subscribe` itself uses for same-phase evaluators
|
|
75
|
+
* (`animation-clock.ts`'s `EvaluatorEntry.order`).
|
|
76
|
+
*
|
|
77
|
+
* ## Cleanup / compensation
|
|
78
|
+
*
|
|
79
|
+
* `run`/`reverse` may return a `CueCleanup` function. It is invoked (and
|
|
80
|
+
* then discarded) at whichever of these happens first:
|
|
81
|
+
*
|
|
82
|
+
* - a reverse-direction crossing of the SAME cue (even if the cue has no
|
|
83
|
+
* explicit `reverse` handler — this is the "compensation" half of the
|
|
84
|
+
* contract: undo whatever `run` set up, symmetrically, when time moves
|
|
85
|
+
* back past it), subject to the same `firesDuringSeek` gating as any
|
|
86
|
+
* other reverse-direction reaction;
|
|
87
|
+
* - the cue being re-armed by a loop wrap (`resetsOnLoop`) or by
|
|
88
|
+
* `reset()` — any not-yet-compensated effect is cleaned up before the
|
|
89
|
+
* cue is made eligible to fire again;
|
|
90
|
+
* - `CueRunner.dispose()` — final teardown.
|
|
91
|
+
*
|
|
92
|
+
* `run`'s cleanup and `reverse`'s cleanup are tracked independently, so an
|
|
93
|
+
* explicit `reverse` handler that ALSO returns a cleanup gets its own
|
|
94
|
+
* compensation slot (invoked on re-arm/dispose, since there is no
|
|
95
|
+
* "un-reverse" direction to compensate it from).
|
|
96
|
+
*
|
|
97
|
+
* ## Error isolation
|
|
98
|
+
*
|
|
99
|
+
* Every `run`/`reverse`/cleanup invocation is individually try/caught. A
|
|
100
|
+
* throw is recorded as a `CueError` (`cueId` + `time` + which `phase`
|
|
101
|
+
* threw) via `getErrors()`/the optional `onError` callback, and NEVER
|
|
102
|
+
* re-thrown — one failing cue can neither block a sibling cue in the same
|
|
103
|
+
* crossing nor corrupt the clock (the clock has already committed its new
|
|
104
|
+
* position before any cue runs; a cue is a pure reaction to a completed
|
|
105
|
+
* crossing, never a participant in producing one).
|
|
106
|
+
*/
|
|
107
|
+
/** Optional compensation/cleanup a cue handler may return. */
|
|
108
|
+
export type CueCleanup = () => void;
|
|
109
|
+
/**
|
|
110
|
+
* `void` (not `undefined`) is required here so an ordinary handler written
|
|
111
|
+
* as `run: (ctx) => { ctx.player.lockInput(); }` (no explicit `return`,
|
|
112
|
+
* which TS types as `void`) stays assignable — TS's special-cased "a
|
|
113
|
+
* `void`-typed callback return position accepts any return value"
|
|
114
|
+
* assignability rule does NOT apply to `undefined`; swapping this to
|
|
115
|
+
* `undefined | CueCleanup` breaks every cue author whose handler doesn't
|
|
116
|
+
* end in a bare `return;`.
|
|
117
|
+
*/
|
|
118
|
+
export type CueHandlerResult = void | CueCleanup;
|
|
119
|
+
/**
|
|
120
|
+
* A single cinematic cue: a stable id, a time in seconds, and the gameplay
|
|
121
|
+
* reaction(s) to crossing that time. See the module doc above and spec
|
|
122
|
+
* §5.4 for the full contract.
|
|
123
|
+
*/
|
|
124
|
+
export interface CinematicCue<TContext = unknown> {
|
|
125
|
+
/** Stable identifier, unique within one `CueRunner`. */
|
|
126
|
+
readonly id: string;
|
|
127
|
+
/** Time in seconds, in the same domain as the driving `AnimationClock`. */
|
|
128
|
+
readonly time: number;
|
|
129
|
+
/** Forward-crossing behavior. May return a cleanup/compensation function. */
|
|
130
|
+
run(ctx: TContext): CueHandlerResult;
|
|
131
|
+
/** Optional reverse (backward-crossing) behavior. May return its own cleanup. */
|
|
132
|
+
reverse?(ctx: TContext): CueHandlerResult;
|
|
133
|
+
/**
|
|
134
|
+
* Whether this cue reacts to a `CueRunner.seek()`-sourced crossing (in
|
|
135
|
+
* either direction). Default `false` — explicit seeks (authoring-time
|
|
136
|
+
* scrubbing, skip/jump) do not fire gameplay-consequential cues unless a
|
|
137
|
+
* cue opts in.
|
|
138
|
+
*/
|
|
139
|
+
readonly firesDuringSeek?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Whether a loop-wrapping crossing re-arms this cue so it can fire again
|
|
142
|
+
* next lap. Default `false` — the cue fires (at most) once for the
|
|
143
|
+
* lifetime of the runner, until an explicit `reset()`.
|
|
144
|
+
*/
|
|
145
|
+
readonly resetsOnLoop?: boolean;
|
|
146
|
+
}
|
|
147
|
+
export type CueErrorPhase = 'run' | 'reverse' | 'cleanup';
|
|
148
|
+
/** A failed cue's identity + which phase threw, never a live Error re-throw. */
|
|
149
|
+
export interface CueError {
|
|
150
|
+
readonly cueId: string;
|
|
151
|
+
readonly time: number;
|
|
152
|
+
readonly phase: CueErrorPhase;
|
|
153
|
+
readonly error: unknown;
|
|
154
|
+
}
|
|
155
|
+
/** Which `AnimationClock` method produced the crossing being evaluated. */
|
|
156
|
+
export type CueCrossingSource = 'advance' | 'seek';
|
|
157
|
+
export interface CueRunnerOptions<TContext> {
|
|
158
|
+
/** The game context passed to every `run`/`reverse` call. */
|
|
159
|
+
context: TContext;
|
|
160
|
+
/**
|
|
161
|
+
* Which `AnimationClock` phase to evaluate cues in. Default `'gameLogic'`
|
|
162
|
+
* — gameplay consequences run before the `'animation'` phase Theatre
|
|
163
|
+
* bindings use (`theatre-clock-binding.ts`), matching `PHASE_ORDER`.
|
|
164
|
+
*/
|
|
165
|
+
phase?: SystemPhaseName;
|
|
166
|
+
/** Called synchronously whenever a cue's run/reverse/cleanup throws. */
|
|
167
|
+
onError?: (err: CueError) => void;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The runner's public surface is intentionally context-agnostic (`TContext`
|
|
171
|
+
* only shapes construction — the cue handlers it drives — not this object's
|
|
172
|
+
* own methods), so it takes no type parameter.
|
|
173
|
+
*/
|
|
174
|
+
export interface CueRunner {
|
|
175
|
+
/**
|
|
176
|
+
* Explicit seek, tagged as `'seek'`-sourced for `firesDuringSeek` gating.
|
|
177
|
+
* Prefer this over calling the underlying clock's `seek()` directly.
|
|
178
|
+
*/
|
|
179
|
+
seek(t: number): ClockCrossing;
|
|
180
|
+
/**
|
|
181
|
+
* Playback tick, tagged as `'advance'`-sourced. Prefer this over calling
|
|
182
|
+
* the underlying clock's `advance()` directly. No-op (returns `null`)
|
|
183
|
+
* under the same conditions `AnimationClock.advance` is a no-op.
|
|
184
|
+
*/
|
|
185
|
+
advance(dt: number): ClockCrossing | null;
|
|
186
|
+
/** Re-arms every cue (the "restart" policy) and runs any pending cleanups. */
|
|
187
|
+
reset(): void;
|
|
188
|
+
/** Every cue failure recorded so far, in the order they occurred. */
|
|
189
|
+
getErrors(): readonly CueError[];
|
|
190
|
+
/** Clears the recorded error log (does not affect cue armed state). */
|
|
191
|
+
clearErrors(): void;
|
|
192
|
+
/** Unsubscribes from the clock and runs any pending cleanups. */
|
|
193
|
+
dispose(): void;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Build a cue runner bound to `clock`, evaluating `cues` on every crossing.
|
|
197
|
+
* See the module doc comment for the full policy contract.
|
|
198
|
+
*/
|
|
199
|
+
export declare function createCueRunner<TContext>(clock: AnimationClock, cues: readonly CinematicCue<TContext>[], options: CueRunnerOptions<TContext>): CueRunner;
|
|
200
|
+
//# sourceMappingURL=cinematic-cues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cinematic-cues.d.ts","sourceRoot":"","sources":["../../src/animation/cinematic-cues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAGd,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuGG;AAEH,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAEpC;;;;;;;;GAQG;AAEH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,UAAU,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,GAAG,OAAO;IAC9C,wDAAwD;IACxD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAAC;IACrC,iFAAiF;IACjF,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1D,gFAAgF;AAChF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,gBAAgB,CAAC,QAAQ;IACxC,6DAA6D;IAC7D,OAAO,EAAE,QAAQ,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,wEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IAC1C,8EAA8E;IAC9E,KAAK,IAAI,IAAI,CAAC;IACd,qEAAqE;IACrE,SAAS,IAAI,SAAS,QAAQ,EAAE,CAAC;IACjC,uEAAuE;IACvE,WAAW,IAAI,IAAI,CAAC;IACpB,iEAAiE;IACjE,OAAO,IAAI,IAAI,CAAC;CACjB;AAsBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EACtC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,SAAS,YAAY,CAAC,QAAQ,CAAC,EAAE,EACvC,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAClC,SAAS,CAoNX"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
function crossesForward(interval, cueTime) {
|
|
2
|
+
return interval.direction === 'forward' && cueTime > interval.from && cueTime <= interval.to;
|
|
3
|
+
}
|
|
4
|
+
function crossesReverse(interval, cueTime) {
|
|
5
|
+
return interval.direction === 'reverse' && cueTime < interval.from && cueTime >= interval.to;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Build a cue runner bound to `clock`, evaluating `cues` on every crossing.
|
|
9
|
+
* See the module doc comment for the full policy contract.
|
|
10
|
+
*/
|
|
11
|
+
export function createCueRunner(clock, cues, options) {
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
for (const cue of cues) {
|
|
14
|
+
if (seen.has(cue.id)) {
|
|
15
|
+
throw new Error(`[CueRunner] duplicate cue id "${cue.id}" — ids must be unique`);
|
|
16
|
+
}
|
|
17
|
+
seen.add(cue.id);
|
|
18
|
+
}
|
|
19
|
+
const ordered = cues.map((cue, registrationOrder) => ({
|
|
20
|
+
cue,
|
|
21
|
+
registrationOrder,
|
|
22
|
+
}));
|
|
23
|
+
ordered.sort((a, b) => {
|
|
24
|
+
if (a.cue.time !== b.cue.time)
|
|
25
|
+
return a.cue.time - b.cue.time;
|
|
26
|
+
return a.registrationOrder - b.registrationOrder;
|
|
27
|
+
});
|
|
28
|
+
const context = options.context;
|
|
29
|
+
const phase = options.phase ?? 'gameLogic';
|
|
30
|
+
const errors = [];
|
|
31
|
+
const states = new Map();
|
|
32
|
+
for (const { cue } of ordered) {
|
|
33
|
+
states.set(cue.id, {
|
|
34
|
+
firedForward: false,
|
|
35
|
+
firedReverse: false,
|
|
36
|
+
forwardCleanup: undefined,
|
|
37
|
+
reverseCleanup: undefined,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function stateOf(id) {
|
|
41
|
+
const state = states.get(id);
|
|
42
|
+
if (!state)
|
|
43
|
+
throw new Error(`[CueRunner] unknown cue id "${id}"`); // unreachable — defensive
|
|
44
|
+
return state;
|
|
45
|
+
}
|
|
46
|
+
function reportError(cueId, time, errPhase, error) {
|
|
47
|
+
const cueError = { cueId, time, phase: errPhase, error };
|
|
48
|
+
errors.push(cueError);
|
|
49
|
+
options.onError?.(cueError);
|
|
50
|
+
}
|
|
51
|
+
function invokeHandler(cue, errPhase, handler) {
|
|
52
|
+
try {
|
|
53
|
+
const result = handler(context);
|
|
54
|
+
return typeof result === 'function' ? result : undefined;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
reportError(cue.id, cue.time, errPhase, error);
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function invokeCleanup(cue, cleanup) {
|
|
62
|
+
try {
|
|
63
|
+
cleanup();
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
reportError(cue.id, cue.time, 'cleanup', error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// NOTE: no crossing-scoped "already fired this crossing" guard beyond the
|
|
70
|
+
// per-cue `state.firedForward`/`state.firedReverse` flags below — those
|
|
71
|
+
// flags are sufficient (each cue is visited at most once per interval,
|
|
72
|
+
// and a fire sets the flag before the next interval is scanned) AND, in
|
|
73
|
+
// the resetsOnLoop case, `rearmLoopCues` deliberately clears them mid
|
|
74
|
+
// crossing so a cue CAN legitimately fire again in a later interval of
|
|
75
|
+
// the same multi-lap crossing (once per lap boundary actually crossed).
|
|
76
|
+
// A crossing-wide "fired once ever" set would silently defeat that.
|
|
77
|
+
function processForwardInterval(interval, source) {
|
|
78
|
+
for (const { cue } of ordered) {
|
|
79
|
+
const state = stateOf(cue.id);
|
|
80
|
+
if (state.firedForward)
|
|
81
|
+
continue;
|
|
82
|
+
if (!crossesForward(interval, cue.time))
|
|
83
|
+
continue;
|
|
84
|
+
if (source === 'seek' && !cue.firesDuringSeek)
|
|
85
|
+
continue;
|
|
86
|
+
state.firedForward = true;
|
|
87
|
+
const cleanup = invokeHandler(cue, 'run', cue.run);
|
|
88
|
+
if (cleanup)
|
|
89
|
+
state.forwardCleanup = cleanup;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Split out of processReverseInterval to keep both functions under the
|
|
93
|
+
// project's cognitive-complexity budget: this is the "what happens to ONE
|
|
94
|
+
// cue on a reverse crossing" reaction — the explicit reverse() handler
|
|
95
|
+
// (if any, fire-once) plus the automatic forward-cleanup compensation
|
|
96
|
+
// (independent of whether reverse() exists) — see the module doc's
|
|
97
|
+
// "Cleanup / compensation" section.
|
|
98
|
+
function reactToReverseCrossing(cue, state) {
|
|
99
|
+
if (cue.reverse && !state.firedReverse) {
|
|
100
|
+
state.firedReverse = true;
|
|
101
|
+
const cleanup = invokeHandler(cue, 'reverse', cue.reverse);
|
|
102
|
+
if (cleanup)
|
|
103
|
+
state.reverseCleanup = cleanup;
|
|
104
|
+
}
|
|
105
|
+
if (state.forwardCleanup) {
|
|
106
|
+
const cleanup = state.forwardCleanup;
|
|
107
|
+
state.forwardCleanup = undefined;
|
|
108
|
+
invokeCleanup(cue, cleanup);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function processReverseInterval(interval, source) {
|
|
112
|
+
for (const { cue } of ordered) {
|
|
113
|
+
if (!crossesReverse(interval, cue.time))
|
|
114
|
+
continue;
|
|
115
|
+
if (source === 'seek' && !cue.firesDuringSeek)
|
|
116
|
+
continue;
|
|
117
|
+
reactToReverseCrossing(cue, stateOf(cue.id));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function rearmLoopCues() {
|
|
121
|
+
for (const { cue } of ordered) {
|
|
122
|
+
if (!cue.resetsOnLoop)
|
|
123
|
+
continue;
|
|
124
|
+
const state = stateOf(cue.id);
|
|
125
|
+
if (!state.firedForward && !state.firedReverse)
|
|
126
|
+
continue; // nothing to rearm
|
|
127
|
+
if (state.forwardCleanup) {
|
|
128
|
+
invokeCleanup(cue, state.forwardCleanup);
|
|
129
|
+
state.forwardCleanup = undefined;
|
|
130
|
+
}
|
|
131
|
+
if (state.reverseCleanup) {
|
|
132
|
+
invokeCleanup(cue, state.reverseCleanup);
|
|
133
|
+
state.reverseCleanup = undefined;
|
|
134
|
+
}
|
|
135
|
+
state.firedForward = false;
|
|
136
|
+
state.firedReverse = false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function handleCrossing(crossing, source) {
|
|
140
|
+
for (const interval of crossing.intervals) {
|
|
141
|
+
if (interval.direction === 'forward') {
|
|
142
|
+
processForwardInterval(interval, source);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
processReverseInterval(interval, source);
|
|
146
|
+
}
|
|
147
|
+
if (crossing.looped) {
|
|
148
|
+
const completesLap = (interval.direction === 'forward' && interval.to === clock.range.end) ||
|
|
149
|
+
(interval.direction === 'reverse' && interval.to === clock.range.start);
|
|
150
|
+
if (completesLap)
|
|
151
|
+
rearmLoopCues();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let pendingSource = 'advance';
|
|
156
|
+
const handle = clock.subscribe(phase, (crossing) => {
|
|
157
|
+
handleCrossing(crossing, pendingSource);
|
|
158
|
+
});
|
|
159
|
+
let disposed = false;
|
|
160
|
+
return {
|
|
161
|
+
seek(t) {
|
|
162
|
+
pendingSource = 'seek';
|
|
163
|
+
try {
|
|
164
|
+
return clock.seek(t);
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
pendingSource = 'advance';
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
advance(dt) {
|
|
171
|
+
pendingSource = 'advance';
|
|
172
|
+
return clock.advance(dt);
|
|
173
|
+
},
|
|
174
|
+
reset() {
|
|
175
|
+
for (const { cue } of ordered) {
|
|
176
|
+
const state = stateOf(cue.id);
|
|
177
|
+
if (state.forwardCleanup) {
|
|
178
|
+
invokeCleanup(cue, state.forwardCleanup);
|
|
179
|
+
state.forwardCleanup = undefined;
|
|
180
|
+
}
|
|
181
|
+
if (state.reverseCleanup) {
|
|
182
|
+
invokeCleanup(cue, state.reverseCleanup);
|
|
183
|
+
state.reverseCleanup = undefined;
|
|
184
|
+
}
|
|
185
|
+
state.firedForward = false;
|
|
186
|
+
state.firedReverse = false;
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
getErrors() {
|
|
190
|
+
return errors;
|
|
191
|
+
},
|
|
192
|
+
clearErrors() {
|
|
193
|
+
errors.length = 0;
|
|
194
|
+
},
|
|
195
|
+
dispose() {
|
|
196
|
+
if (disposed)
|
|
197
|
+
return;
|
|
198
|
+
disposed = true;
|
|
199
|
+
handle.dispose();
|
|
200
|
+
for (const { cue } of ordered) {
|
|
201
|
+
const state = stateOf(cue.id);
|
|
202
|
+
if (state.forwardCleanup) {
|
|
203
|
+
invokeCleanup(cue, state.forwardCleanup);
|
|
204
|
+
state.forwardCleanup = undefined;
|
|
205
|
+
}
|
|
206
|
+
if (state.reverseCleanup) {
|
|
207
|
+
invokeCleanup(cue, state.reverseCleanup);
|
|
208
|
+
state.reverseCleanup = undefined;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as THREE from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Build the clip lookup shared by runtime and editor.
|
|
4
|
+
*
|
|
5
|
+
* GLTF exporters disagree about case and may prefix animation names with an
|
|
6
|
+
* armature (`Armature|Idle`). Keep the exact exported suffix while also
|
|
7
|
+
* exposing a lowercase lookup, then apply aliases case-insensitively. This
|
|
8
|
+
* lets authored graphs use either `Idle_Loop` or `idle_loop` without silently
|
|
9
|
+
* falling back to the bind pose.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildClipMap(animations: THREE.AnimationClip[], aliases?: Record<string, string>): Map<string, THREE.AnimationClip>;
|
|
12
|
+
//# sourceMappingURL=clip-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip-map.d.ts","sourceRoot":"","sources":["../../src/animation/clip-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAQpC;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,KAAK,CAAC,aAAa,EAAE,EACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAoBlC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Common aliases used by many free humanoid packs. Scene-authored aliases override these. */
|
|
2
|
+
const DEFAULT_CLIP_ALIASES = {
|
|
3
|
+
walking: 'walk',
|
|
4
|
+
running: 'run',
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Build the clip lookup shared by runtime and editor.
|
|
8
|
+
*
|
|
9
|
+
* GLTF exporters disagree about case and may prefix animation names with an
|
|
10
|
+
* armature (`Armature|Idle`). Keep the exact exported suffix while also
|
|
11
|
+
* exposing a lowercase lookup, then apply aliases case-insensitively. This
|
|
12
|
+
* lets authored graphs use either `Idle_Loop` or `idle_loop` without silently
|
|
13
|
+
* falling back to the bind pose.
|
|
14
|
+
*/
|
|
15
|
+
export function buildClipMap(animations, aliases = {}) {
|
|
16
|
+
const clips = new Map();
|
|
17
|
+
const canonical = new Map();
|
|
18
|
+
for (const clip of animations) {
|
|
19
|
+
const raw = clip.name.split('|').pop()?.trim() || clip.name;
|
|
20
|
+
canonical.set(raw.toLowerCase(), clip);
|
|
21
|
+
if (!clips.has(raw))
|
|
22
|
+
clips.set(raw, clip);
|
|
23
|
+
if (!clips.has(raw.toLowerCase()))
|
|
24
|
+
clips.set(raw.toLowerCase(), clip);
|
|
25
|
+
}
|
|
26
|
+
const mergedAliases = { ...DEFAULT_CLIP_ALIASES, ...aliases };
|
|
27
|
+
for (const [source, alias] of Object.entries(mergedAliases)) {
|
|
28
|
+
const clip = canonical.get(source.toLowerCase());
|
|
29
|
+
if (!clip)
|
|
30
|
+
continue;
|
|
31
|
+
if (!clips.has(alias))
|
|
32
|
+
clips.set(alias, clip);
|
|
33
|
+
if (!clips.has(alias.toLowerCase()))
|
|
34
|
+
clips.set(alias.toLowerCase(), clip);
|
|
35
|
+
}
|
|
36
|
+
return clips;
|
|
37
|
+
}
|