@vgai/engine 0.5.0 → 0.5.2
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/package.json +1 -1
- package/schemas/engine-capabilities.json +4 -4
- package/schemas/vgai-game.schema.json +2 -2
- package/src/adapter/authoring.ts +42 -0
- package/src/adapter/index.ts +3 -0
- package/src/adapter/ingest/overlay-apply.ts +50 -6
- package/src/adapter/ingest/scene-capture.ts +51 -2
- package/src/adapter/vgai-scene-game-adapter.ts +24 -0
- package/src/manifest/schema.ts +7 -3
- package/src/runtime/create-runtime.ts +97 -0
- package/src/runtime/game.ts +11 -1
- package/src/scene/asset-ref-check.ts +1 -1
- package/src/scene/scene-loader.ts +2 -2
- package/src/scene/user-data.ts +18 -0
- package/src/world3d-react/behavior.tsx +19 -11
- package/src/world3d-react/r3f-adapter.tsx +8 -0
- package/dist/adapter/adapter-surface.d.ts +0 -30
- package/dist/adapter/adapter-surface.d.ts.map +0 -1
- package/dist/adapter/adapter-surface.js +0 -18
- package/dist/adapter/authoring.d.ts +0 -461
- package/dist/adapter/authoring.d.ts.map +0 -1
- package/dist/adapter/authoring.js +0 -22
- package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
- package/dist/adapter/colyseus-networking-adapter.js +0 -38
- package/dist/adapter/first-party-systems.d.ts +0 -38
- package/dist/adapter/first-party-systems.d.ts.map +0 -1
- package/dist/adapter/first-party-systems.js +0 -77
- package/dist/adapter/game-adapter.d.ts +0 -133
- package/dist/adapter/game-adapter.d.ts.map +0 -1
- package/dist/adapter/game-adapter.js +0 -10
- package/dist/adapter/host-context.d.ts +0 -71
- package/dist/adapter/host-context.d.ts.map +0 -1
- package/dist/adapter/host-context.js +0 -16
- package/dist/adapter/index.d.ts +0 -22
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter/index.js +0 -15
- package/dist/adapter/ingest/game-contract.d.ts +0 -53
- package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
- package/dist/adapter/ingest/game-contract.js +0 -30
- package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
- package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-applier.js +0 -132
- package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
- package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-apply.js +0 -101
- package/dist/adapter/ingest/overlay-file.d.ts +0 -79
- package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-file.js +0 -66
- package/dist/adapter/ingest/overlay-report.d.ts +0 -113
- package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
- package/dist/adapter/ingest/overlay-report.js +0 -103
- package/dist/adapter/ingest/scene-capture.d.ts +0 -97
- package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
- package/dist/adapter/ingest/scene-capture.js +0 -248
- package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
- package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
- package/dist/adapter/ingest/upstream-pin.js +0 -50
- package/dist/adapter/loop-gate-report.d.ts +0 -34
- package/dist/adapter/loop-gate-report.d.ts.map +0 -1
- package/dist/adapter/loop-gate-report.js +0 -37
- package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
- package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
- package/dist/adapter/rapier-physics-adapter.js +0 -46
- package/dist/adapter/system-adapter.d.ts +0 -206
- package/dist/adapter/system-adapter.d.ts.map +0 -1
- package/dist/adapter/system-adapter.js +0 -13
- package/dist/adapter/transform.d.ts +0 -18
- package/dist/adapter/transform.d.ts.map +0 -1
- package/dist/adapter/transform.js +0 -1
- package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -108
- package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
- package/dist/adapter/vgai-scene-game-adapter.js +0 -762
- package/dist/ai/navigation.d.ts +0 -64
- package/dist/ai/navigation.d.ts.map +0 -1
- package/dist/ai/navigation.js +0 -133
- package/dist/animation/anim-graph-types.d.ts +0 -25
- package/dist/animation/anim-graph-types.d.ts.map +0 -1
- package/dist/animation/anim-graph-types.js +0 -1
- package/dist/animation/animation-clock.d.ts +0 -213
- package/dist/animation/animation-clock.d.ts.map +0 -1
- package/dist/animation/animation-clock.js +0 -301
- package/dist/animation/blend-node.d.ts +0 -22
- package/dist/animation/blend-node.d.ts.map +0 -1
- package/dist/animation/blend-node.js +0 -97
- package/dist/animation/camera-ownership.d.ts +0 -250
- package/dist/animation/camera-ownership.d.ts.map +0 -1
- package/dist/animation/camera-ownership.js +0 -169
- package/dist/animation/cinematic-cues.d.ts +0 -200
- package/dist/animation/cinematic-cues.d.ts.map +0 -1
- package/dist/animation/cinematic-cues.js +0 -213
- package/dist/animation/clip-map.d.ts +0 -12
- package/dist/animation/clip-map.d.ts.map +0 -1
- package/dist/animation/clip-map.js +0 -37
- package/dist/animation/gsap-registration.d.ts +0 -119
- package/dist/animation/gsap-registration.d.ts.map +0 -1
- package/dist/animation/gsap-registration.js +0 -92
- package/dist/animation/theatre-clock-binding.d.ts +0 -89
- package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
- package/dist/animation/theatre-clock-binding.js +0 -29
- package/dist/animation/theatre-director.d.ts +0 -242
- package/dist/animation/theatre-director.d.ts.map +0 -1
- package/dist/animation/theatre-director.js +0 -235
- package/dist/animation/theatre-object-binding.d.ts +0 -305
- package/dist/animation/theatre-object-binding.d.ts.map +0 -1
- package/dist/animation/theatre-object-binding.js +0 -351
- package/dist/animation/xstate-animation-binding.d.ts +0 -56
- package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
- package/dist/animation/xstate-animation-binding.js +0 -331
- package/dist/animation/xstate-animation-meta.d.ts +0 -266
- package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
- package/dist/animation/xstate-animation-meta.js +0 -252
- package/dist/assets.d.ts +0 -26
- package/dist/assets.d.ts.map +0 -1
- package/dist/assets.js +0 -55
- package/dist/audio/index.d.ts +0 -4
- package/dist/audio/index.d.ts.map +0 -1
- package/dist/audio/index.js +0 -24
- package/dist/audio/tone-clock-binding.d.ts +0 -75
- package/dist/audio/tone-clock-binding.d.ts.map +0 -1
- package/dist/audio/tone-clock-binding.js +0 -29
- package/dist/audio/tone-context.d.ts +0 -114
- package/dist/audio/tone-context.d.ts.map +0 -1
- package/dist/audio/tone-context.js +0 -39
- package/dist/audio/tone-offline-render.d.ts +0 -90
- package/dist/audio/tone-offline-render.d.ts.map +0 -1
- package/dist/audio/tone-offline-render.js +0 -56
- package/dist/audio/wav-encode.d.ts +0 -38
- package/dist/audio/wav-encode.d.ts.map +0 -1
- package/dist/audio/wav-encode.js +0 -97
- package/dist/character/cloth-sim.d.ts +0 -179
- package/dist/character/cloth-sim.d.ts.map +0 -1
- package/dist/character/cloth-sim.js +0 -334
- package/dist/character/spring-chain.d.ts +0 -135
- package/dist/character/spring-chain.d.ts.map +0 -1
- package/dist/character/spring-chain.js +0 -165
- package/dist/core/game-loop.d.ts +0 -42
- package/dist/core/game-loop.d.ts.map +0 -1
- package/dist/core/game-loop.js +0 -167
- package/dist/core/seeded-random.d.ts +0 -69
- package/dist/core/seeded-random.d.ts.map +0 -1
- package/dist/core/seeded-random.js +0 -121
- package/dist/core/system-runner.d.ts +0 -120
- package/dist/core/system-runner.d.ts.map +0 -1
- package/dist/core/system-runner.js +0 -297
- package/dist/core/types.d.ts +0 -92
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -25
- package/dist/data/data-asset.d.ts +0 -101
- package/dist/data/data-asset.d.ts.map +0 -1
- package/dist/data/data-asset.js +0 -122
- package/dist/data/data-check-core.d.ts +0 -110
- package/dist/data/data-check-core.d.ts.map +0 -1
- package/dist/data/data-check-core.js +0 -178
- package/dist/data/data-ref.d.ts +0 -79
- package/dist/data/data-ref.d.ts.map +0 -1
- package/dist/data/data-ref.js +0 -130
- package/dist/data/vite-plugin-data.d.ts +0 -79
- package/dist/data/vite-plugin-data.d.ts.map +0 -1
- package/dist/data/vite-plugin-data.js +0 -217
- package/dist/dev/console-bridge.d.ts +0 -22
- package/dist/dev/console-bridge.d.ts.map +0 -1
- package/dist/dev/console-bridge.js +0 -71
- package/dist/dev/debug-draw.d.ts +0 -24
- package/dist/dev/debug-draw.d.ts.map +0 -1
- package/dist/dev/debug-draw.js +0 -73
- package/dist/dev/logger.d.ts +0 -30
- package/dist/dev/logger.d.ts.map +0 -1
- package/dist/dev/logger.js +0 -90
- package/dist/dev/performance-profiler.d.ts +0 -60
- package/dist/dev/performance-profiler.d.ts.map +0 -1
- package/dist/dev/performance-profiler.js +0 -181
- package/dist/dev/webgl-gpu-timer.d.ts +0 -8
- package/dist/dev/webgl-gpu-timer.d.ts.map +0 -1
- package/dist/dev/webgl-gpu-timer.js +0 -52
- package/dist/ecs/component-manager.d.ts +0 -205
- package/dist/ecs/component-manager.d.ts.map +0 -1
- package/dist/ecs/component-manager.js +0 -706
- package/dist/ecs/game-component.d.ts +0 -146
- package/dist/ecs/game-component.d.ts.map +0 -1
- package/dist/ecs/game-component.js +0 -141
- package/dist/ecs/hmr-swap-report.d.ts +0 -53
- package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
- package/dist/ecs/hmr-swap-report.js +0 -55
- package/dist/humanoid/bake.operation.d.ts +0 -119
- package/dist/humanoid/bake.operation.d.ts.map +0 -1
- package/dist/humanoid/bake.operation.js +0 -228
- package/dist/humanoid/body.d.ts +0 -101
- package/dist/humanoid/body.d.ts.map +0 -1
- package/dist/humanoid/body.js +0 -530
- package/dist/humanoid/clips.d.ts +0 -62
- package/dist/humanoid/clips.d.ts.map +0 -1
- package/dist/humanoid/clips.js +0 -121
- package/dist/humanoid/compose.d.ts +0 -75
- package/dist/humanoid/compose.d.ts.map +0 -1
- package/dist/humanoid/compose.js +0 -176
- package/dist/humanoid/generate.d.ts +0 -92
- package/dist/humanoid/generate.d.ts.map +0 -1
- package/dist/humanoid/generate.js +0 -124
- package/dist/humanoid/index.d.ts +0 -24
- package/dist/humanoid/index.d.ts.map +0 -1
- package/dist/humanoid/index.js +0 -18
- package/dist/humanoid/schema.d.ts +0 -35
- package/dist/humanoid/schema.d.ts.map +0 -1
- package/dist/humanoid/schema.js +0 -87
- package/dist/humanoid/skeleton.d.ts +0 -103
- package/dist/humanoid/skeleton.d.ts.map +0 -1
- package/dist/humanoid/skeleton.js +0 -289
- package/dist/index.d.ts +0 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -30
- package/dist/input/input-manager.d.ts +0 -945
- package/dist/input/input-manager.d.ts.map +0 -1
- package/dist/input/input-manager.js +0 -2207
- package/dist/input/input-types.d.ts +0 -174
- package/dist/input/input-types.d.ts.map +0 -1
- package/dist/input/input-types.js +0 -1
- package/dist/input/prompt-labels.d.ts +0 -21
- package/dist/input/prompt-labels.d.ts.map +0 -1
- package/dist/input/prompt-labels.js +0 -121
- package/dist/input/rebind-controller.d.ts +0 -59
- package/dist/input/rebind-controller.d.ts.map +0 -1
- package/dist/input/rebind-controller.js +0 -85
- package/dist/input/schema.d.ts +0 -16
- package/dist/input/schema.d.ts.map +0 -1
- package/dist/input/schema.js +0 -228
- package/dist/loader.d.ts +0 -43
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -59
- package/dist/manifest/index.d.ts +0 -5
- package/dist/manifest/index.d.ts.map +0 -1
- package/dist/manifest/index.js +0 -8
- package/dist/manifest/load-file.d.ts +0 -4
- package/dist/manifest/load-file.d.ts.map +0 -1
- package/dist/manifest/load-file.js +0 -14
- package/dist/manifest/load.d.ts +0 -144
- package/dist/manifest/load.d.ts.map +0 -1
- package/dist/manifest/load.js +0 -273
- package/dist/manifest/schema.d.ts +0 -230
- package/dist/manifest/schema.d.ts.map +0 -1
- package/dist/manifest/schema.js +0 -394
- package/dist/physics/collision-system.d.ts +0 -41
- package/dist/physics/collision-system.d.ts.map +0 -1
- package/dist/physics/collision-system.js +0 -64
- package/dist/physics/physics-registry.d.ts +0 -45
- package/dist/physics/physics-registry.d.ts.map +0 -1
- package/dist/physics/physics-registry.js +0 -65
- package/dist/physics/transform-writer.d.ts +0 -16
- package/dist/physics/transform-writer.d.ts.map +0 -1
- package/dist/physics/transform-writer.js +0 -38
- package/dist/physics/trigger-dispatch.d.ts +0 -24
- package/dist/physics/trigger-dispatch.d.ts.map +0 -1
- package/dist/physics/trigger-dispatch.js +0 -80
- package/dist/react/game-state.d.ts +0 -156
- package/dist/react/game-state.d.ts.map +0 -1
- package/dist/react/game-state.js +0 -222
- package/dist/react/root-adapter.d.ts +0 -11
- package/dist/react/root-adapter.d.ts.map +0 -1
- package/dist/react/root-adapter.js +0 -41
- package/dist/react/unmanaged-root-detector.d.ts +0 -12
- package/dist/react/unmanaged-root-detector.d.ts.map +0 -1
- package/dist/react/unmanaged-root-detector.js +0 -45
- package/dist/react/use-data.d.ts +0 -60
- package/dist/react/use-data.d.ts.map +0 -1
- package/dist/react/use-data.js +0 -101
- package/dist/react/use-selection.d.ts +0 -75
- package/dist/react/use-selection.d.ts.map +0 -1
- package/dist/react/use-selection.js +0 -90
- package/dist/render/auto-batcher.d.ts +0 -34
- package/dist/render/auto-batcher.d.ts.map +0 -1
- package/dist/render/auto-batcher.js +0 -140
- package/dist/render/render-batch-system.d.ts +0 -33
- package/dist/render/render-batch-system.d.ts.map +0 -1
- package/dist/render/render-batch-system.js +0 -230
- package/dist/render/render-features.d.ts +0 -47
- package/dist/render/render-features.d.ts.map +0 -1
- package/dist/render/render-features.js +0 -105
- package/dist/render/render-settings.d.ts +0 -36
- package/dist/render/render-settings.d.ts.map +0 -1
- package/dist/render/render-settings.js +0 -51
- package/dist/runtime/create-runtime.d.ts +0 -249
- package/dist/runtime/create-runtime.d.ts.map +0 -1
- package/dist/runtime/create-runtime.js +0 -641
- package/dist/runtime/debug-bridge.d.ts +0 -257
- package/dist/runtime/debug-bridge.d.ts.map +0 -1
- package/dist/runtime/debug-bridge.js +0 -224
- package/dist/runtime/debug-registry.d.ts +0 -288
- package/dist/runtime/debug-registry.d.ts.map +0 -1
- package/dist/runtime/debug-registry.js +0 -513
- package/dist/runtime/frame-selector-cache.d.ts +0 -41
- package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
- package/dist/runtime/frame-selector-cache.js +0 -65
- package/dist/runtime/game.d.ts +0 -496
- package/dist/runtime/game.d.ts.map +0 -1
- package/dist/runtime/game.js +0 -741
- package/dist/runtime/gameplay-rng-trap.d.ts +0 -48
- package/dist/runtime/gameplay-rng-trap.d.ts.map +0 -1
- package/dist/runtime/gameplay-rng-trap.js +0 -96
- package/dist/runtime/input-router.d.ts +0 -78
- package/dist/runtime/input-router.d.ts.map +0 -1
- package/dist/runtime/input-router.js +0 -171
- package/dist/runtime/mount-game.d.ts +0 -129
- package/dist/runtime/mount-game.d.ts.map +0 -1
- package/dist/runtime/mount-game.js +0 -152
- package/dist/runtime/mount-manifest.d.ts +0 -173
- package/dist/runtime/mount-manifest.d.ts.map +0 -1
- package/dist/runtime/mount-manifest.js +0 -297
- package/dist/runtime/render-audio-control.d.ts +0 -110
- package/dist/runtime/render-audio-control.d.ts.map +0 -1
- package/dist/runtime/render-audio-control.js +0 -111
- package/dist/runtime/render-control.d.ts +0 -291
- package/dist/runtime/render-control.d.ts.map +0 -1
- package/dist/runtime/render-control.js +0 -264
- package/dist/runtime/render-seed.d.ts +0 -57
- package/dist/runtime/render-seed.d.ts.map +0 -1
- package/dist/runtime/render-seed.js +0 -74
- package/dist/runtime/state-bridge.d.ts +0 -61
- package/dist/runtime/state-bridge.d.ts.map +0 -1
- package/dist/runtime/state-bridge.js +0 -63
- package/dist/runtime/types.d.ts +0 -253
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -1
- package/dist/scene/asset-loaders.d.ts +0 -79
- package/dist/scene/asset-loaders.d.ts.map +0 -1
- package/dist/scene/asset-loaders.js +0 -141
- package/dist/scene/asset-paths.d.ts +0 -11
- package/dist/scene/asset-paths.d.ts.map +0 -1
- package/dist/scene/asset-paths.js +0 -108
- package/dist/scene/asset-ref-check.d.ts +0 -88
- package/dist/scene/asset-ref-check.d.ts.map +0 -1
- package/dist/scene/asset-ref-check.js +0 -214
- package/dist/scene/asset-registry.d.ts +0 -38
- package/dist/scene/asset-registry.d.ts.map +0 -1
- package/dist/scene/asset-registry.js +0 -66
- package/dist/scene/collider-dimensions.d.ts +0 -63
- package/dist/scene/collider-dimensions.d.ts.map +0 -1
- package/dist/scene/collider-dimensions.js +0 -98
- package/dist/scene/component-registry.d.ts +0 -22
- package/dist/scene/component-registry.d.ts.map +0 -1
- package/dist/scene/component-registry.js +0 -37
- package/dist/scene/defaults.d.ts +0 -252
- package/dist/scene/defaults.d.ts.map +0 -1
- package/dist/scene/defaults.js +0 -151
- package/dist/scene/geometries/index.d.ts +0 -8
- package/dist/scene/geometries/index.d.ts.map +0 -1
- package/dist/scene/geometries/index.js +0 -7
- package/dist/scene/geometries/terrain.d.ts +0 -2
- package/dist/scene/geometries/terrain.d.ts.map +0 -1
- package/dist/scene/geometries/terrain.js +0 -37
- package/dist/scene/geometry-registry.d.ts +0 -24
- package/dist/scene/geometry-registry.d.ts.map +0 -1
- package/dist/scene/geometry-registry.js +0 -20
- package/dist/scene/instance-registry.d.ts +0 -36
- package/dist/scene/instance-registry.d.ts.map +0 -1
- package/dist/scene/instance-registry.js +0 -55
- package/dist/scene/instancers/grid.d.ts +0 -2
- package/dist/scene/instancers/grid.d.ts.map +0 -1
- package/dist/scene/instancers/grid.js +0 -36
- package/dist/scene/instancers/index.d.ts +0 -8
- package/dist/scene/instancers/index.d.ts.map +0 -1
- package/dist/scene/instancers/index.js +0 -7
- package/dist/scene/light-camera-factory.d.ts +0 -23
- package/dist/scene/light-camera-factory.d.ts.map +0 -1
- package/dist/scene/light-camera-factory.js +0 -68
- package/dist/scene/material-factory.d.ts +0 -17
- package/dist/scene/material-factory.d.ts.map +0 -1
- package/dist/scene/material-factory.js +0 -197
- package/dist/scene/material-registry.d.ts +0 -40
- package/dist/scene/material-registry.d.ts.map +0 -1
- package/dist/scene/material-registry.js +0 -44
- package/dist/scene/materials/index.d.ts +0 -8
- package/dist/scene/materials/index.d.ts.map +0 -1
- package/dist/scene/materials/index.js +0 -7
- package/dist/scene/materials/water.d.ts +0 -2
- package/dist/scene/materials/water.d.ts.map +0 -1
- package/dist/scene/materials/water.js +0 -54
- package/dist/scene/parse.d.ts +0 -23
- package/dist/scene/parse.d.ts.map +0 -1
- package/dist/scene/parse.js +0 -179
- package/dist/scene/particles-factory.d.ts +0 -33
- package/dist/scene/particles-factory.d.ts.map +0 -1
- package/dist/scene/particles-factory.js +0 -282
- package/dist/scene/scene-apply.d.ts +0 -109
- package/dist/scene/scene-apply.d.ts.map +0 -1
- package/dist/scene/scene-apply.js +0 -370
- package/dist/scene/scene-diff-schema.d.ts +0 -285
- package/dist/scene/scene-diff-schema.d.ts.map +0 -1
- package/dist/scene/scene-diff-schema.js +0 -92
- package/dist/scene/scene-diff-types.d.ts +0 -40
- package/dist/scene/scene-diff-types.d.ts.map +0 -1
- package/dist/scene/scene-diff-types.js +0 -14
- package/dist/scene/scene-loader.d.ts +0 -167
- package/dist/scene/scene-loader.d.ts.map +0 -1
- package/dist/scene/scene-loader.js +0 -1211
- package/dist/scene/scene-query.d.ts +0 -11
- package/dist/scene/scene-query.d.ts.map +0 -1
- package/dist/scene/scene-query.js +0 -63
- package/dist/scene/scene-types.d.ts +0 -10
- package/dist/scene/scene-types.d.ts.map +0 -1
- package/dist/scene/scene-types.js +0 -8
- package/dist/scene/scene-version.d.ts +0 -26
- package/dist/scene/scene-version.d.ts.map +0 -1
- package/dist/scene/scene-version.js +0 -34
- package/dist/scene/schema/animation.d.ts +0 -8
- package/dist/scene/schema/animation.d.ts.map +0 -1
- package/dist/scene/schema/animation.js +0 -42
- package/dist/scene/schema/audio.d.ts +0 -13
- package/dist/scene/schema/audio.d.ts.map +0 -1
- package/dist/scene/schema/audio.js +0 -22
- package/dist/scene/schema/camera.d.ts +0 -28
- package/dist/scene/schema/camera.d.ts.map +0 -1
- package/dist/scene/schema/camera.js +0 -17
- package/dist/scene/schema/collider.d.ts +0 -40
- package/dist/scene/schema/collider.d.ts.map +0 -1
- package/dist/scene/schema/collider.js +0 -55
- package/dist/scene/schema/entity-ref.d.ts +0 -31
- package/dist/scene/schema/entity-ref.d.ts.map +0 -1
- package/dist/scene/schema/entity-ref.js +0 -61
- package/dist/scene/schema/entity.d.ts +0 -1036
- package/dist/scene/schema/entity.d.ts.map +0 -1
- package/dist/scene/schema/entity.js +0 -153
- package/dist/scene/schema/environment.d.ts +0 -425
- package/dist/scene/schema/environment.d.ts.map +0 -1
- package/dist/scene/schema/environment.js +0 -357
- package/dist/scene/schema/index.d.ts +0 -37
- package/dist/scene/schema/index.d.ts.map +0 -1
- package/dist/scene/schema/index.js +0 -19
- package/dist/scene/schema/instances.d.ts +0 -14
- package/dist/scene/schema/instances.d.ts.map +0 -1
- package/dist/scene/schema/instances.js +0 -28
- package/dist/scene/schema/joint.d.ts +0 -23
- package/dist/scene/schema/joint.d.ts.map +0 -1
- package/dist/scene/schema/joint.js +0 -23
- package/dist/scene/schema/light.d.ts +0 -38
- package/dist/scene/schema/light.d.ts.map +0 -1
- package/dist/scene/schema/light.js +0 -26
- package/dist/scene/schema/material.d.ts +0 -199
- package/dist/scene/schema/material.d.ts.map +0 -1
- package/dist/scene/schema/material.js +0 -103
- package/dist/scene/schema/mesh.d.ts +0 -48
- package/dist/scene/schema/mesh.d.ts.map +0 -1
- package/dist/scene/schema/mesh.js +0 -82
- package/dist/scene/schema/particles.d.ts +0 -2178
- package/dist/scene/schema/particles.d.ts.map +0 -1
- package/dist/scene/schema/particles.js +0 -321
- package/dist/scene/schema/physics.d.ts +0 -56
- package/dist/scene/schema/physics.d.ts.map +0 -1
- package/dist/scene/schema/physics.js +0 -37
- package/dist/scene/schema/scene-file.d.ts +0 -303
- package/dist/scene/schema/scene-file.d.ts.map +0 -1
- package/dist/scene/schema/scene-file.js +0 -256
- package/dist/scene/schema/shadow.d.ts +0 -28
- package/dist/scene/schema/shadow.d.ts.map +0 -1
- package/dist/scene/schema/shadow.js +0 -20
- package/dist/scene/schema/spline.d.ts +0 -25
- package/dist/scene/schema/spline.d.ts.map +0 -1
- package/dist/scene/schema/spline.js +0 -15
- package/dist/scene/schema/tuples.d.ts +0 -12
- package/dist/scene/schema/tuples.d.ts.map +0 -1
- package/dist/scene/schema/tuples.js +0 -14
- package/dist/scene/user-data.d.ts +0 -185
- package/dist/scene/user-data.d.ts.map +0 -1
- package/dist/scene/user-data.js +0 -144
- package/dist/setup/setup-audio.d.ts +0 -20
- package/dist/setup/setup-audio.d.ts.map +0 -1
- package/dist/setup/setup-audio.js +0 -41
- package/dist/setup/setup-particles.d.ts +0 -17
- package/dist/setup/setup-particles.d.ts.map +0 -1
- package/dist/setup/setup-particles.js +0 -16
- package/dist/setup/setup-physics.d.ts +0 -25
- package/dist/setup/setup-physics.d.ts.map +0 -1
- package/dist/setup/setup-physics.js +0 -51
- package/dist/setup/setup-renderer.d.ts +0 -69
- package/dist/setup/setup-renderer.d.ts.map +0 -1
- package/dist/setup/setup-renderer.js +0 -363
- package/dist/tools/define-tool.d.ts +0 -130
- package/dist/tools/define-tool.d.ts.map +0 -1
- package/dist/tools/define-tool.js +0 -96
- package/dist/world2d/authoring-2d.d.ts +0 -80
- package/dist/world2d/authoring-2d.d.ts.map +0 -1
- package/dist/world2d/authoring-2d.js +0 -195
- package/dist/world2d/capture-to-scene2d.d.ts +0 -5
- package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
- package/dist/world2d/capture-to-scene2d.js +0 -49
- package/dist/world2d/collision-2d.d.ts +0 -52
- package/dist/world2d/collision-2d.d.ts.map +0 -1
- package/dist/world2d/collision-2d.js +0 -70
- package/dist/world2d/components-2d.d.ts +0 -47
- package/dist/world2d/components-2d.d.ts.map +0 -1
- package/dist/world2d/components-2d.js +0 -77
- package/dist/world2d/index.d.ts +0 -34
- package/dist/world2d/index.d.ts.map +0 -1
- package/dist/world2d/index.js +0 -32
- package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
- package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
- package/dist/world2d/ingest-iframe-2d.js +0 -166
- package/dist/world2d/ingest2d.d.ts +0 -97
- package/dist/world2d/ingest2d.d.ts.map +0 -1
- package/dist/world2d/ingest2d.js +0 -40
- package/dist/world2d/physics2d-registry.d.ts +0 -24
- package/dist/world2d/physics2d-registry.d.ts.map +0 -1
- package/dist/world2d/physics2d-registry.js +0 -38
- package/dist/world2d/pixi-game-adapter.d.ts +0 -107
- package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
- package/dist/world2d/pixi-game-adapter.js +0 -210
- package/dist/world2d/pixi-surface.d.ts +0 -39
- package/dist/world2d/pixi-surface.d.ts.map +0 -1
- package/dist/world2d/pixi-surface.js +0 -47
- package/dist/world2d/scene-capture-2d.d.ts +0 -43
- package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
- package/dist/world2d/scene-capture-2d.js +0 -92
- package/dist/world2d/scene2d-loader.d.ts +0 -27
- package/dist/world2d/scene2d-loader.d.ts.map +0 -1
- package/dist/world2d/scene2d-loader.js +0 -275
- package/dist/world2d/schema/entity2d.d.ts +0 -102
- package/dist/world2d/schema/entity2d.d.ts.map +0 -1
- package/dist/world2d/schema/entity2d.js +0 -119
- package/dist/world2d/schema/physics2d.d.ts +0 -46
- package/dist/world2d/schema/physics2d.d.ts.map +0 -1
- package/dist/world2d/schema/physics2d.js +0 -45
- package/dist/world2d/schema/sprite.d.ts +0 -42
- package/dist/world2d/schema/sprite.d.ts.map +0 -1
- package/dist/world2d/schema/sprite.js +0 -63
- package/dist/world2d/schema/tilemap.d.ts +0 -15
- package/dist/world2d/schema/tilemap.d.ts.map +0 -1
- package/dist/world2d/schema/tilemap.js +0 -19
- package/dist/world2d/schema/tuples2d.d.ts +0 -20
- package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
- package/dist/world2d/schema/tuples2d.js +0 -19
- package/dist/world2d/system-adapters-2d.d.ts +0 -16
- package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
- package/dist/world2d/system-adapters-2d.js +0 -37
- package/dist/world2d/transform-writer-2d.d.ts +0 -16
- package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
- package/dist/world2d/transform-writer-2d.js +0 -22
- package/dist/world2d/types.d.ts +0 -59
- package/dist/world2d/types.d.ts.map +0 -1
- package/dist/world2d/types.js +0 -1
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Character primitive — Jolt soft-body cloth grids (capes, skirts, banners)
|
|
3
|
-
* on top of the raw `jolt-physics` WASM bindings.
|
|
4
|
-
*
|
|
5
|
-
* THIN COMPOSITION HELPER, not a wrapper (CLAUDE.md "use libraries
|
|
6
|
-
* directly"): every export assembles the library's own objects
|
|
7
|
-
* (`Jolt.SoftBodySharedSettings`, `Jolt.Body`, `Jolt.JoltInterface`) —
|
|
8
|
-
* nothing from the library is re-exported. This file never imports the WASM
|
|
9
|
-
* module itself — the caller does the async `JoltInit()` and passes the
|
|
10
|
-
* resolved module in, mirroring `setup-physics.ts`'s `setupPhysics(rapier:
|
|
11
|
-
* typeof RAPIER, ...)` pattern for Rapier. `import type Jolt from
|
|
12
|
-
* 'jolt-physics/wasm-compat'` below is TYPE-ONLY (erased at compile time —
|
|
13
|
-
* no runtime WASM import here).
|
|
14
|
-
*
|
|
15
|
-
* Sharp edges this module exists partly to contain (see the mission brief /
|
|
16
|
-
* `cloth-hair-bench/jolt-cloth.ts`'s header for the full discovery):
|
|
17
|
-
* - `Body.GetMotionProperties()` needs the `Jolt.castObject` downcast to
|
|
18
|
-
* `Jolt.SoftBodyMotionProperties` to reach `GetVertex`.
|
|
19
|
-
* - `SoftBodySharedSettings.CreateConstraints` takes a POINTER-typed
|
|
20
|
-
* 1-element `ArraySoftBodySharedSettingsVertexAttributes` (push_back,
|
|
21
|
-
* not resize+at — `.at()` on these embind vectors returns a copy).
|
|
22
|
-
* - Kinematic pins must set BOTH `SoftBodyVertex.mPosition` and
|
|
23
|
-
* `.mVelocity` (finite-differenced) every tick, or the cloth's own
|
|
24
|
-
* constraint solver fights a teleporting anchor.
|
|
25
|
-
* - NO per-frame embind allocations (reviewer finding on Phase 1's
|
|
26
|
-
* spike, which leaked a `new Jolt.Vec3(...)`/`new Jolt.RVec3(...)` per
|
|
27
|
-
* pinned vertex per frame): `tick()` below preallocates ONE `Jolt.Vec3`
|
|
28
|
-
* for position and ONE for velocity and reuses them via `.Set(...)` —
|
|
29
|
-
* embind property setters (`vertex.mPosition = tmpVec3`) copy the value
|
|
30
|
-
* in, so reassigning the SAME wrapper object across many vertices in one
|
|
31
|
-
* frame is safe. `KinematicCollider.moveTo` does the same with one
|
|
32
|
-
* `Jolt.RVec3` + one `Jolt.Quat` (identity, orientation is not simulated
|
|
33
|
-
* here) allocated once at construction.
|
|
34
|
-
* - CONSTRUCTION-TIME embind temporaries need `Jolt.destroy(...)` too, once
|
|
35
|
-
* Jolt has copied their data out (reviewer finding on Phase 2 — these
|
|
36
|
-
* were leaking WASM heap per build/dispose cycle even with `tick()`
|
|
37
|
-
* itself allocation-free). Two different lifetimes are at play:
|
|
38
|
-
* - Per-vertex/per-face grid temporaries (`SoftBodySharedSettingsVertex`
|
|
39
|
-
* + its `Float3`, `SoftBodySharedSettingsFace`, the single
|
|
40
|
-
* `vertexAttr`) are copied BY VALUE into `sharedSettings`'s own
|
|
41
|
-
* storage the instant `push_back`/the property setter runs — freed
|
|
42
|
-
* right there, matching the reuse-then-`Jolt.destroy()`-once pattern
|
|
43
|
-
* in Jolt's own `soft-body-creator.js` sample. `bodyCreation`
|
|
44
|
-
* (`SoftBodyCreationSettings`) is the same story: `CreateSoftBody`
|
|
45
|
-
* copies what it needs, so it's freed right after — same contract as
|
|
46
|
-
* `JoltSettings` → `JoltInterface` below.
|
|
47
|
-
* - `sharedSettings` itself (`SoftBodySharedSettings`) is different: it
|
|
48
|
-
* is REFCOUNTED (`AddRef`/`Release`/`GetRefCount` in the vendored
|
|
49
|
-
* typings, like `Shape`) and the body reads it every step
|
|
50
|
-
* (`SoftBodyMotionProperties.GetSettings()`) for face/constraint
|
|
51
|
-
* topology. Refcounted RefTargets are freed BY JOLT ITSELF when the
|
|
52
|
-
* last reference drops (Release of the final ref IS the delete) —
|
|
53
|
-
* so it gets NO explicit `Jolt.destroy(...)` at all: destroying
|
|
54
|
-
* `bodyCreation` releases the ctor's ref, and `dispose()`'s
|
|
55
|
-
* `DestroyBody` releases the body's (last) ref, which deletes it.
|
|
56
|
-
* An explicit destroy on top would be a use-after-free (empirically
|
|
57
|
-
* confirmed with a `GetRefCount()` probe against real Jolt WASM).
|
|
58
|
-
* Same rule for the collider's `Shape`: `destroy(creation)` releases
|
|
59
|
-
* the creation-settings ref, `DestroyBody` releases the body's —
|
|
60
|
-
* never destroy the shape directly.
|
|
61
|
-
* - The preallocated tick-loop temporaries described above (`tmpPos`/
|
|
62
|
-
* `tmpVel` in `buildClothGrid`, `tmpPos`/`identityQuat` in
|
|
63
|
-
* `buildKinematicCollider`) are plain (non-refcounted) `Vec3`/`RVec3`/
|
|
64
|
-
* `Quat` wrappers reused for the object's whole lifetime — freed in that
|
|
65
|
-
* object's own `dispose()`.
|
|
66
|
-
*/
|
|
67
|
-
import * as THREE from 'three';
|
|
68
|
-
const LAYER_NON_MOVING = 0;
|
|
69
|
-
const LAYER_MOVING = 1;
|
|
70
|
-
const NUM_OBJECT_LAYERS = 2;
|
|
71
|
-
const NUM_BROAD_PHASE_LAYERS = 2;
|
|
72
|
-
export function createJoltWorld(jolt, options = {}) {
|
|
73
|
-
const gravity = options.gravity ?? { x: 0, y: -9.81, z: 0 };
|
|
74
|
-
const collisionSteps = options.collisionSteps ?? 1;
|
|
75
|
-
const objectFilter = new jolt.ObjectLayerPairFilterTable(NUM_OBJECT_LAYERS);
|
|
76
|
-
objectFilter.EnableCollision(LAYER_MOVING, LAYER_MOVING);
|
|
77
|
-
const bpInterface = new jolt.BroadPhaseLayerInterfaceTable(NUM_OBJECT_LAYERS, NUM_BROAD_PHASE_LAYERS);
|
|
78
|
-
bpInterface.MapObjectToBroadPhaseLayer(LAYER_NON_MOVING, new jolt.BroadPhaseLayer(LAYER_NON_MOVING));
|
|
79
|
-
bpInterface.MapObjectToBroadPhaseLayer(LAYER_MOVING, new jolt.BroadPhaseLayer(LAYER_MOVING));
|
|
80
|
-
const settings = new jolt.JoltSettings();
|
|
81
|
-
settings.mObjectLayerPairFilter = objectFilter;
|
|
82
|
-
settings.mBroadPhaseLayerInterface = bpInterface;
|
|
83
|
-
settings.mObjectVsBroadPhaseLayerFilter = new jolt.ObjectVsBroadPhaseLayerFilterTable(bpInterface, NUM_BROAD_PHASE_LAYERS, objectFilter, NUM_OBJECT_LAYERS);
|
|
84
|
-
const joltInterface = new jolt.JoltInterface(settings);
|
|
85
|
-
jolt.destroy(settings);
|
|
86
|
-
const physicsSystem = joltInterface.GetPhysicsSystem();
|
|
87
|
-
physicsSystem.SetGravity(new jolt.Vec3(gravity.x, gravity.y, gravity.z));
|
|
88
|
-
const bodyInterface = physicsSystem.GetBodyInterface();
|
|
89
|
-
return {
|
|
90
|
-
jolt,
|
|
91
|
-
joltInterface,
|
|
92
|
-
physicsSystem,
|
|
93
|
-
bodyInterface,
|
|
94
|
-
movingLayer: LAYER_MOVING,
|
|
95
|
-
step(dt) {
|
|
96
|
-
joltInterface.Step(dt, collisionSteps);
|
|
97
|
-
},
|
|
98
|
-
dispose() {
|
|
99
|
-
jolt.destroy(joltInterface);
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
export function buildKinematicCollider(world, shape) {
|
|
104
|
-
const { jolt, bodyInterface } = world;
|
|
105
|
-
const joltShape = shape.kind === 'sphere'
|
|
106
|
-
? new jolt.SphereShape(shape.radius)
|
|
107
|
-
: new jolt.CapsuleShape(shape.halfHeight, shape.radius);
|
|
108
|
-
const creation = new jolt.BodyCreationSettings(joltShape, new jolt.RVec3(0, 0, 0), new jolt.Quat(0, 0, 0, 1), jolt.EMotionType_Kinematic, world.movingLayer);
|
|
109
|
-
// A per-tick-driven kinematic collider must NEVER sleep: Jolt puts a
|
|
110
|
-
// near-zero-velocity kinematic body to sleep after ~0.5 s, and
|
|
111
|
-
// `Body.MoveKinematic` (unlike the BodyInterface variant) does NOT wake
|
|
112
|
-
// it — after any brief stillness (e.g. a garment-settle warm-up) the
|
|
113
|
-
// collider would silently freeze at its old pose FOREVER while the
|
|
114
|
-
// character walks away (observed live: the whole cape sailed through the
|
|
115
|
-
// torso and every contact-robustness knob was powerless against it).
|
|
116
|
-
creation.mAllowSleeping = false;
|
|
117
|
-
const body = bodyInterface.CreateBody(creation);
|
|
118
|
-
bodyInterface.AddBody(body.GetID(), jolt.EActivation_Activate);
|
|
119
|
-
// `CreateBody` copied what it needs — free the one-shot settings struct
|
|
120
|
-
// now (same contract as `SoftBodyCreationSettings` in `buildClothGrid`).
|
|
121
|
-
// This also releases `creation`'s reference on the REFCOUNTED `joltShape`;
|
|
122
|
-
// the body holds the remaining shape ref, so `joltShape` must NOT get a
|
|
123
|
-
// `jolt.destroy` anywhere — `DestroyBody` in `dispose()` releases that
|
|
124
|
-
// last ref and Jolt deletes the shape itself (see module header).
|
|
125
|
-
jolt.destroy(creation);
|
|
126
|
-
// Preallocated once, reused every `moveTo` call — see module header.
|
|
127
|
-
const tmpPos = new jolt.RVec3(0, 0, 0);
|
|
128
|
-
const identityQuat = new jolt.Quat(0, 0, 0, 1);
|
|
129
|
-
return {
|
|
130
|
-
body,
|
|
131
|
-
moveTo(worldPos, dt) {
|
|
132
|
-
tmpPos.Set(worldPos.x, worldPos.y, worldPos.z);
|
|
133
|
-
body.MoveKinematic(tmpPos, identityQuat, dt);
|
|
134
|
-
},
|
|
135
|
-
dispose() {
|
|
136
|
-
bodyInterface.RemoveBody(body.GetID());
|
|
137
|
-
bodyInterface.DestroyBody(body.GetID());
|
|
138
|
-
jolt.destroy(tmpPos);
|
|
139
|
-
jolt.destroy(identityQuat);
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
/** Build the `SoftBodySharedSettings` (vertex grid + face list + edge/shear/
|
|
144
|
-
* bend constraints) for a `cols`x`rows` cloth. Split out of `buildClothGrid`
|
|
145
|
-
* purely to keep that function's complexity down — not reused elsewhere. */
|
|
146
|
-
function buildSoftBodySharedSettings(jolt, options, pins, idx) {
|
|
147
|
-
const { cols, rows } = options;
|
|
148
|
-
const vertexMassKg = options.vertexMassKg ?? 0.02;
|
|
149
|
-
const pinSet = new Set(pins.map((p) => idx(p.row, p.col)));
|
|
150
|
-
const sharedSettings = new jolt.SoftBodySharedSettings();
|
|
151
|
-
const vertices = sharedSettings.mVertices;
|
|
152
|
-
for (let row = 0; row < rows; row++) {
|
|
153
|
-
for (let col = 0; col < cols; col++) {
|
|
154
|
-
const p = options.restPosition(row, col);
|
|
155
|
-
const v = new jolt.SoftBodySharedSettingsVertex();
|
|
156
|
-
const pos = new jolt.Float3(p.x, p.y, p.z);
|
|
157
|
-
v.mPosition = pos;
|
|
158
|
-
v.mInvMass = pinSet.has(idx(row, col)) ? 0 : 1 / vertexMassKg;
|
|
159
|
-
vertices.push_back(v);
|
|
160
|
-
// `push_back` (like the property-setter assignment above it) copies
|
|
161
|
-
// BY VALUE into `sharedSettings`'s own storage — Jolt's own
|
|
162
|
-
// `soft-body-creator.js` sample reuses/destroys a single `v` the same
|
|
163
|
-
// way across its whole grid loop — so both temporaries are safe to
|
|
164
|
-
// free the instant the copy has happened.
|
|
165
|
-
jolt.destroy(pos);
|
|
166
|
-
jolt.destroy(v);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
sharedSettings.mVertices = vertices;
|
|
170
|
-
const faces = sharedSettings.mFaces;
|
|
171
|
-
for (let row = 0; row < rows - 1; row++) {
|
|
172
|
-
for (let col = 0; col < cols - 1; col++) {
|
|
173
|
-
const faceA = new jolt.SoftBodySharedSettingsFace(idx(row, col), idx(row + 1, col), idx(row, col + 1), 0);
|
|
174
|
-
faces.push_back(faceA);
|
|
175
|
-
jolt.destroy(faceA);
|
|
176
|
-
const faceB = new jolt.SoftBodySharedSettingsFace(idx(row, col + 1), idx(row + 1, col), idx(row + 1, col + 1), 0);
|
|
177
|
-
faces.push_back(faceB);
|
|
178
|
-
jolt.destroy(faceB);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
sharedSettings.mFaces = faces;
|
|
182
|
-
const vertexAttr = new jolt.SoftBodySharedSettingsVertexAttributes();
|
|
183
|
-
vertexAttr.mCompliance = options.compliance ?? 0.0002;
|
|
184
|
-
vertexAttr.mShearCompliance = options.shearCompliance ?? 0.0002;
|
|
185
|
-
vertexAttr.mBendCompliance = options.bendCompliance ?? 0.002;
|
|
186
|
-
const vertexAttrArr = new jolt.ArraySoftBodySharedSettingsVertexAttributes();
|
|
187
|
-
vertexAttrArr.push_back(vertexAttr);
|
|
188
|
-
// Same value-copy-then-free story as above: `CreateConstraints` below
|
|
189
|
-
// reads from `vertexAttrArr`'s OWN backing copy (via `.data()`), not this
|
|
190
|
-
// original wrapper, so it's safe to free right after the push_back.
|
|
191
|
-
jolt.destroy(vertexAttr);
|
|
192
|
-
sharedSettings.CreateConstraints(vertexAttrArr.data(), vertexAttrArr.size(), jolt.SoftBodySharedSettings_EBendType_Distance);
|
|
193
|
-
sharedSettings.Optimize();
|
|
194
|
-
jolt.destroy(vertexAttrArr);
|
|
195
|
-
return sharedSettings;
|
|
196
|
-
}
|
|
197
|
-
/** Build the renderable (non-skinned) mesh: a plain `BufferGeometry` whose
|
|
198
|
-
* `position` attribute `ClothGrid.tick` overwrites every frame. */
|
|
199
|
-
function buildClothMesh(scene, options, idx) {
|
|
200
|
-
const { cols, rows } = options;
|
|
201
|
-
const geometry = new THREE.BufferGeometry();
|
|
202
|
-
const positionAttr = new THREE.BufferAttribute(new Float32Array(rows * cols * 3), 3);
|
|
203
|
-
positionAttr.setUsage(THREE.DynamicDrawUsage);
|
|
204
|
-
geometry.setAttribute('position', positionAttr);
|
|
205
|
-
const indices = [];
|
|
206
|
-
for (let row = 0; row < rows - 1; row++) {
|
|
207
|
-
for (let col = 0; col < cols - 1; col++) {
|
|
208
|
-
indices.push(idx(row, col), idx(row + 1, col), idx(row, col + 1));
|
|
209
|
-
indices.push(idx(row, col + 1), idx(row + 1, col), idx(row + 1, col + 1));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
geometry.setIndex(indices);
|
|
213
|
-
const material = new THREE.MeshStandardMaterial({
|
|
214
|
-
color: options.color ?? 0x7a2f3a,
|
|
215
|
-
roughness: 0.85,
|
|
216
|
-
side: options.doubleSided === false ? THREE.FrontSide : THREE.DoubleSide,
|
|
217
|
-
});
|
|
218
|
-
const mesh = new THREE.Mesh(geometry, material);
|
|
219
|
-
mesh.castShadow = true;
|
|
220
|
-
mesh.frustumCulled = false;
|
|
221
|
-
scene.add(mesh);
|
|
222
|
-
return { mesh, geometry, positionAttr, material };
|
|
223
|
-
}
|
|
224
|
-
export function buildClothGrid(world, scene, options) {
|
|
225
|
-
const { jolt, bodyInterface } = world;
|
|
226
|
-
const { cols, rows } = options;
|
|
227
|
-
const pins = options.pins ?? Array.from({ length: cols }, (_, col) => ({ row: 0, col }));
|
|
228
|
-
const idx = (row, col) => row * cols + col;
|
|
229
|
-
const sharedSettings = buildSoftBodySharedSettings(jolt, options, pins, idx);
|
|
230
|
-
const bodyCreation = new jolt.SoftBodyCreationSettings(sharedSettings, new jolt.RVec3(0, 0, 0), new jolt.Quat(0, 0, 0, 1), world.movingLayer);
|
|
231
|
-
bodyCreation.mNumIterations = options.numIterations ?? 4;
|
|
232
|
-
if (options.vertexRadius !== undefined)
|
|
233
|
-
bodyCreation.mVertexRadius = options.vertexRadius;
|
|
234
|
-
if (options.linearDamping !== undefined)
|
|
235
|
-
bodyCreation.mLinearDamping = options.linearDamping;
|
|
236
|
-
bodyCreation.mPressure = 0;
|
|
237
|
-
bodyCreation.mGravityFactor = options.gravityFactor ?? 1;
|
|
238
|
-
bodyCreation.mFacesDoubleSided = true;
|
|
239
|
-
bodyCreation.mUpdatePosition = false;
|
|
240
|
-
// Kinematically-pinned cloth must never sleep either: `tick()` drives the
|
|
241
|
-
// pins by writing `SoftBodyVertex.mPosition/.mVelocity` DIRECTLY, which
|
|
242
|
-
// does not count as activity — a cape that settles still for ~0.5 s would
|
|
243
|
-
// sleep and stay frozen while its pins walk away.
|
|
244
|
-
bodyCreation.mAllowSleeping = false;
|
|
245
|
-
const clothBody = bodyInterface.CreateSoftBody(bodyCreation);
|
|
246
|
-
bodyInterface.AddBody(clothBody.GetID(), jolt.EActivation_Activate);
|
|
247
|
-
// `CreateSoftBody` copies what it needs out of `bodyCreation` into the
|
|
248
|
-
// body's own storage (same "settings object is a one-shot constructor
|
|
249
|
-
// argument" contract as `JoltSettings` → `JoltInterface` above) — safe to
|
|
250
|
-
// free right away, same as that pattern. `bodyCreation` itself is a plain
|
|
251
|
-
// (non-refcounted) settings struct, unlike `sharedSettings` below: freeing
|
|
252
|
-
// it here still correctly releases bodyCreation's OWN internal reference
|
|
253
|
-
// to `sharedSettings` (which the body has, by now, separately taken its
|
|
254
|
-
// own reference to via `CreateSoftBody`).
|
|
255
|
-
jolt.destroy(bodyCreation);
|
|
256
|
-
// `Body` only exposes the base `GetMotionProperties()`; soft bodies need
|
|
257
|
-
// the downcast to reach `GetVertex`/`GetVertices`.
|
|
258
|
-
const motionProperties = jolt.castObject(clothBody.GetMotionProperties(), jolt.SoftBodyMotionProperties);
|
|
259
|
-
const { mesh, geometry, positionAttr, material } = buildClothMesh(scene, options, idx);
|
|
260
|
-
// Preallocated tick-loop temporaries — see module header.
|
|
261
|
-
const tmpPos = new jolt.Vec3(0, 0, 0);
|
|
262
|
-
const tmpVel = new jolt.Vec3(0, 0, 0);
|
|
263
|
-
const prevPinWorld = pins.map((p) => options.restPosition(p.row, p.col));
|
|
264
|
-
return {
|
|
265
|
-
cols,
|
|
266
|
-
rows,
|
|
267
|
-
vertexCount: rows * cols,
|
|
268
|
-
pins,
|
|
269
|
-
mesh,
|
|
270
|
-
geometry,
|
|
271
|
-
tick(dt, pinTargets) {
|
|
272
|
-
for (let i = 0; i < pins.length; i++) {
|
|
273
|
-
const target = pinTargets[i];
|
|
274
|
-
if (!target)
|
|
275
|
-
continue;
|
|
276
|
-
const pin = pins[i];
|
|
277
|
-
const prev = prevPinWorld[i];
|
|
278
|
-
const vertex = motionProperties.GetVertex(idx(pin.row, pin.col));
|
|
279
|
-
tmpPos.Set(target.x, target.y, target.z);
|
|
280
|
-
vertex.mPosition = tmpPos;
|
|
281
|
-
if (dt > 0) {
|
|
282
|
-
tmpVel.Set((target.x - prev.x) / dt, (target.y - prev.y) / dt, (target.z - prev.z) / dt);
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
tmpVel.Set(0, 0, 0);
|
|
286
|
-
}
|
|
287
|
-
vertex.mVelocity = tmpVel;
|
|
288
|
-
prev.copy(target);
|
|
289
|
-
}
|
|
290
|
-
world.step(dt);
|
|
291
|
-
const posArr = positionAttr.array;
|
|
292
|
-
for (let i = 0; i < rows * cols; i++) {
|
|
293
|
-
const v = motionProperties.GetVertex(i);
|
|
294
|
-
const p = v.mPosition;
|
|
295
|
-
posArr[i * 3] = p.GetX();
|
|
296
|
-
posArr[i * 3 + 1] = p.GetY();
|
|
297
|
-
posArr[i * 3 + 2] = p.GetZ();
|
|
298
|
-
}
|
|
299
|
-
positionAttr.needsUpdate = true;
|
|
300
|
-
geometry.computeVertexNormals();
|
|
301
|
-
},
|
|
302
|
-
samplePoints(out = []) {
|
|
303
|
-
const n = rows * cols;
|
|
304
|
-
out.length = n;
|
|
305
|
-
for (let i = 0; i < n; i++) {
|
|
306
|
-
const v = motionProperties.GetVertex(i);
|
|
307
|
-
const p = v.mPosition;
|
|
308
|
-
if (!out[i])
|
|
309
|
-
out[i] = new THREE.Vector3();
|
|
310
|
-
out[i].set(p.GetX(), p.GetY(), p.GetZ());
|
|
311
|
-
}
|
|
312
|
-
return out;
|
|
313
|
-
},
|
|
314
|
-
dispose() {
|
|
315
|
-
bodyInterface.RemoveBody(clothBody.GetID());
|
|
316
|
-
// NO explicit `jolt.destroy(sharedSettings)` — anywhere. It is a
|
|
317
|
-
// refcounted RefTarget that Jolt frees ITSELF when its last reference
|
|
318
|
-
// drops, and in Jolt's RefTarget::Release releasing the last ref IS
|
|
319
|
-
// the delete. Refcount chain, probed live against real Jolt WASM via
|
|
320
|
-
// `GetRefCount()`: 0 after `new` → 1 after the
|
|
321
|
-
// `SoftBodyCreationSettings` ctor took its ref → 2 after
|
|
322
|
-
// `CreateSoftBody` (the body's own ref) → back to 1 after the
|
|
323
|
-
// construction-time `destroy(bodyCreation)` → `DestroyBody` below
|
|
324
|
-
// releases that last (body) reference and thereby deletes it. Any
|
|
325
|
-
// `destroy(sharedSettings)` after this line would be a use-after-free.
|
|
326
|
-
bodyInterface.DestroyBody(clothBody.GetID());
|
|
327
|
-
jolt.destroy(tmpPos);
|
|
328
|
-
jolt.destroy(tmpVel);
|
|
329
|
-
scene.remove(mesh);
|
|
330
|
-
geometry.dispose();
|
|
331
|
-
material.dispose();
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Character primitive — spring-bone chains (hair, ponytails, cloth strips)
|
|
3
|
-
* on top of `@pixiv/three-vrm-springbone`'s raw API.
|
|
4
|
-
*
|
|
5
|
-
* This is a THIN COMPOSITION HELPER, not a wrapper (CLAUDE.md "use libraries
|
|
6
|
-
* directly"): every export here is a small function that assembles the
|
|
7
|
-
* library's own objects (`THREE.Bone`, `VRMSpringBoneJoint`,
|
|
8
|
-
* `VRMSpringBoneCollider`, `VRMSpringBoneManager`) — nothing from the
|
|
9
|
-
* library is re-exported, and callers still import `@pixiv/three-vrm-
|
|
10
|
-
* springbone` types directly for anything beyond what's here. Kept
|
|
11
|
-
* deliberately bare: composing a specific character (a caped viking, a
|
|
12
|
-
* ponytailed ranger) is ordinary calling code on top of these pieces, not a
|
|
13
|
-
* costume/preset system in the engine.
|
|
14
|
-
*
|
|
15
|
-
* Sharp edge this module exists partly to contain (see the mission brief /
|
|
16
|
-
* `cloth-hair-bench/spring-rig.ts`'s header for the full discovery):
|
|
17
|
-
* `VRMSpringBoneCollider` overrides `updateWorldMatrix` (the ON-DEMAND,
|
|
18
|
-
* manually-invoked method), NOT `updateMatrixWorld` (the one the renderer
|
|
19
|
-
* calls automatically) — `SpringColliderRig.reposition()` below calls
|
|
20
|
-
* `collider.updateWorldMatrix(true, false)` itself every tick so callers
|
|
21
|
-
* can't forget it.
|
|
22
|
-
*/
|
|
23
|
-
import { VRMSpringBoneCollider, type VRMSpringBoneColliderGroup, VRMSpringBoneJoint, VRMSpringBoneManager } from '@pixiv/three-vrm-springbone';
|
|
24
|
-
import * as THREE from 'three';
|
|
25
|
-
export interface BoneChain {
|
|
26
|
-
/** Swinging bones, root (nearest the anchor) first. */
|
|
27
|
-
bones: THREE.Bone[];
|
|
28
|
-
/** A non-simulated leaf `Object3D` past the last bone — the spring joint
|
|
29
|
-
* "tail" target for the last bone in the chain. */
|
|
30
|
-
tip: THREE.Object3D;
|
|
31
|
-
}
|
|
32
|
-
/** World-space offset from `parent`'s CURRENT world position -> the local
|
|
33
|
-
* position a new direct child of `parent` must have to sit there. Requires
|
|
34
|
-
* `parent.matrixWorld` to be current. Sidesteps ever reasoning about a
|
|
35
|
-
* bone's local rest-axis convention (arbitrary per-bone on an imported
|
|
36
|
-
* rig) — the caller only ever thinks in world-space directions. */
|
|
37
|
-
export declare function worldOffsetToLocalPos(parent: THREE.Object3D, worldDir: THREE.Vector3, length: number): THREE.Vector3;
|
|
38
|
-
/** Build a straight chain of `count` new `THREE.Bone`s under `parent`, each
|
|
39
|
-
* offset `segmentLength` further along the WORLD-space unit vector
|
|
40
|
-
* `worldDir` — the natural rest shape for hair/cloth hanging under gravity.
|
|
41
|
-
* Ends with a `tip` `Object3D` (one more segment past the last bone) so
|
|
42
|
-
* every bone has an explicit spring-joint child target. Can be anchored to
|
|
43
|
-
* either an existing rig bone (hair off a head) or any plain `Object3D`. */
|
|
44
|
-
export declare function buildBoneChain(parent: THREE.Object3D, namePrefix: string, count: number, segmentLength: number, worldDir: THREE.Vector3): BoneChain;
|
|
45
|
-
export interface ChainJointSettings {
|
|
46
|
-
stiffness?: number;
|
|
47
|
-
gravityPower?: number;
|
|
48
|
-
gravityDir?: THREE.Vector3;
|
|
49
|
-
dragForce?: number;
|
|
50
|
-
hitRadius?: number;
|
|
51
|
-
}
|
|
52
|
-
export interface ChainJointHandle {
|
|
53
|
-
joints: VRMSpringBoneJoint[];
|
|
54
|
-
/** Deregisters every joint this chain added from `manager`. Does NOT
|
|
55
|
-
* detach the bones from the scene graph (the caller owns that). */
|
|
56
|
-
dispose(): void;
|
|
57
|
-
}
|
|
58
|
-
/** Register one `VRMSpringBoneJoint` per bone in `chain` on `manager` (each
|
|
59
|
-
* targeting the next bone, the last targeting `chain.tip`). Does not call
|
|
60
|
-
* `manager.setInitState()` — batch that once after all chains for a
|
|
61
|
-
* manager are registered and the scene's world matrices are current (sharp
|
|
62
|
-
* edge: `VRMSpringBoneJoint` sets `bone.matrixAutoUpdate = false`, so
|
|
63
|
-
* `setInitState()` must run AFTER `scene.updateMatrixWorld(true)`). */
|
|
64
|
-
export declare function registerChainJoints(manager: VRMSpringBoneManager, chain: BoneChain, colliderGroups: VRMSpringBoneColliderGroup[], settings?: ChainJointSettings): ChainJointHandle;
|
|
65
|
-
export interface SphereColliderDef {
|
|
66
|
-
shape: 'sphere';
|
|
67
|
-
name: string;
|
|
68
|
-
/** The collider tracks this object's world position every `reposition()`. */
|
|
69
|
-
followBone: THREE.Object3D;
|
|
70
|
-
radius: number;
|
|
71
|
-
/** Extra WORLD-space offset added after sampling `followBone`'s position
|
|
72
|
-
* (e.g. nudging a head collider up from the neck joint). */
|
|
73
|
-
worldOffset?: THREE.Vector3;
|
|
74
|
-
}
|
|
75
|
-
export interface CapsuleColliderDef {
|
|
76
|
-
shape: 'capsule';
|
|
77
|
-
name: string;
|
|
78
|
-
followBone: THREE.Object3D;
|
|
79
|
-
radius: number;
|
|
80
|
-
/** Capsule tail, in the collider's own local space (world-axis-aligned —
|
|
81
|
-
* colliders are parented directly to the scene, see `buildSpringColliderRig`). */
|
|
82
|
-
tail: THREE.Vector3;
|
|
83
|
-
worldOffset?: THREE.Vector3;
|
|
84
|
-
}
|
|
85
|
-
export type ColliderDef = SphereColliderDef | CapsuleColliderDef;
|
|
86
|
-
export interface SpringColliderRig {
|
|
87
|
-
group: VRMSpringBoneColliderGroup;
|
|
88
|
-
colliders: Map<string, VRMSpringBoneCollider>;
|
|
89
|
-
/** Reposition every collider from its `followBone`'s CURRENT world
|
|
90
|
-
* transform and refresh its `colliderMatrix` (see module header). Call
|
|
91
|
-
* once per tick, BEFORE `manager.update(dt)`. */
|
|
92
|
-
reposition(): void;
|
|
93
|
-
dispose(): void;
|
|
94
|
-
}
|
|
95
|
-
/** Build sphere/capsule colliders parented directly to `scene` (world
|
|
96
|
-
* space) — sidesteps reasoning about any bone's local rest-axis convention
|
|
97
|
-
* for the collider shape's offset/tail vectors. */
|
|
98
|
-
export declare function buildSpringColliderRig(scene: THREE.Scene, defs: ColliderDef[]): SpringColliderRig;
|
|
99
|
-
export interface SpringChainRigOptions {
|
|
100
|
-
parent: THREE.Object3D;
|
|
101
|
-
namePrefix: string;
|
|
102
|
-
count: number;
|
|
103
|
-
segmentLength: number;
|
|
104
|
-
worldDir: THREE.Vector3;
|
|
105
|
-
/** Colliders this chain collides against. Omit for a chain with no
|
|
106
|
-
* collision (e.g. a side strand tucked away from the body). */
|
|
107
|
-
colliderRig?: SpringColliderRig;
|
|
108
|
-
settings?: ChainJointSettings;
|
|
109
|
-
}
|
|
110
|
-
export interface SpringChainRig {
|
|
111
|
-
bones: THREE.Bone[];
|
|
112
|
-
tip: THREE.Object3D;
|
|
113
|
-
/** The manager owning this chain's joints — a "manager-compatible handle"
|
|
114
|
-
* a caller can also register additional joints on directly. */
|
|
115
|
-
manager: VRMSpringBoneManager;
|
|
116
|
-
/** Repositions `colliderRig` (if given) and steps the spring simulation.
|
|
117
|
-
* Handles the collider `updateWorldMatrix` footgun internally — callers
|
|
118
|
-
* never need to call `collider.updateWorldMatrix` themselves. */
|
|
119
|
-
tick(dt: number): void;
|
|
120
|
-
dispose(): void;
|
|
121
|
-
}
|
|
122
|
-
/** Compose `buildBoneChain` + `registerChainJoints` behind one call for the
|
|
123
|
-
* common single-chain case: builds the chain, gives it its OWN
|
|
124
|
-
* `VRMSpringBoneManager` (managers are cheap — one per independent chain
|
|
125
|
-
* keeps `dispose()`/`tick()` fully self-contained), registers its joints,
|
|
126
|
-
* and calls `setInitState()` once construction is complete.
|
|
127
|
-
*
|
|
128
|
-
* For MULTIPLE chains sharing one collider rig (e.g. a ponytail + two side
|
|
129
|
-
* strands all colliding against the same head), build each chain with its
|
|
130
|
-
* own `buildSpringChainRig` call (same `colliderRig` passed to each) and
|
|
131
|
-
* tick all of them — `colliderRig.reposition()` is idempotent per frame, so
|
|
132
|
-
* calling it once per chain tick is correct, just slightly redundant work
|
|
133
|
-
* (cheap: it only touches a handful of colliders). */
|
|
134
|
-
export declare function buildSpringChainRig(options: SpringChainRigOptions): SpringChainRig;
|
|
135
|
-
//# sourceMappingURL=spring-chain.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spring-chain.d.ts","sourceRoot":"","sources":["../../src/character/spring-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAG/B,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB;wDACoD;IACpD,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC;CACrB;AAED;;;;oEAIoE;AACpE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,CAAC,QAAQ,EACtB,QAAQ,EAAE,KAAK,CAAC,OAAO,EACvB,MAAM,EAAE,MAAM,GACb,KAAK,CAAC,OAAO,CAKf;AAED;;;;;6EAK6E;AAC7E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,KAAK,CAAC,QAAQ,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,KAAK,CAAC,OAAO,GACtB,SAAS,CAmBX;AAMD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B;wEACoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;wEAKwE;AACxE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,0BAA0B,EAAE,EAC5C,QAAQ,GAAE,kBAAuB,GAChC,gBAAgB,CA0BlB;AAMD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf;iEAC6D;IAC7D,WAAW,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf;uFACmF;IACnF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,0BAA0B,CAAC;IAClC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC9C;;sDAEkD;IAClD,UAAU,IAAI,IAAI,CAAC;IACnB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;oDAEoD;AACpD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,iBAAiB,CA0CjG;AAMD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;IACxB;oEACgE;IAChE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC;IACpB;oEACgE;IAChE,OAAO,EAAE,oBAAoB,CAAC;IAC9B;;sEAEkE;IAClE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;uDAWuD;AACvD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CA0BlF"}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Character primitive — spring-bone chains (hair, ponytails, cloth strips)
|
|
3
|
-
* on top of `@pixiv/three-vrm-springbone`'s raw API.
|
|
4
|
-
*
|
|
5
|
-
* This is a THIN COMPOSITION HELPER, not a wrapper (CLAUDE.md "use libraries
|
|
6
|
-
* directly"): every export here is a small function that assembles the
|
|
7
|
-
* library's own objects (`THREE.Bone`, `VRMSpringBoneJoint`,
|
|
8
|
-
* `VRMSpringBoneCollider`, `VRMSpringBoneManager`) — nothing from the
|
|
9
|
-
* library is re-exported, and callers still import `@pixiv/three-vrm-
|
|
10
|
-
* springbone` types directly for anything beyond what's here. Kept
|
|
11
|
-
* deliberately bare: composing a specific character (a caped viking, a
|
|
12
|
-
* ponytailed ranger) is ordinary calling code on top of these pieces, not a
|
|
13
|
-
* costume/preset system in the engine.
|
|
14
|
-
*
|
|
15
|
-
* Sharp edge this module exists partly to contain (see the mission brief /
|
|
16
|
-
* `cloth-hair-bench/spring-rig.ts`'s header for the full discovery):
|
|
17
|
-
* `VRMSpringBoneCollider` overrides `updateWorldMatrix` (the ON-DEMAND,
|
|
18
|
-
* manually-invoked method), NOT `updateMatrixWorld` (the one the renderer
|
|
19
|
-
* calls automatically) — `SpringColliderRig.reposition()` below calls
|
|
20
|
-
* `collider.updateWorldMatrix(true, false)` itself every tick so callers
|
|
21
|
-
* can't forget it.
|
|
22
|
-
*/
|
|
23
|
-
import { VRMSpringBoneCollider, VRMSpringBoneColliderShapeCapsule, VRMSpringBoneColliderShapeSphere, VRMSpringBoneJoint, VRMSpringBoneManager, } from '@pixiv/three-vrm-springbone';
|
|
24
|
-
import * as THREE from 'three';
|
|
25
|
-
const DEFAULT_GRAVITY_DIR = new THREE.Vector3(0, -1, 0);
|
|
26
|
-
/** World-space offset from `parent`'s CURRENT world position -> the local
|
|
27
|
-
* position a new direct child of `parent` must have to sit there. Requires
|
|
28
|
-
* `parent.matrixWorld` to be current. Sidesteps ever reasoning about a
|
|
29
|
-
* bone's local rest-axis convention (arbitrary per-bone on an imported
|
|
30
|
-
* rig) — the caller only ever thinks in world-space directions. */
|
|
31
|
-
export function worldOffsetToLocalPos(parent, worldDir, length) {
|
|
32
|
-
const parentWorld = new THREE.Vector3();
|
|
33
|
-
parent.getWorldPosition(parentWorld);
|
|
34
|
-
const targetWorld = parentWorld.clone().addScaledVector(worldDir, length);
|
|
35
|
-
return parent.worldToLocal(targetWorld.clone());
|
|
36
|
-
}
|
|
37
|
-
/** Build a straight chain of `count` new `THREE.Bone`s under `parent`, each
|
|
38
|
-
* offset `segmentLength` further along the WORLD-space unit vector
|
|
39
|
-
* `worldDir` — the natural rest shape for hair/cloth hanging under gravity.
|
|
40
|
-
* Ends with a `tip` `Object3D` (one more segment past the last bone) so
|
|
41
|
-
* every bone has an explicit spring-joint child target. Can be anchored to
|
|
42
|
-
* either an existing rig bone (hair off a head) or any plain `Object3D`. */
|
|
43
|
-
export function buildBoneChain(parent, namePrefix, count, segmentLength, worldDir) {
|
|
44
|
-
const bones = [];
|
|
45
|
-
let cur = parent;
|
|
46
|
-
cur.updateWorldMatrix(true, false);
|
|
47
|
-
for (let i = 0; i < count; i++) {
|
|
48
|
-
const localPos = worldOffsetToLocalPos(cur, worldDir, segmentLength);
|
|
49
|
-
const bone = new THREE.Bone();
|
|
50
|
-
bone.name = `${namePrefix}${i}`;
|
|
51
|
-
bone.position.copy(localPos);
|
|
52
|
-
cur.add(bone);
|
|
53
|
-
bone.updateWorldMatrix(true, false);
|
|
54
|
-
bones.push(bone);
|
|
55
|
-
cur = bone;
|
|
56
|
-
}
|
|
57
|
-
const tip = new THREE.Object3D();
|
|
58
|
-
tip.name = `${namePrefix}Tip`;
|
|
59
|
-
tip.position.copy(worldOffsetToLocalPos(cur, worldDir, segmentLength));
|
|
60
|
-
cur.add(tip);
|
|
61
|
-
return { bones, tip };
|
|
62
|
-
}
|
|
63
|
-
/** Register one `VRMSpringBoneJoint` per bone in `chain` on `manager` (each
|
|
64
|
-
* targeting the next bone, the last targeting `chain.tip`). Does not call
|
|
65
|
-
* `manager.setInitState()` — batch that once after all chains for a
|
|
66
|
-
* manager are registered and the scene's world matrices are current (sharp
|
|
67
|
-
* edge: `VRMSpringBoneJoint` sets `bone.matrixAutoUpdate = false`, so
|
|
68
|
-
* `setInitState()` must run AFTER `scene.updateMatrixWorld(true)`). */
|
|
69
|
-
export function registerChainJoints(manager, chain, colliderGroups, settings = {}) {
|
|
70
|
-
const joints = [];
|
|
71
|
-
for (let i = 0; i < chain.bones.length; i++) {
|
|
72
|
-
const bone = chain.bones[i];
|
|
73
|
-
const child = chain.bones[i + 1] ?? chain.tip;
|
|
74
|
-
const joint = new VRMSpringBoneJoint(bone, child, {
|
|
75
|
-
stiffness: settings.stiffness ?? 1.2,
|
|
76
|
-
gravityPower: settings.gravityPower ?? 0.9,
|
|
77
|
-
gravityDir: settings.gravityDir ?? DEFAULT_GRAVITY_DIR,
|
|
78
|
-
dragForce: settings.dragForce ?? 0.35,
|
|
79
|
-
hitRadius: settings.hitRadius ?? 0.02,
|
|
80
|
-
}, colliderGroups);
|
|
81
|
-
manager.addJoint(joint);
|
|
82
|
-
joints.push(joint);
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
joints,
|
|
86
|
-
dispose() {
|
|
87
|
-
for (const joint of joints)
|
|
88
|
-
manager.deleteJoint(joint);
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
/** Build sphere/capsule colliders parented directly to `scene` (world
|
|
93
|
-
* space) — sidesteps reasoning about any bone's local rest-axis convention
|
|
94
|
-
* for the collider shape's offset/tail vectors. */
|
|
95
|
-
export function buildSpringColliderRig(scene, defs) {
|
|
96
|
-
const colliders = new Map();
|
|
97
|
-
const followers = [];
|
|
98
|
-
for (const def of defs) {
|
|
99
|
-
const collider = def.shape === 'sphere'
|
|
100
|
-
? new VRMSpringBoneCollider(new VRMSpringBoneColliderShapeSphere({ radius: def.radius }))
|
|
101
|
-
: new VRMSpringBoneCollider(new VRMSpringBoneColliderShapeCapsule({
|
|
102
|
-
radius: def.radius,
|
|
103
|
-
offset: new THREE.Vector3(0, 0, 0),
|
|
104
|
-
tail: def.tail,
|
|
105
|
-
}));
|
|
106
|
-
scene.add(collider);
|
|
107
|
-
colliders.set(def.name, collider);
|
|
108
|
-
followers.push({ def, collider });
|
|
109
|
-
}
|
|
110
|
-
const group = {
|
|
111
|
-
name: 'body',
|
|
112
|
-
colliders: [...colliders.values()],
|
|
113
|
-
};
|
|
114
|
-
const worldTmp = new THREE.Vector3();
|
|
115
|
-
return {
|
|
116
|
-
group,
|
|
117
|
-
colliders,
|
|
118
|
-
reposition() {
|
|
119
|
-
for (const { def, collider } of followers) {
|
|
120
|
-
def.followBone.getWorldPosition(worldTmp);
|
|
121
|
-
collider.position.copy(worldTmp);
|
|
122
|
-
if (def.worldOffset)
|
|
123
|
-
collider.position.add(def.worldOffset);
|
|
124
|
-
collider.updateWorldMatrix(true, false);
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
dispose() {
|
|
128
|
-
for (const collider of colliders.values())
|
|
129
|
-
scene.remove(collider);
|
|
130
|
-
colliders.clear();
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
/** Compose `buildBoneChain` + `registerChainJoints` behind one call for the
|
|
135
|
-
* common single-chain case: builds the chain, gives it its OWN
|
|
136
|
-
* `VRMSpringBoneManager` (managers are cheap — one per independent chain
|
|
137
|
-
* keeps `dispose()`/`tick()` fully self-contained), registers its joints,
|
|
138
|
-
* and calls `setInitState()` once construction is complete.
|
|
139
|
-
*
|
|
140
|
-
* For MULTIPLE chains sharing one collider rig (e.g. a ponytail + two side
|
|
141
|
-
* strands all colliding against the same head), build each chain with its
|
|
142
|
-
* own `buildSpringChainRig` call (same `colliderRig` passed to each) and
|
|
143
|
-
* tick all of them — `colliderRig.reposition()` is idempotent per frame, so
|
|
144
|
-
* calling it once per chain tick is correct, just slightly redundant work
|
|
145
|
-
* (cheap: it only touches a handful of colliders). */
|
|
146
|
-
export function buildSpringChainRig(options) {
|
|
147
|
-
const chain = buildBoneChain(options.parent, options.namePrefix, options.count, options.segmentLength, options.worldDir);
|
|
148
|
-
const manager = new VRMSpringBoneManager();
|
|
149
|
-
const colliderGroups = options.colliderRig ? [options.colliderRig.group] : [];
|
|
150
|
-
const jointHandle = registerChainJoints(manager, chain, colliderGroups, options.settings);
|
|
151
|
-
manager.setInitState();
|
|
152
|
-
return {
|
|
153
|
-
bones: chain.bones,
|
|
154
|
-
tip: chain.tip,
|
|
155
|
-
manager,
|
|
156
|
-
tick(dt) {
|
|
157
|
-
options.colliderRig?.reposition();
|
|
158
|
-
manager.update(dt);
|
|
159
|
-
},
|
|
160
|
-
dispose() {
|
|
161
|
-
jointHandle.dispose();
|
|
162
|
-
chain.bones[0]?.removeFromParent();
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
}
|