@babylonjs/lite 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +381 -375
- package/dist/index.js.map +1 -1
- package/index.d.ts +757 -0
- package/lib/audio/analyzer.js +65 -0
- package/lib/audio/analyzer.js.map +1 -0
- package/lib/audio/audio-bus.js +38 -0
- package/lib/audio/audio-bus.js.map +1 -0
- package/lib/audio/audio-engine.js +188 -0
- package/lib/audio/audio-engine.js.map +1 -0
- package/lib/audio/audio-fetch.js +18 -0
- package/lib/audio/audio-fetch.js.map +1 -0
- package/lib/audio/audio-param.js +96 -0
- package/lib/audio/audio-param.js.map +1 -0
- package/lib/audio/audio-signal.js +46 -0
- package/lib/audio/audio-signal.js.map +1 -0
- package/lib/audio/bus.js +33 -0
- package/lib/audio/bus.js.map +1 -0
- package/lib/audio/host-types.js +2 -0
- package/lib/audio/host-types.js.map +1 -0
- package/lib/audio/index.js +12 -0
- package/lib/audio/index.js.map +1 -0
- package/lib/audio/sound-buffer.js +59 -0
- package/lib/audio/sound-buffer.js.map +1 -0
- package/lib/audio/sound-source.js +57 -0
- package/lib/audio/sound-source.js.map +1 -0
- package/lib/audio/sound-sub-graph.js +72 -0
- package/lib/audio/sound-sub-graph.js.map +1 -0
- package/lib/audio/spatial.js +466 -0
- package/lib/audio/spatial.js.map +1 -0
- package/lib/audio/static-sound.js +313 -0
- package/lib/audio/static-sound.js.map +1 -0
- package/lib/audio/stereo.js +40 -0
- package/lib/audio/stereo.js.map +1 -0
- package/lib/audio/streaming-sound.js +377 -0
- package/lib/audio/streaming-sound.js.map +1 -0
- package/lib/audio/unmute-ui.js +72 -0
- package/lib/audio/unmute-ui.js.map +1 -0
- package/lib/audio/visualizer.js +101 -0
- package/lib/audio/visualizer.js.map +1 -0
- package/lib/engine/engine.js +1 -1
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -1
- package/lib/light/types.js.map +1 -1
- package/lib/loader-gltf/animation-pointer-basecolor.js +25 -0
- package/lib/loader-gltf/animation-pointer-basecolor.js.map +1 -0
- package/lib/loader-gltf/animation-pointer-ext.js +244 -0
- package/lib/loader-gltf/animation-pointer-ext.js.map +1 -0
- package/lib/loader-gltf/animation-pointer-lights.js +46 -0
- package/lib/loader-gltf/animation-pointer-lights.js.map +1 -0
- package/lib/loader-gltf/animation-pointer.js +4 -1
- package/lib/loader-gltf/animation-pointer.js.map +1 -1
- package/lib/loader-gltf/gltf-animation.js +5 -3
- package/lib/loader-gltf/gltf-animation.js.map +1 -1
- package/lib/loader-gltf/gltf-color-normalize.js +10 -1
- package/lib/loader-gltf/gltf-color-normalize.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-animation-pointer.js +67 -47
- package/lib/loader-gltf/gltf-feature-animation-pointer.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-lights-punctual.js +51 -9
- package/lib/loader-gltf/gltf-feature-lights-punctual.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-primitive.js +20 -0
- package/lib/loader-gltf/gltf-feature-primitive.js.map +1 -0
- package/lib/loader-gltf/gltf-feature-registry.js +25 -0
- package/lib/loader-gltf/gltf-feature-registry.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-skeleton.js +18 -3
- package/lib/loader-gltf/gltf-feature-skeleton.js.map +1 -1
- package/lib/loader-gltf/gltf-interleave.js +3 -2
- package/lib/loader-gltf/gltf-interleave.js.map +1 -1
- package/lib/loader-gltf/gltf-light-pointer-state.js +18 -0
- package/lib/loader-gltf/gltf-light-pointer-state.js.map +1 -0
- package/lib/loader-gltf/gltf-parser.js +7 -1
- package/lib/loader-gltf/gltf-parser.js.map +1 -1
- package/lib/loader-gltf/gltf-pbr-builder-ext.js +1 -1
- package/lib/loader-gltf/gltf-pbr-builder-ext.js.map +1 -1
- package/lib/loader-gltf/gltf-pbr-builder.js +1 -1
- package/lib/loader-gltf/gltf-pbr-builder.js.map +1 -1
- package/lib/loader-gltf/gltf-sampler-denorm.js +20 -0
- package/lib/loader-gltf/gltf-sampler-denorm.js.map +1 -0
- package/lib/loader-gltf/gltf-sampler-desc.js +11 -2
- package/lib/loader-gltf/gltf-sampler-desc.js.map +1 -1
- package/lib/loader-gltf/gltf-uv-denorm.js +28 -0
- package/lib/loader-gltf/gltf-uv-denorm.js.map +1 -0
- package/lib/loader-gltf/load-gltf.js +15 -6
- package/lib/loader-gltf/load-gltf.js.map +1 -1
- package/lib/material/material-rebuild.js +4 -0
- package/lib/material/material-rebuild.js.map +1 -1
- package/lib/material/mesh-features.js +8 -1
- package/lib/material/mesh-features.js.map +1 -1
- package/lib/material/pbr/fragments/reflectance-fragment.js +1 -1
- package/lib/material/pbr/fragments/reflectance-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js +1 -1
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js.map +1 -1
- package/lib/material/pbr/pbr-pipeline.js +7 -3
- package/lib/material/pbr/pbr-pipeline.js.map +1 -1
- package/lib/material/pbr/pbr-primitive-resolver.js +34 -0
- package/lib/material/pbr/pbr-primitive-resolver.js.map +1 -0
- package/lib/material/pbr/pbr-renderable.js +1 -1
- package/lib/material/pbr/pbr-renderable.js.map +1 -1
- package/lib/material/shader/shader-material.js +9 -5
- package/lib/material/shader/shader-material.js.map +1 -1
- package/lib/material/shader/shader-thin-instance.js +1 -1
- package/lib/material/shader/shader-thin-instance.js.map +1 -1
- package/lib/material/standard/standard-renderable.js +1 -1
- package/lib/material/standard/standard-renderable.js.map +1 -1
- package/lib/mesh/mesh-dispose.js +1 -0
- package/lib/mesh/mesh-dispose.js.map +1 -1
- package/lib/mesh/thin-instance-cull-binding.js +15 -6
- package/lib/mesh/thin-instance-cull-binding.js.map +1 -1
- package/lib/scene/scene-core.js +1 -0
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/scene/scene-material-swap.js +2 -0
- package/lib/scene/scene-material-swap.js.map +1 -1
- package/lib/shadow/csm-shadow-task-hooks.js +67 -9
- package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
- package/lib/sprite/sprite-2d.js +4 -0
- package/lib/sprite/sprite-2d.js.map +1 -1
- package/lib/sprite/sprite-pipeline.js +25 -22
- package/lib/sprite/sprite-pipeline.js.map +1 -1
- package/lib/text/_gpu/text-pipeline.js +1 -1
- package/lib/text/_gpu/text-pipeline.js.map +1 -1
- package/lib/text/text-renderer.js +3 -1
- package/lib/text/text-renderer.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualizer.js","sources":["../../../src/audio/visualizer.ts"],"sourcesContent":["/**\n * Real-time audio visualizer — opt-in demo helper.\n *\n * Draws a frequency-bar + waveform display from an {@link AnalyzerSubNode} tap\n * to a 2D `<canvas>`. This is a Lite-specific presentation helper — Babylon.js\n * AudioV2 has no canvas visualizer — so it is intentional adaptation glue, not a\n * port. It builds on the faithful analyzer port (Phase 5) and is fully\n * tree-shakable: importing nothing from here costs nothing, and the module is\n * never referenced by the core sound/bus/engine modules.\n *\n * The render loop uses `requestAnimationFrame` when available; a single frame can\n * also be drawn directly via {@link renderAudioVisualizerFrame} (used in tests).\n */\n\nimport { enableAnalyzer, getByteFrequencyData, getByteTimeDomainData } from \"./analyzer.js\";\nimport { type AudioGraphHost } from \"./host-types.js\";\n\n/** What to draw in the visualizer. */\nexport type AudioVisualizerMode = \"bars\" | \"waveform\" | \"both\";\n\n/** Default visualizer settings. */\nconst Defaults = {\n fftSize: 2048,\n smoothing: 0.8,\n mode: \"both\" as AudioVisualizerMode,\n backgroundColor: \"#101014\",\n barColor: \"#4fc3f7\",\n waveformColor: \"#ffffff\",\n} as const;\n\n/** Options for {@link createAudioVisualizer}. */\nexport interface AudioVisualizerOptions {\n /** FFT window size (a power of two). Defaults to `2048`. */\n fftSize?: number;\n /** Analyzer time-averaging constant in `[0, 1]`. Defaults to `0.8`. */\n smoothing?: number;\n /** What to draw. Defaults to `\"both\"`. */\n mode?: AudioVisualizerMode;\n /** Canvas background fill. Defaults to `\"#101014\"`. */\n backgroundColor?: string;\n /** Frequency-bar color. Defaults to `\"#4fc3f7\"`. */\n barColor?: string;\n /** Waveform line color. Defaults to `\"#ffffff\"`. */\n waveformColor?: string;\n}\n\n/** Visualizer state. Pure state — driven by the visualizer functions. */\nexport interface AudioVisualizer {\n /** The canvas being drawn to. */\n readonly canvas: HTMLCanvasElement;\n /** @internal */ _host: AudioGraphHost;\n /** @internal */ _ctx2d: CanvasRenderingContext2D;\n /** @internal */ _mode: AudioVisualizerMode;\n /** @internal */ _bgColor: string;\n /** @internal */ _barColor: string;\n /** @internal */ _waveColor: string;\n /** @internal */ _freq: Uint8Array;\n /** @internal */ _time: Uint8Array;\n /** @internal */ _raf: number | null;\n /** @internal */ _dispose(): void;\n}\n\n/**\n * Creates a real-time visualizer that taps the host's analyzer and draws to the\n * given canvas. Enables the analyzer on the host if it is not already enabled.\n * Call {@link startAudioVisualizer} to begin the animation loop.\n * @param host - A `StaticSound`, `StreamingSound`, `AudioBus`, or input source.\n * @param canvas - The destination 2D canvas.\n * @param options - Visualizer options.\n * @returns The visualizer handle; dispose it with {@link disposeAudioVisualizer}.\n * @throws If a 2D context cannot be obtained from the canvas.\n */\nexport function createAudioVisualizer(host: AudioGraphHost, canvas: HTMLCanvasElement, options: AudioVisualizerOptions = {}): AudioVisualizer {\n const fftSize = options.fftSize ?? Defaults.fftSize;\n enableAnalyzer(host, { fftSize, smoothing: options.smoothing ?? Defaults.smoothing });\n\n const ctx2d = canvas.getContext(\"2d\");\n if (!ctx2d) {\n throw new Error(\"Unable to get a 2D context from the visualizer canvas.\");\n }\n\n const viz: AudioVisualizer = {\n canvas,\n _host: host,\n _ctx2d: ctx2d,\n _mode: options.mode ?? Defaults.mode,\n _bgColor: options.backgroundColor ?? Defaults.backgroundColor,\n _barColor: options.barColor ?? Defaults.barColor,\n _waveColor: options.waveformColor ?? Defaults.waveformColor,\n _freq: new Uint8Array(fftSize / 2),\n _time: new Uint8Array(fftSize),\n _raf: null,\n _dispose: () => disposeAudioVisualizer(viz),\n };\n return viz;\n}\n\nfunction drawBars(viz: AudioVisualizer, width: number, height: number): void {\n const ctx = viz._ctx2d;\n const bins = viz._freq;\n getByteFrequencyData(viz._host, bins);\n const count = bins.length;\n const barWidth = width / count;\n ctx.fillStyle = viz._barColor;\n for (let i = 0; i < count; i++) {\n const magnitude = bins[i]! / 255;\n const barHeight = magnitude * height;\n ctx.fillRect(i * barWidth, height - barHeight, Math.max(barWidth - 1, 1), barHeight);\n }\n}\n\nfunction drawWaveform(viz: AudioVisualizer, width: number, height: number): void {\n const ctx = viz._ctx2d;\n const samples = viz._time;\n getByteTimeDomainData(viz._host, samples);\n const count = samples.length;\n const step = width / count;\n ctx.lineWidth = 2;\n ctx.strokeStyle = viz._waveColor;\n ctx.beginPath();\n for (let i = 0; i < count; i++) {\n // Byte time-domain data is centered on 128; map to [0, height].\n const y = (samples[i]! / 255) * height;\n const x = i * step;\n if (i === 0) {\n ctx.moveTo(x, y);\n } else {\n ctx.lineTo(x, y);\n }\n }\n ctx.stroke();\n}\n\n/**\n * Draws a single visualizer frame from the current analyzer data. Safe to call\n * directly (e.g. from a custom loop or a test) without starting the built-in\n * animation loop.\n * @param viz - The visualizer handle.\n */\nexport function renderAudioVisualizerFrame(viz: AudioVisualizer): void {\n const { width, height } = viz.canvas;\n const ctx = viz._ctx2d;\n ctx.fillStyle = viz._bgColor;\n ctx.fillRect(0, 0, width, height);\n\n if (viz._mode === \"bars\" || viz._mode === \"both\") {\n drawBars(viz, width, height);\n }\n if (viz._mode === \"waveform\" || viz._mode === \"both\") {\n drawWaveform(viz, width, height);\n }\n}\n\n/**\n * Starts the `requestAnimationFrame` render loop. No-op if already running or if\n * `requestAnimationFrame` is unavailable (e.g. a non-browser environment).\n * @param viz - The visualizer handle.\n */\nexport function startAudioVisualizer(viz: AudioVisualizer): void {\n if (viz._raf !== null || typeof requestAnimationFrame !== \"function\") {\n return;\n }\n const loop = () => {\n renderAudioVisualizerFrame(viz);\n viz._raf = requestAnimationFrame(loop);\n };\n viz._raf = requestAnimationFrame(loop);\n}\n\n/**\n * Stops the render loop if it is running.\n * @param viz - The visualizer handle.\n */\nexport function stopAudioVisualizer(viz: AudioVisualizer): void {\n if (viz._raf !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(viz._raf);\n }\n viz._raf = null;\n }\n}\n\n/**\n * Stops the render loop and releases the visualizer. The underlying analyzer tap\n * stays on the host (dispose the host to release it).\n * @param viz - The visualizer handle.\n */\nexport function disposeAudioVisualizer(viz: AudioVisualizer): void {\n stopAudioVisualizer(viz);\n}\n"],"names":[],"mappings":"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"}
|
package/lib/engine/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _setHpmAllocator } from '../math/_matrix-allocator.js';
|
|
2
2
|
import { isDomCanvas, _buildSurface, resizeSurface, _refreshScRT, setSurfaceSize } from './surface.js';
|
|
3
3
|
|
|
4
|
-
const VERSION = /* @__PURE__ */ (() => "1.
|
|
4
|
+
const VERSION = /* @__PURE__ */ (() => "1.5.0" )();
|
|
5
5
|
let _vis = 0;
|
|
6
6
|
function bumpVisibilityEpoch() {
|
|
7
7
|
_vis = _vis + 1 | 0;
|
package/lib/index.js
CHANGED
|
@@ -194,4 +194,15 @@ export { onPhysicsTrigger, setPhysicsShapeIsTrigger } from './physics/havok-trig
|
|
|
194
194
|
export { createPhysicsViewer, disposePhysicsViewer, hidePhysicsBody, showPhysicsBody, showPhysicsConstraint } from './physics/physics-viewer.js';
|
|
195
195
|
export { CharacterCollisionObservable, CharacterSupportedState, PhysicsCharacterController, createPhysicsCharacterController } from './physics/character-controller.js';
|
|
196
196
|
export { addAgent, addBoxObstacle, addCylinderObstacle, agentGoto, computePath, createDebugNavMeshGeometry, createNavCrowd, createNavMesh, createNavMeshFromSources, createNavigationPluginAsync, disposeNavigationPlugin, findRandomPoint, findRandomPointAroundCircle, getAgentPosition, getAgentVelocity, getClosestPoint, getNavigationRandomSeed, raycast, removeObstacle, setNavigationRandomSeed, updateNavCrowd, updateNavMeshObstacles } from './navigation/navigation.js';
|
|
197
|
+
export { createAudioEngineAsync, disposeAudioEngine, getMasterVolume, setMasterVolume, unlockAudioEngineAsync } from './audio/audio-engine.js';
|
|
198
|
+
export { SoundState, createSoundAsync, disposeSound, pauseSound, playSound, resumeSound, setSoundVolume, stopSound } from './audio/static-sound.js';
|
|
199
|
+
export { createStreamingSoundAsync, disposeStreamingSound, pauseStreamingSound, playStreamingSound, preloadStreamingInstanceAsync, preloadStreamingInstancesAsync, resumeStreamingSound, setStreamingSoundVolume, stopStreamingSound } from './audio/streaming-sound.js';
|
|
200
|
+
export { createAudioBusAsync, disposeAudioBus, setBusVolume } from './audio/audio-bus.js';
|
|
201
|
+
export { attachSpatialTarget, detachSpatialTarget, enableSpatial, setSpatialAutoUpdate, setSpatialListener, setSpatialListenerPosition, setSpatialOrientation, setSpatialPosition, updateSpatialAudio } from './audio/spatial.js';
|
|
202
|
+
export { enableStereo, setStereoPan } from './audio/stereo.js';
|
|
203
|
+
export { enableAnalyzer, getByteFrequencyData, getByteTimeDomainData, getFloatFrequencyData, getFloatTimeDomainData } from './audio/analyzer.js';
|
|
204
|
+
export { createMicrophoneSoundSourceAsync, createSoundSourceAsync, disposeSoundSource, setSoundSourceVolume } from './audio/sound-source.js';
|
|
205
|
+
export { createUnmuteUI, disposeUnmuteUI, setUnmuteUIEnabled } from './audio/unmute-ui.js';
|
|
206
|
+
export { createAudioVisualizer, disposeAudioVisualizer, renderAudioVisualizerFrame, startAudioVisualizer, stopAudioVisualizer } from './audio/visualizer.js';
|
|
207
|
+
export { createSoundBufferAsync } from './audio/sound-buffer.js';
|
|
197
208
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/light/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/light/types.ts"],"sourcesContent":["/** Light extension types and registry.\n *\n * Each light type provides pipeline integration callbacks.\n * PBR + Standard both consume the shared lights UBO (render/lights-ubo.ts);\n * light type is encoded in vLightData.w (1=dir, 2=spot, 3=hemi, other=point). */\n\nimport type { Mat4 } from \"../math/types.js\";\nimport type { IWorldMatrixProvider, IParentable } from \"../scene/parentable.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\n\n/** Shared base for all light types.\n * Provides pipeline integration callbacks so render pipelines are light-agnostic. */\nexport interface LightBase extends IWorldMatrixProvider, IParentable {\n readonly lightType: string;\n children: SceneNode[];\n /** Mesh IDs excluded from this light. If set, these meshes are NOT lit by this light. */\n excludedMeshIds?: ReadonlySet<string>;\n /** If non-empty, ONLY these mesh IDs are lit by this light. Takes priority over excludedMeshIds. */\n includedOnlyMeshIds?: ReadonlySet<string>;\n /** Shadow generator attached to this light. Set this to make the light cast shadows. */\n shadowGenerator?: import(\"../shadow/shadow-generator.js\").ShadowGenerator;\n\n parent: IWorldMatrixProvider | null;\n readonly worldMatrix: Mat4;\n readonly worldMatrixVersion: number;\n /** @internal Write this light's 64-byte entry into the shared lights UBO.\n * Positions are written precision-only (raw world space); under floating\n * origin the active-camera offset is subtracted afterwards by\n * `engine._applyLightFoOffset`, which is kept out of non-LWR bundles. */\n readonly _writeLightUbo?: ((data: Float32Array, offset: number) => void) | undefined;\n /** @internal Monotonically increasing version — bumped when any UBO-relevant property changes. */\n readonly _lightVersion: number;\n}\n\n/** Maximum number of scene lights packed into the shared lights UBO.\n * Babylon.js defaults to 4 lights per material; Babylon Lite's cap is scene-wide\n * because all materials index the same group-0 lights buffer. Raise via\n * `setMaxLights(n)` before creating any scene / loading any asset that needs\n * more lights (e.g. the glTF loader auto-raises this when an asset declares\n * more KHR_lights_punctual lights than the current cap). */\nexport let MAX_LIGHTS = 16;\n\n/** Raise (or lower) the maximum number of scene lights in the shared lights UBO.\n * Must be called BEFORE scene pipelines are compiled — existing pipelines\n * and UBOs bake the cap into their WGSL/layout. */\nexport function setMaxLights(n: number): void {\n if (!Number.isFinite(n) || n < 1) {\n throw new Error(`setMaxLights: expected positive integer, got ${n}`);\n }\n MAX_LIGHTS = n | 0;\n}\n\n/** Bytes per light entry in the lights UBO (4 × vec4 = 64 bytes). */\nexport const LIGHT_ENTRY_FLOATS = 16;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/light/types.ts"],"sourcesContent":["/** Light extension types and registry.\n *\n * Each light type provides pipeline integration callbacks.\n * PBR + Standard both consume the shared lights UBO (render/lights-ubo.ts);\n * light type is encoded in vLightData.w (1=dir, 2=spot, 3=hemi, other=point). */\n\nimport type { Mat4 } from \"../math/types.js\";\nimport type { IWorldMatrixProvider, IParentable } from \"../scene/parentable.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\n\n/** Shared base for all light types.\n * Provides pipeline integration callbacks so render pipelines are light-agnostic. */\nexport interface LightBase extends IWorldMatrixProvider, IParentable {\n readonly lightType: string;\n children: SceneNode[];\n /** Mesh IDs excluded from this light. If set, these meshes are NOT lit by this light. */\n excludedMeshIds?: ReadonlySet<string>;\n /** If non-empty, ONLY these mesh IDs are lit by this light. Takes priority over excludedMeshIds. */\n includedOnlyMeshIds?: ReadonlySet<string>;\n /** Shadow generator attached to this light. Set this to make the light cast shadows. */\n shadowGenerator?: import(\"../shadow/shadow-generator.js\").ShadowGenerator;\n\n parent: IWorldMatrixProvider | null;\n readonly worldMatrix: Mat4;\n readonly worldMatrixVersion: number;\n /** @internal Write this light's 64-byte entry into the shared lights UBO.\n * Positions are written precision-only (raw world space); under floating\n * origin the active-camera offset is subtracted afterwards by\n * `engine._applyLightFoOffset`, which is kept out of non-LWR bundles. */\n readonly _writeLightUbo?: ((data: Float32Array, offset: number) => void) | undefined;\n /** @internal Monotonically increasing version — bumped when any UBO-relevant property changes. */\n readonly _lightVersion: number;\n /** @internal Bumps `_lightVersion` after direct mutation of scalar/array light fields. */\n readonly _bumpLightVersion?: (() => void) | undefined;\n}\n\n/** Maximum number of scene lights packed into the shared lights UBO.\n * Babylon.js defaults to 4 lights per material; Babylon Lite's cap is scene-wide\n * because all materials index the same group-0 lights buffer. Raise via\n * `setMaxLights(n)` before creating any scene / loading any asset that needs\n * more lights (e.g. the glTF loader auto-raises this when an asset declares\n * more KHR_lights_punctual lights than the current cap). */\nexport let MAX_LIGHTS = 16;\n\n/** Raise (or lower) the maximum number of scene lights in the shared lights UBO.\n * Must be called BEFORE scene pipelines are compiled — existing pipelines\n * and UBOs bake the cap into their WGSL/layout. */\nexport function setMaxLights(n: number): void {\n if (!Number.isFinite(n) || n < 1) {\n throw new Error(`setMaxLights: expected positive integer, got ${n}`);\n }\n MAX_LIGHTS = n | 0;\n}\n\n/** Bytes per light entry in the lights UBO (4 × vec4 = 64 bytes). */\nexport const LIGHT_ENTRY_FLOATS = 16;\n"],"names":[],"mappings":"AA0CO,IAAI,UAAA,GAAa;AAKjB,SAAS,aAAa,CAAA,EAAiB;AAC1C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,IAAI,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,CAAC,CAAA,CAAE,CAAA;AAAA,EACvE;AACA,EAAA,UAAA,GAAa,CAAA,GAAI,CAAA;AACrB;AAGO,MAAM,kBAAA,GAAqB;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
let _animBaseColorDefs = null;
|
|
2
|
+
function collectBaseColorDefs(json) {
|
|
3
|
+
for (const anim of json.animations ?? []) {
|
|
4
|
+
for (const ch of anim.channels ?? []) {
|
|
5
|
+
const ptr = ch.target?.extensions?.KHR_animation_pointer?.pointer;
|
|
6
|
+
const m = ptr && /^\/materials\/(\d+)\/pbrMetallicRoughness\/baseColorFactor$/.exec(ptr);
|
|
7
|
+
const def = m && json.materials?.[+m[1]];
|
|
8
|
+
if (def) {
|
|
9
|
+
(_animBaseColorDefs ??= /* @__PURE__ */ new WeakSet()).add(def);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function whiteFallback(mat) {
|
|
15
|
+
if (mat._rawMatDef && _animBaseColorDefs?.has(mat._rawMatDef) && !mat._baseColorImage) {
|
|
16
|
+
const f = mat._baseColorFactor;
|
|
17
|
+
const real = [f[0], f[1], f[2], f[3]];
|
|
18
|
+
mat._baseColorFactor = [1, 1, 1, 1];
|
|
19
|
+
return { baseColorFactor: real };
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { collectBaseColorDefs, whiteFallback };
|
|
25
|
+
//# sourceMappingURL=animation-pointer-basecolor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation-pointer-basecolor.js","sources":["../../../src/loader-gltf/animation-pointer-basecolor.ts"],"sourcesContent":["/** KHR_animation_pointer — animated baseColorFactor white-fallback handling.\n *\n * Dynamic-imported by the animation-pointer feature ONLY when a channel targets a\n * material's pbrMetallicRoughness/baseColorFactor, so scenes that animate just node\n * visibility / TRS / lights / UV transforms (e.g. scene34) never pay for it. */\nimport type { GltfMaterialData } from \"./gltf-material.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\n\n// Raw glTF material defs (json.materials[i] objects) whose baseColorFactor is animated.\n// Lazy-init (not a module-level allocation) so this module stays tree-shakable per GUIDANCE.\nlet _animBaseColorDefs: WeakSet<object> | null = null;\n\n/** Record every material def targeted by a baseColorFactor pointer so the white-fallback\n * below can recognise it during material assembly. */\nexport function collectBaseColorDefs(json: any): void {\n for (const anim of json.animations ?? []) {\n for (const ch of anim.channels ?? []) {\n const ptr = ch.target?.extensions?.KHR_animation_pointer?.pointer as string | undefined;\n const m = ptr && /^\\/materials\\/(\\d+)\\/pbrMetallicRoughness\\/baseColorFactor$/.exec(ptr);\n const def = m && json.materials?.[+m[1]!];\n if (def) {\n (_animBaseColorDefs ??= new WeakSet<object>()).add(def);\n }\n }\n }\n}\n\n/** For an UNTEXTURED material whose baseColorFactor is animated, the loader would bake the\n * (initial) factor into the 1×1 base-colour fallback AND multiply the animated factor in\n * the shader — doubling colour and alpha. Bake a WHITE fallback instead and route the\n * factor through the (animatable) baseColorFactor uniform. */\nexport function whiteFallback(mat: GltfMaterialData): Partial<PbrMaterialProps> | null {\n if (mat._rawMatDef && _animBaseColorDefs?.has(mat._rawMatDef) && !mat._baseColorImage) {\n const f = mat._baseColorFactor;\n const real: [number, number, number, number] = [f[0]!, f[1]!, f[2]!, f[3]!];\n mat._baseColorFactor = [1, 1, 1, 1];\n return { baseColorFactor: real };\n }\n return null;\n}\n"],"names":[],"mappings":"AAUA,IAAI,kBAAA,GAA6C,IAAA;AAI1C,SAAS,qBAAqB,IAAA,EAAiB;AAClD,EAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,UAAA,IAAc,EAAC,EAAG;AACtC,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,QAAA,IAAY,EAAC,EAAG;AAClC,MAAA,MAAM,GAAA,GAAM,EAAA,CAAG,MAAA,EAAQ,UAAA,EAAY,qBAAA,EAAuB,OAAA;AAC1D,MAAA,MAAM,CAAA,GAAI,GAAA,IAAO,6DAAA,CAA8D,IAAA,CAAK,GAAG,CAAA;AACvF,MAAA,MAAM,MAAM,CAAA,IAAK,IAAA,CAAK,YAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AACxC,MAAA,IAAI,GAAA,EAAK;AACL,QAAA,CAAC,kBAAA,qBAAuB,IAAI,OAAA,EAAgB,EAAG,IAAI,GAAG,CAAA;AAAA,MAC1D;AAAA,IACJ;AAAA,EACJ;AACJ;AAMO,SAAS,cAAc,GAAA,EAAyD;AACnF,EAAA,IAAI,GAAA,CAAI,cAAc,kBAAA,EAAoB,GAAA,CAAI,IAAI,UAAU,CAAA,IAAK,CAAC,GAAA,CAAI,eAAA,EAAiB;AACnF,IAAA,MAAM,IAAI,GAAA,CAAI,gBAAA;AACd,IAAA,MAAM,IAAA,GAAyC,CAAC,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAE,CAAA;AAC1E,IAAA,GAAA,CAAI,gBAAA,GAAmB,CAAC,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AAClC,IAAA,OAAO,EAAE,iBAAiB,IAAA,EAAK;AAAA,EACnC;AACA,EAAA,OAAO,IAAA;AACX;;;;"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { _appendPointerHandlers } from './animation-pointer.js';
|
|
2
|
+
|
|
3
|
+
function iorToF0Factor(ior) {
|
|
4
|
+
return ((ior - 1) / (ior + 1)) ** 2 / 0.04;
|
|
5
|
+
}
|
|
6
|
+
function bump(mat) {
|
|
7
|
+
mat._uboVersion++;
|
|
8
|
+
}
|
|
9
|
+
const _extHandlers = [
|
|
10
|
+
// BJS 9.5 registers the glTF metallicFactor pointer twice, with the second
|
|
11
|
+
// entry overwriting the first to animate PBRMaterial.roughness. Match that
|
|
12
|
+
// behavior for parity; roughnessFactor itself is not registered by BJS.
|
|
13
|
+
[
|
|
14
|
+
/^\/materials\/(\d+)\/pbrMetallicRoughness\/metallicFactor$/,
|
|
15
|
+
(m, ctx) => {
|
|
16
|
+
const mat = ctx.materials?.[+m[1]];
|
|
17
|
+
if (!mat) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
arity: 1,
|
|
22
|
+
writer: (out, off) => {
|
|
23
|
+
mat.roughnessFactor = out[off];
|
|
24
|
+
mat._uboVersion++;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
// /materials/{m}/normalTexture/scale — scalar glTF normal-map strength. The
|
|
30
|
+
// shader scale mod is provided by the lazy pbr-template-ext (loaded for materials
|
|
31
|
+
// that already carry a UV transform / vertex colour / UV2), so this writer only
|
|
32
|
+
// updates the existing `normalScale` UBO slot — no core shader path is added.
|
|
33
|
+
[
|
|
34
|
+
/^\/materials\/(\d+)\/normalTexture\/scale$/,
|
|
35
|
+
(m, ctx) => {
|
|
36
|
+
const mat = ctx.materials?.[+m[1]];
|
|
37
|
+
if (!mat) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
arity: 1,
|
|
42
|
+
writer: (out, off) => {
|
|
43
|
+
mat.normalTextureScale = out[off];
|
|
44
|
+
mat._uboVersion++;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
// /materials/{m}/extensions/KHR_materials_transmission/transmissionFactor
|
|
50
|
+
[
|
|
51
|
+
/^\/materials\/(\d+)\/extensions\/KHR_materials_transmission\/transmissionFactor$/,
|
|
52
|
+
(m, ctx) => {
|
|
53
|
+
const mat = ctx.materials?.[+m[1]];
|
|
54
|
+
const refr = mat?.subsurface?.refraction;
|
|
55
|
+
if (!mat || !refr) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
arity: 1,
|
|
60
|
+
writer: (out, off) => {
|
|
61
|
+
mat.transmissive = true;
|
|
62
|
+
refr.intensity = out[off];
|
|
63
|
+
bump(mat);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
// /materials/{m}/extensions/KHR_materials_ior/ior
|
|
69
|
+
[
|
|
70
|
+
/^\/materials\/(\d+)\/extensions\/KHR_materials_ior\/ior$/,
|
|
71
|
+
(m, ctx) => {
|
|
72
|
+
const mat = ctx.materials?.[+m[1]];
|
|
73
|
+
if (!mat) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
arity: 1,
|
|
78
|
+
writer: (out, off) => {
|
|
79
|
+
const ior = out[off];
|
|
80
|
+
if (mat.subsurface?.refraction) {
|
|
81
|
+
mat.subsurface.refraction.indexOfRefraction = ior;
|
|
82
|
+
}
|
|
83
|
+
mat.metallicF0Factor = iorToF0Factor(ior);
|
|
84
|
+
mat.specularWeight = 1;
|
|
85
|
+
mat._hasReflExt = true;
|
|
86
|
+
bump(mat);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
// /materials/{m}/extensions/KHR_materials_volume/{thicknessFactor|attenuationDistance|attenuationColor}
|
|
92
|
+
[
|
|
93
|
+
/^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/(thicknessFactor|attenuationDistance|attenuationColor)$/,
|
|
94
|
+
(m, ctx) => {
|
|
95
|
+
const mat = ctx.materials?.[+m[1]];
|
|
96
|
+
if (!mat?.subsurface) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
arity: m[2] === "attenuationColor" ? 3 : 1,
|
|
101
|
+
writer: (out, off) => {
|
|
102
|
+
const ss = mat.subsurface;
|
|
103
|
+
if (m[2] === "thicknessFactor") {
|
|
104
|
+
ss.thickness ??= { min: 0, max: 0, useGlTFChannel: true };
|
|
105
|
+
ss.thickness.max = out[off];
|
|
106
|
+
if (ss.refraction) {
|
|
107
|
+
ss.refraction.useThicknessAsDepth = true;
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
ss.tint ??= { color: [1, 1, 1], atDistance: 1 };
|
|
111
|
+
if (m[2] === "attenuationDistance") {
|
|
112
|
+
ss.tint.atDistance = out[off];
|
|
113
|
+
} else {
|
|
114
|
+
ss.tint.color = [out[off], out[off + 1], out[off + 2]];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
bump(mat);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
// /materials/{m}/extensions/KHR_materials_iridescence/{iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum}
|
|
123
|
+
[
|
|
124
|
+
/^\/materials\/(\d+)\/extensions\/KHR_materials_iridescence\/(iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum)$/,
|
|
125
|
+
(m, ctx) => {
|
|
126
|
+
const mat = ctx.materials?.[+m[1]];
|
|
127
|
+
const iri = mat?.iridescence;
|
|
128
|
+
if (!mat || !iri) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
arity: 1,
|
|
133
|
+
writer: (out, off) => {
|
|
134
|
+
const v = out[off];
|
|
135
|
+
if (m[2] === "iridescenceFactor") {
|
|
136
|
+
iri.intensity = v;
|
|
137
|
+
} else if (m[2] === "iridescenceIor") {
|
|
138
|
+
iri.indexOfRefraction = v;
|
|
139
|
+
} else {
|
|
140
|
+
iri.maximumThickness = v;
|
|
141
|
+
}
|
|
142
|
+
bump(mat);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
// /materials/{m}/occlusionTexture/strength — scalar ambient-occlusion strength.
|
|
148
|
+
// The occlusion mix (mix(1, orm.r, strength)) is supplied by the lazy reflectance
|
|
149
|
+
// ext, which the animation feature activates via `_hasReflExt`; this writer only
|
|
150
|
+
// updates the `occlusionStrength` UBO slot that ext owns — zero core shader cost.
|
|
151
|
+
[
|
|
152
|
+
/^\/materials\/(\d+)\/occlusionTexture\/strength$/,
|
|
153
|
+
(m, ctx) => {
|
|
154
|
+
const mat = ctx.materials?.[+m[1]];
|
|
155
|
+
if (!mat) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
arity: 1,
|
|
160
|
+
writer: (out, off) => {
|
|
161
|
+
mat.occlusionStrength = out[off];
|
|
162
|
+
mat._uboVersion++;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
];
|
|
168
|
+
_appendPointerHandlers(_extHandlers);
|
|
169
|
+
function seedExtMaterials(json, map) {
|
|
170
|
+
const occlusionStrengthAnimated = /* @__PURE__ */ new Set();
|
|
171
|
+
const transmissionAnimated = /* @__PURE__ */ new Set();
|
|
172
|
+
const iorAnimated = /* @__PURE__ */ new Set();
|
|
173
|
+
const volumeThicknessAnimated = /* @__PURE__ */ new Set();
|
|
174
|
+
const volumeTintAnimated = /* @__PURE__ */ new Set();
|
|
175
|
+
for (const anim of json.animations ?? []) {
|
|
176
|
+
for (const ch of anim.channels ?? []) {
|
|
177
|
+
const ptr = ch.target?.extensions?.KHR_animation_pointer?.pointer;
|
|
178
|
+
const os = ptr && /^\/materials\/(\d+)\/occlusionTexture\/strength$/.exec(ptr);
|
|
179
|
+
if (os) {
|
|
180
|
+
occlusionStrengthAnimated.add(+os[1]);
|
|
181
|
+
}
|
|
182
|
+
const tr = ptr && /^\/materials\/(\d+)\/extensions\/KHR_materials_transmission\/transmissionFactor$/.exec(ptr);
|
|
183
|
+
if (tr) {
|
|
184
|
+
transmissionAnimated.add(+tr[1]);
|
|
185
|
+
}
|
|
186
|
+
const ior = ptr && /^\/materials\/(\d+)\/extensions\/KHR_materials_ior\/ior$/.exec(ptr);
|
|
187
|
+
if (ior) {
|
|
188
|
+
iorAnimated.add(+ior[1]);
|
|
189
|
+
}
|
|
190
|
+
const vt = ptr && /^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/thicknessFactor$/.exec(ptr);
|
|
191
|
+
if (vt) {
|
|
192
|
+
volumeThicknessAnimated.add(+vt[1]);
|
|
193
|
+
}
|
|
194
|
+
const vc = ptr && /^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/(attenuationColor|attenuationDistance)$/.exec(ptr);
|
|
195
|
+
if (vc) {
|
|
196
|
+
volumeTintAnimated.add(+vc[1]);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
for (let matIdx = 0; matIdx < map.length; matIdx++) {
|
|
201
|
+
const pm = map[matIdx];
|
|
202
|
+
if (!pm) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const def = json.materials?.[matIdx];
|
|
206
|
+
if (occlusionStrengthAnimated.has(matIdx)) {
|
|
207
|
+
pm.occlusionStrength = def?.occlusionTexture?.strength ?? 1;
|
|
208
|
+
pm._hasReflExt = true;
|
|
209
|
+
pm._occlStrengthAnimated = true;
|
|
210
|
+
}
|
|
211
|
+
if (transmissionAnimated.has(matIdx)) {
|
|
212
|
+
pm.transmissive = true;
|
|
213
|
+
pm.subsurface ??= {};
|
|
214
|
+
pm.subsurface.refraction ??= {
|
|
215
|
+
intensity: def?.extensions?.KHR_materials_transmission?.transmissionFactor ?? 0,
|
|
216
|
+
indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (iorAnimated.has(matIdx)) {
|
|
220
|
+
pm.subsurface ??= {};
|
|
221
|
+
pm.subsurface.refraction ??= { intensity: 0, indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5 };
|
|
222
|
+
const ior = def?.extensions?.KHR_materials_ior?.ior ?? 1.5;
|
|
223
|
+
pm.metallicF0Factor = iorToF0Factor(ior);
|
|
224
|
+
pm.specularWeight = 1;
|
|
225
|
+
pm._hasReflExt = true;
|
|
226
|
+
}
|
|
227
|
+
if (volumeThicknessAnimated.has(matIdx) || volumeTintAnimated.has(matIdx)) {
|
|
228
|
+
pm.subsurface ??= {};
|
|
229
|
+
const eVol = def?.extensions?.KHR_materials_volume;
|
|
230
|
+
if (volumeThicknessAnimated.has(matIdx)) {
|
|
231
|
+
pm.subsurface.thickness ??= { min: 0, max: eVol?.thicknessFactor ?? 0, useGlTFChannel: true };
|
|
232
|
+
if (pm.subsurface.refraction) {
|
|
233
|
+
pm.subsurface.refraction.useThicknessAsDepth = true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (volumeTintAnimated.has(matIdx)) {
|
|
237
|
+
pm.subsurface.tint ??= { color: eVol?.attenuationColor ?? [1, 1, 1], atDistance: eVol?.attenuationDistance ?? 1 };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export { seedExtMaterials };
|
|
244
|
+
//# sourceMappingURL=animation-pointer-ext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation-pointer-ext.js","sources":["../../../src/loader-gltf/animation-pointer-ext.ts"],"sourcesContent":["/** KHR_animation_pointer — material factor / extension pointer writers + seeding.\n *\n * Holds the metallic / normalScale / occlusion / transmission / IOR / volume /\n * iridescence pointer writers and the load-time material seeding they need. This\n * module is dynamic-imported by the animation-pointer feature ONLY when a channel\n * targets one of these material pointers, so scenes that animate just node TRS /\n * visibility / base-color / UV transforms / lights never pay for it. On import it\n * appends its handlers to the shared resolver registry. */\nimport { _appendPointerHandlers, type PointerFactory, type PointerMaterial } from \"./animation-pointer.js\";\n\nfunction iorToF0Factor(ior: number): number {\n return ((ior - 1) / (ior + 1)) ** 2 / 0.04;\n}\n\nfunction bump(mat: PointerMaterial): void {\n mat._uboVersion++;\n}\n\nconst _extHandlers: [RegExp, PointerFactory][] = [\n // BJS 9.5 registers the glTF metallicFactor pointer twice, with the second\n // entry overwriting the first to animate PBRMaterial.roughness. Match that\n // behavior for parity; roughnessFactor itself is not registered by BJS.\n [\n /^\\/materials\\/(\\d+)\\/pbrMetallicRoughness\\/metallicFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat.roughnessFactor = out[off]!;\n mat._uboVersion++;\n },\n };\n },\n ],\n // /materials/{m}/normalTexture/scale — scalar glTF normal-map strength. The\n // shader scale mod is provided by the lazy pbr-template-ext (loaded for materials\n // that already carry a UV transform / vertex colour / UV2), so this writer only\n // updates the existing `normalScale` UBO slot — no core shader path is added.\n [\n /^\\/materials\\/(\\d+)\\/normalTexture\\/scale$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat.normalTextureScale = out[off]!;\n mat._uboVersion++;\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_transmission/transmissionFactor\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_transmission\\/transmissionFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n const refr = mat?.subsurface?.refraction;\n if (!mat || !refr) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat.transmissive = true;\n refr.intensity = out[off]!;\n bump(mat);\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_ior/ior\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_ior\\/ior$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n const ior = out[off]!;\n if (mat.subsurface?.refraction) {\n mat.subsurface.refraction.indexOfRefraction = ior;\n }\n mat.metallicF0Factor = iorToF0Factor(ior);\n mat.specularWeight = 1.0;\n mat._hasReflExt = true;\n bump(mat);\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_volume/{thicknessFactor|attenuationDistance|attenuationColor}\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_volume\\/(thicknessFactor|attenuationDistance|attenuationColor)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.subsurface) {\n return null;\n }\n return {\n arity: m[2] === \"attenuationColor\" ? 3 : 1,\n writer: (out, off) => {\n const ss = mat.subsurface!;\n if (m[2] === \"thicknessFactor\") {\n ss.thickness ??= { min: 0, max: 0, useGlTFChannel: true };\n ss.thickness.max = out[off]!;\n if (ss.refraction) {\n ss.refraction.useThicknessAsDepth = true;\n }\n } else {\n ss.tint ??= { color: [1, 1, 1], atDistance: 1 };\n if (m[2] === \"attenuationDistance\") {\n ss.tint.atDistance = out[off]!;\n } else {\n ss.tint.color = [out[off]!, out[off + 1]!, out[off + 2]!];\n }\n }\n bump(mat);\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_iridescence/{iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum}\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_iridescence\\/(iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n const iri = mat?.iridescence;\n if (!mat || !iri) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n const v = out[off]!;\n if (m[2] === \"iridescenceFactor\") {\n iri.intensity = v;\n } else if (m[2] === \"iridescenceIor\") {\n iri.indexOfRefraction = v;\n } else {\n iri.maximumThickness = v;\n }\n bump(mat);\n },\n };\n },\n ],\n // /materials/{m}/occlusionTexture/strength — scalar ambient-occlusion strength.\n // The occlusion mix (mix(1, orm.r, strength)) is supplied by the lazy reflectance\n // ext, which the animation feature activates via `_hasReflExt`; this writer only\n // updates the `occlusionStrength` UBO slot that ext owns — zero core shader cost.\n [\n /^\\/materials\\/(\\d+)\\/occlusionTexture\\/strength$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat.occlusionStrength = out[off]!;\n mat._uboVersion++;\n },\n };\n },\n ],\n];\n\n_appendPointerHandlers(_extHandlers);\n\n/** Seed load-time material state so the material-extension pointer writers above have\n * something to drive. A material whose transmission / IOR / volume / occlusion-strength\n * is animated from its default (e.g. transmissionFactor 0, occlusionStrength 1) would\n * otherwise compile without the relevant shader path, so the animation would write a\n * value nothing samples. Called by the feature's materialMap once this module is loaded;\n * `map` is indexed by glTF material index. */\nexport function seedExtMaterials(json: any, map: (PointerMaterial | undefined)[]): void {\n const occlusionStrengthAnimated = new Set<number>();\n const transmissionAnimated = new Set<number>();\n const iorAnimated = new Set<number>();\n const volumeThicknessAnimated = new Set<number>();\n const volumeTintAnimated = new Set<number>();\n for (const anim of json.animations ?? []) {\n for (const ch of anim.channels ?? []) {\n const ptr = ch.target?.extensions?.KHR_animation_pointer?.pointer as string | undefined;\n const os = ptr && /^\\/materials\\/(\\d+)\\/occlusionTexture\\/strength$/.exec(ptr);\n if (os) {\n occlusionStrengthAnimated.add(+os[1]!);\n }\n const tr = ptr && /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_transmission\\/transmissionFactor$/.exec(ptr);\n if (tr) {\n transmissionAnimated.add(+tr[1]!);\n }\n const ior = ptr && /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_ior\\/ior$/.exec(ptr);\n if (ior) {\n iorAnimated.add(+ior[1]!);\n }\n const vt = ptr && /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_volume\\/thicknessFactor$/.exec(ptr);\n if (vt) {\n volumeThicknessAnimated.add(+vt[1]!);\n }\n const vc = ptr && /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_volume\\/(attenuationColor|attenuationDistance)$/.exec(ptr);\n if (vc) {\n volumeTintAnimated.add(+vc[1]!);\n }\n }\n }\n for (let matIdx = 0; matIdx < map.length; matIdx++) {\n const pm = map[matIdx];\n if (!pm) {\n continue;\n }\n const def = json.materials?.[matIdx];\n // An animated occlusionTexture.strength is applied through the lazy reflectance\n // ext (mix(1, orm.r, strength)). Route the material to it via `_hasReflExt` and\n // force activation even though the load-time strength may still be its default 1.0\n // (the ext's default-factor F0 path is identical to the base template).\n if (occlusionStrengthAnimated.has(matIdx)) {\n pm.occlusionStrength = def?.occlusionTexture?.strength ?? 1;\n pm._hasReflExt = true;\n (pm as { _occlStrengthAnimated?: boolean })._occlStrengthAnimated = true;\n }\n if (transmissionAnimated.has(matIdx)) {\n pm.transmissive = true;\n pm.subsurface ??= {};\n pm.subsurface.refraction ??= {\n intensity: def?.extensions?.KHR_materials_transmission?.transmissionFactor ?? 0,\n indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5,\n };\n }\n if (iorAnimated.has(matIdx)) {\n pm.subsurface ??= {};\n pm.subsurface.refraction ??= { intensity: 0, indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5 };\n const ior = def?.extensions?.KHR_materials_ior?.ior ?? 1.5;\n pm.metallicF0Factor = iorToF0Factor(ior);\n pm.specularWeight = 1.0;\n pm._hasReflExt = true;\n }\n if (volumeThicknessAnimated.has(matIdx) || volumeTintAnimated.has(matIdx)) {\n pm.subsurface ??= {};\n const eVol = def?.extensions?.KHR_materials_volume;\n if (volumeThicknessAnimated.has(matIdx)) {\n pm.subsurface.thickness ??= { min: 0, max: eVol?.thicknessFactor ?? 0, useGlTFChannel: true };\n if (pm.subsurface.refraction) {\n pm.subsurface.refraction.useThicknessAsDepth = true;\n }\n }\n if (volumeTintAnimated.has(matIdx)) {\n pm.subsurface.tint ??= { color: eVol?.attenuationColor ?? [1, 1, 1], atDistance: eVol?.attenuationDistance ?? 1 };\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getGltfPunctualLight } from './gltf-light-pointer-state.js';
|
|
2
|
+
import { _appendPointerHandlers } from './animation-pointer.js';
|
|
3
|
+
|
|
4
|
+
const _lightHandlers = [
|
|
5
|
+
// /extensions/KHR_lights_punctual/lights/{l}/{color|intensity|range|spot/outerConeAngle}
|
|
6
|
+
[
|
|
7
|
+
/^\/extensions\/KHR_lights_punctual\/lights\/(\d+)\/(color|intensity|range|spot\/outerConeAngle)$/,
|
|
8
|
+
(m, ctx) => {
|
|
9
|
+
const lightIdx = +m[1];
|
|
10
|
+
const field = m[2];
|
|
11
|
+
const getLight = () => {
|
|
12
|
+
return getGltfPunctualLight(ctx._json, lightIdx) ?? null;
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
arity: field === "color" ? 3 : 1,
|
|
16
|
+
writer: (out, off) => {
|
|
17
|
+
const light = getLight();
|
|
18
|
+
if (!light) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (field === "color") {
|
|
22
|
+
if (light.diffuse) {
|
|
23
|
+
light.diffuse[0] = out[off];
|
|
24
|
+
light.diffuse[1] = out[off + 1];
|
|
25
|
+
light.diffuse[2] = out[off + 2];
|
|
26
|
+
}
|
|
27
|
+
if (light.specular) {
|
|
28
|
+
light.specular[0] = out[off];
|
|
29
|
+
light.specular[1] = out[off + 1];
|
|
30
|
+
light.specular[2] = out[off + 2];
|
|
31
|
+
}
|
|
32
|
+
} else if (field === "intensity") {
|
|
33
|
+
light.intensity = out[off];
|
|
34
|
+
} else if (field === "range") {
|
|
35
|
+
light.range = out[off];
|
|
36
|
+
} else if (light.lightType === "spot") {
|
|
37
|
+
light.angle = out[off] * 2;
|
|
38
|
+
}
|
|
39
|
+
light._bumpLightVersion?.();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
];
|
|
45
|
+
_appendPointerHandlers(_lightHandlers);
|
|
46
|
+
//# sourceMappingURL=animation-pointer-lights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation-pointer-lights.js","sources":["../../../src/loader-gltf/animation-pointer-lights.ts"],"sourcesContent":["/** KHR_animation_pointer — punctual-light pointer handler.\n *\n * Dynamic-imported by the animation-pointer feature ONLY when a channel targets a\n * KHR_lights_punctual light property, so scenes that don't animate lights never pay\n * for it. On import it appends its handler to the shared resolver registry. */\nimport type { LightBase } from \"../light/types.js\";\nimport { getGltfPunctualLight } from \"./gltf-light-pointer-state.js\";\nimport { _appendPointerHandlers, type PointerFactory } from \"./animation-pointer.js\";\n\nconst _lightHandlers: [RegExp, PointerFactory][] = [\n // /extensions/KHR_lights_punctual/lights/{l}/{color|intensity|range|spot/outerConeAngle}\n [\n /^\\/extensions\\/KHR_lights_punctual\\/lights\\/(\\d+)\\/(color|intensity|range|spot\\/outerConeAngle)$/,\n (m, ctx) => {\n const lightIdx = +m[1]!;\n const field = m[2]!;\n const getLight = ():\n | (LightBase & {\n diffuse?: [number, number, number];\n specular?: [number, number, number];\n intensity?: number;\n range?: number;\n angle?: number;\n })\n | null => {\n return (getGltfPunctualLight(ctx._json, lightIdx) as ReturnType<typeof getLight>) ?? null;\n };\n return {\n arity: field === \"color\" ? 3 : 1,\n writer: (out, off) => {\n const light = getLight();\n if (!light) {\n return;\n }\n if (field === \"color\") {\n // Mutate the existing diffuse/specular arrays in place — pointer\n // writers can run every frame, so avoid allocating a tuple per keyframe.\n // The UBO refresh is driven by `_bumpLightVersion()` below, not the assignment.\n if (light.diffuse) {\n light.diffuse[0] = out[off]!;\n light.diffuse[1] = out[off + 1]!;\n light.diffuse[2] = out[off + 2]!;\n }\n if (light.specular) {\n light.specular[0] = out[off]!;\n light.specular[1] = out[off + 1]!;\n light.specular[2] = out[off + 2]!;\n }\n } else if (field === \"intensity\") {\n light.intensity = out[off]!;\n } else if (field === \"range\") {\n light.range = out[off]!;\n } else if (light.lightType === \"spot\") {\n light.angle = out[off]! * 2;\n }\n light._bumpLightVersion?.();\n },\n };\n },\n ],\n];\n\n_appendPointerHandlers(_lightHandlers);\n"],"names":[],"mappings":";;;AASA,MAAM,cAAA,GAA6C;AAAA;AAAA,EAE/C;AAAA,IACI,kGAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,QAAA,GAAW,CAAC,CAAA,CAAE,CAAC,CAAA;AACrB,MAAA,MAAM,KAAA,GAAQ,EAAE,CAAC,CAAA;AACjB,MAAA,MAAM,WAAW,MAQH;AACV,QAAA,OAAQ,oBAAA,CAAqB,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA,IAAqC,IAAA;AAAA,MACzF,CAAA;AACA,MAAA,OAAO;AAAA,QACH,KAAA,EAAO,KAAA,KAAU,OAAA,GAAU,CAAA,GAAI,CAAA;AAAA,QAC/B,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,UAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,UAAA,IAAI,CAAC,KAAA,EAAO;AACR,YAAA;AAAA,UACJ;AACA,UAAA,IAAI,UAAU,OAAA,EAAS;AAInB,YAAA,IAAI,MAAM,OAAA,EAAS;AACf,cAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,cAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AAC9B,cAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,YAClC;AACA,YAAA,IAAI,MAAM,QAAA,EAAU;AAChB,cAAA,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA;AAC3B,cAAA,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AAC/B,cAAA,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,YACnC;AAAA,UACJ,CAAA,MAAA,IAAW,UAAU,WAAA,EAAa;AAC9B,YAAA,KAAA,CAAM,SAAA,GAAY,IAAI,GAAG,CAAA;AAAA,UAC7B,CAAA,MAAA,IAAW,UAAU,OAAA,EAAS;AAC1B,YAAA,KAAA,CAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AAAA,UACzB,CAAA,MAAA,IAAW,KAAA,CAAM,SAAA,KAAc,MAAA,EAAQ;AACnC,YAAA,KAAA,CAAM,KAAA,GAAQ,GAAA,CAAI,GAAG,CAAA,GAAK,CAAA;AAAA,UAC9B;AACA,UAAA,KAAA,CAAM,iBAAA,IAAoB;AAAA,QAC9B;AAAA,OACJ;AAAA,IACJ;AAAA;AAER,CAAA;AAEA,sBAAA,CAAuB,cAAc,CAAA"}
|
|
@@ -203,6 +203,9 @@ const _registry = [
|
|
|
203
203
|
}
|
|
204
204
|
]
|
|
205
205
|
];
|
|
206
|
+
function _appendPointerHandlers(handlers) {
|
|
207
|
+
_registry.push(...handlers);
|
|
208
|
+
}
|
|
206
209
|
const _warned = /* @__PURE__ */ new Set();
|
|
207
210
|
function resolveAnimationPointer(pointer, ctx) {
|
|
208
211
|
for (const [rx, make] of _registry) {
|
|
@@ -218,5 +221,5 @@ function resolveAnimationPointer(pointer, ctx) {
|
|
|
218
221
|
return null;
|
|
219
222
|
}
|
|
220
223
|
|
|
221
|
-
export { resolveAnimationPointer };
|
|
224
|
+
export { _appendPointerHandlers, resolveAnimationPointer };
|
|
222
225
|
//# sourceMappingURL=animation-pointer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation-pointer.js","sources":["../../../src/loader-gltf/animation-pointer.ts"],"sourcesContent":["/** KHR_animation_pointer — JSON-pointer resolver registry.\n * Handlers are registered incrementally (one per parity scene). Unknown\n * pointers return null and warn once. */\nimport type { SceneNode } from \"../scene/scene-node.js\";\nimport { setSubtreeVisible } from \"../scene/visibility.js\";\n\nexport interface ResolvedPointer {\n writer: (output: Float32Array, offset: number) => void;\n arity: number;\n}\n\n/** Minimal mutable view of a UV-transform texture slot the pointer writers drive.\n * Mirrors the fields `material/pbr/fragments/uv-transform-fragment.ts` reads. */\nexport interface PointerUvTexture {\n uScale?: number;\n vScale?: number;\n uOffset?: number;\n vOffset?: number;\n /** KHR_texture_transform rotation (radians) — drives the UV matrix's rotation. */\n uAng?: number;\n}\n\n/** Minimal mutable view of a runtime material a pointer can animate. Bumping\n * `_uboVersion` makes the renderable re-upload the material UBO next frame. */\nexport interface PointerMaterial {\n /** @internal */\n _uboVersion: number;\n baseColorTexture?: PointerUvTexture;\n emissiveTexture?: PointerUvTexture;\n normalTexture?: PointerUvTexture;\n ormTexture?: PointerUvTexture;\n /** Independent-occlusion UV carrier (orm-unpack); present only when occlusion\n * is sampled from the ORM texture with its own transform. */\n occlusionTexture?: PointerUvTexture;\n specGlossTexture?: PointerUvTexture;\n /** Runtime emissive (linear RGB) = emissiveFactor × emissiveStrength. */\n emissiveColor?: [number, number, number];\n /** Runtime base-color factor (linear RGBA). */\n baseColorFactor?: [number, number, number, number];\n /** @internal Animated glTF emissiveFactor, kept separate so an emissiveStrength\n * pointer can recombine without losing the factor (and vice-versa). */\n _animEmissiveFactor?: [number, number, number];\n /** @internal Animated KHR_materials_emissive_strength value. */\n _animEmissiveStrength?: number;\n}\n\n/** Recompute emissiveColor = factor × strength after either input animates, then\n * flag the material UBO for re-upload. */\nfunction applyEmissive(mat: PointerMaterial): void {\n if (!mat.emissiveColor) {\n return;\n }\n const f = mat._animEmissiveFactor ?? [0, 0, 0];\n const s = mat._animEmissiveStrength ?? 1;\n mat.emissiveColor[0] = f[0]! * s;\n mat.emissiveColor[1] = f[1]! * s;\n mat.emissiveColor[2] = f[2]! * s;\n mat._uboVersion++;\n}\n\nexport interface PointerContext {\n nodes: readonly (SceneNode | undefined)[];\n /** Runtime materials indexed by glTF material index (built by the pointer feature). */\n materials?: readonly (PointerMaterial | undefined)[];\n}\n\ntype PointerFactory = (match: RegExpExecArray, ctx: PointerContext) => ResolvedPointer | null;\n\n// Maps a KHR_texture_transform pointer's texture-slot segment to the material field.\n// NOTE: metallicRoughnessTexture is intentionally absent. Babylon.js has a long-standing\n// loader bug — its KHR_animation_pointer registration for the MR texture transform omits the\n// `/extensions/KHR_texture_transform/` path segment (and adds a stray leading slash), so the\n// interpolation is never attached and BJS silently skips animating the MR texture transform\n// (offset/scale/rotation stay frozen at their static load-time values). We match BJS for parity\n// (verified: animating MR regresses scene241 col1 MR rows by ~4.9 MAD vs the immutable golden,\n// which renders these spheres with static roughness/metallic). Do NOT animate the MR transform.\nconst TX_SLOT: Record<string, keyof PointerMaterial> = {\n \"pbrMetallicRoughness/baseColorTexture\": \"baseColorTexture\",\n emissiveTexture: \"emissiveTexture\",\n normalTexture: \"normalTexture\",\n occlusionTexture: \"ormTexture\",\n};\n\n/** Resolve a glTF material-extension texture slot to the runtime PBR material's\n * mutable texture object, so a KHR_texture_transform pointer on an extension\n * texture can drive its UV transform. Only slots whose fragment actually applies\n * the per-texture UV transform are listed (others would animate a value the\n * shader ignores). */\nfunction resolveExtTexture(mat: PointerMaterial, ext: string, field: string): PointerUvTexture | undefined {\n const m = mat as unknown as {\n iridescence?: Record<string, unknown>;\n sheen?: Record<string, unknown>;\n clearCoat?: Record<string, unknown>;\n anisotropy?: Record<string, unknown>;\n reflectanceTexture?: PointerUvTexture;\n metallicReflectanceTexture?: PointerUvTexture;\n subsurface?: { translucency?: Record<string, unknown>; refraction?: Record<string, unknown>; thickness?: Record<string, unknown> };\n };\n switch (`${ext}/${field}`) {\n case \"KHR_materials_iridescence/iridescenceTexture\":\n return privateTexture(m.iridescence, \"texture\");\n case \"KHR_materials_iridescence/iridescenceThicknessTexture\":\n return privateTexture(m.iridescence, \"thicknessTexture\");\n case \"KHR_materials_anisotropy/anisotropyTexture\":\n return privateTexture(m.anisotropy, \"texture\");\n case \"KHR_materials_sheen/sheenColorTexture\":\n return privateTexture(m.sheen, \"texture\");\n case \"KHR_materials_sheen/sheenRoughnessTexture\":\n // Drive the separate roughness texture when present; otherwise roughness shares\n // the colour texture (.a), so fall back to animating that single sheen texture.\n return privateTexture(m.sheen, (m.sheen as { roughnessTexture?: unknown })?.roughnessTexture ? \"roughnessTexture\" : \"texture\");\n case \"KHR_materials_clearcoat/clearcoatTexture\":\n return privateTexture(m.clearCoat, \"texture\");\n case \"KHR_materials_clearcoat/clearcoatRoughnessTexture\":\n return privateTexture(m.clearCoat, \"roughnessTexture\");\n case \"KHR_materials_clearcoat/clearcoatNormalTexture\":\n return privateTexture(m.clearCoat, \"bumpTexture\");\n case \"KHR_materials_specular/specularTexture\":\n return privateTexture(m as unknown as Record<string, unknown>, \"metallicReflectanceTexture\");\n case \"KHR_materials_specular/specularColorTexture\":\n return privateTexture(m as unknown as Record<string, unknown>, \"reflectanceTexture\");\n case \"KHR_materials_diffuse_transmission/diffuseTransmissionColorTexture\":\n return privateTexture(m.subsurface?.translucency, \"colorTexture\");\n case \"KHR_materials_diffuse_transmission/diffuseTransmissionTexture\":\n return privateTexture(m.subsurface?.translucency, \"intensityTexture\");\n case \"KHR_materials_transmission/transmissionTexture\":\n return privateTexture(m.subsurface?.refraction, \"texture\");\n case \"KHR_materials_volume/thicknessTexture\":\n return privateTexture(m.subsurface?.thickness, \"texture\");\n default:\n return undefined;\n }\n}\n\n/** Make a material's animated texture wrapper a private copy so that mutating its\n * per-texture UV-transform fields (uOffset/uScale/uAng…) never leaks into other\n * materials that share the same cached GPU texture wrapper. This happens when one\n * image (e.g. a packed ORM/occlusion texture, or a sheen texture) is reused across\n * several materials and only some of them animate its KHR_texture_transform — the\n * shared wrapper would otherwise be mutated for all of them. The clone shares GPU\n * resources (texture/view/sampler) via object spread; only the transform fields\n * become independent. Idempotent via `_animPriv` so multiple channels\n * (offset/scale/rotation) on the same slot reuse one private wrapper.\n * @param parent - The object holding the texture slot (the material, or an extension\n * sub-object such as `material.sheen`).\n * @param key - The slot field name on `parent`. */\nfunction privateTexture(parent: Record<string, unknown> | undefined, key: string): PointerUvTexture | undefined {\n const cur = parent?.[key] as (PointerUvTexture & { _animPriv?: true }) | undefined;\n if (!cur) {\n return undefined;\n }\n if (cur._animPriv) {\n return cur;\n }\n const clone = { ...(cur as object), _animPriv: true } as PointerUvTexture & { _animPriv: true };\n parent![key] = clone;\n return clone;\n}\n\n/** Build an offset/scale/rotation UV-transform writer for a resolved texture. */\nfunction uvTransformWriter(mat: PointerMaterial, tex: PointerUvTexture, kind: string | undefined): ResolvedPointer {\n if (kind === \"rotation\") {\n return {\n arity: 1,\n writer: (out, off) => {\n tex.uAng = out[off]!;\n mat._uboVersion++;\n },\n };\n }\n const isScale = kind === \"scale\";\n return {\n arity: 2,\n writer: (out, off) => {\n if (isScale) {\n tex.uScale = out[off]!;\n tex.vScale = out[off + 1]!;\n } else {\n tex.uOffset = out[off]!;\n tex.vOffset = out[off + 1]!;\n }\n mat._uboVersion++;\n },\n };\n}\n\nconst _registry: [RegExp, PointerFactory][] = [\n // /nodes/{n}/extensions/KHR_node_visibility/visible — scalar (0 = hidden).\n // The setter cascade handles descendants per the KHR_node_visibility spec\n // and bumps the module-scoped visibility epoch so the engine invalidates\n // its cached render bundle.\n [\n /^\\/nodes\\/(\\d+)\\/extensions\\/KHR_node_visibility\\/visible$/,\n (m, ctx) => {\n const n = ctx.nodes[+m[1]!];\n if (!n) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n setSubtreeVisible(n, out[off]! !== 0);\n },\n };\n },\n ],\n // /materials/{m}/.../KHR_texture_transform/{offset|scale|rotation} — animated UV\n // transform. offset/scale are vec2; rotation is a scalar (radians). Mutates the\n // slot texture's uOffset/vOffset, uScale/vScale, or uAng and bumps the material's\n // UBO version so the renderable re-uploads the UV matrix.\n [\n /^\\/materials\\/(\\d+)\\/(pbrMetallicRoughness\\/baseColorTexture|emissiveTexture|normalTexture|occlusionTexture)\\/extensions\\/KHR_texture_transform\\/(offset|scale|rotation)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n const slot = m[2]!;\n // orm-unpack: when occlusion has its own UV carrier (independent transform), drive\n // that; otherwise occlusion shares the single ORM transform (TX_SLOT fallback).\n const field: keyof PointerMaterial = slot === \"occlusionTexture\" && mat.occlusionTexture ? \"occlusionTexture\" : TX_SLOT[slot]!;\n // Isolate the animated slot so mutating its UV transform can't leak into other\n // materials that share the same cached texture wrapper (e.g. a reused ORM image).\n const tex = privateTexture(mat as unknown as Record<string, unknown>, field as string);\n if (!tex) {\n return null;\n }\n return uvTransformWriter(mat, tex, m[3]);\n },\n ],\n // /materials/{m}/extensions/{KHR_materials_*}/{slot}Texture/.../KHR_texture_transform/{offset|scale|rotation}\n // — animated UV transform on a material-extension texture (iridescence, sheen,\n // diffuse transmission). Resolves the runtime extension texture and drives its\n // UV transform exactly like the core slots.\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/(KHR_materials_\\w+)\\/(\\w+Texture)\\/extensions\\/KHR_texture_transform\\/(offset|scale|rotation)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n const tex = mat && resolveExtTexture(mat, m[2]!, m[3]!);\n if (!mat || !tex) {\n return null;\n }\n return uvTransformWriter(mat, tex, m[4]);\n },\n ],\n // /materials/{m}/emissiveFactor — vec3. Recombined with emissiveStrength into\n // the runtime emissiveColor. Requires the material to carry an emissive slot\n // (non-zero load-time emissiveFactor) so the UBO field exists.\n [\n /^\\/materials\\/(\\d+)\\/emissiveFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.emissiveColor) {\n return null;\n }\n return {\n arity: 3,\n writer: (out, off) => {\n mat._animEmissiveFactor = [out[off]!, out[off + 1]!, out[off + 2]!];\n applyEmissive(mat);\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_emissive_strength/emissiveStrength —\n // scalar HDR multiplier on emissiveFactor.\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_emissive_strength\\/emissiveStrength$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.emissiveColor) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat._animEmissiveStrength = out[off]!;\n applyEmissive(mat);\n },\n };\n },\n ],\n // /materials/{m}/pbrMetallicRoughness/baseColorFactor — vec4 linear RGBA factor.\n // Only animatable when the material already carries a baseColorFactor UBO slot.\n [\n /^\\/materials\\/(\\d+)\\/pbrMetallicRoughness\\/baseColorFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.baseColorFactor) {\n return null;\n }\n return {\n arity: 4,\n writer: (out, off) => {\n mat.baseColorFactor![0] = out[off]!;\n mat.baseColorFactor![1] = out[off + 1]!;\n mat.baseColorFactor![2] = out[off + 2]!;\n mat.baseColorFactor![3] = out[off + 3]!;\n mat._uboVersion++;\n },\n };\n },\n ],\n];\n\nconst _warned = new Set<string>();\n\nexport function resolveAnimationPointer(pointer: string, ctx: PointerContext): ResolvedPointer | null {\n for (const [rx, make] of _registry) {\n const m = rx.exec(pointer);\n if (m) {\n return make(m, ctx);\n }\n }\n if (!_warned.has(pointer)) {\n _warned.add(pointer);\n\n console.warn(`[babylon-lite] KHR_animation_pointer: no handler for \"${pointer}\"`);\n }\n return null;\n}\n"],"names":[],"mappings":";;AAgDA,SAAS,cAAc,GAAA,EAA4B;AAC/C,EAAA,IAAI,CAAC,IAAI,aAAA,EAAe;AACpB,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,IAAI,GAAA,CAAI,mBAAA,IAAuB,CAAC,CAAA,EAAG,GAAG,CAAC,CAAA;AAC7C,EAAA,MAAM,CAAA,GAAI,IAAI,qBAAA,IAAyB,CAAA;AACvC,EAAA,GAAA,CAAI,aAAA,CAAc,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA;AAC/B,EAAA,GAAA,CAAI,aAAA,CAAc,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA;AAC/B,EAAA,GAAA,CAAI,aAAA,CAAc,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA;AAC/B,EAAA,GAAA,CAAI,WAAA,EAAA;AACR;AAkBA,MAAM,OAAA,GAAiD;AAAA,EACnD,uCAAA,EAAyC,kBAAA;AAAA,EACzC,eAAA,EAAiB,iBAAA;AAAA,EACjB,aAAA,EAAe,eAAA;AAAA,EACf,gBAAA,EAAkB;AACtB,CAAA;AAOA,SAAS,iBAAA,CAAkB,GAAA,EAAsB,GAAA,EAAa,KAAA,EAA6C;AACvG,EAAA,MAAM,CAAA,GAAI,GAAA;AASV,EAAA,QAAQ,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA;AAAI,IACvB,KAAK,8CAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,WAAA,EAAa,SAAS,CAAA;AAAA,IAClD,KAAK,uDAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,WAAA,EAAa,kBAAkB,CAAA;AAAA,IAC3D,KAAK,4CAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,UAAA,EAAY,SAAS,CAAA;AAAA,IACjD,KAAK,uCAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,KAAA,EAAO,SAAS,CAAA;AAAA,IAC5C,KAAK,2CAAA;AAGD,MAAA,OAAO,eAAe,CAAA,CAAE,KAAA,EAAQ,EAAE,KAAA,EAA0C,gBAAA,GAAmB,qBAAqB,SAAS,CAAA;AAAA,IACjI,KAAK,0CAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,SAAA,EAAW,SAAS,CAAA;AAAA,IAChD,KAAK,mDAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,SAAA,EAAW,kBAAkB,CAAA;AAAA,IACzD,KAAK,gDAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,SAAA,EAAW,aAAa,CAAA;AAAA,IACpD,KAAK,wCAAA;AACD,MAAA,OAAO,cAAA,CAAe,GAAyC,4BAA4B,CAAA;AAAA,IAC/F,KAAK,6CAAA;AACD,MAAA,OAAO,cAAA,CAAe,GAAyC,oBAAoB,CAAA;AAAA,IACvF,KAAK,oEAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,UAAA,EAAY,YAAA,EAAc,cAAc,CAAA;AAAA,IACpE,KAAK,+DAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,UAAA,EAAY,YAAA,EAAc,kBAAkB,CAAA;AAAA,IACxE,KAAK,gDAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,UAAA,EAAY,UAAA,EAAY,SAAS,CAAA;AAAA,IAC7D,KAAK,uCAAA;AACD,MAAA,OAAO,cAAA,CAAe,CAAA,CAAE,UAAA,EAAY,SAAA,EAAW,SAAS,CAAA;AAAA,IAC5D;AACI,MAAA,OAAO,MAAA;AAAA;AAEnB;AAcA,SAAS,cAAA,CAAe,QAA6C,GAAA,EAA2C;AAC5G,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,OAAO,MAAA;AAAA,EACX;AACA,EAAA,IAAI,IAAI,SAAA,EAAW;AACf,IAAA,OAAO,GAAA;AAAA,EACX;AACA,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAI,GAAA,EAAgB,WAAW,IAAA,EAAK;AACpD,EAAA,MAAA,CAAQ,GAAG,CAAA,GAAI,KAAA;AACf,EAAA,OAAO,KAAA;AACX;AAGA,SAAS,iBAAA,CAAkB,GAAA,EAAsB,GAAA,EAAuB,IAAA,EAA2C;AAC/G,EAAA,IAAI,SAAS,UAAA,EAAY;AACrB,IAAA,OAAO;AAAA,MACH,KAAA,EAAO,CAAA;AAAA,MACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,QAAA,GAAA,CAAI,IAAA,GAAO,IAAI,GAAG,CAAA;AAClB,QAAA,GAAA,CAAI,WAAA,EAAA;AAAA,MACR;AAAA,KACJ;AAAA,EACJ;AACA,EAAA,MAAM,UAAU,IAAA,KAAS,OAAA;AACzB,EAAA,OAAO;AAAA,IACH,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,MAAA,IAAI,OAAA,EAAS;AACT,QAAA,GAAA,CAAI,MAAA,GAAS,IAAI,GAAG,CAAA;AACpB,QAAA,GAAA,CAAI,MAAA,GAAS,GAAA,CAAI,GAAA,GAAM,CAAC,CAAA;AAAA,MAC5B,CAAA,MAAO;AACH,QAAA,GAAA,CAAI,OAAA,GAAU,IAAI,GAAG,CAAA;AACrB,QAAA,GAAA,CAAI,OAAA,GAAU,GAAA,CAAI,GAAA,GAAM,CAAC,CAAA;AAAA,MAC7B;AACA,MAAA,GAAA,CAAI,WAAA,EAAA;AAAA,IACR;AAAA,GACJ;AACJ;AAEA,MAAM,SAAA,GAAwC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1C;AAAA,IACI,4DAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,IAAI,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAC1B,MAAA,IAAI,CAAC,CAAA,EAAG;AACJ,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO;AAAA,QACH,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,UAAA,iBAAA,CAAkB,CAAA,EAAG,GAAA,CAAI,GAAG,CAAA,KAAO,CAAC,CAAA;AAAA,QACxC;AAAA,OACJ;AAAA,IACJ;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,IACI,2KAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,MAAM,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAClC,MAAA,IAAI,CAAC,GAAA,EAAK;AACN,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAGhB,MAAA,MAAM,QAA+B,IAAA,KAAS,kBAAA,IAAsB,IAAI,gBAAA,GAAmB,kBAAA,GAAqB,QAAQ,IAAI,CAAA;AAG5H,MAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,EAA2C,KAAe,CAAA;AACrF,MAAA,IAAI,CAAC,GAAA,EAAK;AACN,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,GAAA,EAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,IAC3C;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,IACI,iIAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,MAAM,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAClC,MAAA,MAAM,GAAA,GAAM,OAAO,iBAAA,CAAkB,GAAA,EAAK,EAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAE,CAAA;AACtD,MAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,EAAK;AACd,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,GAAA,EAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,IAC3C;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,IACI,sCAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,MAAM,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAClC,MAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACrB,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO;AAAA,QACH,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,UAAA,GAAA,CAAI,mBAAA,GAAsB,CAAC,GAAA,CAAI,GAAG,CAAA,EAAI,GAAA,CAAI,GAAA,GAAM,CAAC,CAAA,EAAI,GAAA,CAAI,GAAA,GAAM,CAAC,CAAE,CAAA;AAClE,UAAA,aAAA,CAAc,GAAG,CAAA;AAAA,QACrB;AAAA,OACJ;AAAA,IACJ;AAAA,GACJ;AAAA;AAAA;AAAA,EAGA;AAAA,IACI,qFAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,MAAM,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAClC,MAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACrB,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO;AAAA,QACH,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,UAAA,GAAA,CAAI,qBAAA,GAAwB,IAAI,GAAG,CAAA;AACnC,UAAA,aAAA,CAAc,GAAG,CAAA;AAAA,QACrB;AAAA,OACJ;AAAA,IACJ;AAAA,GACJ;AAAA;AAAA;AAAA,EAGA;AAAA,IACI,6DAAA;AAAA,IACA,CAAC,GAAG,GAAA,KAAQ;AACR,MAAA,MAAM,MAAM,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,CAAE,CAAC,CAAE,CAAA;AAClC,MAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AACvB,QAAA,OAAO,IAAA;AAAA,MACX;AACA,MAAA,OAAO;AAAA,QACH,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAClB,UAAA,GAAA,CAAI,eAAA,CAAiB,CAAC,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA;AACjC,UAAA,GAAA,CAAI,eAAA,CAAiB,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AACrC,UAAA,GAAA,CAAI,eAAA,CAAiB,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AACrC,UAAA,GAAA,CAAI,eAAA,CAAiB,CAAC,CAAA,GAAI,GAAA,CAAI,MAAM,CAAC,CAAA;AACrC,UAAA,GAAA,CAAI,WAAA,EAAA;AAAA,QACR;AAAA,OACJ;AAAA,IACJ;AAAA;AAER,CAAA;AAEA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEzB,SAAS,uBAAA,CAAwB,SAAiB,GAAA,EAA6C;AAClG,EAAA,KAAA,MAAW,CAAC,EAAA,EAAI,IAAI,CAAA,IAAK,SAAA,EAAW;AAChC,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA;AACzB,IAAA,IAAI,CAAA,EAAG;AACH,MAAA,OAAO,IAAA,CAAK,GAAG,GAAG,CAAA;AAAA,IACtB;AAAA,EACJ;AACA,EAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AACvB,IAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AAEnB,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,sDAAA,EAAyD,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,IAAA;AACX;;;;"}
|
|
1
|
+
{"version":3,"file":"animation-pointer.js","sources":["../../../src/loader-gltf/animation-pointer.ts"],"sourcesContent":["/** KHR_animation_pointer — JSON-pointer resolver registry.\n * Handlers are registered incrementally (one per parity scene). Unknown\n * pointers return null and warn once. */\nimport type { SceneNode } from \"../scene/scene-node.js\";\nimport { setSubtreeVisible } from \"../scene/visibility.js\";\n\nexport interface ResolvedPointer {\n writer: (output: Float32Array, offset: number) => void;\n arity: number;\n}\n\n/** Minimal mutable view of a UV-transform texture slot the pointer writers drive.\n * Mirrors the fields `material/pbr/fragments/uv-transform-fragment.ts` reads. */\nexport interface PointerUvTexture {\n uScale?: number;\n vScale?: number;\n uOffset?: number;\n vOffset?: number;\n /** KHR_texture_transform rotation (radians) — drives the UV matrix's rotation. */\n uAng?: number;\n}\n\n/** Minimal mutable view of a runtime material a pointer can animate. Bumping\n * `_uboVersion` makes the renderable re-upload the material UBO next frame. */\nexport interface PointerMaterial {\n /** @internal */\n _uboVersion: number;\n baseColorTexture?: PointerUvTexture;\n emissiveTexture?: PointerUvTexture;\n normalTexture?: PointerUvTexture;\n ormTexture?: PointerUvTexture;\n /** Independent-occlusion UV carrier (orm-unpack); present only when occlusion\n * is sampled from the ORM texture with its own transform. */\n occlusionTexture?: PointerUvTexture;\n specGlossTexture?: PointerUvTexture;\n /** Runtime emissive (linear RGB) = emissiveFactor × emissiveStrength. */\n emissiveColor?: [number, number, number];\n /** Runtime base-color factor (linear RGBA). */\n baseColorFactor?: [number, number, number, number];\n roughnessFactor?: number;\n metallicF0Factor?: number;\n specularWeight?: number;\n /** @internal Runtime material needs the reflectance extension shader path. */\n _hasReflExt?: boolean;\n /** Runtime glTF normalTexture.scale (drives the lazy normal-scale shader mod). */\n normalTextureScale?: number;\n /** Runtime glTF occlusionTexture.strength (applied by the lazy reflectance ext). */\n occlusionStrength?: number;\n transmissive?: boolean;\n subsurface?: {\n refraction?: { intensity?: number; indexOfRefraction?: number; useThicknessAsDepth?: boolean };\n thickness?: { min?: number; max?: number; useGlTFChannel?: boolean };\n tint?: { color?: [number, number, number]; atDistance?: number };\n };\n iridescence?: {\n isEnabled?: boolean;\n intensity?: number;\n indexOfRefraction?: number;\n maximumThickness?: number;\n };\n /** @internal Animated glTF emissiveFactor, kept separate so an emissiveStrength\n * pointer can recombine without losing the factor (and vice-versa). */\n _animEmissiveFactor?: [number, number, number];\n /** @internal Animated KHR_materials_emissive_strength value. */\n _animEmissiveStrength?: number;\n}\n\n/** Recompute emissiveColor = factor × strength after either input animates, then\n * flag the material UBO for re-upload. */\nfunction applyEmissive(mat: PointerMaterial): void {\n if (!mat.emissiveColor) {\n return;\n }\n const f = mat._animEmissiveFactor ?? [0, 0, 0];\n const s = mat._animEmissiveStrength ?? 1;\n mat.emissiveColor[0] = f[0]! * s;\n mat.emissiveColor[1] = f[1]! * s;\n mat.emissiveColor[2] = f[2]! * s;\n mat._uboVersion++;\n}\n\nexport interface PointerContext {\n nodes: readonly (SceneNode | undefined)[];\n /** Runtime materials indexed by glTF material index (built by the pointer feature). */\n materials?: readonly (PointerMaterial | undefined)[];\n /** @internal glTF JSON object key used to resolve KHR_lights_punctual definitions. */\n _json?: object;\n}\n\nexport type PointerFactory = (match: RegExpExecArray, ctx: PointerContext) => ResolvedPointer | null;\n\n// Maps a KHR_texture_transform pointer's texture-slot segment to the material field.\n// NOTE: metallicRoughnessTexture is intentionally absent. Babylon.js has a long-standing\n// loader bug — its KHR_animation_pointer registration for the MR texture transform omits the\n// `/extensions/KHR_texture_transform/` path segment (and adds a stray leading slash), so the\n// interpolation is never attached and BJS silently skips animating the MR texture transform\n// (offset/scale/rotation stay frozen at their static load-time values). We match BJS for parity\n// (verified: animating MR regresses scene241 col1 MR rows by ~4.9 MAD vs the immutable golden,\n// which renders these spheres with static roughness/metallic). Do NOT animate the MR transform.\nconst TX_SLOT: Record<string, keyof PointerMaterial> = {\n \"pbrMetallicRoughness/baseColorTexture\": \"baseColorTexture\",\n emissiveTexture: \"emissiveTexture\",\n normalTexture: \"normalTexture\",\n occlusionTexture: \"ormTexture\",\n};\n\n/** Resolve a glTF material-extension texture slot to the runtime PBR material's\n * mutable texture object, so a KHR_texture_transform pointer on an extension\n * texture can drive its UV transform. Only slots whose fragment actually applies\n * the per-texture UV transform are listed (others would animate a value the\n * shader ignores). */\nfunction resolveExtTexture(mat: PointerMaterial, ext: string, field: string): PointerUvTexture | undefined {\n const m = mat as unknown as {\n iridescence?: Record<string, unknown>;\n sheen?: Record<string, unknown>;\n clearCoat?: Record<string, unknown>;\n anisotropy?: Record<string, unknown>;\n reflectanceTexture?: PointerUvTexture;\n metallicReflectanceTexture?: PointerUvTexture;\n subsurface?: { translucency?: Record<string, unknown>; refraction?: Record<string, unknown>; thickness?: Record<string, unknown> };\n };\n switch (`${ext}/${field}`) {\n case \"KHR_materials_iridescence/iridescenceTexture\":\n return privateTexture(m.iridescence, \"texture\");\n case \"KHR_materials_iridescence/iridescenceThicknessTexture\":\n return privateTexture(m.iridescence, \"thicknessTexture\");\n case \"KHR_materials_anisotropy/anisotropyTexture\":\n return privateTexture(m.anisotropy, \"texture\");\n case \"KHR_materials_sheen/sheenColorTexture\":\n return privateTexture(m.sheen, \"texture\");\n case \"KHR_materials_sheen/sheenRoughnessTexture\":\n // Drive the separate roughness texture when present; otherwise roughness shares\n // the colour texture (.a), so fall back to animating that single sheen texture.\n return privateTexture(m.sheen, (m.sheen as { roughnessTexture?: unknown })?.roughnessTexture ? \"roughnessTexture\" : \"texture\");\n case \"KHR_materials_clearcoat/clearcoatTexture\":\n return privateTexture(m.clearCoat, \"texture\");\n case \"KHR_materials_clearcoat/clearcoatRoughnessTexture\":\n return privateTexture(m.clearCoat, \"roughnessTexture\");\n case \"KHR_materials_clearcoat/clearcoatNormalTexture\":\n return privateTexture(m.clearCoat, \"bumpTexture\");\n case \"KHR_materials_specular/specularTexture\":\n return privateTexture(m as unknown as Record<string, unknown>, \"metallicReflectanceTexture\");\n case \"KHR_materials_specular/specularColorTexture\":\n return privateTexture(m as unknown as Record<string, unknown>, \"reflectanceTexture\");\n case \"KHR_materials_diffuse_transmission/diffuseTransmissionColorTexture\":\n return privateTexture(m.subsurface?.translucency, \"colorTexture\");\n case \"KHR_materials_diffuse_transmission/diffuseTransmissionTexture\":\n return privateTexture(m.subsurface?.translucency, \"intensityTexture\");\n case \"KHR_materials_transmission/transmissionTexture\":\n return privateTexture(m.subsurface?.refraction, \"texture\");\n case \"KHR_materials_volume/thicknessTexture\":\n return privateTexture(m.subsurface?.thickness, \"texture\");\n default:\n return undefined;\n }\n}\n\n/** Make a material's animated texture wrapper a private copy so that mutating its\n * per-texture UV-transform fields (uOffset/uScale/uAng…) never leaks into other\n * materials that share the same cached GPU texture wrapper. This happens when one\n * image (e.g. a packed ORM/occlusion texture, or a sheen texture) is reused across\n * several materials and only some of them animate its KHR_texture_transform — the\n * shared wrapper would otherwise be mutated for all of them. The clone shares GPU\n * resources (texture/view/sampler) via object spread; only the transform fields\n * become independent. Idempotent via `_animPriv` so multiple channels\n * (offset/scale/rotation) on the same slot reuse one private wrapper.\n * @param parent - The object holding the texture slot (the material, or an extension\n * sub-object such as `material.sheen`).\n * @param key - The slot field name on `parent`. */\nfunction privateTexture(parent: Record<string, unknown> | undefined, key: string): PointerUvTexture | undefined {\n const cur = parent?.[key] as (PointerUvTexture & { _animPriv?: true }) | undefined;\n if (!cur) {\n return undefined;\n }\n if (cur._animPriv) {\n return cur;\n }\n const clone = { ...(cur as object), _animPriv: true } as PointerUvTexture & { _animPriv: true };\n parent![key] = clone;\n return clone;\n}\n\n/** Build an offset/scale/rotation UV-transform writer for a resolved texture. */\nfunction uvTransformWriter(mat: PointerMaterial, tex: PointerUvTexture, kind: string | undefined): ResolvedPointer {\n if (kind === \"rotation\") {\n return {\n arity: 1,\n writer: (out, off) => {\n tex.uAng = out[off]!;\n mat._uboVersion++;\n },\n };\n }\n const isScale = kind === \"scale\";\n return {\n arity: 2,\n writer: (out, off) => {\n if (isScale) {\n tex.uScale = out[off]!;\n tex.vScale = out[off + 1]!;\n } else {\n tex.uOffset = out[off]!;\n tex.vOffset = out[off + 1]!;\n }\n mat._uboVersion++;\n },\n };\n}\n\nconst _registry: [RegExp, PointerFactory][] = [\n // /nodes/{n}/extensions/KHR_node_visibility/visible — scalar (0 = hidden).\n // The setter cascade handles descendants per the KHR_node_visibility spec\n // and bumps the module-scoped visibility epoch so the engine invalidates\n // its cached render bundle.\n [\n /^\\/nodes\\/(\\d+)\\/extensions\\/KHR_node_visibility\\/visible$/,\n (m, ctx) => {\n const n = ctx.nodes[+m[1]!];\n if (!n) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n setSubtreeVisible(n, out[off]! !== 0);\n },\n };\n },\n ],\n // /materials/{m}/.../KHR_texture_transform/{offset|scale|rotation} — animated UV\n // transform. offset/scale are vec2; rotation is a scalar (radians). Mutates the\n // slot texture's uOffset/vOffset, uScale/vScale, or uAng and bumps the material's\n // UBO version so the renderable re-uploads the UV matrix.\n [\n /^\\/materials\\/(\\d+)\\/(pbrMetallicRoughness\\/baseColorTexture|emissiveTexture|normalTexture|occlusionTexture)\\/extensions\\/KHR_texture_transform\\/(offset|scale|rotation)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat) {\n return null;\n }\n const slot = m[2]!;\n // orm-unpack: when occlusion has its own UV carrier (independent transform), drive\n // that; otherwise occlusion shares the single ORM transform (TX_SLOT fallback).\n const field: keyof PointerMaterial = slot === \"occlusionTexture\" && mat.occlusionTexture ? \"occlusionTexture\" : TX_SLOT[slot]!;\n // Isolate the animated slot so mutating its UV transform can't leak into other\n // materials that share the same cached texture wrapper (e.g. a reused ORM image).\n const tex = privateTexture(mat as unknown as Record<string, unknown>, field as string);\n if (!tex) {\n return null;\n }\n return uvTransformWriter(mat, tex, m[3]);\n },\n ],\n // /materials/{m}/extensions/{KHR_materials_*}/{slot}Texture/.../KHR_texture_transform/{offset|scale|rotation}\n // — animated UV transform on a material-extension texture (iridescence, sheen,\n // diffuse transmission). Resolves the runtime extension texture and drives its\n // UV transform exactly like the core slots.\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/(KHR_materials_\\w+)\\/(\\w+Texture)\\/extensions\\/KHR_texture_transform\\/(offset|scale|rotation)$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n const tex = mat && resolveExtTexture(mat, m[2]!, m[3]!);\n if (!mat || !tex) {\n return null;\n }\n return uvTransformWriter(mat, tex, m[4]);\n },\n ],\n // /materials/{m}/emissiveFactor — vec3. Recombined with emissiveStrength into\n // the runtime emissiveColor. Requires the material to carry an emissive slot\n // (non-zero load-time emissiveFactor) so the UBO field exists.\n [\n /^\\/materials\\/(\\d+)\\/emissiveFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.emissiveColor) {\n return null;\n }\n return {\n arity: 3,\n writer: (out, off) => {\n mat._animEmissiveFactor = [out[off]!, out[off + 1]!, out[off + 2]!];\n applyEmissive(mat);\n },\n };\n },\n ],\n // /materials/{m}/extensions/KHR_materials_emissive_strength/emissiveStrength —\n // scalar HDR multiplier on emissiveFactor.\n [\n /^\\/materials\\/(\\d+)\\/extensions\\/KHR_materials_emissive_strength\\/emissiveStrength$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.emissiveColor) {\n return null;\n }\n return {\n arity: 1,\n writer: (out, off) => {\n mat._animEmissiveStrength = out[off]!;\n applyEmissive(mat);\n },\n };\n },\n ],\n // /materials/{m}/pbrMetallicRoughness/baseColorFactor — vec4 linear RGBA factor.\n // Only animatable when the material already carries a baseColorFactor UBO slot.\n [\n /^\\/materials\\/(\\d+)\\/pbrMetallicRoughness\\/baseColorFactor$/,\n (m, ctx) => {\n const mat = ctx.materials?.[+m[1]!];\n if (!mat?.baseColorFactor) {\n return null;\n }\n return {\n arity: 4,\n writer: (out, off) => {\n mat.baseColorFactor![0] = out[off]!;\n mat.baseColorFactor![1] = out[off + 1]!;\n mat.baseColorFactor![2] = out[off + 2]!;\n mat.baseColorFactor![3] = out[off + 3]!;\n mat._uboVersion++;\n },\n };\n },\n ],\n];\n\n/** Append extended (lazily-loaded) pointer handlers to the resolver registry.\n * Called once by animation-pointer-ext.ts on import. ES-module caching makes the\n * import idempotent, so the handlers are appended exactly once per process. */\nexport function _appendPointerHandlers(handlers: [RegExp, PointerFactory][]): void {\n _registry.push(...handlers);\n}\n\nconst _warned = new Set<string>();\n\nexport function resolveAnimationPointer(pointer: string, ctx: PointerContext): ResolvedPointer | null {\n for (const [rx, make] of _registry) {\n const m = rx.exec(pointer);\n if (m) {\n return make(m, ctx);\n }\n }\n if (!_warned.has(pointer)) {\n _warned.add(pointer);\n\n console.warn(`[babylon-lite] KHR_animation_pointer: no handler for \"${pointer}\"`);\n }\n return null;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -7,9 +7,11 @@ import { computeNodeWorldMatrix, resolveAccessor, findParent } from './gltf-pars
|
|
|
7
7
|
import { getLoaderTmpAnim } from './_loader-scratch.js';
|
|
8
8
|
|
|
9
9
|
let _parsePointerChannel = null;
|
|
10
|
-
|
|
11
|
-
function _installPointerHandlers(parser, converter) {
|
|
10
|
+
function _installPointerHandlers(parser) {
|
|
12
11
|
_parsePointerChannel = parser;
|
|
12
|
+
}
|
|
13
|
+
let _convertSampler = null;
|
|
14
|
+
function _installSamplerConverter(converter) {
|
|
13
15
|
_convertSampler = converter;
|
|
14
16
|
}
|
|
15
17
|
function toSamplerFloat32(src, length, normalized) {
|
|
@@ -244,5 +246,5 @@ function hasWritableNodeChannel(clips, nodeTargets, excludedNodeIndices) {
|
|
|
244
246
|
return false;
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
export { _installPointerHandlers, computeBoneTextureData, extractSkin, parseAnimationData };
|
|
249
|
+
export { _installPointerHandlers, _installSamplerConverter, computeBoneTextureData, extractSkin, parseAnimationData };
|
|
248
250
|
//# sourceMappingURL=gltf-animation.js.map
|