@vgai/engine 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/adapter-surface.d.ts +30 -0
- package/dist/adapter/adapter-surface.d.ts.map +1 -0
- package/dist/adapter/adapter-surface.js +18 -0
- package/dist/adapter/authoring.d.ts +597 -0
- package/dist/adapter/authoring.d.ts.map +1 -0
- package/dist/adapter/authoring.js +22 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts +77 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
- package/dist/adapter/colyseus-networking-adapter.js +76 -0
- package/dist/adapter/first-party-systems.d.ts +23 -0
- package/dist/adapter/first-party-systems.d.ts.map +1 -0
- package/dist/adapter/first-party-systems.js +196 -0
- package/dist/adapter/host-context.d.ts +194 -0
- package/dist/adapter/host-context.d.ts.map +1 -0
- package/dist/adapter/host-context.js +80 -0
- package/dist/adapter/index.d.ts +33 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +25 -0
- package/dist/adapter/ingest/game-contract.d.ts +53 -0
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
- package/dist/adapter/ingest/game-contract.js +30 -0
- package/dist/adapter/ingest/scene-capture.d.ts +121 -0
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
- package/dist/adapter/ingest/scene-capture.js +270 -0
- package/dist/adapter/ingest/structural-ids.d.ts +64 -0
- package/dist/adapter/ingest/structural-ids.d.ts.map +1 -0
- package/dist/adapter/ingest/structural-ids.js +110 -0
- package/dist/adapter/ingest/upstream-pin.d.ts +44 -0
- package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
- package/dist/adapter/ingest/upstream-pin.js +47 -0
- package/dist/adapter/loop-gate-report.d.ts +34 -0
- package/dist/adapter/loop-gate-report.d.ts.map +1 -0
- package/dist/adapter/loop-gate-report.js +37 -0
- package/dist/adapter/rapier-physics-adapter.d.ts +69 -0
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
- package/dist/adapter/rapier-physics-adapter.js +135 -0
- package/dist/adapter/root-adapter.d.ts +195 -0
- package/dist/adapter/root-adapter.d.ts.map +1 -0
- package/dist/adapter/root-adapter.js +25 -0
- package/dist/adapter/setup-three-root-adapter.d.ts +87 -0
- package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -0
- package/dist/adapter/setup-three-root-adapter.js +791 -0
- package/dist/adapter/system-adapter.d.ts +453 -0
- package/dist/adapter/system-adapter.d.ts.map +1 -0
- package/dist/adapter/system-adapter.js +13 -0
- package/dist/adapter/transform.d.ts +18 -0
- package/dist/adapter/transform.d.ts.map +1 -0
- package/dist/adapter/transform.js +1 -0
- package/dist/ai/navigation.d.ts +78 -0
- package/dist/ai/navigation.d.ts.map +1 -0
- package/dist/ai/navigation.js +152 -0
- package/dist/animation/anim-graph-types.d.ts +25 -0
- package/dist/animation/anim-graph-types.d.ts.map +1 -0
- package/dist/animation/anim-graph-types.js +1 -0
- package/dist/animation/animation-clock.d.ts +213 -0
- package/dist/animation/animation-clock.d.ts.map +1 -0
- package/dist/animation/animation-clock.js +301 -0
- package/dist/animation/blend-node.d.ts +22 -0
- package/dist/animation/blend-node.d.ts.map +1 -0
- package/dist/animation/blend-node.js +97 -0
- package/dist/animation/camera-ownership.d.ts +249 -0
- package/dist/animation/camera-ownership.d.ts.map +1 -0
- package/dist/animation/camera-ownership.js +169 -0
- package/dist/animation/cinematic-cues.d.ts +200 -0
- package/dist/animation/cinematic-cues.d.ts.map +1 -0
- package/dist/animation/cinematic-cues.js +213 -0
- package/dist/animation/clip-map.d.ts +12 -0
- package/dist/animation/clip-map.d.ts.map +1 -0
- package/dist/animation/clip-map.js +31 -0
- package/dist/animation/cubic-spline-interpolant.d.ts +54 -0
- package/dist/animation/cubic-spline-interpolant.d.ts.map +1 -0
- package/dist/animation/cubic-spline-interpolant.js +111 -0
- package/dist/animation/theatre-clock-binding.d.ts +89 -0
- package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
- package/dist/animation/theatre-clock-binding.js +29 -0
- package/dist/animation/theatre-director.d.ts +277 -0
- package/dist/animation/theatre-director.d.ts.map +1 -0
- package/dist/animation/theatre-director.js +248 -0
- package/dist/animation/theatre-object-binding.d.ts +305 -0
- package/dist/animation/theatre-object-binding.d.ts.map +1 -0
- package/dist/animation/theatre-object-binding.js +351 -0
- package/dist/animation/xstate-animation-binding.d.ts +119 -0
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
- package/dist/animation/xstate-animation-binding.js +349 -0
- package/dist/animation/xstate-animation-meta.d.ts +266 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
- package/dist/animation/xstate-animation-meta.js +252 -0
- package/dist/asset-formats/camera.d.ts +15 -0
- package/dist/asset-formats/camera.d.ts.map +1 -0
- package/dist/asset-formats/camera.js +15 -0
- package/dist/asset-formats/collider.d.ts +21 -0
- package/dist/asset-formats/collider.d.ts.map +1 -0
- package/dist/asset-formats/collider.js +53 -0
- package/dist/asset-formats/index.d.ts +46 -0
- package/dist/asset-formats/index.d.ts.map +1 -0
- package/dist/asset-formats/index.js +36 -0
- package/dist/asset-formats/instances.d.ts +17 -0
- package/dist/asset-formats/instances.d.ts.map +1 -0
- package/dist/asset-formats/instances.js +31 -0
- package/dist/asset-formats/light.d.ts +21 -0
- package/dist/asset-formats/light.d.ts.map +1 -0
- package/dist/asset-formats/light.js +35 -0
- package/dist/asset-formats/material.d.ts +129 -0
- package/dist/asset-formats/material.d.ts.map +1 -0
- package/dist/asset-formats/material.js +88 -0
- package/dist/asset-formats/mesh.d.ts +22 -0
- package/dist/asset-formats/mesh.d.ts.map +1 -0
- package/dist/asset-formats/mesh.js +64 -0
- package/dist/asset-formats/parse.d.ts +20 -0
- package/dist/asset-formats/parse.d.ts.map +1 -0
- package/dist/asset-formats/parse.js +34 -0
- package/dist/asset-formats/particles.d.ts +1390 -0
- package/dist/asset-formats/particles.d.ts.map +1 -0
- package/dist/asset-formats/particles.js +319 -0
- package/dist/asset-formats/render-env.d.ts +387 -0
- package/dist/asset-formats/render-env.d.ts.map +1 -0
- package/dist/asset-formats/render-env.js +300 -0
- package/dist/asset-formats/tuples.d.ts +12 -0
- package/dist/asset-formats/tuples.d.ts.map +1 -0
- package/dist/asset-formats/tuples.js +14 -0
- package/dist/asset-loaders.d.ts +97 -0
- package/dist/asset-loaders.d.ts.map +1 -0
- package/dist/asset-loaders.js +209 -0
- package/dist/asset-parse-error.d.ts +24 -0
- package/dist/asset-parse-error.d.ts.map +1 -0
- package/dist/asset-parse-error.js +29 -0
- package/dist/asset-registry.d.ts +38 -0
- package/dist/asset-registry.d.ts.map +1 -0
- package/dist/asset-registry.js +66 -0
- package/dist/assets.d.ts +26 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +55 -0
- package/dist/audio/wav-encode.d.ts +38 -0
- package/dist/audio/wav-encode.d.ts.map +1 -0
- package/dist/audio/wav-encode.js +97 -0
- package/dist/canvas-react/engine-bridge.d.ts +45 -0
- package/dist/canvas-react/engine-bridge.d.ts.map +1 -0
- package/dist/canvas-react/engine-bridge.js +45 -0
- package/dist/canvas-react/index.d.ts +42 -0
- package/dist/canvas-react/index.d.ts.map +1 -0
- package/dist/canvas-react/index.js +41 -0
- package/dist/canvas-react/pixi-primitive.d.ts +85 -0
- package/dist/canvas-react/pixi-primitive.d.ts.map +1 -0
- package/dist/canvas-react/pixi-primitive.js +181 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts +71 -0
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-adapter.js +229 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts +56 -0
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -0
- package/dist/canvas-react/pixi-react-root-factory.js +73 -0
- package/dist/canvas-react/world-context.d.ts +88 -0
- package/dist/canvas-react/world-context.d.ts.map +1 -0
- package/dist/canvas-react/world-context.js +212 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +8 -0
- package/dist/core/frame-pacing.d.ts +90 -0
- package/dist/core/frame-pacing.d.ts.map +1 -0
- package/dist/core/frame-pacing.js +89 -0
- package/dist/core/game-loop.d.ts +62 -0
- package/dist/core/game-loop.d.ts.map +1 -0
- package/dist/core/game-loop.js +189 -0
- package/dist/core/seeded-random.d.ts +69 -0
- package/dist/core/seeded-random.d.ts.map +1 -0
- package/dist/core/seeded-random.js +121 -0
- package/dist/core/sim-clock.d.ts +199 -0
- package/dist/core/sim-clock.d.ts.map +1 -0
- package/dist/core/sim-clock.js +291 -0
- package/dist/core/system-runner.d.ts +96 -0
- package/dist/core/system-runner.d.ts.map +1 -0
- package/dist/core/system-runner.js +253 -0
- package/dist/core/types.d.ts +111 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +25 -0
- package/dist/data/data-asset.d.ts +101 -0
- package/dist/data/data-asset.d.ts.map +1 -0
- package/dist/data/data-asset.js +122 -0
- package/dist/data/data-check-core.d.ts +109 -0
- package/dist/data/data-check-core.d.ts.map +1 -0
- package/dist/data/data-check-core.js +177 -0
- package/dist/data/data-ref.d.ts +79 -0
- package/dist/data/data-ref.d.ts.map +1 -0
- package/dist/data/data-ref.js +130 -0
- package/dist/data/vite-plugin-data.d.ts +79 -0
- package/dist/data/vite-plugin-data.d.ts.map +1 -0
- package/dist/data/vite-plugin-data.js +217 -0
- package/dist/defaults.d.ts +233 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +137 -0
- package/dist/dev/chrome-trace.d.ts +45 -0
- package/dist/dev/chrome-trace.d.ts.map +1 -0
- package/dist/dev/chrome-trace.js +114 -0
- package/dist/dev/console-bridge.d.ts +22 -0
- package/dist/dev/console-bridge.d.ts.map +1 -0
- package/dist/dev/console-bridge.js +71 -0
- package/dist/dev/debug-draw.d.ts +24 -0
- package/dist/dev/debug-draw.d.ts.map +1 -0
- package/dist/dev/debug-draw.js +73 -0
- package/dist/dev/instruments.d.ts +133 -0
- package/dist/dev/instruments.d.ts.map +1 -0
- package/dist/dev/instruments.js +231 -0
- package/dist/dev/logger.d.ts +30 -0
- package/dist/dev/logger.d.ts.map +1 -0
- package/dist/dev/logger.js +90 -0
- package/dist/dev/performance-profiler.d.ts +111 -0
- package/dist/dev/performance-profiler.d.ts.map +1 -0
- package/dist/dev/performance-profiler.js +215 -0
- package/dist/dev/render-debug-adapter.d.ts +57 -0
- package/dist/dev/render-debug-adapter.d.ts.map +1 -0
- package/dist/dev/render-debug-adapter.js +141 -0
- package/dist/dev/render-memory.d.ts +53 -0
- package/dist/dev/render-memory.d.ts.map +1 -0
- package/dist/dev/render-memory.js +190 -0
- package/dist/dev/webgl-frame-capture.d.ts +134 -0
- package/dist/dev/webgl-frame-capture.d.ts.map +1 -0
- package/dist/dev/webgl-frame-capture.js +270 -0
- package/dist/dev/webgl-gpu-timer.d.ts +8 -0
- package/dist/dev/webgl-gpu-timer.d.ts.map +1 -0
- package/dist/dev/webgl-gpu-timer.js +52 -0
- package/dist/ecs/scene-index.d.ts +179 -0
- package/dist/ecs/scene-index.d.ts.map +1 -0
- package/dist/ecs/scene-index.js +331 -0
- package/dist/ecs/scene-query.d.ts +6 -0
- package/dist/ecs/scene-query.d.ts.map +1 -0
- package/dist/ecs/scene-query.js +40 -0
- package/dist/ecs/user-data.d.ts +193 -0
- package/dist/ecs/user-data.d.ts.map +1 -0
- package/dist/ecs/user-data.js +145 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/input/input-manager.d.ts +944 -0
- package/dist/input/input-manager.d.ts.map +1 -0
- package/dist/input/input-manager.js +2209 -0
- package/dist/input/input-types.d.ts +174 -0
- package/dist/input/input-types.d.ts.map +1 -0
- package/dist/input/input-types.js +1 -0
- package/dist/input/prompt-labels.d.ts +21 -0
- package/dist/input/prompt-labels.d.ts.map +1 -0
- package/dist/input/prompt-labels.js +121 -0
- package/dist/input/rebind-controller.d.ts +59 -0
- package/dist/input/rebind-controller.d.ts.map +1 -0
- package/dist/input/rebind-controller.js +85 -0
- package/dist/input/schema.d.ts +16 -0
- package/dist/input/schema.d.ts.map +1 -0
- package/dist/input/schema.js +228 -0
- package/dist/loader.d.ts +76 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +114 -0
- package/dist/manifest/editor-port.d.ts +53 -0
- package/dist/manifest/editor-port.d.ts.map +1 -0
- package/dist/manifest/editor-port.js +67 -0
- package/dist/manifest/filename.d.ts +14 -0
- package/dist/manifest/filename.d.ts.map +1 -0
- package/dist/manifest/filename.js +43 -0
- package/dist/manifest/index.d.ts +6 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +9 -0
- package/dist/manifest/load-file.d.ts +7 -0
- package/dist/manifest/load-file.d.ts.map +1 -0
- package/dist/manifest/load-file.js +23 -0
- package/dist/manifest/load.d.ts +161 -0
- package/dist/manifest/load.d.ts.map +1 -0
- package/dist/manifest/load.js +269 -0
- package/dist/manifest/locate.d.ts +24 -0
- package/dist/manifest/locate.d.ts.map +1 -0
- package/dist/manifest/locate.js +48 -0
- package/dist/manifest/schema.d.ts +293 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +633 -0
- package/dist/physics/collider-dimensions.d.ts +63 -0
- package/dist/physics/collider-dimensions.d.ts.map +1 -0
- package/dist/physics/collider-dimensions.js +98 -0
- package/dist/physics/collision-system.d.ts +41 -0
- package/dist/physics/collision-system.d.ts.map +1 -0
- package/dist/physics/collision-system.js +64 -0
- package/dist/physics/physics-registry.d.ts +45 -0
- package/dist/physics/physics-registry.d.ts.map +1 -0
- package/dist/physics/physics-registry.js +65 -0
- package/dist/physics/transform-writer.d.ts +16 -0
- package/dist/physics/transform-writer.d.ts.map +1 -0
- package/dist/physics/transform-writer.js +38 -0
- package/dist/pixi/authoring.d.ts +93 -0
- package/dist/pixi/authoring.d.ts.map +1 -0
- package/dist/pixi/authoring.js +207 -0
- package/dist/pixi/index.d.ts +16 -0
- package/dist/pixi/index.d.ts.map +1 -0
- package/dist/pixi/index.js +15 -0
- package/dist/pixi/ingest-iframe.d.ts +82 -0
- package/dist/pixi/ingest-iframe.d.ts.map +1 -0
- package/dist/pixi/ingest-iframe.js +166 -0
- package/dist/pixi/ingest.d.ts +97 -0
- package/dist/pixi/ingest.d.ts.map +1 -0
- package/dist/pixi/ingest.js +40 -0
- package/dist/pixi/physics-registry.d.ts +24 -0
- package/dist/pixi/physics-registry.d.ts.map +1 -0
- package/dist/pixi/physics-registry.js +38 -0
- package/dist/pixi/scene-capture.d.ts +43 -0
- package/dist/pixi/scene-capture.d.ts.map +1 -0
- package/dist/pixi/scene-capture.js +92 -0
- package/dist/pixi/system-adapters.d.ts +16 -0
- package/dist/pixi/system-adapters.d.ts.map +1 -0
- package/dist/pixi/system-adapters.js +37 -0
- package/dist/react/unmanaged-root-detector.d.ts +18 -0
- package/dist/react/unmanaged-root-detector.d.ts.map +1 -0
- package/dist/react/unmanaged-root-detector.js +70 -0
- package/dist/react/use-data.d.ts +60 -0
- package/dist/react/use-data.d.ts.map +1 -0
- package/dist/react/use-data.js +101 -0
- package/dist/react/use-selection.d.ts +54 -0
- package/dist/react/use-selection.d.ts.map +1 -0
- package/dist/react/use-selection.js +71 -0
- package/dist/react/world-state.d.ts +154 -0
- package/dist/react/world-state.d.ts.map +1 -0
- package/dist/react/world-state.js +220 -0
- package/dist/render/auto-batcher.d.ts +34 -0
- package/dist/render/auto-batcher.d.ts.map +1 -0
- package/dist/render/auto-batcher.js +140 -0
- package/dist/render/instance-mesh.d.ts +5 -0
- package/dist/render/instance-mesh.d.ts.map +1 -0
- package/dist/render/instance-mesh.js +19 -0
- package/dist/render/light-camera-factory.d.ts +24 -0
- package/dist/render/light-camera-factory.d.ts.map +1 -0
- package/dist/render/light-camera-factory.js +71 -0
- package/dist/render/lod.d.ts +13 -0
- package/dist/render/lod.d.ts.map +1 -0
- package/dist/render/lod.js +16 -0
- package/dist/render/material-factory.d.ts +15 -0
- package/dist/render/material-factory.d.ts.map +1 -0
- package/dist/render/material-factory.js +186 -0
- package/dist/render/mesh-shadow.d.ts +11 -0
- package/dist/render/mesh-shadow.d.ts.map +1 -0
- package/dist/render/mesh-shadow.js +19 -0
- package/dist/render/particles-factory.d.ts +99 -0
- package/dist/render/particles-factory.d.ts.map +1 -0
- package/dist/render/particles-factory.js +361 -0
- package/dist/render/render-batch-system.d.ts +33 -0
- package/dist/render/render-batch-system.d.ts.map +1 -0
- package/dist/render/render-batch-system.js +223 -0
- package/dist/render/render-features.d.ts +47 -0
- package/dist/render/render-features.d.ts.map +1 -0
- package/dist/render/render-features.js +105 -0
- package/dist/render/render-settings.d.ts +35 -0
- package/dist/render/render-settings.d.ts.map +1 -0
- package/dist/render/render-settings.js +51 -0
- package/dist/render/spark-renderer-lifecycle.d.ts +18 -0
- package/dist/render/spark-renderer-lifecycle.d.ts.map +1 -0
- package/dist/render/spark-renderer-lifecycle.js +57 -0
- package/dist/render/viewport-shading.d.ts +17 -0
- package/dist/render/viewport-shading.d.ts.map +1 -0
- package/dist/render/viewport-shading.js +87 -0
- package/dist/runtime/create-runtime.d.ts +259 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -0
- package/dist/runtime/create-runtime.js +666 -0
- package/dist/runtime/debug-bridge.d.ts +288 -0
- package/dist/runtime/debug-bridge.d.ts.map +1 -0
- package/dist/runtime/debug-bridge.js +277 -0
- package/dist/runtime/debug-registry.d.ts +287 -0
- package/dist/runtime/debug-registry.d.ts.map +1 -0
- package/dist/runtime/debug-registry.js +528 -0
- package/dist/runtime/dev-layers.d.ts +34 -0
- package/dist/runtime/dev-layers.d.ts.map +1 -0
- package/dist/runtime/dev-layers.js +40 -0
- package/dist/runtime/frame-selector-cache.d.ts +41 -0
- package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
- package/dist/runtime/frame-selector-cache.js +65 -0
- package/dist/runtime/game.d.ts +576 -0
- package/dist/runtime/game.d.ts.map +1 -0
- package/dist/runtime/game.js +1003 -0
- package/dist/runtime/gameplay-rng-trap.d.ts +47 -0
- package/dist/runtime/gameplay-rng-trap.d.ts.map +1 -0
- package/dist/runtime/gameplay-rng-trap.js +95 -0
- package/dist/runtime/input-router.d.ts +78 -0
- package/dist/runtime/input-router.d.ts.map +1 -0
- package/dist/runtime/input-router.js +171 -0
- package/dist/runtime/mount-game.d.ts +126 -0
- package/dist/runtime/mount-game.d.ts.map +1 -0
- package/dist/runtime/mount-game.js +159 -0
- package/dist/runtime/mount-manifest.d.ts +174 -0
- package/dist/runtime/mount-manifest.d.ts.map +1 -0
- package/dist/runtime/mount-manifest.js +304 -0
- package/dist/runtime/presentation.d.ts +85 -0
- package/dist/runtime/presentation.d.ts.map +1 -0
- package/dist/runtime/presentation.js +92 -0
- package/dist/runtime/render-audio-control.d.ts +126 -0
- package/dist/runtime/render-audio-control.d.ts.map +1 -0
- package/dist/runtime/render-audio-control.js +116 -0
- package/dist/runtime/render-control.d.ts +347 -0
- package/dist/runtime/render-control.d.ts.map +1 -0
- package/dist/runtime/render-control.js +317 -0
- package/dist/runtime/render-seed.d.ts +56 -0
- package/dist/runtime/render-seed.d.ts.map +1 -0
- package/dist/runtime/render-seed.js +73 -0
- package/dist/runtime/state-bridge.d.ts +60 -0
- package/dist/runtime/state-bridge.d.ts.map +1 -0
- package/dist/runtime/state-bridge.js +62 -0
- package/dist/runtime/types.d.ts +285 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/unexported-game-trap.d.ts +36 -0
- package/dist/runtime/unexported-game-trap.d.ts.map +1 -0
- package/dist/runtime/unexported-game-trap.js +80 -0
- package/dist/setup/setup-audio.d.ts +20 -0
- package/dist/setup/setup-audio.d.ts.map +1 -0
- package/dist/setup/setup-audio.js +41 -0
- package/dist/setup/setup-particles.d.ts +17 -0
- package/dist/setup/setup-particles.d.ts.map +1 -0
- package/dist/setup/setup-particles.js +16 -0
- package/dist/setup/setup-physics.d.ts +25 -0
- package/dist/setup/setup-physics.d.ts.map +1 -0
- package/dist/setup/setup-physics.js +51 -0
- package/dist/setup/setup-renderer.d.ts +82 -0
- package/dist/setup/setup-renderer.d.ts.map +1 -0
- package/dist/setup/setup-renderer.js +381 -0
- package/dist/world3d-react/engine-bridge.d.ts +47 -0
- package/dist/world3d-react/engine-bridge.d.ts.map +1 -0
- package/dist/world3d-react/engine-bridge.js +48 -0
- package/dist/world3d-react/index.d.ts +47 -0
- package/dist/world3d-react/index.d.ts.map +1 -0
- package/dist/world3d-react/index.js +46 -0
- package/dist/world3d-react/r3f-adapter.d.ts +51 -0
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -0
- package/dist/world3d-react/r3f-adapter.js +368 -0
- package/dist/world3d-react/r3f-root-factory.d.ts +62 -0
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -0
- package/dist/world3d-react/r3f-root-factory.js +79 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts +76 -0
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -0
- package/dist/world3d-react/rapier-physics-bridge.js +120 -0
- package/dist/world3d-react/renderer-config.d.ts +58 -0
- package/dist/world3d-react/renderer-config.d.ts.map +1 -0
- package/dist/world3d-react/renderer-config.js +96 -0
- package/dist/world3d-react/world-context.d.ts +123 -0
- package/dist/world3d-react/world-context.d.ts.map +1 -0
- package/dist/world3d-react/world-context.js +204 -0
- package/dist-config/config.js +303 -0
- package/dist-config/config.js.map +7 -0
- package/package.json +14 -3
- package/src/adapter/rapier-physics-adapter.ts +77 -34
- package/src/config.ts +8 -0
- package/src/core/frame-pacing.ts +26 -0
- package/src/core/game-loop.ts +4 -3
- package/src/dev/instruments.ts +302 -0
- package/src/setup/setup-renderer.ts +2 -0
- package/src/world3d-react/index.ts +9 -0
- package/src/world3d-react/rapier-physics-bridge.tsx +137 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-profiler.d.ts","sourceRoot":"","sources":["../../src/dev/performance-profiler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAUD,qFAAqF;AACrF,wBAAgB,yBAAyB,CAAC,gBAAgB,UAAQ;aAkE3C,OAAO;;;;;;;mBAoCX,MAAM;;;yBAkBF,MAAM,SAAS,MAAM,QAAQ,MAAM;;;uBAiBnC,MAAM;wBAWL;QAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB;;wBAiCmB,MAAM,IAAI;;;EAejC;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
const now = () => globalThis.performance?.now() ?? Date.now();
|
|
2
|
+
function percentile(values, fraction) {
|
|
3
|
+
if (values.length === 0)
|
|
4
|
+
return 0;
|
|
5
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
6
|
+
return sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * fraction))] ?? 0;
|
|
7
|
+
}
|
|
8
|
+
/** Game-owned, bounded external store for browser-native performance diagnostics. */
|
|
9
|
+
export function createPerformanceProfiler(initiallyEnabled = false) {
|
|
10
|
+
const listeners = new Set();
|
|
11
|
+
const frames = [];
|
|
12
|
+
const currentPhases = new Map();
|
|
13
|
+
const currentSystems = new Map();
|
|
14
|
+
const currentComponents = new Map();
|
|
15
|
+
// Per-frame span logs (W4b) — cleared each beginFrame, snapshotted into the
|
|
16
|
+
// frame at endFrame. Distinct from the accumulate-by-name aggregate maps
|
|
17
|
+
// above (which back the cross-frame snapshot rollups): these preserve every
|
|
18
|
+
// individual invocation and its measured start offset, for the trace.
|
|
19
|
+
let frameSystems = [];
|
|
20
|
+
let frameComponents = [];
|
|
21
|
+
let enabled = initiallyEnabled;
|
|
22
|
+
let recording = false;
|
|
23
|
+
let frameId = 0;
|
|
24
|
+
let frameStart = 0;
|
|
25
|
+
let lastFrameStart = 0;
|
|
26
|
+
let phaseStart = 0;
|
|
27
|
+
let systemStart = 0;
|
|
28
|
+
let componentStart = 0;
|
|
29
|
+
let render = {
|
|
30
|
+
gpuMs: null,
|
|
31
|
+
drawCalls: 0,
|
|
32
|
+
triangles: 0,
|
|
33
|
+
geometries: 0,
|
|
34
|
+
textures: 0,
|
|
35
|
+
};
|
|
36
|
+
let snapshot = {
|
|
37
|
+
enabled,
|
|
38
|
+
recording,
|
|
39
|
+
fps: 0,
|
|
40
|
+
cpuMs: 0,
|
|
41
|
+
p95Ms: 0,
|
|
42
|
+
p99Ms: 0,
|
|
43
|
+
frames,
|
|
44
|
+
phases: [],
|
|
45
|
+
systems: [],
|
|
46
|
+
components: [],
|
|
47
|
+
render,
|
|
48
|
+
};
|
|
49
|
+
function publish() {
|
|
50
|
+
const latest = frames.at(-1);
|
|
51
|
+
const intervals = frames.map((frame) => frame.intervalMs).filter((value) => value > 0);
|
|
52
|
+
snapshot = {
|
|
53
|
+
enabled,
|
|
54
|
+
recording,
|
|
55
|
+
fps: latest?.intervalMs ? 1000 / latest.intervalMs : 0,
|
|
56
|
+
cpuMs: latest?.cpuMs ?? 0,
|
|
57
|
+
p95Ms: percentile(intervals, 0.95),
|
|
58
|
+
p99Ms: percentile(intervals, 0.99),
|
|
59
|
+
frames,
|
|
60
|
+
phases: latest?.phases ?? [],
|
|
61
|
+
systems: [...currentSystems].map(([name, ms]) => ({ name, ms })).sort((a, b) => b.ms - a.ms),
|
|
62
|
+
components: [...currentComponents]
|
|
63
|
+
.map(([name, ms]) => ({ name, ms }))
|
|
64
|
+
.sort((a, b) => b.ms - a.ms),
|
|
65
|
+
render,
|
|
66
|
+
};
|
|
67
|
+
for (const listener of listeners)
|
|
68
|
+
listener();
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
get enabled() {
|
|
72
|
+
return enabled;
|
|
73
|
+
},
|
|
74
|
+
set enabled(value) {
|
|
75
|
+
if (enabled === value)
|
|
76
|
+
return;
|
|
77
|
+
enabled = value;
|
|
78
|
+
publish();
|
|
79
|
+
},
|
|
80
|
+
get recording() {
|
|
81
|
+
return recording;
|
|
82
|
+
},
|
|
83
|
+
startRecording() {
|
|
84
|
+
enabled = true;
|
|
85
|
+
recording = true;
|
|
86
|
+
frames.length = 0;
|
|
87
|
+
publish();
|
|
88
|
+
},
|
|
89
|
+
stopRecording() {
|
|
90
|
+
recording = false;
|
|
91
|
+
publish();
|
|
92
|
+
},
|
|
93
|
+
clear() {
|
|
94
|
+
frames.length = 0;
|
|
95
|
+
publish();
|
|
96
|
+
},
|
|
97
|
+
beginFrame() {
|
|
98
|
+
if (!enabled)
|
|
99
|
+
return;
|
|
100
|
+
currentPhases.clear();
|
|
101
|
+
currentSystems.clear();
|
|
102
|
+
currentComponents.clear();
|
|
103
|
+
frameSystems = [];
|
|
104
|
+
frameComponents = [];
|
|
105
|
+
render = { gpuMs: null, drawCalls: 0, triangles: 0, geometries: 0, textures: 0 };
|
|
106
|
+
frameStart = now();
|
|
107
|
+
},
|
|
108
|
+
beginPhase() {
|
|
109
|
+
if (!enabled)
|
|
110
|
+
return;
|
|
111
|
+
phaseStart = now();
|
|
112
|
+
},
|
|
113
|
+
endPhase(name) {
|
|
114
|
+
if (!enabled)
|
|
115
|
+
return;
|
|
116
|
+
const elapsed = now() - phaseStart;
|
|
117
|
+
const existing = currentPhases.get(name);
|
|
118
|
+
// Accumulate ms across re-entries of the same phase, but keep the FIRST
|
|
119
|
+
// measured start offset (earliest entry) as the span's startMs.
|
|
120
|
+
currentPhases.set(name, {
|
|
121
|
+
ms: (existing?.ms ?? 0) + elapsed,
|
|
122
|
+
startMs: existing?.startMs ?? phaseStart - frameStart,
|
|
123
|
+
});
|
|
124
|
+
if (recording)
|
|
125
|
+
performance.measure(`vgai.phase.${name}`, { start: phaseStart, duration: elapsed });
|
|
126
|
+
},
|
|
127
|
+
systemObserver: {
|
|
128
|
+
beginSystem() {
|
|
129
|
+
if (!enabled)
|
|
130
|
+
return;
|
|
131
|
+
systemStart = now();
|
|
132
|
+
},
|
|
133
|
+
endSystem(scope, phase, name) {
|
|
134
|
+
if (!enabled)
|
|
135
|
+
return;
|
|
136
|
+
const end = now();
|
|
137
|
+
const key = `${scope} / ${phase} / ${name}`;
|
|
138
|
+
currentSystems.set(key, (currentSystems.get(key) ?? 0) + end - systemStart);
|
|
139
|
+
frameSystems.push({
|
|
140
|
+
name: key,
|
|
141
|
+
phase,
|
|
142
|
+
startMs: systemStart - frameStart,
|
|
143
|
+
ms: end - systemStart,
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
beginComponent() {
|
|
148
|
+
if (!recording)
|
|
149
|
+
return;
|
|
150
|
+
componentStart = now();
|
|
151
|
+
},
|
|
152
|
+
endComponent(name, phase = '') {
|
|
153
|
+
if (!recording)
|
|
154
|
+
return;
|
|
155
|
+
const end = now();
|
|
156
|
+
currentComponents.set(name, (currentComponents.get(name) ?? 0) + end - componentStart);
|
|
157
|
+
frameComponents.push({
|
|
158
|
+
name,
|
|
159
|
+
phase,
|
|
160
|
+
startMs: componentStart - frameStart,
|
|
161
|
+
ms: end - componentStart,
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
reportRender(stats) {
|
|
165
|
+
if (!enabled)
|
|
166
|
+
return;
|
|
167
|
+
render = {
|
|
168
|
+
gpuMs: stats.gpuMs ?? render.gpuMs,
|
|
169
|
+
drawCalls: render.drawCalls + stats.drawCalls,
|
|
170
|
+
triangles: render.triangles + stats.triangles,
|
|
171
|
+
geometries: render.geometries + stats.geometries,
|
|
172
|
+
textures: render.textures + stats.textures,
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
endFrame() {
|
|
176
|
+
if (!enabled)
|
|
177
|
+
return;
|
|
178
|
+
const timestamp = now();
|
|
179
|
+
const intervalMs = lastFrameStart === 0 ? 0 : frameStart - lastFrameStart;
|
|
180
|
+
lastFrameStart = frameStart;
|
|
181
|
+
const frame = {
|
|
182
|
+
id: ++frameId,
|
|
183
|
+
timestamp,
|
|
184
|
+
intervalMs,
|
|
185
|
+
cpuMs: timestamp - frameStart,
|
|
186
|
+
phases: [...currentPhases]
|
|
187
|
+
.map(([name, { ms, startMs }]) => ({ name, ms, startMs }))
|
|
188
|
+
.sort((a, b) => b.ms - a.ms),
|
|
189
|
+
systems: frameSystems.slice(),
|
|
190
|
+
components: frameComponents.slice(),
|
|
191
|
+
render: { ...render },
|
|
192
|
+
};
|
|
193
|
+
frames.push(frame);
|
|
194
|
+
if (frames.length > 600)
|
|
195
|
+
frames.splice(0, frames.length - 600);
|
|
196
|
+
if (recording)
|
|
197
|
+
performance.measure('vgai.frame', { start: frameStart, duration: frame.cpuMs });
|
|
198
|
+
publish();
|
|
199
|
+
},
|
|
200
|
+
subscribe(listener) {
|
|
201
|
+
listeners.add(listener);
|
|
202
|
+
return () => {
|
|
203
|
+
listeners.delete(listener);
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
getSnapshot() {
|
|
207
|
+
return snapshot;
|
|
208
|
+
},
|
|
209
|
+
exportJSON() {
|
|
210
|
+
// version 2 (W4b): frames now carry per-frame `systems`/`components`
|
|
211
|
+
// spans, per-frame `render` counters, and `startMs` on phase timings.
|
|
212
|
+
return JSON.stringify({ version: 2, capturedAt: new Date().toISOString(), frames }, null, 2);
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-party {@link RenderDebugAdapter} wiring (W4b, F11) — the glue between
|
|
3
|
+
* the WebGL2 frame capture (`webgl-frame-capture.ts`), a live three.js scene,
|
|
4
|
+
* and the render adapter's per-frame render pass.
|
|
5
|
+
*
|
|
6
|
+
* Split OUT of `setup-three-root-adapter.ts` so the capture/attribution/restore
|
|
7
|
+
* flow is unit-testable in a headless Node test with a mock GL context and a
|
|
8
|
+
* plain scene — a real non-headless GPU mount (EffectComposer + WebGLRenderer)
|
|
9
|
+
* cannot run under vitest here, the same reason the adapter suite drives
|
|
10
|
+
* `setup(ctx)` only through hotReload on a data scene. `mount()` owns the
|
|
11
|
+
* DECISION to construct this (only under a real WebGL2 context, never
|
|
12
|
+
* headless — see `frameCaptureContextFor`); this module owns the BEHAVIOR.
|
|
13
|
+
*
|
|
14
|
+
* Attribution model (honest by construction): `captureFrame()` wraps every
|
|
15
|
+
* renderable's `onBeforeRender` to feed one annotation to the capture. three
|
|
16
|
+
* calls `onBeforeRender` immediately before that object's MAIN-pass draw, so
|
|
17
|
+
* main-pass draws are attributed and shadow/composer-pass draws record
|
|
18
|
+
* `annotation: null` (counted as unattributed) — never a fabricated guess. The
|
|
19
|
+
* wrappers are all restored when the capture resolves, rejects, times out, or
|
|
20
|
+
* the adapter is disposed.
|
|
21
|
+
*/
|
|
22
|
+
import type * as THREE from 'three';
|
|
23
|
+
import type { RenderDebugAdapter } from '../adapter/system-adapter';
|
|
24
|
+
import type { RenderMemorySnapshot } from './render-memory';
|
|
25
|
+
import type { WebGLFrameCapture } from './webgl-frame-capture';
|
|
26
|
+
/** Decide whether a mount can host frame capture — a real WebGL2 context with
|
|
27
|
+
* the draw entry points, never a headless/stub renderer. Exported so the
|
|
28
|
+
* mount uses ONE predicate and a unit test can assert both sides (mock GL ⇒
|
|
29
|
+
* the context; headless/missing ⇒ null) without a GPU. */
|
|
30
|
+
export declare function frameCaptureContextFor(headless: boolean, rendererContext: unknown): WebGL2RenderingContext | null;
|
|
31
|
+
export interface RenderDebugAdapterDeps {
|
|
32
|
+
/** The armed-on-demand frame capture over the mount's real context. */
|
|
33
|
+
capture: WebGLFrameCapture;
|
|
34
|
+
/** The live scene root traversed to attribute draws. */
|
|
35
|
+
scene: THREE.Object3D;
|
|
36
|
+
/** Memory snapshot supplier (renderer.info-backed). When omitted, the
|
|
37
|
+
* adapter's `memorySnapshot` is absent (honest capability degradation). */
|
|
38
|
+
memory?: () => RenderMemorySnapshot;
|
|
39
|
+
/** Timeout (ms) after which a pending `captureFrame` rejects — the world
|
|
40
|
+
* never rendered (paused/stopped). Default 5000. */
|
|
41
|
+
timeoutMs?: number;
|
|
42
|
+
/** Injected timer, for tests. Defaults to the real `setTimeout`/
|
|
43
|
+
* `clearTimeout`. */
|
|
44
|
+
setTimeoutFn?: (fn: () => void, ms: number) => unknown;
|
|
45
|
+
clearTimeoutFn?: (handle: unknown) => void;
|
|
46
|
+
}
|
|
47
|
+
export interface RenderDebugWiring {
|
|
48
|
+
readonly adapter: RenderDebugAdapter;
|
|
49
|
+
/** Call at the START of the host render pass, before draws. */
|
|
50
|
+
beforeRender(): void;
|
|
51
|
+
/** Call at the END of the host render pass, after draws (in a `finally`). */
|
|
52
|
+
afterRender(): void;
|
|
53
|
+
/** Restore any pending attribution wrappers and reject a pending capture. */
|
|
54
|
+
dispose(): void;
|
|
55
|
+
}
|
|
56
|
+
export declare function createRenderDebugAdapter(deps: RenderDebugAdapterDeps): RenderDebugWiring;
|
|
57
|
+
//# sourceMappingURL=render-debug-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-debug-adapter.d.ts","sourceRoot":"","sources":["../../src/dev/render-debug-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAgC,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE7F;;;2DAG2D;AAC3D,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,OAAO,GACvB,sBAAsB,GAAG,IAAI,CAO/B;AAED,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,OAAO,EAAE,iBAAiB,CAAC;IAC3B,wDAAwD;IACxD,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC;IACtB;gFAC4E;IAC5E,MAAM,CAAC,EAAE,MAAM,oBAAoB,CAAC;IACpC;yDACqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;0BACsB;IACtB,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,+DAA+D;IAC/D,YAAY,IAAI,IAAI,CAAC;IACrB,6EAA6E;IAC7E,WAAW,IAAI,IAAI,CAAC;IACpB,6EAA6E;IAC7E,OAAO,IAAI,IAAI,CAAC;CACjB;AAkDD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,sBAAsB,GAAG,iBAAiB,CAgFxF"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-party {@link RenderDebugAdapter} wiring (W4b, F11) — the glue between
|
|
3
|
+
* the WebGL2 frame capture (`webgl-frame-capture.ts`), a live three.js scene,
|
|
4
|
+
* and the render adapter's per-frame render pass.
|
|
5
|
+
*
|
|
6
|
+
* Split OUT of `setup-three-root-adapter.ts` so the capture/attribution/restore
|
|
7
|
+
* flow is unit-testable in a headless Node test with a mock GL context and a
|
|
8
|
+
* plain scene — a real non-headless GPU mount (EffectComposer + WebGLRenderer)
|
|
9
|
+
* cannot run under vitest here, the same reason the adapter suite drives
|
|
10
|
+
* `setup(ctx)` only through hotReload on a data scene. `mount()` owns the
|
|
11
|
+
* DECISION to construct this (only under a real WebGL2 context, never
|
|
12
|
+
* headless — see `frameCaptureContextFor`); this module owns the BEHAVIOR.
|
|
13
|
+
*
|
|
14
|
+
* Attribution model (honest by construction): `captureFrame()` wraps every
|
|
15
|
+
* renderable's `onBeforeRender` to feed one annotation to the capture. three
|
|
16
|
+
* calls `onBeforeRender` immediately before that object's MAIN-pass draw, so
|
|
17
|
+
* main-pass draws are attributed and shadow/composer-pass draws record
|
|
18
|
+
* `annotation: null` (counted as unattributed) — never a fabricated guess. The
|
|
19
|
+
* wrappers are all restored when the capture resolves, rejects, times out, or
|
|
20
|
+
* the adapter is disposed.
|
|
21
|
+
*/
|
|
22
|
+
/** Decide whether a mount can host frame capture — a real WebGL2 context with
|
|
23
|
+
* the draw entry points, never a headless/stub renderer. Exported so the
|
|
24
|
+
* mount uses ONE predicate and a unit test can assert both sides (mock GL ⇒
|
|
25
|
+
* the context; headless/missing ⇒ null) without a GPU. */
|
|
26
|
+
export function frameCaptureContextFor(headless, rendererContext) {
|
|
27
|
+
if (headless)
|
|
28
|
+
return null;
|
|
29
|
+
if (!rendererContext || typeof rendererContext !== 'object')
|
|
30
|
+
return null;
|
|
31
|
+
const gl = rendererContext;
|
|
32
|
+
if (typeof gl.getExtension !== 'function')
|
|
33
|
+
return null;
|
|
34
|
+
if (typeof gl.drawArrays !== 'function' || typeof gl.drawElements !== 'function')
|
|
35
|
+
return null;
|
|
36
|
+
return rendererContext;
|
|
37
|
+
}
|
|
38
|
+
/** Objects three actually issues draws for (and thus calls `onBeforeRender`
|
|
39
|
+
* on before the main-pass draw). */
|
|
40
|
+
function isRenderable(object) {
|
|
41
|
+
const o = object;
|
|
42
|
+
return Boolean(o.isMesh || o.isSkinnedMesh || o.isPoints || o.isLine || o.isSprite);
|
|
43
|
+
}
|
|
44
|
+
function annotationFor(object) {
|
|
45
|
+
const mesh = object;
|
|
46
|
+
const geometry = mesh.geometry;
|
|
47
|
+
const rawMaterial = mesh.material;
|
|
48
|
+
const material = (Array.isArray(rawMaterial) ? rawMaterial[0] : rawMaterial);
|
|
49
|
+
const entityId = object.userData?.['entityId'];
|
|
50
|
+
return {
|
|
51
|
+
object: {
|
|
52
|
+
name: object.name || object.type,
|
|
53
|
+
type: object.type,
|
|
54
|
+
...(entityId !== undefined ? { entityId: String(entityId) } : {}),
|
|
55
|
+
},
|
|
56
|
+
geometry: {
|
|
57
|
+
type: geometry?.type ?? 'unknown',
|
|
58
|
+
name: geometry?.name ?? '',
|
|
59
|
+
attributes: geometry ? Object.keys(geometry.attributes) : [],
|
|
60
|
+
indexed: Boolean(geometry?.index),
|
|
61
|
+
},
|
|
62
|
+
material: {
|
|
63
|
+
type: material?.type ?? 'unknown',
|
|
64
|
+
name: material?.name ?? '',
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function createRenderDebugAdapter(deps) {
|
|
69
|
+
const { capture, scene, memory } = deps;
|
|
70
|
+
const timeoutMs = deps.timeoutMs ?? 5000;
|
|
71
|
+
const setTimer = deps.setTimeoutFn ?? ((fn, ms) => setTimeout(fn, ms));
|
|
72
|
+
const clearTimer = deps.clearTimeoutFn ?? ((h) => clearTimeout(h));
|
|
73
|
+
let pending = null;
|
|
74
|
+
function wrapOnBeforeRender() {
|
|
75
|
+
const restores = [];
|
|
76
|
+
scene.traverse((object) => {
|
|
77
|
+
if (!isRenderable(object))
|
|
78
|
+
return;
|
|
79
|
+
const original = object.onBeforeRender;
|
|
80
|
+
object.onBeforeRender = function patched(...args) {
|
|
81
|
+
capture.annotateNextDraw(annotationFor(object));
|
|
82
|
+
original.apply(this, args);
|
|
83
|
+
};
|
|
84
|
+
restores.push(() => {
|
|
85
|
+
object.onBeforeRender = original;
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
return restores;
|
|
89
|
+
}
|
|
90
|
+
function settlePending() {
|
|
91
|
+
const p = pending;
|
|
92
|
+
if (p && !p.settled) {
|
|
93
|
+
p.settled = true;
|
|
94
|
+
clearTimer(p.timer);
|
|
95
|
+
for (const restore of p.restores)
|
|
96
|
+
restore();
|
|
97
|
+
pending = null;
|
|
98
|
+
return p;
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const adapter = {
|
|
103
|
+
captureFrame() {
|
|
104
|
+
if (pending) {
|
|
105
|
+
return Promise.reject(new Error('RenderDebugAdapter: a frame capture is already pending'));
|
|
106
|
+
}
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const restores = wrapOnBeforeRender();
|
|
109
|
+
capture.arm();
|
|
110
|
+
// Assign `pending` BEFORE arming the timer so a synchronous injected
|
|
111
|
+
// timer (test) sees a settle-able pending rather than a null one.
|
|
112
|
+
const p = { resolve, reject, restores, timer: null, settled: false };
|
|
113
|
+
pending = p;
|
|
114
|
+
p.timer = setTimer(() => {
|
|
115
|
+
if (settlePending()) {
|
|
116
|
+
reject(new Error(`RenderDebugAdapter: no frame rendered within ${timeoutMs}ms — the world may be paused or stopped`));
|
|
117
|
+
}
|
|
118
|
+
}, timeoutMs);
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
...(memory ? { memorySnapshot: () => memory() } : {}),
|
|
122
|
+
};
|
|
123
|
+
return {
|
|
124
|
+
adapter,
|
|
125
|
+
beforeRender() {
|
|
126
|
+
capture.beginPass();
|
|
127
|
+
},
|
|
128
|
+
afterRender() {
|
|
129
|
+
const result = capture.endPass();
|
|
130
|
+
if (result && pending) {
|
|
131
|
+
const p = settlePending();
|
|
132
|
+
p?.resolve(result);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
dispose() {
|
|
136
|
+
const p = settlePending();
|
|
137
|
+
if (p)
|
|
138
|
+
p.reject(new Error('RenderDebugAdapter: disposed before a frame was captured'));
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-party GPU-memory estimator (W4b, F11 profiler memory tab).
|
|
3
|
+
*
|
|
4
|
+
* Walks a live three.js scene and reports geometry/texture byte footprints
|
|
5
|
+
* from data this engine ALREADY holds — attribute buffers and texture images —
|
|
6
|
+
* plus the renderer's own resource counts (`renderer.info`). Uses three.js
|
|
7
|
+
* directly, no wrapper.
|
|
8
|
+
*
|
|
9
|
+
* HONESTY (adapters never fabricate; unmeasurable = absent-with-reason):
|
|
10
|
+
* - `estimateGeometryBytes` is EXACT: the summed `byteLength` of every
|
|
11
|
+
* attribute and index array. Not an estimate at all — it is what the
|
|
12
|
+
* buffers occupy in CPU memory (and, uploaded 1:1, on the GPU).
|
|
13
|
+
* - `estimateTextureBytes` returns `null` when the footprint is genuinely
|
|
14
|
+
* unknowable at this seam (no image dimensions, or a pixel format/type we
|
|
15
|
+
* can't size). A null NEVER enters the totals — it goes to `unestimated[]`
|
|
16
|
+
* with a reason, so the panel can say "N textures unmeasured" instead of
|
|
17
|
+
* silently undercounting.
|
|
18
|
+
* - JS heap is deliberately NOT here: `performance.memory` is a browser-only
|
|
19
|
+
* global read editor-side (M2), not an engine-scene property.
|
|
20
|
+
*/
|
|
21
|
+
import * as THREE from 'three';
|
|
22
|
+
export interface RenderMemoryEntry {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly bytes: number;
|
|
25
|
+
}
|
|
26
|
+
export interface RenderMemoryUnestimated {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly reason: string;
|
|
29
|
+
}
|
|
30
|
+
export interface RenderMemorySnapshot {
|
|
31
|
+
readonly counts: {
|
|
32
|
+
readonly geometries: number;
|
|
33
|
+
readonly textures: number;
|
|
34
|
+
/** Compiled program count, or `null` when the renderer doesn't expose it
|
|
35
|
+
* (`renderer.info.programs` is populated only after the first render). */
|
|
36
|
+
readonly programs: number | null;
|
|
37
|
+
};
|
|
38
|
+
/** Sum of every ESTIMABLE texture (nulls excluded — they are in
|
|
39
|
+
* `unestimated`). */
|
|
40
|
+
readonly estimatedTextureBytes: number;
|
|
41
|
+
/** Exact sum of geometry attribute + index buffers. */
|
|
42
|
+
readonly estimatedGeometryBytes: number;
|
|
43
|
+
readonly topTextures: readonly RenderMemoryEntry[];
|
|
44
|
+
readonly topGeometries: readonly RenderMemoryEntry[];
|
|
45
|
+
readonly unestimated: readonly RenderMemoryUnestimated[];
|
|
46
|
+
}
|
|
47
|
+
/** EXACT CPU/GPU footprint of a geometry's attribute + index buffers. */
|
|
48
|
+
export declare function estimateGeometryBytes(geometry: THREE.BufferGeometry): number;
|
|
49
|
+
/** Estimated GPU footprint of a texture, or `null` when unknowable at this
|
|
50
|
+
* seam (the caller routes null into `unestimated[]` with a reason). */
|
|
51
|
+
export declare function estimateTextureBytes(texture: THREE.Texture): number | null;
|
|
52
|
+
export declare function collectRenderMemory(scene: THREE.Object3D, info: THREE.WebGLInfo): RenderMemorySnapshot;
|
|
53
|
+
//# sourceMappingURL=render-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-memory.d.ts","sourceRoot":"","sources":["../../src/dev/render-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B;mFAC2E;QAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC,CAAC;IACF;0BACsB;IACtB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,uDAAuD;IACvD,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC1D;AA+CD,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,MAAM,CAoB5E;AAED;wEACwE;AACxE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,MAAM,GAAG,IAAI,CA0B1E;AAsDD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,CAAC,QAAQ,EACrB,IAAI,EAAE,KAAK,CAAC,SAAS,GACpB,oBAAoB,CAsCtB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-party GPU-memory estimator (W4b, F11 profiler memory tab).
|
|
3
|
+
*
|
|
4
|
+
* Walks a live three.js scene and reports geometry/texture byte footprints
|
|
5
|
+
* from data this engine ALREADY holds — attribute buffers and texture images —
|
|
6
|
+
* plus the renderer's own resource counts (`renderer.info`). Uses three.js
|
|
7
|
+
* directly, no wrapper.
|
|
8
|
+
*
|
|
9
|
+
* HONESTY (adapters never fabricate; unmeasurable = absent-with-reason):
|
|
10
|
+
* - `estimateGeometryBytes` is EXACT: the summed `byteLength` of every
|
|
11
|
+
* attribute and index array. Not an estimate at all — it is what the
|
|
12
|
+
* buffers occupy in CPU memory (and, uploaded 1:1, on the GPU).
|
|
13
|
+
* - `estimateTextureBytes` returns `null` when the footprint is genuinely
|
|
14
|
+
* unknowable at this seam (no image dimensions, or a pixel format/type we
|
|
15
|
+
* can't size). A null NEVER enters the totals — it goes to `unestimated[]`
|
|
16
|
+
* with a reason, so the panel can say "N textures unmeasured" instead of
|
|
17
|
+
* silently undercounting.
|
|
18
|
+
* - JS heap is deliberately NOT here: `performance.memory` is a browser-only
|
|
19
|
+
* global read editor-side (M2), not an engine-scene property.
|
|
20
|
+
*/
|
|
21
|
+
import * as THREE from 'three';
|
|
22
|
+
const TOP_N = 10;
|
|
23
|
+
/** Channel count per pixel format. Packed/compressed formats are handled by
|
|
24
|
+
* the byte-size logic in {@link estimateTextureBytes}, not here. */
|
|
25
|
+
const FORMAT_CHANNELS = {
|
|
26
|
+
[THREE.AlphaFormat]: 1,
|
|
27
|
+
[THREE.RedFormat]: 1,
|
|
28
|
+
[THREE.RedIntegerFormat]: 1,
|
|
29
|
+
[THREE.RGFormat]: 2,
|
|
30
|
+
[THREE.RGIntegerFormat]: 2,
|
|
31
|
+
[THREE.RGBAFormat]: 4,
|
|
32
|
+
[THREE.RGBAIntegerFormat]: 4,
|
|
33
|
+
[THREE.DepthFormat]: 1,
|
|
34
|
+
[THREE.DepthStencilFormat]: 2,
|
|
35
|
+
};
|
|
36
|
+
/** Bytes per channel for a (non-packed) pixel type. */
|
|
37
|
+
const TYPE_BYTES = {
|
|
38
|
+
[THREE.UnsignedByteType]: 1,
|
|
39
|
+
[THREE.ByteType]: 1,
|
|
40
|
+
[THREE.ShortType]: 2,
|
|
41
|
+
[THREE.UnsignedShortType]: 2,
|
|
42
|
+
[THREE.IntType]: 4,
|
|
43
|
+
[THREE.UnsignedIntType]: 4,
|
|
44
|
+
[THREE.FloatType]: 4,
|
|
45
|
+
[THREE.HalfFloatType]: 2,
|
|
46
|
+
};
|
|
47
|
+
/** Packed pixel types occupy a FIXED size per texel regardless of channel
|
|
48
|
+
* count — sized here directly rather than via channels × type-bytes. */
|
|
49
|
+
const PACKED_TYPE_TEXEL_BYTES = {
|
|
50
|
+
[THREE.UnsignedShort4444Type]: 2,
|
|
51
|
+
[THREE.UnsignedShort5551Type]: 2,
|
|
52
|
+
[THREE.UnsignedInt248Type]: 4,
|
|
53
|
+
};
|
|
54
|
+
function bytesPerTexel(format, type) {
|
|
55
|
+
const packed = PACKED_TYPE_TEXEL_BYTES[type];
|
|
56
|
+
if (packed !== undefined)
|
|
57
|
+
return packed;
|
|
58
|
+
const channels = FORMAT_CHANNELS[format];
|
|
59
|
+
const typeBytes = TYPE_BYTES[type];
|
|
60
|
+
if (channels === undefined || typeBytes === undefined)
|
|
61
|
+
return null;
|
|
62
|
+
return channels * typeBytes;
|
|
63
|
+
}
|
|
64
|
+
/** EXACT CPU/GPU footprint of a geometry's attribute + index buffers. */
|
|
65
|
+
export function estimateGeometryBytes(geometry) {
|
|
66
|
+
// Interleaved attributes share ONE backing buffer (`attribute.data.array`);
|
|
67
|
+
// a plain attribute owns its own (`attribute.array`). Count each unique
|
|
68
|
+
// backing view exactly once.
|
|
69
|
+
const counted = new Set();
|
|
70
|
+
let bytes = 0;
|
|
71
|
+
const add = (view) => {
|
|
72
|
+
if (view && !counted.has(view)) {
|
|
73
|
+
counted.add(view);
|
|
74
|
+
bytes += view.byteLength;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
for (const attribute of Object.values(geometry.attributes)) {
|
|
78
|
+
const interleaved = attribute.data?.array;
|
|
79
|
+
add(interleaved ?? attribute.array);
|
|
80
|
+
}
|
|
81
|
+
add(geometry.index?.array);
|
|
82
|
+
return bytes;
|
|
83
|
+
}
|
|
84
|
+
/** Estimated GPU footprint of a texture, or `null` when unknowable at this
|
|
85
|
+
* seam (the caller routes null into `unestimated[]` with a reason). */
|
|
86
|
+
export function estimateTextureBytes(texture) {
|
|
87
|
+
// Compressed textures carry their real per-mip byte arrays — sum them; no
|
|
88
|
+
// format math needed and no estimate involved.
|
|
89
|
+
const compressed = texture;
|
|
90
|
+
if (compressed.isCompressedTexture &&
|
|
91
|
+
Array.isArray(compressed.mipmaps)) {
|
|
92
|
+
let bytes = 0;
|
|
93
|
+
for (const mip of compressed.mipmaps) {
|
|
94
|
+
const data = mip.data;
|
|
95
|
+
if (data?.byteLength)
|
|
96
|
+
bytes += data.byteLength;
|
|
97
|
+
}
|
|
98
|
+
return bytes;
|
|
99
|
+
}
|
|
100
|
+
const image = texture.image;
|
|
101
|
+
const width = image?.width;
|
|
102
|
+
const height = image?.height;
|
|
103
|
+
if (!width || !height)
|
|
104
|
+
return null;
|
|
105
|
+
const bpt = bytesPerTexel(texture.format, texture.type);
|
|
106
|
+
if (bpt === null)
|
|
107
|
+
return null;
|
|
108
|
+
const base = width * height * bpt;
|
|
109
|
+
return texture.generateMipmaps ? Math.round(base * 1.333) : base;
|
|
110
|
+
}
|
|
111
|
+
function textureName(texture) {
|
|
112
|
+
return texture.name || texture.image?.src || `texture:${texture.uuid}`;
|
|
113
|
+
}
|
|
114
|
+
function geometryName(geometry) {
|
|
115
|
+
return geometry.name || `${geometry.type}:${geometry.uuid}`;
|
|
116
|
+
}
|
|
117
|
+
function unestimatedReason(texture) {
|
|
118
|
+
const image = texture.image;
|
|
119
|
+
if (!image?.width || !image?.height)
|
|
120
|
+
return 'no image dimensions available';
|
|
121
|
+
return `unsupported format/type (format 0x${texture.format.toString(16)}, type 0x${texture.type.toString(16)})`;
|
|
122
|
+
}
|
|
123
|
+
/** Collect every unique geometry and texture referenced by a scene graph. */
|
|
124
|
+
function collectResources(scene) {
|
|
125
|
+
const geometries = new Map();
|
|
126
|
+
const textures = new Map();
|
|
127
|
+
const addMaterialTextures = (material) => {
|
|
128
|
+
for (const value of Object.values(material)) {
|
|
129
|
+
if (value && value.isTexture) {
|
|
130
|
+
const tex = value;
|
|
131
|
+
textures.set(tex.uuid, tex);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
scene.traverse((object) => {
|
|
136
|
+
const geometry = object.geometry;
|
|
137
|
+
if (geometry?.isBufferGeometry)
|
|
138
|
+
geometries.set(geometry.uuid, geometry);
|
|
139
|
+
const material = object.material;
|
|
140
|
+
if (Array.isArray(material))
|
|
141
|
+
material.forEach(addMaterialTextures);
|
|
142
|
+
else if (material)
|
|
143
|
+
addMaterialTextures(material);
|
|
144
|
+
});
|
|
145
|
+
// Scene-level environment/background textures count too.
|
|
146
|
+
for (const maybe of [scene]) {
|
|
147
|
+
for (const value of [maybe.background, maybe.environment]) {
|
|
148
|
+
if (value && value.isTexture) {
|
|
149
|
+
const tex = value;
|
|
150
|
+
textures.set(tex.uuid, tex);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { geometries, textures };
|
|
155
|
+
}
|
|
156
|
+
export function collectRenderMemory(scene, info) {
|
|
157
|
+
const { geometries, textures } = collectResources(scene);
|
|
158
|
+
const geometryEntries = [];
|
|
159
|
+
let estimatedGeometryBytes = 0;
|
|
160
|
+
for (const geometry of geometries.values()) {
|
|
161
|
+
const bytes = estimateGeometryBytes(geometry);
|
|
162
|
+
estimatedGeometryBytes += bytes;
|
|
163
|
+
geometryEntries.push({ name: geometryName(geometry), bytes });
|
|
164
|
+
}
|
|
165
|
+
const textureEntries = [];
|
|
166
|
+
const unestimated = [];
|
|
167
|
+
let estimatedTextureBytes = 0;
|
|
168
|
+
for (const texture of textures.values()) {
|
|
169
|
+
const bytes = estimateTextureBytes(texture);
|
|
170
|
+
if (bytes === null) {
|
|
171
|
+
unestimated.push({ name: textureName(texture), reason: unestimatedReason(texture) });
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
estimatedTextureBytes += bytes;
|
|
175
|
+
textureEntries.push({ name: textureName(texture), bytes });
|
|
176
|
+
}
|
|
177
|
+
const byBytesDesc = (a, b) => b.bytes - a.bytes;
|
|
178
|
+
return {
|
|
179
|
+
counts: {
|
|
180
|
+
geometries: info.memory.geometries,
|
|
181
|
+
textures: info.memory.textures,
|
|
182
|
+
programs: info.programs ? info.programs.length : null,
|
|
183
|
+
},
|
|
184
|
+
estimatedTextureBytes,
|
|
185
|
+
estimatedGeometryBytes,
|
|
186
|
+
topTextures: textureEntries.sort(byBytesDesc).slice(0, TOP_N),
|
|
187
|
+
topGeometries: geometryEntries.sort(byBytesDesc).slice(0, TOP_N),
|
|
188
|
+
unestimated,
|
|
189
|
+
};
|
|
190
|
+
}
|