@viggle/splat-engine-three 0.0.0-stage → 0.1.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -2
  3. package/dist/chunks/chunk-MM6DJU6S.js +7801 -0
  4. package/dist/chunks/chunk-MM6DJU6S.js.map +7 -0
  5. package/dist/index.js +52 -0
  6. package/dist/index.js.map +7 -0
  7. package/dist/types/anim/animation-conversion.d.ts +25 -0
  8. package/dist/types/anim/bind-pose.d.ts +15 -0
  9. package/dist/types/anim/keyframe-splines.d.ts +59 -0
  10. package/dist/types/anim/rest-relative.d.ts +32 -0
  11. package/dist/types/anim/spline.d.ts +14 -0
  12. package/dist/types/animation.d.ts +216 -0
  13. package/dist/types/armature.d.ts +524 -0
  14. package/dist/types/character.d.ts +540 -0
  15. package/dist/types/engine.d.ts +166 -0
  16. package/dist/types/environment.d.ts +53 -0
  17. package/dist/types/index.d.ts +37 -0
  18. package/dist/types/lighting/color.d.ts +13 -0
  19. package/dist/types/lighting/point-light.d.ts +33 -0
  20. package/dist/types/lighting/sky-light.d.ts +22 -0
  21. package/dist/types/lighting/sun-light.d.ts +34 -0
  22. package/dist/types/loader/animation/animation-glb.d.ts +117 -0
  23. package/dist/types/loader/character/index.d.ts +33 -0
  24. package/dist/types/loader/character/legacy/index.d.ts +34 -0
  25. package/dist/types/loader/character/legacy/interleaved-splat.d.ts +101 -0
  26. package/dist/types/loader/character/legacy/planar-splat.d.ts +139 -0
  27. package/dist/types/loader/character/load.d.ts +33 -0
  28. package/dist/types/loader/character/types.d.ts +129 -0
  29. package/dist/types/loader/character/v1/decode.d.ts +32 -0
  30. package/dist/types/loader/environment/ply.d.ts +16 -0
  31. package/dist/types/loader/shared/bin-cache.d.ts +19 -0
  32. package/dist/types/loader/skeleton/index.d.ts +19 -0
  33. package/dist/types/loader/skeleton/skeleton-data-441.d.ts +5 -0
  34. package/dist/types/loader/skeleton/skeleton-data.d.ts +6 -0
  35. package/dist/types/math.d.ts +82 -0
  36. package/dist/types/skeletal/animation-player.d.ts +185 -0
  37. package/dist/types/skeletal/bone-mask.d.ts +27 -0
  38. package/dist/types/skeletal/bone-stretch.d.ts +65 -0
  39. package/dist/types/skeletal/pose.d.ts +27 -0
  40. package/dist/types/skeletal/skeleton.d.ts +57 -0
  41. package/dist/types/skeletal/splat-skinning.d.ts +69 -0
  42. package/dist/types/splat/backend.d.ts +57 -0
  43. package/dist/types/splat/bone-binding.d.ts +38 -0
  44. package/dist/types/splat/depth-sort.d.ts +58 -0
  45. package/dist/types/splat/packed-splats.d.ts +36 -0
  46. package/dist/types/splat/splat-mesh.d.ts +71 -0
  47. package/dist/types/splat/splat.d.ts +186 -0
  48. package/dist/types/splat/transform-palette.d.ts +42 -0
  49. package/dist/types/splat/webgl/backend.d.ts +17 -0
  50. package/dist/types/splat/webgl/shaders.d.ts +2 -0
  51. package/dist/types/splat/webgl/splat-mesh.d.ts +52 -0
  52. package/dist/types/splat/webgpu/backend.d.ts +25 -0
  53. package/dist/types/splat/webgpu/lighting.d.ts +34 -0
  54. package/dist/types/splat/webgpu/radix-sort.d.ts +46 -0
  55. package/dist/types/splat/webgpu/splat-mesh.d.ts +71 -0
  56. package/dist/types/three/loaders.d.ts +77 -0
  57. package/dist/types/three/splat-character.d.ts +192 -0
  58. package/dist/types/types.d.ts +30 -0
  59. package/dist/types/webgpu.d.ts +5 -0
  60. package/dist/webgpu.js +813 -0
  61. package/dist/webgpu.js.map +7 -0
  62. package/package.json +46 -4
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/three/splat-character.ts", "../../src/character.ts", "../../src/math.ts", "../../src/loader/skeleton/skeleton-data.ts", "../../src/loader/skeleton/skeleton-data-441.ts", "../../src/loader/skeleton/index.ts", "../../src/anim/rest-relative.ts", "../../src/anim/spline.ts", "../../src/anim/keyframe-splines.ts", "../../src/anim/animation-conversion.ts", "../../src/loader/animation/animation-glb.ts", "../../src/loader/shared/bin-cache.ts", "../../src/animation.ts", "../../src/armature.ts", "../../src/skeletal/animation-player.ts", "../../src/skeletal/bone-stretch.ts", "../../src/skeletal/pose.ts", "../../src/anim/bind-pose.ts", "../../src/skeletal/skeleton.ts", "../../src/splat/bone-binding.ts", "../../src/skeletal/splat-skinning.ts", "../../src/engine.ts", "../../src/splat/packed-splats.ts", "../../src/loader/character/types.ts", "../../src/loader/character/legacy/interleaved-splat.ts", "../../src/loader/character/legacy/planar-splat.ts", "../../src/loader/character/legacy/index.ts", "../../src/loader/character/v1/decode.ts", "../../src/loader/character/index.ts", "../../src/loader/character/load.ts", "../../src/skeletal/bone-mask.ts", "../../src/splat/splat.ts", "../../src/splat/splat-mesh.ts", "../../src/splat/webgl/splat-mesh.ts", "../../src/splat/depth-sort.ts", "../../src/splat/transform-palette.ts", "../../src/splat/webgl/shaders.ts", "../../src/splat/webgl/backend.ts", "../../src/three/loaders.ts", "../../src/loader/environment/ply.ts", "../../src/environment.ts", "../../src/lighting/sun-light.ts", "../../src/lighting/color.ts", "../../src/lighting/sky-light.ts", "../../src/lighting/point-light.ts"],
4
+ "sourcesContent": ["import { Color, Matrix4, Object3D, SRGBColorSpace, Vector3 } from 'three';\nimport type { ColorRepresentation, Object3DEventMap } from 'three';\n\nimport type { Animation } from '../animation';\nimport type { Armature } from '../armature';\nimport { Character } from '../character';\nimport type { SplatEngine } from '../engine';\nimport type { CharacterBundle } from '../loader/character/load';\nimport type { BodyRegion, BoneMask } from '../skeletal/bone-mask';\nimport type { Splat } from '../splat/splat';\n\n/**\n * What a clip's horizontal travel does to the character.\n *\n * - `'off'` - the clip plays in place.\n * - `'apply'` - the character's body moves with the clip, beneath\n * {@link SplatCharacter.position}, which stays where you put it.\n * - `'extract'` - the clip plays in place and its travel is handed to you by\n * {@link SplatCharacter.consumeRootMotion}, to feed a controller or physics.\n *\n * @group Characters & Animation\n */\nexport type SplatRootMotion = 'off' | 'apply' | 'extract';\n\n/** @group Characters & Animation */\nexport interface SplatPlayOptions {\n /** Repeat when the clip ends. Default `true`. */\n loop?: boolean;\n}\n\n/** @group Characters & Animation */\nexport interface SplatCrossFadeOptions extends SplatPlayOptions {\n /** Start the new clip at the same fraction of its length the old one had reached. Default `false`. */\n preserveTime?: boolean;\n}\n\n/** @group Characters & Animation */\nexport interface SplatLayerOptions {\n /** The bones the layer drives, as a named region. Give this or `mask`. */\n region?: BodyRegion;\n /** The bones the layer drives, as an explicit mask. Give this or `region`. */\n mask?: BoneMask;\n /** Repeat when the clip ends. Default `true`. */\n loop?: boolean;\n /** Seconds to blend the layer in. Default `0`. */\n fadeDuration?: number;\n /** How strongly the layer overrides the base pose, 0..1. Default `1`. */\n weight?: number;\n}\n\n/**\n * Events a {@link SplatCharacter} dispatches, alongside the usual `Object3D` ones.\n * @group Characters & Animation\n */\nexport interface SplatCharacterEventMap extends Object3DEventMap {\n /** A non-looping clip reached its last frame. */\n finished: { clip: Animation };\n /** A looping clip wrapped around to its start. */\n loop: { clip: Animation };\n /** An event authored into the clip was crossed. */\n clipevent: { clip: Animation | null; name: string; frame: number; payload?: unknown };\n}\n\nconst _color = new Color();\nconst _rgb = { r: 0, g: 0, b: 0 };\nlet _clipSerial = 0;\n\n/**\n * A gaussian-splat character, as a three.js object.\n *\n * Add it to a scene, move it with `position` / `rotation` / `scale`, and call\n * {@link SplatCharacter.update} once per frame - the role `AnimationMixer.update`\n * plays for a skinned mesh. Create one with {@link VSplatLoader}.\n *\n * ```ts\n * const character = await new VSplatLoader().loadAsync('/assets/hero.vsplat');\n * scene.add(character);\n * character.position.set(1, 0, 0);\n *\n * const run = await new SplatClipLoader().loadAsync('/assets/run.glb');\n * character.play(run);\n *\n * renderer.setAnimationLoop(() => {\n * character.update(clock.getDelta());\n * renderer.render(scene, camera);\n * });\n * ```\n *\n * `position` is the model origin. A character in its rest pose stands on it;\n * how closely a clip keeps the feet on it depends on the clip.\n *\n * Animation is driven by this class rather than by `AnimationMixer`: a splat\n * character has no `Bone` hierarchy for a mixer to write to. Clips are\n * {@link Animation} objects from {@link SplatClipLoader}.\n *\n * @group Characters & Animation\n */\nexport class SplatCharacter extends Object3D<SplatCharacterEventMap> {\n /** Type flag, in the three.js manner. */\n readonly isSplatCharacter = true;\n override readonly type: string = 'SplatCharacter';\n\n /**\n * The engine-level character this object wraps. Everything not surfaced\n * here - multi-level LOD, variant splats, animation LOD - is reachable\n * through it.\n */\n readonly character: Character;\n\n private readonly _engine: SplatEngine;\n private readonly _bundles: CharacterBundle[];\n private _clip: Animation | null = null;\n private _loop = true;\n private _finishedSent = false;\n private _rootMotion: SplatRootMotion = 'off';\n private _disposed = false;\n\n /**\n * @param bundles - Decoded character bundles, finest level of detail first.\n * They are read, never modified, so clones share them.\n * @internal Use {@link VSplatLoader}.\n */\n constructor(engine: SplatEngine, bundles: CharacterBundle[], name = 'character') {\n super();\n this.name = name;\n this._engine = engine;\n this._bundles = bundles;\n\n const character = Character.fromBundles(engine, bundles, name);\n // This object's own update() drives the character, and this object is its\n // parent - not the engine's update loop or its content root.\n character.detachAutoUpdate();\n this.add(character.armature.object3D);\n this.character = character;\n\n character.onAnimEvent((e) => {\n this.dispatchEvent({ type: 'clipevent', clip: this._clip, name: e.name, frame: e.frame, payload: e.payload });\n });\n }\n\n /** The rig: bone names, bone matrices, bone-length scaling. */\n get armature(): Armature {\n return this.character.armature;\n }\n\n /** The splats that draw this character, one per level of detail. */\n get splats(): readonly Splat[] {\n return this.character.splats;\n }\n\n // \u2500\u2500 Per-frame \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Advance the animation by `delta` seconds and pose the splats. Call once\n * per frame, before rendering.\n */\n update(delta: number): void {\n if (this._disposed) return;\n const armature = this.character.armature;\n const before = armature.animationTime;\n this.character.update(delta);\n\n const clip = this._clip;\n if (!clip || !armature.isPlaying) return;\n if (this._loop) {\n // A looping clip wraps its time; nothing else moves it backwards.\n if (delta > 0 && !armature.paused && armature.animationTime < before) {\n this.dispatchEvent({ type: 'loop', clip });\n }\n } else if (armature.isFinished && !this._finishedSent) {\n this._finishedSent = true;\n this.dispatchEvent({ type: 'finished', clip });\n }\n }\n\n // \u2500\u2500 Playback \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Start `clip` from its first frame, cutting from whatever was playing. */\n play(clip: Animation, options?: SplatPlayOptions): this {\n const loop = options?.loop ?? true;\n const armature = this.character.armature;\n armature.frameRate = clip.frameRate;\n this.character.playAnimation(this._keyFor(clip), { loop, rootMotion: this._rootMotion === 'apply' });\n this._started(clip, loop);\n return this;\n }\n\n /** Blend from the current pose into `clip` over `duration` seconds. */\n crossFadeTo(clip: Animation, duration = 0.3, options?: SplatCrossFadeOptions): this {\n const loop = options?.loop ?? true;\n const armature = this.character.armature;\n armature.frameRate = clip.frameRate;\n this.character.crossfadeTo(this._keyFor(clip), {\n duration,\n loop,\n rootMotion: this._rootMotion === 'apply',\n preserveTime: options?.preserveTime,\n });\n this._started(clip, loop);\n return this;\n }\n\n /** Stop playback and return to the rest pose, blending over `fadeDuration` seconds. */\n stop(fadeDuration = 0): this {\n this.character.stop(fadeDuration);\n this._clip = null;\n return this;\n }\n\n /**\n * Play `clip` on a named layer that overrides part of the body - an upper\n * body wave over a full-body run, say. Calling it again with the same layer\n * name replaces what that layer plays.\n */\n playLayer(layer: string, clip: Animation, options: SplatLayerOptions): this {\n this.character.playLayer(layer, this._keyFor(clip), {\n region: options.region,\n mask: options.mask,\n loop: options.loop,\n crossfade: options.fadeDuration,\n weight: options.weight,\n });\n return this;\n }\n\n setLayerWeight(layer: string, weight: number): this {\n this.character.setLayerWeight(layer, weight);\n return this;\n }\n\n stopLayer(layer: string, fadeDuration = 0): this {\n this.character.stopLayer(layer, fadeDuration);\n return this;\n }\n\n /** The clip the base track is playing, or `null`. */\n get clip(): Animation | null {\n return this.character.isPlaying ? this._clip : null;\n }\n\n get isPlaying(): boolean {\n return this.character.isPlaying;\n }\n\n get paused(): boolean {\n return this.character.armature.paused;\n }\n\n set paused(value: boolean) {\n this.character.armature.paused = value;\n this.character.setAllLayersPaused(value);\n }\n\n /** Playback speed multiplier. `1` is the authored speed. */\n get timeScale(): number {\n return this.character.playbackSpeed;\n }\n\n set timeScale(value: number) {\n this.character.playbackSpeed = value;\n }\n\n /** Position in the current clip, in seconds. */\n get time(): number {\n const armature = this.character.armature;\n return armature.animationTime / armature.frameRate;\n }\n\n set time(seconds: number) {\n const armature = this.character.armature;\n armature.animationTime = seconds * armature.frameRate;\n if (!this._loop) this._finishedSent = armature.isFinished;\n }\n\n /** Length of the current clip in seconds, or `0` when nothing is playing. */\n get duration(): number {\n const armature = this.character.armature;\n return armature.animationDuration / armature.frameRate;\n }\n\n // \u2500\u2500 Root motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** See {@link SplatRootMotion}. Applies to the current clip and every later one. */\n get rootMotion(): SplatRootMotion {\n return this._rootMotion;\n }\n\n set rootMotion(mode: SplatRootMotion) {\n this._rootMotion = mode;\n this.character.armature.rootMotionMode = mode;\n }\n\n /**\n * The clip's horizontal travel since the last call, in this object's local\n * space. Non-zero only in `'extract'` mode. `y` is always `0`.\n */\n consumeRootMotion(target: Vector3 = new Vector3()): Vector3 {\n const { dx, dz } = this.character.consumeRootMotionDelta();\n return target.set(dx, 0, dz);\n }\n\n // \u2500\u2500 Appearance \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Blend the character's colour toward `color` by `amount` (0..1) - a hit\n * flash, a selection highlight. `amount = 0` restores the authored colour.\n */\n setTint(color: ColorRepresentation, amount = 1): this {\n // Splat colour is display-referred, so the tint is taken in sRGB.\n _color.set(color).getRGB(_rgb, SRGBColorSpace);\n this.character.setTint(amount, _rgb);\n return this;\n }\n\n /** Contrast and saturation multipliers for the character's colour. `(1, 1)` is unchanged. */\n setGrade(contrast: number, saturation: number): this {\n for (const splat of this.character.splats) splat.setGrade(contrast, saturation);\n return this;\n }\n\n // \u2500\u2500 Rig \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Bone names, in rig order. */\n get boneNames(): readonly string[] {\n return this.character.armature.rigBoneNames;\n }\n\n /**\n * World matrix of a bone as of the last {@link SplatCharacter.update} - for\n * attaching a prop to a hand, or aiming a camera at a head.\n *\n * @returns `target`, or `null` when the rig has no bone of that name.\n */\n getBoneWorldMatrix(name: string, target: Matrix4 = new Matrix4()): Matrix4 | null {\n const armature = this.character.armature;\n const index = armature.rigBoneNames.indexOf(name);\n const matrix = index < 0 ? null : armature.getBoneWorldMatrix(index);\n return matrix ? target.fromArray(matrix.data) : null;\n }\n\n // \u2500\u2500 Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * A second character from the same decoded data, at the same transform. The\n * copy starts in the rest pose with nothing playing; it does not share this\n * one's animation state.\n */\n override clone(): this {\n const copy = new SplatCharacter(this._engine, this._bundles, this.name);\n copy.position.copy(this.position);\n copy.quaternion.copy(this.quaternion);\n copy.scale.copy(this.scale);\n copy.visible = this.visible;\n copy.renderOrder = this.renderOrder;\n copy.layers.mask = this.layers.mask;\n copy.userData = { ...this.userData };\n copy.rootMotion = this._rootMotion;\n return copy as this;\n }\n\n /**\n * Release every GPU resource the character holds. The object stays in the\n * scene graph, empty; remove it yourself if you no longer want it there.\n */\n override dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n this.character.destroy();\n super.dispose();\n }\n\n private _keyFor(clip: Animation): string {\n // The engine addresses clips by name; give each clip object one of its own.\n if (!clip.registeredName || this._engine.skeletalAnimationLibrary.get(clip.registeredName) === undefined) {\n clip.register(this._engine, `clip:${++_clipSerial}:${clip.name}`);\n }\n return clip.registeredName!;\n }\n\n private _started(clip: Animation, loop: boolean): void {\n this._clip = clip;\n this._loop = loop;\n this._finishedSent = false;\n // Starting a clip resets the armature to in-place or applied; restore 'extract'.\n this.character.armature.rootMotionMode = this._rootMotion;\n }\n}\n", "import { Euler, MathUtils, Vector3 } from 'three';\nimport type { Object3D } from 'three';\n\nimport { Animation } from './animation';\nimport { Armature } from './armature';\nimport type { SplatEngine } from './engine';\nimport { EngineDisposedError } from './engine';\nimport { loadCharacterBundle, loadCharacterBundleFromBytes } from './loader/character/load';\nimport type { CharacterBundle } from './loader/character/load';\nimport { Vec3 } from './math';\nimport type { AnimEventCallback } from './skeletal/animation-player';\nimport { makeRegionMask } from './skeletal/bone-mask';\nimport type { BodyRegion, BoneMask } from './skeletal/bone-mask';\nimport { Splat } from './splat/splat';\n\n/**\n * Options for {@link Character.load}.\n *\n * @group Characters & Animation\n */\nexport interface LoadCharacterOptions {\n /**\n * Name used for the armature and any embedded animation registered on the\n * engine. Defaults to the file basename (stripped of extension).\n */\n name?: string;\n /** Initial position, `y` at GROUND CONTACT - same convention as\n * {@link Character.setPosition}. Defaults to the origin. */\n position?: { x: number; y: number; z: number };\n /**\n * Which rest translations pose the rig.\n *\n * - `'auto'` (default) - `'bundled'` for a bundle carrying a correction\n * receipt, `'builtin'` for one without. Apps should pass nothing: the\n * discriminator lives in the file, so the decision belongs here rather than\n * in each consuming app, where the copies would otherwise drift apart.\n * - `'builtin'` - the canonical std-male tables from the skeleton library.\n * Every character is posed on one shared skeleton.\n * - `'bundled'` - the per-character `joints` array for BODY bones, canonical\n * for `FACIAL_*` ones and for toes. See `keepsCanonicalRest` for the\n * measurements behind both exclusions.\n *\n * The explicit values exist for the comparison scenes, which show one\n * character both ways on purpose.\n *\n * The body tables disagree, and not subtly: on a sample character 81 of 86\n * body bones differ by more than 1 mm, worst 36 mm at `foot_r`, with the\n * canonical limbs uniformly SHORTER (thigh -14.7 mm, calf -36.4 mm). That\n * leaves the canonical knee ~36 mm high and the canonical foot floating\n * ~72 mm off the ground on a character whose own skeleton reaches it.\n *\n * At rest the choice is invisible - skinning cancels `worldPose \u00B7 inverseBind`\n * to identity either way. It only shows once a joint ROTATES, because the\n * rotation happens about the chosen pivot: a splat at the true knee swung\n * about a centre 36 mm away lands ~51 mm off through a 90\u00B0 bend.\n *\n * Clips are authored on the canonical rig - their body translations match\n * `REST_TRANSLATIONS_441` to 0.0007 mm - which USED to make a canonical bind\n * the only one that agreed with the pose, and `'bundled'` a diagnostic.\n * That is no longer so: a bone whose translation never changes across a clip\n * is now read as a rest declaration and left to the character\n * (`Animation`'s `translationMask`, derived for `.anim`, GLB and the\n * `.bin`-embedded clip alike). Playback is effectively rotation-only for\n * every bone the clip does not actually translate - 341 of 342 on the body\n * rig, 829 of 1185 on the full one - so `'bundled'` now inherits the\n * character's own lengths instead of having them overwritten.\n *\n * Bundles carry translations only, never rotations, so `'bundled'` yields\n * per-character bone LENGTHS with canonical joint ORIENTATIONS - a hybrid.\n * Falls back to `'builtin'` when the bundle has no joints (older files) or\n * the array length disagrees with the bone count.\n */\n restSource?: 'auto' | 'builtin' | 'bundled';\n}\n\n/**\n * High-level facade around an {@link Armature} + one or more {@link Splat}s\n * loaded from a character bundle, of any container the reader implements.\n * Construct via {@link Character.load} - the constructor is only used\n * internally.\n *\n * Exposes transform setters (which automatically trigger splat re-sorts) and\n * simple playback verbs ({@link Character.playAnimation}, {@link Character.crossfadeTo},\n * {@link Character.stop}) that delegate to the underlying armature.\n *\n * @group Characters & Animation\n */\n/**\n * Bones whose per-character rest translation is NOT trustworthy, so `'bundled'`\n * keeps the canonical value for them. Both groups were picked on measurement\n * across four generated characters, not by anatomy.\n *\n * `FACIAL_*` - 160-181 mm from canonical at worst, against a face only ~200 mm\n * tall, and clips are authored on the canonical rig, so a per-character facial\n * bind fights the pose (143 mm of displacement measured; 0 mm at rest).\n *\n * `*toe_*` - error relative to BONE LENGTH is what shows here, and absolute\n * numbers hide it. Toes run a median 35% and up to 323% of their own length\n * (`indextoe_01_l`: 17 mm long, displaced 54.8 mm), against a median 14% and\n * max 56% for the rest of the body.\n *\n * Finger tips are the next candidates on the same measure - `index_03_l` 56%,\n * `middle_03_l` 47%, `ring_03_l` 44% - an order of magnitude better than the\n * worst toes but well above the body median. Left in deliberately; revisit if\n * hands are seen to distort.\n */\nfunction keepsCanonicalRest(name: string | undefined): boolean {\n if (!name) return false;\n return name.startsWith('FACIAL_') || name.includes('toe_');\n}\n\nexport class Character {\n /** Render-LOD level pyramid - when more than one entry, only one is\n * enabled at a time (the active level). `splats[0]` is always the\n * highest-fidelity (L0). Single-LOD characters have `splats.length === 1`. */\n public splats: Splat[];\n\n /**\n * The currently-rendered splat. For single-bin characters this is\n * always `splats[0]`; for multi-LOD characters it tracks the active\n * render-LOD level and flips with `setRenderLod` / `setRenderLevel`.\n *\n * Safe for read-only queries (`.numSplats`, `.object3D`, `.isInFrustum`,\n * etc.). For **state mutations** that should persist across LOD swaps\n * (tint, sort, visibility) prefer the Character-level helpers\n * ({@link setTint}, {@link requestSort}) - writing to a single splat\n * here only affects whichever level is active right now and the change\n * vanishes when the active level swaps.\n */\n get splat(): Splat {\n return this.splats[this._activeLevel];\n }\n\n // Render LOD configuration.\n private _renderLodEnabled = false;\n private _renderLodNearDist = Infinity;\n private _renderLodFarDist = Infinity;\n private _activeLevel = 0;\n\n // Linked splats that live OUTSIDE the LOD pyramid - added via\n // {@link addVariantSplat} and managed by higher-level systems (e.g. the\n // DamageVariant preset). They share the armature, animate every frame,\n // and stay enabled by default. Character ownership covers lifecycle\n // (destroy / setActive) but not visibility - that's the variant system's\n // job, via per-splat variant masks.\n private _variantSplats: Splat[] = [];\n\n /** Whether this character is live (ticking + rendering). Toggled by\n * {@link setActive} for object pooling - a deactivated character keeps all\n * its GPU resources (splats, textures, compiled shaders) but stops\n * updating and rendering, so it can be reactivated at a new position with\n * none of the ~tens-of-ms `new Splat` setup cost. */\n private _active = true;\n\n /** Set by {@link destroy}. Async loaders that resolve afterwards (LOD\n * upgrades, variant splats) check this so they don't re-add splats that\n * nothing owns or ticks anymore - without it, a character destroyed while\n * a finer LOD is still downloading leaks that splat into the scene as a\n * frozen, orphaned figure. */\n private _destroyed = false;\n\n /** True once {@link destroy} has run. Progressive-load choreography\n * (coarse-first upgrade loops) should stop streaming when this flips. */\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n // \u2500\u2500\u2500 TEMPORARY: `VIGGCHAR` v1 \u2192 legacy ground-convention shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // DELETE THIS WHOLE BLOCK - the field, the two converters, and the one line\n // in `_buildFromLoadResult` that fills it - when `.bin` retires. The shift is\n // then always 0, every method here is the identity, and removing them cannot\n // move anything.\n //\n // WHY IT EXISTS. The two character containers disagree about where a\n // character's feet sit relative to its model origin:\n //\n // legacy `.bin` feet 7-21 cm BELOW the origin. No ground pass ever ran;\n // they bind wherever the rig put them, and (measured across\n // the 13 assets shipped in this container) they disagree with\n // EACH OTHER by up to 14 cm.\n // VIGGCHAR v1 feet ON the origin. The bake lifts the splats until the\n // lowest visible gaussian (alpha >= 0.02) lands on y = 0 and\n // records that lift in the root joint row - per character,\n // not a constant (0.0432 .. 0.16207 m on real assets).\n //\n // Game code universally assumes \"model origin == ground contact\". That is\n // true for legacy - the canonical rest root row is exactly [0,0,0], which\n // `loader/skeleton/ground-convention.test.ts` pins - and false for v1, so a\n // `.vsplat` character rendered its whole bake shift too high and floated.\n //\n // WHAT IT IS NOT. This is a DE-correction, not a fix: it puts v1 back onto\n // legacy's (wrong, but shipped) convention so that nothing already on screen\n // moves. Normalising ground contact for real - measuring the lowest splat per\n // character at runtime - would move every legacy character and is a separate,\n // product-level call. Do not turn this into that.\n private _bakedGroundShiftY = 0;\n\n /**\n * The ground shift a `VIGGCHAR` v1 bake folded into this character, in\n * metres. `0` for legacy `.bin` bundles and for anything without one.\n *\n * Diagnostics and ground-snap tooling only. {@link setPosition},\n * {@link getPosition} and {@link Character.load}'s `position` option already\n * apply it, so game code should not need to read this - and code that\n * measures ground contact empirically (a {@link getLowestWorldY} probe) must\n * NOT apply it, because such a probe observes the shift's result already and\n * would double-correct.\n */\n get bakedGroundShiftY(): number {\n return this._bakedGroundShiftY;\n }\n\n /**\n * Convert a ground-contact Y - the convention {@link setPosition} takes -\n * into the raw Y to write on `armature.object3D`.\n *\n * For hot paths that must bypass {@link setPosition} and write the pivot\n * directly (a per-frame sync with a pooled `Vec3`, say). Everything else\n * should use {@link setPosition} and never see this.\n */\n groundToEntityY(groundY: number): number {\n return groundY - this._bakedGroundShiftY;\n }\n\n /**\n * Exact inverse of {@link groundToEntityY}: a raw `armature.object3D` Y back\n * into the ground-contact convention.\n *\n * Read positions back through this (or through {@link getPosition}) so that a\n * read/modify/write round-trip - a motor integrating velocity, a tween\n * sampling its own start value - can never apply the shift twice.\n */\n entityToGroundY(entityY: number): number {\n return entityY + this._bakedGroundShiftY;\n }\n // \u2500\u2500\u2500 end temporary shim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private _updateHandler!: (dt: number) => void;\n\n /** Skeleton + animation controller. */\n armature: Armature;\n private _engine: SplatEngine;\n\n /**\n * The three.js object for the whole character - the armature's pivot, with\n * the character's splats parented under it. Already added to the engine's\n * content root; reparent it if you need the character under something else.\n */\n get object3D(): Object3D {\n return this.armature.object3D;\n }\n\n // Fields are declared and assigned explicitly rather than via TypeScript\n // parameter properties: this file is consumed as raw TS by apps that build\n // with `erasableSyntaxOnly`, which rejects parameter properties outright.\n constructor(\n armature: Armature,\n splats: Splat[],\n engine: SplatEngine,\n ) {\n this.armature = armature;\n this._engine = engine;\n if (splats.length === 0) throw new Error('Character: at least one Splat required');\n this.splats = splats;\n // Render-LOD characters start with only L0 visible; the rest are\n // pre-disabled so updatePositions never runs on them at startup. Use\n // `setRenderingEnabled` not raw `object3D.visible` - see the helper's\n // docstring for why both flags must be toggled together.\n splats[0].setRenderingEnabled(true);\n for (let i = 1; i < splats.length; i++) splats[i].setRenderingEnabled(false);\n }\n\n /**\n * Load a character bundle and add it to the engine's content root.\n *\n * The bundle's bone count selects the rig: 441 bones = full body + facial\n * rig, otherwise the 86-bone standard-male body rig. If the bundle contains\n * an embedded animation, it is registered on the engine under\n * {@link LoadCharacterOptions.name} (or the file basename).\n *\n * @param engine - Target engine.\n * @param urlOrUrls - One bundle URL, or an array of LOD levels for the same\n * character, finest first. Every level shares the armature and animation\n * from the FIRST entry; see {@link setRenderLod} for how a level is picked\n * at runtime and {@link addLodLevel} for adding one later.\n * @param opts - See {@link LoadCharacterOptions}.\n * @returns A fully-wired character whose armature drives the splat every frame.\n *\n * @example\n * ```ts\n * const character = await Character.load(engine, '/assets/hero.vsplat');\n * character.playAnimation('idle', { loop: true });\n * ```\n */\n static async load(\n engine: SplatEngine,\n urlOrUrls: string | string[],\n opts?: LoadCharacterOptions,\n ): Promise<Character> {\n const urls = Array.isArray(urlOrUrls) ? urlOrUrls : [urlOrUrls];\n if (urls.length === 0) throw new Error('Character.load: urls is empty');\n const results = await Promise.all(urls.map((u) => loadCharacterBundle(u)));\n const defaultName = urls[0].split('/').pop()?.replace(/\\.\\w+$/, '') ?? 'character';\n return Character._buildFromLoadResult(engine, results, defaultName, opts);\n }\n\n /**\n * Load a `.bin` character bundle from in-memory bytes.\n *\n * Same shape as {@link Character.load} but consumes bytes directly. Use for\n * runtime-generated content (an offline generation pipeline's output, hot\n * swaps, tests) where there is no fetchable URL.\n *\n * @param engine - Target engine.\n * @param bytes - Raw `.bin` bundle bytes.\n * @param opts - See {@link LoadCharacterOptions}. `opts.name` is required for\n * anim registration since there is no URL basename to fall back on.\n * @returns A fully-wired character whose armature drives the splat every frame.\n *\n * @example\n * ```ts\n * const character = await Character.loadFromBytes(engine, generatedBundle, { name: 'hero' });\n * character.playAnimation('idle', { loop: true });\n * ```\n */\n static async loadFromBytes(\n engine: SplatEngine,\n bytes: Uint8Array,\n opts?: LoadCharacterOptions,\n ): Promise<Character> {\n const result = await loadCharacterBundleFromBytes(bytes);\n return Character._buildFromLoadResult(engine, [result], 'character', opts);\n }\n\n /**\n * Load a `.vsplat` bundle.\n *\n * The extension is advisory: the bytes go to the same magic-dispatching\n * reader {@link Character.load} uses, so a `.vsplat` may be a `VIGGCHAR`\n * version 1 bundle or one of the legacy planar containers. None of those\n * carries an animation chunk, so the character comes up in its rest pose;\n * register clips separately with {@link Animation.loadGlb} if you need motion.\n *\n * Differs from {@link Character.load} only in skipping the in-memory\n * `ArrayBuffer` cache - see `loader/shared/asset-loader.ts`.\n *\n * @param engine - Target engine.\n * @param source - URL, or raw `.vsplat` bytes.\n * @param opts - See {@link LoadCharacterOptions}.\n */\n static async loadVsplat(\n engine: SplatEngine,\n source: string | Uint8Array,\n opts?: LoadCharacterOptions,\n ): Promise<Character> {\n const result = typeof source === 'string'\n ? await loadCharacterBundle(source)\n : await loadCharacterBundleFromBytes(source);\n const defaultName = typeof source === 'string'\n ? source.split('/').pop()?.replace(/\\.\\w+$/, '') ?? 'character'\n : 'character';\n return Character._buildFromLoadResult(engine, [result], defaultName, opts);\n }\n\n /**\n * Build a character from bundles that are already decoded. The bundles are\n * read, never modified, so the same ones can back any number of characters.\n * @internal\n */\n static fromBundles(\n engine: SplatEngine,\n bundles: CharacterBundle[],\n defaultName: string,\n opts?: LoadCharacterOptions,\n ): Character {\n return Character._buildFromLoadResult(engine, bundles, defaultName, opts);\n }\n\n private static _buildFromLoadResult(\n engine: SplatEngine,\n results: CharacterBundle[],\n defaultName: string,\n opts?: LoadCharacterOptions,\n ): Character {\n // The funnel for `load`, `loadFromBytes` and `loadVsplat` alike, and the\n // first thing after their awaits that touches the GPU - `linkSplat` below\n // uploads the bone palette. If the engine was disposed while the bytes were\n // in flight, stop here: past this point the failure is a null-dereference\n // inside a texture upload, which reads as a corrupt asset rather than a\n // cancelled load. A caller's own post-await guard cannot cover this,\n // because the throw would happen before its `await` ever returns.\n if (engine.destroyed) {\n throw new EngineDisposedError('Character.load');\n }\n\n const library = engine.skeletonLibrary;\n if (!library?.stdMaleRestTranslations || !library.stdMaleRestRotations || !library.stdMaleParents) {\n throw new Error('Skeleton library not loaded on engine');\n }\n\n // Armature + animation come from results[0] - the LOD pyramid shares\n // one skeleton across all levels; additional results contribute only\n // their splat data. Skeleton / animation in tail bins are duplicates\n // of L0 and are intentionally ignored.\n const primary = results[0];\n\n if (primary.animationData) {\n const animation = new Animation(\n primary.animationData.data,\n primary.animationData.numFrames,\n primary.animationData.numBones,\n primary.animationData.keyframeFrames,\n );\n animation.register(engine, opts?.name ?? defaultName);\n }\n\n // Pick armature rig to match bin bone count. 441 = full body+facial rig;\n // anything else defaults to std male 86-bone body rig.\n const binBoneCount = primary.armatureData?.numBones;\n const use441 = binBoneCount === 441 && library.parents441 && library.restTranslations441 && library.restRotations441;\n const builtinRest = use441 ? library.restTranslations441! : library.stdMaleRestTranslations;\n\n // `restSource: 'bundled'` takes the per-character `joints` for BODY bones and\n // keeps the canonical rest for the bones `keepsCanonicalRest` names - FACIAL_*\n // and toes. Only translations move - bundles carry no rotations - and only\n // when the array is present and sized to the rig, so older bundles silently\n // keep today's behaviour.\n //\n // The face is excluded deliberately, on measurement. Per-character facial\n // joints are unreliable: across four characters they run 160\u2013181 mm from\n // canonical at worst against a ~200 mm-tall face, while the body stays a\n // plausible 45\u201360 mm. And clips are authored on the canonical rig, so a\n // facial clip poses in canonical space while a per-character bind sits\n // elsewhere - measured at 143 mm of facial displacement, 7x more than with\n // facial channels removed, and exactly 0 mm at rest.\n //\n // Body joints are kept because they ARE trustworthy and are what a future\n // rotation-only animation path would need.\n const bundledJoints = primary.armatureData?.joints;\n const boneNames = use441 ? library.boneNames441 : library.boneNames;\n\n // `'auto'` (the default) resolves per bundle, which is the whole point: one\n // build has to render corrected characters on their own rig AND leave every\n // character made before corrections exactly as it renders today. A bundle\n // that was corrected had the ankle and the ground shift baked into its\n // splats and into joint 0; only `'bundled'` reads that root shift back, so\n // posing such a character from the shared tables moves the skin and leaves\n // the skeleton behind. A bundle that was NOT corrected has joints that no\n // pipeline ever vetted, so it keeps the canonical tables.\n const restSource = opts?.restSource ?? 'auto';\n const wantsBundled = restSource === 'auto'\n ? primary.armatureData?.corrected === true\n : restSource === 'bundled';\n const canBundle =\n wantsBundled &&\n bundledJoints instanceof Float32Array &&\n bundledJoints.length === builtinRest.length;\n\n let restTranslations = builtinRest;\n if (canBundle) {\n const joints = bundledJoints as Float32Array;\n const merged = new Float32Array(builtinRest);\n const n = merged.length / 3;\n for (let b = 0; b < n; b++) {\n // No names (unknown rig) => trust the bundle for every bone; the 86-bone\n // rig has no facial bones and its toes are named the same way anyway.\n if (keepsCanonicalRest(boneNames?.[b])) continue;\n merged[b * 3] = joints[b * 3];\n merged[b * 3 + 1] = joints[b * 3 + 1];\n merged[b * 3 + 2] = joints[b * 3 + 2];\n }\n restTranslations = merged;\n }\n\n const armature = use441\n ? new Armature(opts?.name ?? defaultName, {\n numBones: 441,\n stdMaleRestTranslations: restTranslations,\n stdMaleRestRotations: library.restRotations441,\n stdMaleParents: library.parents441,\n })\n : new Armature(opts?.name ?? defaultName, {\n numBones: library.stdMaleRestTranslations.length / 3,\n stdMaleRestTranslations: restTranslations,\n stdMaleRestRotations: library.stdMaleRestRotations,\n stdMaleParents: library.stdMaleParents,\n });\n armature.addToScene(engine);\n\n // One Splat per LOD level. All link to the same armature \u2192 all get the\n // same per-frame bone palette upload. SplatSkinning.pushTransforms\n // skips disabled splats, so hidden LODs pay no CPU.\n const splats: Splat[] = results.map((r) => {\n const s = new Splat(engine, r.source);\n armature.linkSplat(s);\n return s;\n });\n\n // Row 0 of a v1 joints block IS the baked ground shift: the lift is added\n // to the root, because shifting the root moves every bone below it, so no\n // other row carries any of it. The decoder has already de-interleaved the\n // component-major file block into row-major `[x,y,z]` triples, so index 1\n // is the root row's Y. (Verified on real assets: x and z are exactly 0.)\n //\n // Gated on the CONTAINER via `restIsPerCharacter`, never on the\n // `armatureData.corrected` receipt - some legacy bundles carry that receipt\n // and keying on it would move characters that already render correctly.\n // Taken from the bundle whenever it is v1, independent of which rest table\n // the merge above chose: the shift lives in the GEOMETRY, so it applies\n // even when the canonical rest was kept. See the shim block on the class.\n const bakedGroundShiftY =\n primary.armatureData?.restIsPerCharacter === true && bundledJoints instanceof Float32Array\n ? bundledJoints[1]\n : 0;\n\n if (opts?.position) {\n // `position.y` is ground contact, the same convention `setPosition` takes\n // - spelled out here rather than deferred, because the Character that\n // owns the conversion does not exist yet.\n armature.move(new Vec3(\n opts.position.x,\n opts.position.y - bakedGroundShiftY,\n opts.position.z,\n ));\n }\n\n const character = new Character(armature, splats, engine);\n character._bakedGroundShiftY = bakedGroundShiftY;\n character._wireUpdate();\n return character;\n }\n\n /** Build + register the per-frame update handler. Called once at\n * construction; kept separate so the handler can close over `this`. */\n private _wireUpdate(): void {\n this._updateHandler = (dt: number) => {\n if (this._renderLodEnabled && this.splats.length > 1) {\n const next = this._pickRenderLevel();\n if (next !== this._activeLevel) {\n this.splats[this._activeLevel].setRenderingEnabled(false);\n this.splats[next].setRenderingEnabled(true);\n this._activeLevel = next;\n }\n }\n this.armature.update(dt);\n };\n this._engine.addUpdater(this._updateHandler);\n }\n\n /** Pick the render-LOD level for this frame based on camera distance.\n * near band \u2192 L0; far band \u2192 last; in between \u2192 intermediate level. */\n private _pickRenderLevel(): number {\n const N = this.splats.length;\n if (N < 2) return 0;\n const distSq = this.armature.cameraDistanceSq();\n if (distSq === null) return this._activeLevel;\n const near = this._renderLodNearDist;\n const far = this._renderLodFarDist;\n if (distSq < near * near) return 0;\n if (distSq >= far * far) return N - 1;\n // Divide [near, far] into (N-1) equal sub-bands; band i renders L(i+1).\n const dist = Math.sqrt(distSq);\n const bands = N - 1;\n const t = (dist - near) / (far - near);\n return 1 + Math.min(bands - 1, Math.floor(t * bands));\n }\n\n /**\n * Enable distance-based render LOD. Per frame, the character switches\n * between the loaded LOD splats (`splats[0..N-1]`, from finest to\n * coarsest). Near the camera \u2192 L0 (full); beyond `farDist` \u2192 last level;\n * in between \u2192 intermediate levels split evenly across the band.\n *\n * Composes with {@link Armature.setAnimationLod} / {@link Armature.setSortLod}:\n * render LOD throws away splats at distance, the other two throttle\n * animation / sort work - stack all three for maximum CPU savings.\n *\n * No-op if only one LOD level was loaded.\n *\n * @example\n * ```ts\n * const c = await Character.load(engine, ['hero.l0.vsplat', 'hero.l1.vsplat', 'hero.l2.vsplat']);\n * c.setRenderLod({ nearDist: 8, farDist: 20 });\n * ```\n */\n setRenderLod(opts: { nearDist: number; farDist: number }): void {\n if (this.splats.length < 2) return;\n this._renderLodNearDist = opts.nearDist;\n this._renderLodFarDist = opts.farDist;\n this._renderLodEnabled = true;\n }\n\n /** Disable render LOD - pins the character to the highest-fidelity level\n * (L0). Other loaded LOD splats remain in memory but are not rendered. */\n disableRenderLod(): void {\n this._renderLodEnabled = false;\n if (this._activeLevel !== 0) {\n this.splats[this._activeLevel].setRenderingEnabled(false);\n this.splats[0].setRenderingEnabled(true);\n this._activeLevel = 0;\n }\n }\n\n /** Force a specific render-LOD level, bypassing distance bands. Useful\n * for debugging / A-B comparisons in the profiling scene. */\n setRenderLevel(level: number): void {\n const N = this.splats.length;\n if (N < 2) return;\n const clamped = Math.max(0, Math.min(N - 1, Math.floor(level)));\n if (clamped === this._activeLevel) return;\n this.splats[this._activeLevel].setRenderingEnabled(false);\n this.splats[clamped].setRenderingEnabled(true);\n this._activeLevel = clamped;\n }\n\n /** Number of LOD levels loaded for this character (>=1). */\n get renderLodLevels(): number {\n return this.splats.length;\n }\n\n /** Active render-LOD level (0 = highest fidelity). */\n get activeRenderLevel(): number {\n return this._activeLevel;\n }\n\n /**\n * Tint every LOD splat. Fans out to `splats[*]` so the tint persists\n * across render-LOD swaps - writing to a single splat (e.g. the legacy\n * `c.splat.setTint(...)`) only affects that level, and the tint\n * \"vanishes\" the next time `setRenderLod` swaps the visible level.\n *\n * Same signature as {@link Splat.setTint}.\n */\n setTint(\n intensity: number,\n color?: { r: number; g: number; b: number },\n ): void {\n for (const s of this.splats) {\n if (color) s.setTint(intensity, color);\n else s.setTint(intensity);\n }\n }\n\n /**\n * Re-sort every LOD splat. Cheap when called on inactive splats (no GPU\n * sort runs there), and necessary for the active one to reflect a fresh\n * transform on the next frame. Fans out so a swap to a previously-\n * inactive LOD doesn't render with a stale sort order.\n */\n requestSort(): void {\n for (const s of this.splats) s.requestSort();\n }\n\n /**\n * World-space Y of the character's lowest point, using\n * {@link Splat.getGroundWorldY}'s noise-robust low-quantile estimate across\n * every enabled splat (the active render-LOD level, plus any variant splats\n * that are currently visible). Returns `null` if no splat is enabled (e.g.\n * mid-load). Ground-snap tooling only - the per-frame render path doesn't\n * use it.\n *\n * This is a MEASUREMENT of where the character actually renders, so it\n * already includes {@link bakedGroundShiftY}. A caller that snaps to ground\n * from this number must not also apply that shift, or it corrects twice.\n */\n getLowestWorldY(quantile = 0.005): number | null {\n let min = Infinity;\n for (const s of this.splats) {\n if (!s.renderingEnabled) continue;\n const y = s.getGroundWorldY(quantile);\n if (y < min) min = y;\n }\n return min === Infinity ? null : min;\n }\n\n /**\n * Async primitive: load one more LOD level from `url` and link it to this\n * character's armature, leaving it disabled (not rendered) until the caller\n * explicitly picks it via {@link setRenderLevel}.\n *\n * Lets game code compose its own LOD-loading policy on top of an existing\n * Character without the engine deciding when to swap. Typical pattern is\n * progressive: load the smallest LOD via {@link Character.load} for instant\n * first-frame, then background-load finer levels with `addLodLevel` and\n * `setRenderLevel(splats.length - 1)` each time one arrives.\n *\n * Skeleton + animation are shared with the existing armature - any joints\n * / animation data inside the additional `.bin` is intentionally ignored\n * (it must match the original; only the splat + bone-weights chunks are\n * consumed). The newly loaded `Splat` is pushed onto `this.splats` and\n * starts in the disabled state.\n *\n * @param url - URL of another `.bin` (any LOD level of the same character).\n * @returns Resolves once the splat is fully loaded, linked, and GPU-uploaded.\n *\n * @example\n * ```ts\n * // Progressive: start at L2 (smallest), upgrade as finer levels arrive.\n * const c = await Character.load(engine, urls[2], opts);\n * (async () => {\n * await c.addLodLevel(urls[1]);\n * c.setRenderLevel(c.splats.length - 1);\n * await c.addLodLevel(urls[0]);\n * c.setRenderLevel(c.splats.length - 1);\n * })();\n * ```\n */\n async addLodLevel(url: string): Promise<void> {\n const result = await loadCharacterBundle(url);\n // Destroyed while the level was downloading (e.g. a rapid character swap)\n // - adding the splat now would orphan it in the scene with nothing\n // ticking or owning it. Drop the bytes instead.\n if (this._destroyed) return;\n const splat = new Splat(this._engine, result.source);\n this.armature.linkSplat(splat);\n splat.setRenderingEnabled(false);\n this.splats.push(splat);\n }\n\n /**\n * Load an additional splat cloud, link it to this character's armature,\n * and leave it ENABLED so it renders alongside the LOD pyramid. Returns\n * the newly-created {@link Splat} so higher-level systems can drive it\n * directly (typically via {@link Splat.setSplatGroups} +\n * {@link Splat.setVariantMask}).\n *\n * Use case: damage / outfit / state variants where two skinned clouds\n * share one skeleton and per-region visibility masks decide which\n * gaussians each cloud contributes. See the `DamageVariant` preset for\n * the body-part scheme built on top of this primitive.\n *\n * The variant splat's lifecycle is owned by this Character - it is\n * destroyed in {@link destroy} and enabled/disabled by {@link setActive}.\n * Call {@link removeVariantSplat} to retire one early.\n *\n * @param url - URL of a `.bin` rigged to the same skeleton as this\n * character. The skeleton/animation chunks (if present) are ignored.\n */\n async addVariantSplat(url: string): Promise<Splat> {\n const result = await loadCharacterBundle(url);\n // Same guard as addLodLevel: a variant landing after destroy() would be\n // an unowned orphan. Reject so the awaiting caller's flow (itself tied\n // to the destroyed character) fails loudly instead of leaking.\n if (this._destroyed) {\n throw new Error('Character destroyed while variant splat was loading');\n }\n const splat = new Splat(this._engine, result.source);\n this.armature.linkSplat(splat);\n splat.setRenderingEnabled(true);\n this._variantSplats.push(splat);\n return splat;\n }\n\n /** Remove and destroy a splat previously added via {@link addVariantSplat}.\n * No-op if `splat` was not from this character. */\n removeVariantSplat(splat: Splat): void {\n const idx = this._variantSplats.indexOf(splat);\n if (idx < 0) return;\n this._variantSplats.splice(idx, 1);\n this.armature.unlinkSplat(splat);\n splat.destroy();\n }\n\n /** Read-only view of currently-attached variant splats (in insertion order). */\n get variantSplats(): readonly Splat[] {\n return this._variantSplats;\n }\n\n /**\n * Set the character's position, with `y` measured at GROUND CONTACT: pass the\n * floor height and the feet land on it, whichever container the character\n * came from. Triggers a splat re-sort.\n *\n * `y` goes through {@link groundToEntityY} on the way to the pivot. That is\n * the identity for every legacy `.bin` character, so this is byte-identical\n * to the historical \"y is the model origin\" behaviour for everything already\n * shipped; only `VIGGCHAR` v1 bundles move. Read the position back with\n * {@link getPosition}, never with `armature.object3D.position`, or a\n * round-trip will double-apply the shift.\n */\n setPosition(x: number, y: number, z: number) {\n this.armature.move(new Vec3(x, this.groundToEntityY(y), z));\n }\n\n /**\n * The character's current position in the armature pivot's parent space, in\n * the same convention {@link setPosition} takes (`y` at ground contact).\n *\n * The exact inverse of {@link setPosition}: reading a position and writing it\n * straight back is a no-op. That is the property to preserve - it is what\n * lets a caller integrate velocity, tween, or clamp against a position it\n * read without the ground shim compounding once per frame.\n *\n * Returns a fresh {@link Vec3}; the pivot's own vector is not exposed.\n */\n getPosition(out: Vector3 = new Vector3()): Vector3 {\n const p = this.armature.object3D.position;\n return out.set(p.x, this.entityToGroundY(p.y), p.z);\n }\n\n /** Set the character's rotation in Euler degrees. Triggers a splat re-sort. */\n setRotation(xDeg: number, yDeg: number, zDeg: number) {\n // 'ZYX' is the order that reproduces the PlayCanvas build's euler convention.\n this.armature.object3D.quaternion.setFromEuler(\n _euler.set(xDeg * MathUtils.DEG2RAD, yDeg * MathUtils.DEG2RAD, zDeg * MathUtils.DEG2RAD, 'ZYX'),\n );\n this.requestSort();\n }\n\n /** Set non-uniform scale. Triggers a splat re-sort. */\n setScale(x: number, y: number, z: number) {\n this.armature.object3D.scale.set(x, y, z);\n this.requestSort();\n }\n\n /**\n * Immediately start a registered animation (no crossfade).\n *\n * The animation must have been registered on the engine via\n * {@link Animation.register} or embedded in the `.bin` bundle.\n *\n * @param animName - Animation name in `engine.skeletalAnimationLibrary`.\n * @param opts.loop - Loop playback. Default `true`.\n * @param opts.rootMotion - Drive the armature position from the pelvis X/Z channel. Default `false`.\n * @returns `true` if the animation was found and started; `false` otherwise.\n */\n playAnimation(animName: string, opts?: { loop?: boolean; rootMotion?: boolean }): boolean {\n return this.armature.playAnimation(\n animName,\n opts?.rootMotion ?? false,\n opts?.loop ?? true,\n );\n }\n\n /**\n * Smoothly blend from the current pose to a new animation.\n *\n * Snapshots the current bone poses and interpolates toward the new\n * animation over `duration` seconds. Safe to call mid-crossfade - always\n * starts from wherever bones actually are.\n *\n * @param animName - Animation name in `engine.skeletalAnimationLibrary`.\n * @param opts.duration - Crossfade length in seconds. Default `0.08`.\n * @param opts.loop - Loop the target animation. Default `true`.\n * @param opts.rootMotion - Drive the armature position from the pelvis X/Z channel. Default `false`.\n * @returns `true` if the animation was found and the blend started; `false` otherwise.\n */\n crossfadeTo(\n animName: string,\n opts?: { duration?: number; loop?: boolean; rootMotion?: boolean; preserveTime?: boolean },\n ): boolean {\n return this.armature.crossfadeTo(animName, opts);\n }\n\n /**\n * Play `animName` on the named overlay layer, restricted to a bone mask.\n * Layers compose over the base animation each frame - masked bones blend\n * toward the overlay by `opts.weight` (defaults to `1`).\n *\n * Pass `opts.region: 'upperBody' | 'lowerBody'` to use the built-in masks\n * (canonical 86-bone rig), or `opts.mask` directly to supply your own.\n *\n * Typical use: `character.playAnimation('walk_loop'); character.playLayer('aim', 'aim_rifle', { region: 'upperBody' });`\n */\n playLayer(\n layerName: string,\n animName: string,\n opts?: {\n region?: BodyRegion;\n mask?: BoneMask;\n loop?: boolean;\n crossfade?: number;\n weight?: number;\n },\n ): boolean {\n let mask = opts?.mask;\n if (!mask && opts?.region) mask = makeRegionMask(opts.region, this.armature.boneNames);\n if (!mask) return false;\n return this.armature.playLayerAnimation(layerName, animName, mask, opts);\n }\n\n /** Set the overlay weight (0..1) on a layer. */\n setLayerWeight(layerName: string, weight: number): void {\n this.armature.setLayerWeight(layerName, weight);\n }\n\n /** Stop and tear down a layer; ramps weight to zero over `fadeDuration` if > 0. */\n stopLayer(layerName: string, fadeDuration = 0): void {\n this.armature.stopLayer(layerName, fadeDuration);\n }\n\n /** Pause or resume every active overlay layer at once. */\n setAllLayersPaused(paused: boolean): void {\n this.armature.setAllLayersPaused(paused);\n }\n\n /**\n * Name of the currently-playing animation, or `null` if no animation is\n * active. Mirrors {@link Armature.currentAnimationName}.\n */\n get currentAnimationName(): string | null {\n return this.armature.currentAnimationName;\n }\n\n /** `true` if an animation is currently active. */\n get isPlaying(): boolean {\n return this.armature.isPlaying;\n }\n\n /**\n * Playback-speed multiplier for the active clip (`1` = author speed, `2` =\n * double speed). Scales only how fast animation time advances, not the\n * authored frame rate or crossfade timing. Mirrors\n * {@link Armature.playbackSpeed}. Use it to tie a locomotion clip's speed\n * to the pivot's movement speed.\n */\n get playbackSpeed(): number {\n return this.armature.playbackSpeed;\n }\n set playbackSpeed(v: number) {\n this.armature.playbackSpeed = v;\n }\n\n /**\n * `true` when a non-looping animation has reached its last frame and is no\n * longer advancing.\n */\n get isFinished(): boolean {\n return this.armature.isFinished;\n }\n\n /**\n * Subscribe to frame-aligned animation events fired as `animTime` advances.\n * The active animation's {@link Animation.events} array is the source; the\n * engine doesn't interpret `name` or `payload` - games define their own\n * vocabulary and route inside the callback.\n *\n * Listeners persist across animation switches. Returns an unsubscribe handle.\n *\n * @example\n * ```ts\n * character.onAnimEvent((e) => {\n * if (e.name === 'footstep') playFootstepSfx(e.payload);\n * });\n * ```\n */\n onAnimEvent(cb: AnimEventCallback): () => void {\n return this.armature.onAnimEvent(cb);\n }\n\n /**\n * Stop playback.\n *\n * With `fadeDuration = 0` (the default), snaps immediately to the rest\n * pose. A positive value crossfades back to rest over that many seconds.\n */\n stop(fadeDuration = 0) {\n this.armature.stop(fadeDuration);\n }\n\n /**\n * Read and reset the pelvis X/Z delta the animation produced since the\n * last call. Only meaningful when\n * {@link Armature.rootMotionMode | armature.rootMotionMode} is `'extract'`;\n * returns `{0, 0}` otherwise.\n *\n * Typical use: a motor / character controller reads this each tick and\n * feeds it into its own velocity integration, so animation root motion\n * composes cleanly with physics, networking, or input.\n *\n * ```ts\n * // in your render loop, after engine.update(dt):\n * const { dx, dz } = character.consumeRootMotionDelta();\n * motor.setMoveVelocity(dx / dt, dz / dt);\n * motor.update(dt);\n * ```\n */\n consumeRootMotionDelta(): { dx: number; dz: number } {\n return this.armature.consumeRootMotionDelta();\n }\n\n /** True while the character is ticking + rendering (see {@link setActive}). */\n get active(): boolean { return this._active; }\n\n /**\n * Activate / deactivate this character WITHOUT releasing GPU resources -\n * the basis for object pooling. Deactivating detaches the per-frame update\n * handler and disables every splat object and the armature pivot, so the\n * character stops animating and rendering but keeps all its splats,\n * textures and compiled shaders alive. Reactivating re-attaches the update\n * handler and re-enables the armature; render-LOD then re-picks which splat\n * shows on the next frame (so we only force the current level visible to\n * cover the LOD-disabled case).\n *\n * Reactivate is the cheap path that skips the entire `new Splat` setup cost\n * (texture creation + bone upload + shader compile, ~tens of ms per\n * character) that a fresh {@link load} pays. Callers reposition via\n * `armature.move(...)` and restart animation via `playAnimation(...)` after\n * reactivating.\n *\n * Idempotent.\n */\n setActive(on: boolean): void {\n if (on === this._active) return;\n this._active = on;\n if (on) {\n this.armature.object3D.visible = true;\n // Show the current LOD level; render-LOD (if enabled) re-evaluates and\n // fixes this on the next update. With LOD off, splats.length === 1 and\n // this is the only one.\n this.splats[this._activeLevel]?.setRenderingEnabled(true);\n for (const s of this._variantSplats) s.setRenderingEnabled(true);\n this._engine.addUpdater(this._updateHandler);\n } else {\n this._engine.removeUpdater(this._updateHandler);\n for (const s of this.splats) s.setRenderingEnabled(false);\n for (const s of this._variantSplats) s.setRenderingEnabled(false);\n this.armature.object3D.visible = false;\n }\n }\n\n /**\n * Detach the per-frame playback tick without touching rendering/GPU\n * resources (unlike {@link setActive}). For hosts that drive the armature's\n * clock themselves and apply their own per-frame pose edits, the auto-tick\n * would re-evaluate and overwrite those edits. Idempotent.\n */\n detachAutoUpdate(): void {\n this._engine.removeUpdater(this._updateHandler);\n }\n\n /**\n * Advance this character by `dt` seconds: pick the render LOD, evaluate the\n * pose, push it to the splats. `engine.update()` calls this for every\n * character still on auto-update; call it yourself after\n * {@link detachAutoUpdate}.\n */\n update(dt: number): void {\n this._updateHandler(dt);\n }\n\n /**\n * Release all GPU/CPU resources: removes the engine update handler, unlinks\n * the splat from the armature, destroys both, and removes the armature\n * pivot from the scene graph.\n */\n destroy() {\n if (this._destroyed) return;\n this._destroyed = true;\n this._engine.removeUpdater(this._updateHandler);\n for (const s of this.splats) {\n this.armature.unlinkSplat(s);\n s.destroy();\n }\n for (const s of this._variantSplats) {\n this.armature.unlinkSplat(s);\n s.destroy();\n }\n this._variantSplats.length = 0;\n this.armature.destroy();\n }\n}\n\nconst _euler = new Euler();\n", "/**\n * Internal math kernel for the skeletal core.\n *\n * The rig, animation and skinning code is shared with the PlayCanvas build of\n * this engine and was written against that engine's `Vec3` / `Quat` / `Mat4`.\n * These classes keep the same method names, argument orders and formulas, so\n * the shared files compile unchanged and the bone matrices they produce match\n * the PlayCanvas build to float precision - which is what the A/B suite checks.\n *\n * Deliberately NOT `THREE.Vector3` and friends: the conventions differ in ways\n * that silently change results (`lerp(a, b, t)` vs `lerp(v, t)`, a two-argument\n * `cross`, a `Float32Array`-backed matrix), and a port that swapped them by\n * hand would be a port nobody could diff against the original.\n *\n * Nothing here is part of the public API. Values cross into three.js types at\n * the `Character` / `Armature` boundary.\n */\n\nexport class Vec3 {\n x: number;\n y: number;\n z: number;\n\n constructor(x = 0, y = 0, z = 0) {\n this.x = x;\n this.y = y;\n this.z = z;\n }\n\n set(x: number, y: number, z: number): this {\n this.x = x;\n this.y = y;\n this.z = z;\n return this;\n }\n\n copy(rhs: { x: number; y: number; z: number }): this {\n this.x = rhs.x;\n this.y = rhs.y;\n this.z = rhs.z;\n return this;\n }\n\n clone(): Vec3 {\n return new Vec3(this.x, this.y, this.z);\n }\n\n add(rhs: Vec3): this {\n this.x += rhs.x;\n this.y += rhs.y;\n this.z += rhs.z;\n return this;\n }\n\n add2(lhs: Vec3, rhs: Vec3): this {\n this.x = lhs.x + rhs.x;\n this.y = lhs.y + rhs.y;\n this.z = lhs.z + rhs.z;\n return this;\n }\n\n sub2(lhs: Vec3, rhs: Vec3): this {\n this.x = lhs.x - rhs.x;\n this.y = lhs.y - rhs.y;\n this.z = lhs.z - rhs.z;\n return this;\n }\n\n mulScalar(scalar: number): this {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n return this;\n }\n\n dot(rhs: Vec3): number {\n return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z;\n }\n\n cross(lhs: Vec3, rhs: Vec3): this {\n const lx = lhs.x, ly = lhs.y, lz = lhs.z;\n const rx = rhs.x, ry = rhs.y, rz = rhs.z;\n this.x = ly * rz - ry * lz;\n this.y = lz * rx - rz * lx;\n this.z = lx * ry - rx * ly;\n return this;\n }\n\n length(): number {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);\n }\n\n normalize(): this {\n const lengthSq = this.x * this.x + this.y * this.y + this.z * this.z;\n if (lengthSq > 0) {\n const invLength = 1 / Math.sqrt(lengthSq);\n this.x *= invLength;\n this.y *= invLength;\n this.z *= invLength;\n }\n return this;\n }\n\n lerp(lhs: Vec3, rhs: Vec3, alpha: number): this {\n this.x = lhs.x + alpha * (rhs.x - lhs.x);\n this.y = lhs.y + alpha * (rhs.y - lhs.y);\n this.z = lhs.z + alpha * (rhs.z - lhs.z);\n return this;\n }\n}\n\nexport class Quat {\n x: number;\n y: number;\n z: number;\n w: number;\n\n constructor(x = 0, y = 0, z = 0, w = 1) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n }\n\n set(x: number, y: number, z: number, w: number): this {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n return this;\n }\n\n copy(rhs: { x: number; y: number; z: number; w: number }): this {\n this.x = rhs.x;\n this.y = rhs.y;\n this.z = rhs.z;\n this.w = rhs.w;\n return this;\n }\n\n clone(): Quat {\n return new Quat(this.x, this.y, this.z, this.w);\n }\n\n conjugate(): this {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n return this;\n }\n\n dot(other: Quat): number {\n return this.x * other.x + this.y * other.y + this.z * other.z + this.w * other.w;\n }\n\n length(): number {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);\n }\n\n mulScalar(scalar: number): this {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n this.w *= scalar;\n return this;\n }\n\n normalize(): this {\n let len = this.length();\n if (len === 0) {\n this.x = this.y = this.z = 0;\n this.w = 1;\n } else {\n len = 1 / len;\n this.x *= len;\n this.y *= len;\n this.z *= len;\n this.w *= len;\n }\n return this;\n }\n\n /** `this = lhs * rhs`. Safe when `this` aliases either operand. */\n mul2(lhs: Quat, rhs: Quat): this {\n const q1x = lhs.x, q1y = lhs.y, q1z = lhs.z, q1w = lhs.w;\n const q2x = rhs.x, q2y = rhs.y, q2z = rhs.z, q2w = rhs.w;\n this.x = q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y;\n this.y = q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z;\n this.z = q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x;\n this.w = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z;\n return this;\n }\n\n mul(rhs: Quat): this {\n return this.mul2(this, rhs);\n }\n\n slerp(lhs: Quat, rhs: Quat, alpha: number): this {\n const lx = lhs.x, ly = lhs.y, lz = lhs.z, lw = lhs.w;\n let rx = rhs.x, ry = rhs.y, rz = rhs.z, rw = rhs.w;\n\n let cosHalfTheta = lw * rw + lx * rx + ly * ry + lz * rz;\n if (cosHalfTheta < 0) {\n rw = -rw;\n rx = -rx;\n ry = -ry;\n rz = -rz;\n cosHalfTheta = -cosHalfTheta;\n }\n\n if (Math.abs(cosHalfTheta) >= 1) {\n this.w = lw;\n this.x = lx;\n this.y = ly;\n this.z = lz;\n return this;\n }\n\n const halfTheta = Math.acos(cosHalfTheta);\n const sinHalfTheta = Math.sqrt(1 - cosHalfTheta * cosHalfTheta);\n\n if (Math.abs(sinHalfTheta) < 0.001) {\n this.w = lw * 0.5 + rw * 0.5;\n this.x = lx * 0.5 + rx * 0.5;\n this.y = ly * 0.5 + ry * 0.5;\n this.z = lz * 0.5 + rz * 0.5;\n return this;\n }\n\n const ratioA = Math.sin((1 - alpha) * halfTheta) / sinHalfTheta;\n const ratioB = Math.sin(alpha * halfTheta) / sinHalfTheta;\n this.w = lw * ratioA + rw * ratioB;\n this.x = lx * ratioA + rx * ratioB;\n this.y = ly * ratioA + ry * ratioB;\n this.z = lz * ratioA + rz * ratioB;\n return this;\n }\n\n /** Rotation of the upper 3x3 of `m`, with any scale (and a mirror) divided out. */\n setFromMat4(m: Mat4): this {\n const d = m.data;\n let m00 = d[0], m01 = d[1], m02 = d[2];\n let m10 = d[4], m11 = d[5], m12 = d[6];\n let m20 = d[8], m21 = d[9], m22 = d[10];\n\n const det = m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m12 * m20) + m02 * (m10 * m21 - m11 * m20);\n if (det < 0) {\n m00 = -m00;\n m01 = -m01;\n m02 = -m02;\n }\n\n let l: number;\n l = m00 * m00 + m01 * m01 + m02 * m02;\n if (l === 0) return this.set(0, 0, 0, 1);\n l = 1 / Math.sqrt(l);\n m00 *= l;\n m01 *= l;\n m02 *= l;\n\n l = m10 * m10 + m11 * m11 + m12 * m12;\n if (l === 0) return this.set(0, 0, 0, 1);\n l = 1 / Math.sqrt(l);\n m10 *= l;\n m11 *= l;\n m12 *= l;\n\n l = m20 * m20 + m21 * m21 + m22 * m22;\n if (l === 0) return this.set(0, 0, 0, 1);\n l = 1 / Math.sqrt(l);\n m20 *= l;\n m21 *= l;\n m22 *= l;\n\n if (m22 < 0) {\n if (m00 > m11) {\n this.set(1 + m00 - m11 - m22, m01 + m10, m20 + m02, m12 - m21);\n } else {\n this.set(m01 + m10, 1 - m00 + m11 - m22, m12 + m21, m20 - m02);\n }\n } else {\n if (m00 < -m11) {\n this.set(m20 + m02, m12 + m21, 1 - m00 - m11 + m22, m01 - m10);\n } else {\n this.set(m12 - m21, m20 - m02, m01 - m10, 1 + m00 + m11 + m22);\n }\n }\n\n return this.mulScalar(1.0 / this.length());\n }\n}\n\n/** Column-major 4x4, `Float32Array`-backed. Same element layout as `THREE.Matrix4.elements`. */\nexport class Mat4 {\n data: Float32Array;\n\n constructor() {\n const data = new Float32Array(16);\n data[0] = data[5] = data[10] = data[15] = 1;\n this.data = data;\n }\n\n copy(rhs: Mat4): this {\n this.data.set(rhs.data);\n return this;\n }\n\n clone(): Mat4 {\n return new Mat4().copy(this);\n }\n\n setIdentity(): this {\n const m = this.data;\n m.fill(0);\n m[0] = m[5] = m[10] = m[15] = 1;\n return this;\n }\n\n /** Copy from any 16-element column-major source (e.g. `THREE.Matrix4.elements`). */\n setFromArray(src: ArrayLike<number>): this {\n const m = this.data;\n for (let i = 0; i < 16; i++) m[i] = src[i];\n return this;\n }\n\n setTRS(t: Vec3, r: Quat, s: Vec3): this {\n const qx = r.x, qy = r.y, qz = r.z, qw = r.w;\n const sx = s.x, sy = s.y, sz = s.z;\n\n const x2 = qx + qx;\n const y2 = qy + qy;\n const z2 = qz + qz;\n const xx = qx * x2;\n const xy = qx * y2;\n const xz = qx * z2;\n const yy = qy * y2;\n const yz = qy * z2;\n const zz = qz * z2;\n const wx = qw * x2;\n const wy = qw * y2;\n const wz = qw * z2;\n\n const m = this.data;\n m[0] = (1 - (yy + zz)) * sx;\n m[1] = (xy + wz) * sx;\n m[2] = (xz - wy) * sx;\n m[3] = 0;\n m[4] = (xy - wz) * sy;\n m[5] = (1 - (xx + zz)) * sy;\n m[6] = (yz + wx) * sy;\n m[7] = 0;\n m[8] = (xz + wy) * sz;\n m[9] = (yz - wx) * sz;\n m[10] = (1 - (xx + yy)) * sz;\n m[11] = 0;\n m[12] = t.x;\n m[13] = t.y;\n m[14] = t.z;\n m[15] = 1;\n return this;\n }\n\n /** `this = lhs * rhs`. Safe when `this` aliases either operand. */\n mul2(lhs: Mat4, rhs: Mat4): this {\n const a = lhs.data;\n const b = rhs.data;\n const r = this.data;\n\n const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];\n const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];\n const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];\n const a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];\n\n let b0: number, b1: number, b2: number, b3: number;\n\n b0 = b[0]; b1 = b[1]; b2 = b[2]; b3 = b[3];\n r[0] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;\n r[1] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;\n r[2] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;\n r[3] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;\n\n b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];\n r[4] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;\n r[5] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;\n r[6] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;\n r[7] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;\n\n b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];\n r[8] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;\n r[9] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;\n r[10] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;\n r[11] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;\n\n b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];\n r[12] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3;\n r[13] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3;\n r[14] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3;\n r[15] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3;\n return this;\n }\n\n mul(rhs: Mat4): this {\n return this.mul2(this, rhs);\n }\n\n invert(): this {\n const s = this.data;\n const a00 = s[0], a01 = s[1], a02 = s[2], a03 = s[3];\n const a10 = s[4], a11 = s[5], a12 = s[6], a13 = s[7];\n const a20 = s[8], a21 = s[9], a22 = s[10], a23 = s[11];\n const a30 = s[12], a31 = s[13], a32 = s[14], a33 = s[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n const det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n if (det === 0) {\n this.setIdentity();\n } else {\n const invDet = 1 / det;\n const t = this.data;\n t[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n t[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n t[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n t[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n t[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n t[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n t[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n t[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n t[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n t[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n t[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n t[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n t[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n t[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n t[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n t[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n }\n return this;\n }\n\n getTranslation(t: Vec3 = new Vec3()): Vec3 {\n return t.set(this.data[12], this.data[13], this.data[14]);\n }\n\n getScale(scale: Vec3 = new Vec3()): Vec3 {\n const d = this.data;\n return scale.set(\n Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]),\n Math.sqrt(d[4] * d[4] + d[5] * d[5] + d[6] * d[6]),\n Math.sqrt(d[8] * d[8] + d[9] * d[9] + d[10] * d[10]),\n );\n }\n}\n", "// Auto-generated skeleton data - do not edit manually.\n\nexport const NUM_BONES = 86;\n\nexport const BONE_NAMES: string[] = [\"root\",\"pelvis\",\"spine_01\",\"spine_02\",\"spine_03\",\"spine_04\",\"spine_05\",\"neck_01\",\"neck_02\",\"head\",\"clavicle_l\",\"upperarm_l\",\"lowerarm_l\",\"hand_l\",\"pinky_metacarpal_l\",\"pinky_01_l\",\"pinky_02_l\",\"pinky_03_l\",\"ring_metacarpal_l\",\"ring_01_l\",\"ring_02_l\",\"ring_03_l\",\"thumb_01_l\",\"thumb_02_l\",\"thumb_03_l\",\"middle_metacarpal_l\",\"middle_01_l\",\"middle_02_l\",\"middle_03_l\",\"index_metacarpal_l\",\"index_01_l\",\"index_02_l\",\"index_03_l\",\"clavicle_r\",\"upperarm_r\",\"lowerarm_r\",\"hand_r\",\"pinky_metacarpal_r\",\"pinky_01_r\",\"pinky_02_r\",\"pinky_03_r\",\"ring_metacarpal_r\",\"ring_01_r\",\"ring_02_r\",\"ring_03_r\",\"thumb_01_r\",\"thumb_02_r\",\"thumb_03_r\",\"middle_metacarpal_r\",\"middle_01_r\",\"middle_02_r\",\"middle_03_r\",\"index_metacarpal_r\",\"index_01_r\",\"index_02_r\",\"index_03_r\",\"thigh_r\",\"calf_r\",\"foot_r\",\"ball_r\",\"littletoe_01_r\",\"littletoe_02_r\",\"ringtoe_01_r\",\"ringtoe_02_r\",\"middletoe_01_r\",\"middletoe_02_r\",\"bigtoe_01_r\",\"bigtoe_02_r\",\"indextoe_01_r\",\"indextoe_02_r\",\"calf_twist_01_r\",\"thigh_l\",\"calf_l\",\"foot_l\",\"ball_l\",\"indextoe_01_l\",\"indextoe_02_l\",\"bigtoe_01_l\",\"bigtoe_02_l\",\"littletoe_01_l\",\"littletoe_02_l\",\"middletoe_01_l\",\"middletoe_02_l\",\"ringtoe_01_l\",\"ringtoe_02_l\",\"calf_twist_01_l\"];\n\nexport const SKELETON_1185_NAMES: string[] = [\"root\",\"pelvis\",\"spine_01\",\"spine_02\",\"spine_03\",\"spine_04\",\"spine_05\",\"neck_01\",\"neck_02\",\"head\",\"clavicle_l\",\"upperarm_l\",\"upperarm_correctiveRoot_l\",\"upperarm_bck_l\",\"upperarm_fwd_l\",\"upperarm_in_l\",\"upperarm_out_l\",\"lowerarm_l\",\"hand_l\",\"pinky_metacarpal_l\",\"pinky_01_l\",\"pinky_02_l\",\"pinky_03_l\",\"pinky_03_bulge_l\",\"pinky_03_half_l\",\"pinky_03_in_l\",\"pinky_02_dip_l\",\"pinky_02_bulge_l\",\"pinky_02_side_out_l\",\"pinky_02_side_inn_l\",\"pinky_02_half_l\",\"pinky_02_in_l\",\"pinky_02_pip_l\",\"pinky_01_palmMid_l\",\"pinky_01_bulge_l\",\"pinky_01_side_out_l\",\"pinky_01_side_inn_l\",\"pinky_01_half_l\",\"pinky_01_mcp_l\",\"pinky_01_palm_l\",\"pinky_metacarpal_slide_l\",\"ring_metacarpal_l\",\"ring_01_l\",\"ring_02_l\",\"ring_03_l\",\"ring_03_bulge_l\",\"ring_03_half_l\",\"ring_02_dip_l\",\"ring_03_in_l\",\"ring_02_bulge_l\",\"ring_02_side_out_l\",\"ring_02_side_inn_l\",\"ring_02_half_l\",\"ring_02_in_l\",\"ring_02_pip_l\",\"ring_01_palmMid_l\",\"ring_01_bulge_l\",\"ring_01_side_out_l\",\"ring_01_side_inn_l\",\"ring_01_half_l\",\"ring_01_mcp_l\",\"ring_01_palm_l\",\"ring_metacarpal_slide_l\",\"thumb_01_l\",\"thumb_02_l\",\"thumb_03_l\",\"thumb_03_bulge_l\",\"thumb_03_side_out_l\",\"thumb_03_side_inn_l\",\"thumb_03_half_l\",\"thumb_03_pip_l\",\"thumb_03_in_l\",\"thumb_02_bulge_l\",\"thumb_02_side_out_l\",\"thumb_02_side_inn_l\",\"thumb_02_half_l\",\"thumb_02_in_l\",\"thumb_02_mcp_l\",\"thumb_01_side_out_l\",\"thumb_01_side_inn_l\",\"middle_metacarpal_l\",\"middle_01_l\",\"middle_02_l\",\"middle_03_l\",\"middle_03_bulge_l\",\"middle_03_half_l\",\"middle_03_in_l\",\"middle_02_dip_l\",\"middle_02_bulge_l\",\"middle_02_side_out_l\",\"middle_02_side_inn_l\",\"middle_02_half_l\",\"middle_02_pip_l\",\"middle_02_in_l\",\"middle_01_palmMid_l\",\"middle_01_bulge_l\",\"middle_01_side_out_l\",\"middle_01_side_inn_l\",\"middle_01_half_l\",\"middle_01_mcp_l\",\"middle_01_palm_l\",\"middle_metacarpal_slide_l\",\"index_metacarpal_l\",\"index_01_l\",\"index_02_l\",\"index_03_l\",\"index_03_bulge_l\",\"index_03_half_l\",\"index_02_dip_l\",\"index_03_in_l\",\"index_02_bulge_l\",\"index_02_side_out_l\",\"index_02_side_inn_l\",\"index_02_half_l\",\"index_02_in_l\",\"index_02_pip_l\",\"index_01_palmMid_l\",\"index_01_bulge_l\",\"index_01_side_out_l\",\"index_01_side_inn_l\",\"index_01_half_l\",\"index_01_mcp_l\",\"index_01_palm_l\",\"index_metacarpal_slide_l\",\"wrist_inner_l\",\"wrist_outer_l\",\"lowerarm_twist_02_l\",\"lowerarm_twist_01_l\",\"lowerarm_correctiveRoot_l\",\"lowerarm_in_l\",\"lowerarm_out_l\",\"lowerarm_fwd_l\",\"lowerarm_bck_l\",\"upperarm_twist_01_l\",\"upperarm_twistCor_01_l\",\"upperarm_twist_02_l\",\"upperarm_tricep_l\",\"upperarm_bicep_l\",\"upperarm_twistCor_02_l\",\"clavicle_out_l\",\"clavicle_scap_l\",\"clavicle_r\",\"upperarm_r\",\"upperarm_correctiveRoot_r\",\"upperarm_bck_r\",\"upperarm_in_r\",\"upperarm_fwd_r\",\"upperarm_out_r\",\"lowerarm_r\",\"hand_r\",\"pinky_metacarpal_r\",\"pinky_01_r\",\"pinky_02_r\",\"pinky_03_r\",\"pinky_03_bulge_r\",\"pinky_03_half_r\",\"pinky_03_in_r\",\"pinky_02_dip_r\",\"pinky_02_bulge_r\",\"pinky_02_side_out_r\",\"pinky_02_side_inn_r\",\"pinky_02_half_r\",\"pinky_02_in_r\",\"pinky_02_pip_r\",\"pinky_01_palmMid_r\",\"pinky_01_bulge_r\",\"pinky_01_side_out_r\",\"pinky_01_side_inn_r\",\"pinky_01_half_r\",\"pinky_01_mcp_r\",\"pinky_01_palm_r\",\"pinky_metacarpal_slide_r\",\"ring_metacarpal_r\",\"ring_01_r\",\"ring_02_r\",\"ring_03_r\",\"ring_03_bulge_r\",\"ring_03_half_r\",\"ring_02_dip_r\",\"ring_03_in_r\",\"ring_02_bulge_r\",\"ring_02_side_out_r\",\"ring_02_side_inn_r\",\"ring_02_half_r\",\"ring_02_in_r\",\"ring_02_pip_r\",\"ring_01_palmMid_r\",\"ring_01_bulge_r\",\"ring_01_side_out_r\",\"ring_01_side_inn_r\",\"ring_01_half_r\",\"ring_01_mcp_r\",\"ring_01_palm_r\",\"ring_metacarpal_slide_r\",\"thumb_01_r\",\"thumb_02_r\",\"thumb_03_r\",\"thumb_03_bulge_r\",\"thumb_03_side_out_r\",\"thumb_03_side_inn_r\",\"thumb_03_half_r\",\"thumb_03_pip_r\",\"thumb_03_in_r\",\"thumb_02_bulge_r\",\"thumb_02_side_out_r\",\"thumb_02_side_inn_r\",\"thumb_02_half_r\",\"thumb_02_in_r\",\"thumb_02_mcp_r\",\"thumb_01_side_out_r\",\"thumb_01_side_inn_r\",\"middle_metacarpal_r\",\"middle_01_r\",\"middle_02_r\",\"middle_03_r\",\"middle_03_bulge_r\",\"middle_03_half_r\",\"middle_03_in_r\",\"middle_02_dip_r\",\"middle_02_bulge_r\",\"middle_02_side_out_r\",\"middle_02_side_inn_r\",\"middle_02_half_r\",\"middle_02_pip_r\",\"middle_02_in_r\",\"middle_01_palmMid_r\",\"middle_01_bulge_r\",\"middle_01_side_out_r\",\"middle_01_side_inn_r\",\"middle_01_half_r\",\"middle_01_mcp_r\",\"middle_01_palm_r\",\"middle_metacarpal_slide_r\",\"index_metacarpal_r\",\"index_01_r\",\"index_02_r\",\"index_03_r\",\"index_03_bulge_r\",\"index_03_half_r\",\"index_02_dip_r\",\"index_03_in_r\",\"index_02_bulge_r\",\"index_02_side_out_r\",\"index_02_side_inn_r\",\"index_02_half_r\",\"index_02_in_r\",\"index_02_pip_r\",\"index_01_palmMid_r\",\"index_01_bulge_r\",\"index_01_side_out_r\",\"index_01_side_inn_r\",\"index_01_half_r\",\"index_01_mcp_r\",\"index_01_palm_r\",\"index_metacarpal_slide_r\",\"wrist_inner_r\",\"wrist_outer_r\",\"lowerarm_twist_02_r\",\"lowerarm_twist_01_r\",\"lowerarm_correctiveRoot_r\",\"lowerarm_out_r\",\"lowerarm_in_r\",\"lowerarm_fwd_r\",\"lowerarm_bck_r\",\"upperarm_twist_01_r\",\"upperarm_twistCor_01_r\",\"upperarm_twist_02_r\",\"upperarm_tricep_r\",\"upperarm_bicep_r\",\"upperarm_twistCor_02_r\",\"clavicle_out_r\",\"clavicle_scap_r\",\"clavicle_pec_r\",\"spine_04_latissimus_l\",\"spine_04_latissimus_r\",\"clavicle_pec_l\",\"thigh_r\",\"calf_r\",\"foot_r\",\"ball_r\",\"littletoe_01_r\",\"littletoe_02_r\",\"ringtoe_01_r\",\"ringtoe_02_r\",\"middletoe_01_r\",\"middletoe_02_r\",\"bigtoe_01_r\",\"bigtoe_02_r\",\"indextoe_01_r\",\"indextoe_02_r\",\"ankle_bck_r\",\"ankle_fwd_r\",\"calf_twist_02_r\",\"calf_twistCor_02_r\",\"calf_twist_01_r\",\"calf_correctiveRoot_r\",\"calf_kneeBack_r\",\"calf_knee_r\",\"thigh_twist_01_r\",\"thigh_twistCor_01_r\",\"thigh_twist_02_r\",\"thigh_twistCor_02_r\",\"thigh_correctiveRoot_r\",\"thigh_fwd_r\",\"thigh_bck_r\",\"thigh_out_r\",\"thigh_in_r\",\"thigh_bck_lwr_r\",\"thigh_fwd_lwr_r\",\"thigh_l\",\"calf_l\",\"foot_l\",\"ball_l\",\"indextoe_01_l\",\"indextoe_02_l\",\"bigtoe_01_l\",\"bigtoe_02_l\",\"littletoe_01_l\",\"littletoe_02_l\",\"middletoe_01_l\",\"middletoe_02_l\",\"ringtoe_01_l\",\"ringtoe_02_l\",\"ankle_bck_l\",\"ankle_fwd_l\",\"calf_twist_02_l\",\"calf_twistCor_02_l\",\"calf_twist_01_l\",\"calf_correctiveRoot_l\",\"calf_kneeBack_l\",\"calf_knee_l\",\"thigh_twist_01_l\",\"thigh_twistCor_01_l\",\"thigh_twist_02_l\",\"thigh_twistCor_02_l\",\"thigh_correctiveRoot_l\",\"thigh_bck_l\",\"thigh_fwd_l\",\"thigh_out_l\",\"thigh_bck_lwr_l\",\"thigh_in_l\",\"thigh_fwd_lwr_l\",\"FACIAL_C_Neck1Root\",\"FACIAL_C_NeckB\",\"FACIAL_L_NeckB1\",\"FACIAL_R_NeckB1\",\"FACIAL_L_NeckB2\",\"FACIAL_R_NeckB2\",\"FACIAL_C_12IPV_NeckB1\",\"FACIAL_C_12IPV_NeckB2\",\"FACIAL_L_12IPV_NeckB3\",\"FACIAL_R_12IPV_NeckB3\",\"FACIAL_L_12IPV_NeckB4\",\"FACIAL_R_12IPV_NeckB4\",\"FACIAL_L_12IPV_NeckB5\",\"FACIAL_R_12IPV_NeckB5\",\"FACIAL_L_12IPV_NeckB6\",\"FACIAL_R_12IPV_NeckB6\",\"FACIAL_L_12IPV_NeckB7\",\"FACIAL_R_12IPV_NeckB7\",\"FACIAL_C_NeckBackB\",\"FACIAL_L_NeckBackB\",\"FACIAL_R_NeckBackB\",\"FACIAL_C_12IPV_NeckBackB1\",\"FACIAL_C_12IPV_NeckBackB2\",\"FACIAL_L_12IPV_NeckBackB1\",\"FACIAL_R_12IPV_NeckBackB1\",\"FACIAL_L_12IPV_NeckBackB2\",\"FACIAL_R_12IPV_NeckBackB2\",\"FACIAL_C_Neck2Root\",\"FACIAL_C_AdamsApple\",\"FACIAL_C_12IPV_AdamsA1\",\"FACIAL_C_12IPV_AdamsA2\",\"FACIAL_L_NeckA1\",\"FACIAL_R_NeckA1\",\"FACIAL_L_NeckA2\",\"FACIAL_R_NeckA2\",\"FACIAL_L_NeckA3\",\"FACIAL_R_NeckA3\",\"FACIAL_L_12IPV_NeckA1\",\"FACIAL_R_12IPV_NeckA1\",\"FACIAL_L_12IPV_NeckA2\",\"FACIAL_R_12IPV_NeckA2\",\"FACIAL_L_12IPV_NeckA3\",\"FACIAL_R_12IPV_NeckA3\",\"FACIAL_L_12IPV_NeckA4\",\"FACIAL_R_12IPV_NeckA4\",\"FACIAL_L_12IPV_NeckA5\",\"FACIAL_R_12IPV_NeckA5\",\"FACIAL_L_12IPV_NeckA6\",\"FACIAL_R_12IPV_NeckA6\",\"FACIAL_C_NeckBackA\",\"FACIAL_L_NeckBackA\",\"FACIAL_R_NeckBackA\",\"FACIAL_C_12IPV_NeckBackA1\",\"FACIAL_C_12IPV_NeckBackA2\",\"FACIAL_L_12IPV_NeckBackA1\",\"FACIAL_R_12IPV_NeckBackA1\",\"FACIAL_L_12IPV_NeckBackA2\",\"FACIAL_R_12IPV_NeckBackA2\",\"FACIAL_C_FacialRoot\",\"FACIAL_C_Hair1\",\"FACIAL_L_12IPV_Hair1\",\"FACIAL_R_12IPV_Hair1\",\"FACIAL_C_Hair2\",\"FACIAL_C_Hair3\",\"FACIAL_C_Hair4\",\"FACIAL_C_Hair5\",\"FACIAL_C_Hair6\",\"FACIAL_L_HairA1\",\"FACIAL_R_HairA1\",\"FACIAL_L_HairA2\",\"FACIAL_R_HairA2\",\"FACIAL_L_HairA3\",\"FACIAL_R_HairA3\",\"FACIAL_L_HairA4\",\"FACIAL_R_HairA4\",\"FACIAL_L_HairA5\",\"FACIAL_R_HairA5\",\"FACIAL_L_HairA6\",\"FACIAL_R_HairA6\",\"FACIAL_L_HairB1\",\"FACIAL_R_HairB1\",\"FACIAL_L_HairB2\",\"FACIAL_R_HairB2\",\"FACIAL_L_HairB3\",\"FACIAL_R_HairB3\",\"FACIAL_L_HairB4\",\"FACIAL_R_HairB4\",\"FACIAL_L_HairB5\",\"FACIAL_R_HairB5\",\"FACIAL_L_Temple\",\"FACIAL_R_Temple\",\"FACIAL_L_12IPV_Temple1\",\"FACIAL_R_12IPV_Temple1\",\"FACIAL_L_12IPV_Temple2\",\"FACIAL_R_12IPV_Temple2\",\"FACIAL_L_12IPV_Temple3\",\"FACIAL_R_12IPV_Temple3\",\"FACIAL_L_12IPV_Temple4\",\"FACIAL_R_12IPV_Temple4\",\"FACIAL_L_HairC1\",\"FACIAL_R_HairC1\",\"FACIAL_L_HairC2\",\"FACIAL_R_HairC2\",\"FACIAL_L_HairC3\",\"FACIAL_R_HairC3\",\"FACIAL_L_HairC4\",\"FACIAL_R_HairC4\",\"FACIAL_L_Sideburn1\",\"FACIAL_R_Sideburn1\",\"FACIAL_L_Sideburn2\",\"FACIAL_R_Sideburn2\",\"FACIAL_L_Sideburn3\",\"FACIAL_R_Sideburn3\",\"FACIAL_L_Sideburn4\",\"FACIAL_R_Sideburn4\",\"FACIAL_L_Sideburn5\",\"FACIAL_R_Sideburn5\",\"FACIAL_L_Sideburn6\",\"FACIAL_R_Sideburn6\",\"FACIAL_C_ForeheadSkin\",\"FACIAL_L_ForeheadInSkin\",\"FACIAL_R_ForeheadInSkin\",\"FACIAL_L_12IPV_ForeheadSkin1\",\"FACIAL_R_12IPV_ForeheadSkin1\",\"FACIAL_L_12IPV_ForeheadSkin2\",\"FACIAL_R_12IPV_ForeheadSkin2\",\"FACIAL_L_12IPV_ForeheadSkin3\",\"FACIAL_R_12IPV_ForeheadSkin3\",\"FACIAL_L_12IPV_ForeheadSkin4\",\"FACIAL_R_12IPV_ForeheadSkin4\",\"FACIAL_L_12IPV_ForeheadSkin5\",\"FACIAL_R_12IPV_ForeheadSkin5\",\"FACIAL_L_12IPV_ForeheadSkin6\",\"FACIAL_R_12IPV_ForeheadSkin6\",\"FACIAL_L_ForeheadMidSkin\",\"FACIAL_R_ForeheadMidSkin\",\"FACIAL_L_ForeheadOutSkin\",\"FACIAL_R_ForeheadOutSkin\",\"FACIAL_C_Skull\",\"FACIAL_C_Forehead\",\"FACIAL_C_Forehead1\",\"FACIAL_L_Forehead1\",\"FACIAL_R_Forehead1\",\"FACIAL_C_Forehead2\",\"FACIAL_L_Forehead2\",\"FACIAL_R_Forehead2\",\"FACIAL_C_Forehead3\",\"FACIAL_L_Forehead3\",\"FACIAL_R_Forehead3\",\"FACIAL_C_12IPV_Forehead1\",\"FACIAL_L_12IPV_Forehead1\",\"FACIAL_R_12IPV_Forehead1\",\"FACIAL_C_12IPV_Forehead2\",\"FACIAL_L_12IPV_Forehead2\",\"FACIAL_R_12IPV_Forehead2\",\"FACIAL_C_12IPV_Forehead3\",\"FACIAL_L_12IPV_Forehead3\",\"FACIAL_R_12IPV_Forehead3\",\"FACIAL_C_12IPV_Forehead4\",\"FACIAL_L_12IPV_Forehead4\",\"FACIAL_R_12IPV_Forehead4\",\"FACIAL_C_12IPV_Forehead5\",\"FACIAL_L_12IPV_Forehead5\",\"FACIAL_R_12IPV_Forehead5\",\"FACIAL_C_12IPV_Forehead6\",\"FACIAL_L_12IPV_Forehead6\",\"FACIAL_R_12IPV_Forehead6\",\"FACIAL_L_ForeheadIn\",\"FACIAL_L_ForeheadInA1\",\"FACIAL_L_ForeheadInA2\",\"FACIAL_L_ForeheadInA3\",\"FACIAL_L_ForeheadInB1\",\"FACIAL_L_ForeheadInB2\",\"FACIAL_L_12IPV_ForeheadIn1\",\"FACIAL_L_12IPV_ForeheadIn2\",\"FACIAL_L_12IPV_ForeheadIn3\",\"FACIAL_L_12IPV_ForeheadIn4\",\"FACIAL_L_12IPV_ForeheadIn5\",\"FACIAL_L_12IPV_ForeheadIn6\",\"FACIAL_L_12IPV_ForeheadIn7\",\"FACIAL_L_12IPV_ForeheadIn8\",\"FACIAL_L_12IPV_ForeheadIn9\",\"FACIAL_L_12IPV_ForeheadIn10\",\"FACIAL_L_12IPV_ForeheadIn11\",\"FACIAL_L_12IPV_ForeheadIn12\",\"FACIAL_L_12IPV_ForeheadIn13\",\"FACIAL_L_12IPV_ForeheadIn14\",\"FACIAL_R_ForeheadIn\",\"FACIAL_R_ForeheadInA1\",\"FACIAL_R_ForeheadInA2\",\"FACIAL_R_ForeheadInA3\",\"FACIAL_R_ForeheadInB1\",\"FACIAL_R_ForeheadInB2\",\"FACIAL_R_12IPV_ForeheadIn1\",\"FACIAL_R_12IPV_ForeheadIn2\",\"FACIAL_R_12IPV_ForeheadIn3\",\"FACIAL_R_12IPV_ForeheadIn5\",\"FACIAL_R_12IPV_ForeheadIn4\",\"FACIAL_R_12IPV_ForeheadIn6\",\"FACIAL_R_12IPV_ForeheadIn7\",\"FACIAL_R_12IPV_ForeheadIn8\",\"FACIAL_R_12IPV_ForeheadIn9\",\"FACIAL_R_12IPV_ForeheadIn10\",\"FACIAL_R_12IPV_ForeheadIn12\",\"FACIAL_R_12IPV_ForeheadIn11\",\"FACIAL_R_12IPV_ForeheadIn13\",\"FACIAL_R_12IPV_ForeheadIn14\",\"FACIAL_L_ForeheadMid\",\"FACIAL_L_ForeheadMid1\",\"FACIAL_L_ForeheadMid2\",\"FACIAL_L_12IPV_ForeheadMid15\",\"FACIAL_L_12IPV_ForeheadMid16\",\"FACIAL_L_12IPV_ForeheadMid17\",\"FACIAL_L_12IPV_ForeheadMid18\",\"FACIAL_L_12IPV_ForeheadMid19\",\"FACIAL_L_12IPV_ForeheadMid20\",\"FACIAL_L_12IPV_ForeheadMid21\",\"FACIAL_L_12IPV_ForeheadMid22\",\"FACIAL_R_ForeheadMid\",\"FACIAL_R_ForeheadMid1\",\"FACIAL_R_ForeheadMid2\",\"FACIAL_R_12IPV_ForeheadMid15\",\"FACIAL_R_12IPV_ForeheadMid16\",\"FACIAL_R_12IPV_ForeheadMid17\",\"FACIAL_R_12IPV_ForeheadMid18\",\"FACIAL_R_12IPV_ForeheadMid19\",\"FACIAL_R_12IPV_ForeheadMid20\",\"FACIAL_R_12IPV_ForeheadMid21\",\"FACIAL_R_12IPV_ForeheadMid22\",\"FACIAL_L_ForeheadOut\",\"FACIAL_L_ForeheadOutA1\",\"FACIAL_L_ForeheadOutA2\",\"FACIAL_L_ForeheadOutB1\",\"FACIAL_L_ForeheadOutB2\",\"FACIAL_L_12IPV_ForeheadOut23\",\"FACIAL_L_12IPV_ForeheadOut24\",\"FACIAL_L_12IPV_ForeheadOut25\",\"FACIAL_L_12IPV_ForeheadOut26\",\"FACIAL_L_12IPV_ForeheadOut27\",\"FACIAL_L_12IPV_ForeheadOut28\",\"FACIAL_L_12IPV_ForeheadOut29\",\"FACIAL_L_12IPV_ForeheadOut30\",\"FACIAL_L_12IPV_ForeheadOut31\",\"FACIAL_L_12IPV_ForeheadOut32\",\"FACIAL_R_ForeheadOut\",\"FACIAL_R_ForeheadOutA1\",\"FACIAL_R_ForeheadOutA2\",\"FACIAL_R_ForeheadOutB1\",\"FACIAL_R_ForeheadOutB2\",\"FACIAL_R_12IPV_ForeheadOut23\",\"FACIAL_R_12IPV_ForeheadOut24\",\"FACIAL_R_12IPV_ForeheadOut25\",\"FACIAL_R_12IPV_ForeheadOut26\",\"FACIAL_R_12IPV_ForeheadOut27\",\"FACIAL_R_12IPV_ForeheadOut28\",\"FACIAL_R_12IPV_ForeheadOut29\",\"FACIAL_R_12IPV_ForeheadOut30\",\"FACIAL_R_12IPV_ForeheadOut31\",\"FACIAL_R_12IPV_ForeheadOut32\",\"FACIAL_L_12IPV_EyesackU0\",\"FACIAL_R_12IPV_EyesackU0\",\"FACIAL_L_EyesackUpper\",\"FACIAL_L_EyesackUpper1\",\"FACIAL_L_EyesackUpper2\",\"FACIAL_L_EyesackUpper3\",\"FACIAL_R_EyesackUpper\",\"FACIAL_R_EyesackUpper1\",\"FACIAL_R_EyesackUpper2\",\"FACIAL_R_EyesackUpper3\",\"FACIAL_L_EyesackUpper4\",\"FACIAL_R_EyesackUpper4\",\"FACIAL_L_EyelidUpperFurrow\",\"FACIAL_L_EyelidUpperFurrow1\",\"FACIAL_L_EyelidUpperFurrow2\",\"FACIAL_L_EyelidUpperFurrow3\",\"FACIAL_R_EyelidUpperFurrow\",\"FACIAL_R_EyelidUpperFurrow1\",\"FACIAL_R_EyelidUpperFurrow2\",\"FACIAL_R_EyelidUpperFurrow3\",\"FACIAL_L_EyelidUpperB\",\"FACIAL_L_EyelidUpperB1\",\"FACIAL_L_EyelidUpperB2\",\"FACIAL_L_EyelidUpperB3\",\"FACIAL_R_EyelidUpperB\",\"FACIAL_R_EyelidUpperB1\",\"FACIAL_R_EyelidUpperB2\",\"FACIAL_R_EyelidUpperB3\",\"FACIAL_L_EyelidUpperA\",\"FACIAL_L_EyelidUpperA1\",\"FACIAL_L_EyelashesUpperA1\",\"FACIAL_L_EyelidUpperA2\",\"FACIAL_L_EyelashesUpperA2\",\"FACIAL_L_EyelidUpperA3\",\"FACIAL_L_EyelashesUpperA3\",\"FACIAL_R_EyelidUpperA\",\"FACIAL_R_EyelidUpperA1\",\"FACIAL_R_EyelashesUpperA1\",\"FACIAL_R_EyelidUpperA2\",\"FACIAL_R_EyelashesUpperA2\",\"FACIAL_R_EyelidUpperA3\",\"FACIAL_R_EyelashesUpperA3\",\"FACIAL_L_Eye\",\"FACIAL_L_EyeParallel\",\"FACIAL_L_Pupil\",\"FACIAL_R_Eye\",\"FACIAL_R_EyeParallel\",\"FACIAL_R_Pupil\",\"FACIAL_L_EyelidLowerA\",\"FACIAL_L_EyelidLowerA1\",\"FACIAL_L_EyelidLowerA2\",\"FACIAL_L_EyelidLowerA3\",\"FACIAL_R_EyelidLowerA\",\"FACIAL_R_EyelidLowerA1\",\"FACIAL_R_EyelidLowerA2\",\"FACIAL_R_EyelidLowerA3\",\"FACIAL_L_EyelidLowerB\",\"FACIAL_L_EyelidLowerB1\",\"FACIAL_L_EyelidLowerB2\",\"FACIAL_L_EyelidLowerB3\",\"FACIAL_R_EyelidLowerB\",\"FACIAL_R_EyelidLowerB1\",\"FACIAL_R_EyelidLowerB2\",\"FACIAL_R_EyelidLowerB3\",\"FACIAL_L_EyeCornerInner\",\"FACIAL_L_EyeCornerInner1\",\"FACIAL_L_EyeCornerInner2\",\"FACIAL_R_EyeCornerInner\",\"FACIAL_R_EyeCornerInner1\",\"FACIAL_R_EyeCornerInner2\",\"FACIAL_L_EyeCornerOuter\",\"FACIAL_L_EyeCornerOuter1\",\"FACIAL_L_EyelashesCornerOuter1\",\"FACIAL_L_EyeCornerOuter2\",\"FACIAL_R_EyeCornerOuter\",\"FACIAL_R_EyeCornerOuter1\",\"FACIAL_R_EyelashesCornerOuter1\",\"FACIAL_R_EyeCornerOuter2\",\"FACIAL_L_12IPV_EyeCornerO1\",\"FACIAL_R_12IPV_EyeCornerO1\",\"FACIAL_L_12IPV_EyeCornerO2\",\"FACIAL_R_12IPV_EyeCornerO2\",\"FACIAL_L_EyesackLower\",\"FACIAL_L_EyesackLower1\",\"FACIAL_L_EyesackLower2\",\"FACIAL_L_12IPV_EyesackL1\",\"FACIAL_L_12IPV_EyesackL2\",\"FACIAL_L_12IPV_EyesackL3\",\"FACIAL_L_12IPV_EyesackL4\",\"FACIAL_L_12IPV_EyesackL5\",\"FACIAL_L_12IPV_EyesackL6\",\"FACIAL_L_12IPV_EyesackL7\",\"FACIAL_L_12IPV_EyesackL8\",\"FACIAL_R_EyesackLower\",\"FACIAL_R_EyesackLower1\",\"FACIAL_R_EyesackLower2\",\"FACIAL_R_12IPV_EyesackL1\",\"FACIAL_R_12IPV_EyesackL2\",\"FACIAL_R_12IPV_EyesackL3\",\"FACIAL_R_12IPV_EyesackL4\",\"FACIAL_R_12IPV_EyesackL5\",\"FACIAL_R_12IPV_EyesackL6\",\"FACIAL_R_12IPV_EyesackL7\",\"FACIAL_R_12IPV_EyesackL8\",\"FACIAL_L_CheekInner\",\"FACIAL_L_CheekInner1\",\"FACIAL_L_CheekInner2\",\"FACIAL_L_CheekInner3\",\"FACIAL_L_CheekInner4\",\"FACIAL_R_CheekInner\",\"FACIAL_R_CheekInner1\",\"FACIAL_R_CheekInner2\",\"FACIAL_R_CheekInner3\",\"FACIAL_R_CheekInner4\",\"FACIAL_L_CheekOuter\",\"FACIAL_L_CheekOuter1\",\"FACIAL_L_CheekOuter2\",\"FACIAL_L_CheekOuter3\",\"FACIAL_R_CheekOuter\",\"FACIAL_R_CheekOuter1\",\"FACIAL_R_CheekOuter2\",\"FACIAL_R_CheekOuter3\",\"FACIAL_L_CheekOuter4\",\"FACIAL_R_CheekOuter4\",\"FACIAL_L_12IPV_CheekOuter1\",\"FACIAL_R_12IPV_CheekOuter1\",\"FACIAL_L_12IPV_CheekOuter2\",\"FACIAL_R_12IPV_CheekOuter2\",\"FACIAL_L_12IPV_CheekOuter3\",\"FACIAL_R_12IPV_CheekOuter3\",\"FACIAL_L_12IPV_CheekOuter4\",\"FACIAL_R_12IPV_CheekOuter4\",\"FACIAL_C_NoseBridge\",\"FACIAL_C_12IPV_NoseBridge1\",\"FACIAL_L_12IPV_NoseBridge1\",\"FACIAL_R_12IPV_NoseBridge1\",\"FACIAL_C_12IPV_NoseBridge2\",\"FACIAL_L_12IPV_NoseBridge2\",\"FACIAL_R_12IPV_NoseBridge2\",\"FACIAL_L_NoseBridge\",\"FACIAL_R_NoseBridge\",\"FACIAL_C_NoseUpper\",\"FACIAL_L_NoseUpper\",\"FACIAL_R_NoseUpper\",\"FACIAL_C_12IPV_NoseUpper1\",\"FACIAL_C_12IPV_NoseUpper2\",\"FACIAL_L_12IPV_NoseUpper1\",\"FACIAL_R_12IPV_NoseUpper1\",\"FACIAL_L_12IPV_NoseUpper2\",\"FACIAL_R_12IPV_NoseUpper2\",\"FACIAL_L_12IPV_NoseUpper3\",\"FACIAL_R_12IPV_NoseUpper3\",\"FACIAL_L_12IPV_NoseUpper4\",\"FACIAL_R_12IPV_NoseUpper4\",\"FACIAL_L_12IPV_NoseUpper5\",\"FACIAL_R_12IPV_NoseUpper5\",\"FACIAL_L_12IPV_NoseUpper6\",\"FACIAL_R_12IPV_NoseUpper6\",\"FACIAL_L_NasolabialBulge1\",\"FACIAL_R_NasolabialBulge1\",\"FACIAL_L_12IPV_NasolabialB13\",\"FACIAL_R_12IPV_NasolabialB13\",\"FACIAL_L_12IPV_NasolabialB14\",\"FACIAL_R_12IPV_NasolabialB14\",\"FACIAL_L_12IPV_NasolabialB15\",\"FACIAL_R_12IPV_NasolabialB15\",\"FACIAL_L_NasolabialBulge\",\"FACIAL_L_NasolabialBulge2\",\"FACIAL_L_NasolabialBulge3\",\"FACIAL_L_12IPV_NasolabialB1\",\"FACIAL_L_12IPV_NasolabialB2\",\"FACIAL_L_12IPV_NasolabialB3\",\"FACIAL_L_12IPV_NasolabialB4\",\"FACIAL_L_12IPV_NasolabialB5\",\"FACIAL_L_12IPV_NasolabialB6\",\"FACIAL_L_12IPV_NasolabialB7\",\"FACIAL_L_12IPV_NasolabialB8\",\"FACIAL_L_12IPV_NasolabialB9\",\"FACIAL_L_12IPV_NasolabialB10\",\"FACIAL_L_12IPV_NasolabialB11\",\"FACIAL_L_12IPV_NasolabialB12\",\"FACIAL_R_NasolabialBulge\",\"FACIAL_R_NasolabialBulge2\",\"FACIAL_R_NasolabialBulge3\",\"FACIAL_R_12IPV_NasolabialB1\",\"FACIAL_R_12IPV_NasolabialB2\",\"FACIAL_R_12IPV_NasolabialB3\",\"FACIAL_R_12IPV_NasolabialB4\",\"FACIAL_R_12IPV_NasolabialB5\",\"FACIAL_R_12IPV_NasolabialB6\",\"FACIAL_R_12IPV_NasolabialB7\",\"FACIAL_R_12IPV_NasolabialB8\",\"FACIAL_R_12IPV_NasolabialB9\",\"FACIAL_R_12IPV_NasolabialB10\",\"FACIAL_R_12IPV_NasolabialB11\",\"FACIAL_R_12IPV_NasolabialB12\",\"FACIAL_L_NasolabialFurrow\",\"FACIAL_R_NasolabialFurrow\",\"FACIAL_L_12IPV_NasolabialF1\",\"FACIAL_R_12IPV_NasolabialF1\",\"FACIAL_L_12IPV_NasolabialF2\",\"FACIAL_R_12IPV_NasolabialF2\",\"FACIAL_L_12IPV_NasolabialF3\",\"FACIAL_R_12IPV_NasolabialF3\",\"FACIAL_L_12IPV_NasolabialF4\",\"FACIAL_R_12IPV_NasolabialF4\",\"FACIAL_L_12IPV_NasolabialF5\",\"FACIAL_R_12IPV_NasolabialF5\",\"FACIAL_L_12IPV_NasolabialF6\",\"FACIAL_R_12IPV_NasolabialF6\",\"FACIAL_L_12IPV_NasolabialF7\",\"FACIAL_R_12IPV_NasolabialF7\",\"FACIAL_L_12IPV_NasolabialF8\",\"FACIAL_R_12IPV_NasolabialF8\",\"FACIAL_L_12IPV_NasolabialF9\",\"FACIAL_R_12IPV_NasolabialF9\",\"FACIAL_L_CheekLower\",\"FACIAL_L_CheekLower1\",\"FACIAL_L_CheekLower2\",\"FACIAL_L_12IPV_CheekL1\",\"FACIAL_L_12IPV_CheekL2\",\"FACIAL_L_12IPV_CheekL3\",\"FACIAL_L_12IPV_CheekL4\",\"FACIAL_R_CheekLower\",\"FACIAL_R_CheekLower1\",\"FACIAL_R_CheekLower2\",\"FACIAL_R_12IPV_CheekL1\",\"FACIAL_R_12IPV_CheekL2\",\"FACIAL_R_12IPV_CheekL3\",\"FACIAL_R_12IPV_CheekL4\",\"FACIAL_L_Ear\",\"FACIAL_L_Ear1\",\"FACIAL_L_Ear2\",\"FACIAL_L_Ear3\",\"FACIAL_L_Ear4\",\"FACIAL_R_Ear\",\"FACIAL_R_Ear1\",\"FACIAL_R_Ear2\",\"FACIAL_R_Ear3\",\"FACIAL_R_Ear4\",\"FACIAL_C_Nose\",\"FACIAL_C_NoseLower\",\"FACIAL_L_NostrilThickness3\",\"FACIAL_R_NostrilThickness3\",\"FACIAL_C_12IPV_NoseL1\",\"FACIAL_C_12IPV_NoseL2\",\"FACIAL_C_NoseTip\",\"FACIAL_C_12IPV_NoseTip1\",\"FACIAL_C_12IPV_NoseTip2\",\"FACIAL_C_12IPV_NoseTip3\",\"FACIAL_L_12IPV_NoseTip1\",\"FACIAL_R_12IPV_NoseTip1\",\"FACIAL_L_12IPV_NoseTip2\",\"FACIAL_R_12IPV_NoseTip2\",\"FACIAL_L_12IPV_NoseTip3\",\"FACIAL_R_12IPV_NoseTip3\",\"FACIAL_L_Nostril\",\"FACIAL_L_NostrilThickness1\",\"FACIAL_L_NostrilThickness2\",\"FACIAL_L_12IPV_Nostril1\",\"FACIAL_L_12IPV_Nostril2\",\"FACIAL_L_12IPV_Nostril3\",\"FACIAL_L_12IPV_Nostril4\",\"FACIAL_L_12IPV_Nostril5\",\"FACIAL_L_12IPV_Nostril6\",\"FACIAL_L_12IPV_Nostril7\",\"FACIAL_L_12IPV_Nostril8\",\"FACIAL_L_12IPV_Nostril9\",\"FACIAL_L_12IPV_Nostril10\",\"FACIAL_L_12IPV_Nostril11\",\"FACIAL_L_12IPV_Nostril12\",\"FACIAL_L_12IPV_Nostril13\",\"FACIAL_L_12IPV_Nostril14\",\"FACIAL_R_Nostril\",\"FACIAL_R_NostrilThickness1\",\"FACIAL_R_NostrilThickness2\",\"FACIAL_R_12IPV_Nostril1\",\"FACIAL_R_12IPV_Nostril2\",\"FACIAL_R_12IPV_Nostril3\",\"FACIAL_R_12IPV_Nostril4\",\"FACIAL_R_12IPV_Nostril5\",\"FACIAL_R_12IPV_Nostril6\",\"FACIAL_R_12IPV_Nostril7\",\"FACIAL_R_12IPV_Nostril8\",\"FACIAL_R_12IPV_Nostril9\",\"FACIAL_R_12IPV_Nostril10\",\"FACIAL_R_12IPV_Nostril11\",\"FACIAL_R_12IPV_Nostril12\",\"FACIAL_R_12IPV_Nostril13\",\"FACIAL_R_12IPV_Nostril14\",\"FACIAL_C_LipUpperSkin\",\"FACIAL_L_LipUpperSkin\",\"FACIAL_R_LipUpperSkin\",\"FACIAL_L_LipUpperOuterSkin\",\"FACIAL_R_LipUpperOuterSkin\",\"FACIAL_C_12IPV_LipUpperSkin1\",\"FACIAL_C_12IPV_LipUpperSkin2\",\"FACIAL_L_12IPV_LipUpperSkin\",\"FACIAL_R_12IPV_LipUpperSkin\",\"FACIAL_L_12IPV_LipUpperOuterSkin1\",\"FACIAL_R_12IPV_LipUpperOuterSkin1\",\"FACIAL_L_12IPV_LipUpperOuterSkin2\",\"FACIAL_R_12IPV_LipUpperOuterSkin2\",\"FACIAL_L_12IPV_MouthInteriorUpper1\",\"FACIAL_R_12IPV_MouthInteriorUpper1\",\"FACIAL_L_12IPV_MouthInteriorUpper2\",\"FACIAL_R_12IPV_MouthInteriorUpper2\",\"FACIAL_C_MouthUpper\",\"FACIAL_C_LipUpper\",\"FACIAL_C_LipUpper1\",\"FACIAL_C_LipUpper2\",\"FACIAL_C_LipUpper3\",\"FACIAL_L_12IPV_LipUpper1\",\"FACIAL_R_12IPV_LipUpper1\",\"FACIAL_L_12IPV_LipUpper2\",\"FACIAL_R_12IPV_LipUpper2\",\"FACIAL_L_12IPV_LipUpper3\",\"FACIAL_R_12IPV_LipUpper3\",\"FACIAL_L_12IPV_LipUpper4\",\"FACIAL_R_12IPV_LipUpper4\",\"FACIAL_L_12IPV_LipUpper5\",\"FACIAL_R_12IPV_LipUpper5\",\"FACIAL_L_LipUpper\",\"FACIAL_L_LipUpper1\",\"FACIAL_L_LipUpper2\",\"FACIAL_L_LipUpper3\",\"FACIAL_L_12IPV_LipUpper6\",\"FACIAL_L_12IPV_LipUpper7\",\"FACIAL_L_12IPV_LipUpper8\",\"FACIAL_L_12IPV_LipUpper9\",\"FACIAL_L_12IPV_LipUpper10\",\"FACIAL_L_12IPV_LipUpper11\",\"FACIAL_L_12IPV_LipUpper12\",\"FACIAL_L_12IPV_LipUpper13\",\"FACIAL_L_12IPV_LipUpper14\",\"FACIAL_L_12IPV_LipUpper15\",\"FACIAL_R_LipUpper\",\"FACIAL_R_LipUpper1\",\"FACIAL_R_LipUpper2\",\"FACIAL_R_LipUpper3\",\"FACIAL_R_12IPV_LipUpper6\",\"FACIAL_R_12IPV_LipUpper7\",\"FACIAL_R_12IPV_LipUpper8\",\"FACIAL_R_12IPV_LipUpper9\",\"FACIAL_R_12IPV_LipUpper10\",\"FACIAL_R_12IPV_LipUpper11\",\"FACIAL_R_12IPV_LipUpper12\",\"FACIAL_R_12IPV_LipUpper13\",\"FACIAL_R_12IPV_LipUpper14\",\"FACIAL_R_12IPV_LipUpper15\",\"FACIAL_L_LipUpperOuter\",\"FACIAL_L_LipUpperOuter1\",\"FACIAL_L_LipUpperOuter2\",\"FACIAL_L_LipUpperOuter3\",\"FACIAL_L_12IPV_LipUpper16\",\"FACIAL_L_12IPV_LipUpper17\",\"FACIAL_L_12IPV_LipUpper18\",\"FACIAL_L_12IPV_LipUpper19\",\"FACIAL_L_12IPV_LipUpper20\",\"FACIAL_L_12IPV_LipUpper21\",\"FACIAL_L_12IPV_LipUpper22\",\"FACIAL_L_12IPV_LipUpper23\",\"FACIAL_L_12IPV_LipUpper24\",\"FACIAL_R_LipUpperOuter\",\"FACIAL_R_LipUpperOuter1\",\"FACIAL_R_LipUpperOuter2\",\"FACIAL_R_LipUpperOuter3\",\"FACIAL_R_12IPV_LipUpper16\",\"FACIAL_R_12IPV_LipUpper17\",\"FACIAL_R_12IPV_LipUpper18\",\"FACIAL_R_12IPV_LipUpper19\",\"FACIAL_R_12IPV_LipUpper20\",\"FACIAL_R_12IPV_LipUpper21\",\"FACIAL_R_12IPV_LipUpper22\",\"FACIAL_R_12IPV_LipUpper23\",\"FACIAL_R_12IPV_LipUpper24\",\"FACIAL_L_LipCorner\",\"FACIAL_L_LipCorner1\",\"FACIAL_L_LipCorner2\",\"FACIAL_L_LipCorner3\",\"FACIAL_L_12IPV_LipCorner1\",\"FACIAL_L_12IPV_LipCorner2\",\"FACIAL_L_12IPV_LipCorner3\",\"FACIAL_R_LipCorner\",\"FACIAL_R_LipCorner1\",\"FACIAL_R_LipCorner2\",\"FACIAL_R_LipCorner3\",\"FACIAL_R_12IPV_LipCorner1\",\"FACIAL_R_12IPV_LipCorner2\",\"FACIAL_R_12IPV_LipCorner3\",\"FACIAL_L_JawBulge\",\"FACIAL_R_JawBulge\",\"FACIAL_L_JawRecess\",\"FACIAL_R_JawRecess\",\"FACIAL_L_Masseter\",\"FACIAL_R_Masseter\",\"FACIAL_C_UnderChin\",\"FACIAL_L_12IPV_UnderChin1\",\"FACIAL_R_12IPV_UnderChin1\",\"FACIAL_L_12IPV_UnderChin2\",\"FACIAL_R_12IPV_UnderChin2\",\"FACIAL_L_UnderChin\",\"FACIAL_R_UnderChin\",\"FACIAL_L_12IPV_UnderChin3\",\"FACIAL_R_12IPV_UnderChin3\",\"FACIAL_L_12IPV_UnderChin4\",\"FACIAL_R_12IPV_UnderChin4\",\"FACIAL_L_12IPV_UnderChin5\",\"FACIAL_R_12IPV_UnderChin5\",\"FACIAL_L_12IPV_UnderChin6\",\"FACIAL_R_12IPV_UnderChin6\",\"FACIAL_C_TeethUpper\",\"FACIAL_C_LowerLipRotation\",\"FACIAL_C_LipLowerSkin\",\"FACIAL_L_LipLowerSkin\",\"FACIAL_R_LipLowerSkin\",\"FACIAL_L_LipLowerOuterSkin\",\"FACIAL_R_LipLowerOuterSkin\",\"FACIAL_C_12IPV_LipLowerSkin1\",\"FACIAL_C_12IPV_LipLowerSkin2\",\"FACIAL_L_12IPV_LipLowerSkin\",\"FACIAL_R_12IPV_LipLowerSkin\",\"FACIAL_L_12IPV_LipLowerOuterSkin1\",\"FACIAL_R_12IPV_LipLowerOuterSkin1\",\"FACIAL_L_12IPV_LipLowerOuterSkin2\",\"FACIAL_R_12IPV_LipLowerOuterSkin2\",\"FACIAL_L_12IPV_LipLowerOuterSkin3\",\"FACIAL_R_12IPV_LipLowerOuterSkin3\",\"FACIAL_L_12IPV_MouthInteriorLower1\",\"FACIAL_R_12IPV_MouthInteriorLower1\",\"FACIAL_L_12IPV_MouthInteriorLower2\",\"FACIAL_R_12IPV_MouthInteriorLower2\",\"FACIAL_C_MouthLower\",\"FACIAL_C_LipLower\",\"FACIAL_C_LipLower1\",\"FACIAL_C_LipLower2\",\"FACIAL_C_LipLower3\",\"FACIAL_L_12IPV_LipLower1\",\"FACIAL_R_12IPV_LipLower1\",\"FACIAL_L_12IPV_LipLower2\",\"FACIAL_R_12IPV_LipLower2\",\"FACIAL_L_12IPV_LipLower3\",\"FACIAL_R_12IPV_LipLower3\",\"FACIAL_L_12IPV_LipLower4\",\"FACIAL_R_12IPV_LipLower4\",\"FACIAL_L_12IPV_LipLower5\",\"FACIAL_R_12IPV_LipLower5\",\"FACIAL_L_LipLower\",\"FACIAL_L_LipLower1\",\"FACIAL_L_LipLower2\",\"FACIAL_L_LipLower3\",\"FACIAL_L_12IPV_LipLower6\",\"FACIAL_L_12IPV_LipLower7\",\"FACIAL_L_12IPV_LipLower8\",\"FACIAL_L_12IPV_LipLower9\",\"FACIAL_L_12IPV_LipLower10\",\"FACIAL_L_12IPV_LipLower11\",\"FACIAL_L_12IPV_LipLower12\",\"FACIAL_L_12IPV_LipLower13\",\"FACIAL_L_12IPV_LipLower14\",\"FACIAL_L_12IPV_LipLower15\",\"FACIAL_R_LipLower\",\"FACIAL_R_LipLower1\",\"FACIAL_R_LipLower2\",\"FACIAL_R_LipLower3\",\"FACIAL_R_12IPV_LipLower6\",\"FACIAL_R_12IPV_LipLower7\",\"FACIAL_R_12IPV_LipLower8\",\"FACIAL_R_12IPV_LipLower9\",\"FACIAL_R_12IPV_LipLower10\",\"FACIAL_R_12IPV_LipLower11\",\"FACIAL_R_12IPV_LipLower12\",\"FACIAL_R_12IPV_LipLower13\",\"FACIAL_R_12IPV_LipLower14\",\"FACIAL_R_12IPV_LipLower15\",\"FACIAL_L_LipLowerOuter\",\"FACIAL_L_LipLowerOuter1\",\"FACIAL_L_LipLowerOuter2\",\"FACIAL_L_LipLowerOuter3\",\"FACIAL_L_12IPV_LipLower16\",\"FACIAL_L_12IPV_LipLower17\",\"FACIAL_L_12IPV_LipLower18\",\"FACIAL_L_12IPV_LipLower19\",\"FACIAL_L_12IPV_LipLower20\",\"FACIAL_L_12IPV_LipLower21\",\"FACIAL_L_12IPV_LipLower22\",\"FACIAL_L_12IPV_LipLower23\",\"FACIAL_L_12IPV_LipLower24\",\"FACIAL_R_LipLowerOuter\",\"FACIAL_R_LipLowerOuter1\",\"FACIAL_R_LipLowerOuter2\",\"FACIAL_R_LipLowerOuter3\",\"FACIAL_R_12IPV_LipLower16\",\"FACIAL_R_12IPV_LipLower17\",\"FACIAL_R_12IPV_LipLower18\",\"FACIAL_R_12IPV_LipLower19\",\"FACIAL_R_12IPV_LipLower20\",\"FACIAL_R_12IPV_LipLower21\",\"FACIAL_R_12IPV_LipLower22\",\"FACIAL_R_12IPV_LipLower23\",\"FACIAL_R_12IPV_LipLower24\",\"FACIAL_C_TeethLower\",\"FACIAL_C_Tongue1\",\"FACIAL_C_TongueUpper1\",\"FACIAL_L_TongueSide1\",\"FACIAL_R_TongueSide1\",\"FACIAL_C_Tongue2\",\"FACIAL_C_TongueUpper2\",\"FACIAL_L_TongueSide2\",\"FACIAL_R_TongueSide2\",\"FACIAL_C_Tongue3\",\"FACIAL_C_TongueUpper3\",\"FACIAL_C_TongueLower3\",\"FACIAL_L_TongueSide3\",\"FACIAL_R_TongueSide3\",\"FACIAL_C_Tongue4\",\"FACIAL_L_TongueSide4\",\"FACIAL_R_TongueSide4\",\"FACIAL_C_Jaw\",\"FACIAL_C_Jawline\",\"FACIAL_L_12IPV_Jawline1\",\"FACIAL_R_12IPV_Jawline1\",\"FACIAL_L_12IPV_Jawline2\",\"FACIAL_R_12IPV_Jawline2\",\"FACIAL_L_Jawline\",\"FACIAL_L_Jawline1\",\"FACIAL_L_Jawline2\",\"FACIAL_L_12IPV_Jawline3\",\"FACIAL_L_12IPV_Jawline4\",\"FACIAL_L_12IPV_Jawline5\",\"FACIAL_L_12IPV_Jawline6\",\"FACIAL_R_Jawline\",\"FACIAL_R_Jawline1\",\"FACIAL_R_Jawline2\",\"FACIAL_R_12IPV_Jawline3\",\"FACIAL_R_12IPV_Jawline4\",\"FACIAL_R_12IPV_Jawline5\",\"FACIAL_R_12IPV_Jawline6\",\"FACIAL_L_ChinSide\",\"FACIAL_R_ChinSide\",\"FACIAL_L_12IPV_ChinS1\",\"FACIAL_R_12IPV_ChinS1\",\"FACIAL_L_12IPV_ChinS2\",\"FACIAL_R_12IPV_ChinS2\",\"FACIAL_L_12IPV_ChinS3\",\"FACIAL_R_12IPV_ChinS3\",\"FACIAL_L_12IPV_ChinS4\",\"FACIAL_R_12IPV_ChinS4\",\"FACIAL_C_Chin1\",\"FACIAL_L_Chin1\",\"FACIAL_R_Chin1\",\"FACIAL_C_Chin2\",\"FACIAL_L_Chin2\",\"FACIAL_R_Chin2\",\"FACIAL_C_Chin3\",\"FACIAL_L_Chin3\",\"FACIAL_R_Chin3\",\"FACIAL_L_12IPV_Chin1\",\"FACIAL_R_12IPV_Chin1\",\"FACIAL_L_12IPV_Chin2\",\"FACIAL_R_12IPV_Chin2\",\"FACIAL_C_12IPV_Chin3\",\"FACIAL_C_12IPV_Chin4\",\"FACIAL_L_12IPV_Chin5\",\"FACIAL_R_12IPV_Chin5\",\"FACIAL_L_12IPV_Chin6\",\"FACIAL_R_12IPV_Chin6\",\"FACIAL_L_12IPV_Chin7\",\"FACIAL_R_12IPV_Chin7\",\"FACIAL_L_12IPV_Chin8\",\"FACIAL_R_12IPV_Chin8\",\"FACIAL_L_12IPV_Chin9\",\"FACIAL_R_12IPV_Chin9\",\"FACIAL_L_12IPV_Chin10\",\"FACIAL_R_12IPV_Chin10\",\"FACIAL_L_12IPV_Chin11\",\"FACIAL_R_12IPV_Chin11\",\"FACIAL_L_12IPV_Chin12\",\"FACIAL_R_12IPV_Chin12\",\"FACIAL_L_12IPV_Chin13\",\"FACIAL_R_12IPV_Chin13\",\"FACIAL_L_12IPV_Chin14\",\"FACIAL_R_12IPV_Chin14\",\"FACIAL_C_Chin\"];\n\n// 86 bones \u00D7 3 floats (x, y, z)\nexport const REST_TRANSLATIONS: number[] = [0,0,0,0.0233437,0.9007828,0,-0.0015207,0,-0.0356119,0,2e-7,-0.063712,0,3e-7,-0.0712212,0,9e-7,-0.0904171,0,0.0000012,-0.1286658,0.0057265,0.0000015,-0.1590279,0,5e-7,-0.052265,-0.0000358,5e-7,-0.0541058,-0.0093304,-0.0114715,-0.1015913,0.0000012,-0.0012262,-0.1655814,2e-7,0,-0.2716819,1e-7,-3e-7,-0.2593559,-0.0044057,0.0185658,-0.0276724,1e-7,0,-0.0463796,0,0,-0.0292089,0,0,-0.0187035,-0.0025285,0.0069261,-0.0286998,-1e-7,0,-0.0493868,0,0,-0.0407549,0,0,-0.0313077,-0.0135881,-0.0229554,-0.0166282,0,-1e-7,-0.04589,0,0,-0.0280468,-0.0013554,-0.003889,-0.0289802,0,0,-0.054799,-1e-7,-1e-7,-0.0465886,-1e-7,-1e-7,-0.0294016,-0.0021233,-0.0205175,-0.0314949,0,0,-0.0518244,0,0,-0.042275,0,0,-0.0229874,-0.0093304,0.0114733,-0.101591,0.0000013,0.0012213,0.1655815,3e-7,0,0.271682,3e-7,-2e-7,0.2593558,0.0044056,-0.0185658,0.0276723,0,0,0.0463795,0,0,0.0292088,0,0,0.0187035,0.0025285,-0.0069261,0.0286997,0,0,0.0493868,0,0,0.040755,0,0,0.0313077,0.013588,0.0229554,0.0166282,0,-2e-7,0.04589,0,0,0.0280468,0.0013553,0.003889,0.0289802,0,0,0.054799,1e-7,0,0.0465887,0,1e-7,0.0294016,0.0021231,0.0205174,0.0314949,-2e-7,0,0.0518244,0,0,0.042275,-1e-7,0,0.0229876,0.0018911,0.0949354,0.0108068,0.0000013,0,-0.4183219,-1e-7,0,-0.392278,-0.1390173,0.0029359,-0.0656343,0.005855,0.0473655,-0.0110311,0.0016728,0.0006973,0.0154311,0.0110356,0.0320973,-0.0011842,0.0003611,0.0039117,0.0209273,0.0133392,0.0163956,0.0058485,-0.0010228,0.0035978,0.0242602,0.0118184,-0.0286874,0.0098808,-0.0015024,0.0007765,0.0313131,0.0150648,-0.00248,0.0074855,-0.0016026,0.0029361,0.0303304,-0.0000021,-7e-7,-0.2618881,0.0018912,-0.0949353,0.0108068,-0.0000013,0,0.4183218,1e-7,0,0.392278,0.1390174,-0.0029358,0.0656343,-0.0150648,0.00248,-0.0074855,0.0016026,-0.0029361,-0.0303304,-0.0118184,0.0286874,-0.0098808,0.0015024,-0.0007765,-0.0313131,-0.005855,-0.0473656,0.0110311,-0.0016728,-0.0006973,-0.0154311,-0.0133392,-0.0163956,-0.0058485,0.0010228,-0.0035978,-0.0242602,-0.0110356,-0.0320974,0.0011842,-0.0003611,-0.0039117,-0.0209273,0.0000021,7e-7,0.261888];\n\n// 86 bones \u00D7 4 floats (qx, qy, qz, qw)\nexport const REST_ROTATIONS: number[] = [0,0,0,-1,-0.7069933,0.012667,0.0126671,-0.7069933,0.0000019,0.0954121,4e-7,-0.9954379,0,-0.0638428,0,-0.99796,0.0000031,-0.0828618,-3e-7,-0.9965611,0,-0.0743946,0,-0.9972289,-1e-7,0.0133748,2e-7,-0.9999105,-1e-7,0.2006889,-1e-7,-0.979655,0,-0.0078937,0,-0.9999688,0,-0.099543,0,-0.9950333,0.7475424,0.0537591,0.078301,-0.6573883,0.3846423,0.0111753,-0.0260349,-0.9226308,2e-7,0.3143818,-1e-7,-0.9492966,1e-7,-1e-7,-0.7071068,-0.7071068,-0.1810116,-0.0874972,-0.0672794,-0.9772679,0,-0.1045285,0,-0.9945219,0,-0.1736482,0,-0.9848077,0,-0.0348995,0,-0.9993908,-0.1045125,0.0018243,-0.0173568,-0.9943704,0,-0.1564345,0,-0.9876884,0,-0.2164396,0,-0.976296,0,-0.0436194,0,-0.9990482,0.3371452,0.0446987,0.5606716,-0.7549719,0,-0.1736482,0,-0.9848077,0,-0.0871558,0,-0.9961947,-0.0090226,0.0435558,0.0065938,-0.9989885,0,-0.2079117,0,-0.9781476,0,-0.1736482,0,-0.9848077,0,-0.0348995,0,-0.9993908,0.0522085,0.0036507,0.0696609,-0.9961969,0,-0.1736481,0,-0.9848078,0,-0.1045285,0,-0.9945219,0,-0.0348995,0,-0.9993908,0.0782987,-0.6573692,-0.7475592,-0.0537623,0.3846281,0.0111704,-0.0260382,-0.9226367,-2e-7,0.3143817,2e-7,-0.9492967,-1e-7,0,-0.7071068,-0.7071068,-0.1810116,-0.0874972,-0.0672793,-0.9772679,0,-0.1045284,0,-0.9945219,0,-0.1736482,0,-0.9848077,0,-0.0348995,0,-0.9993908,-0.1045125,0.0018243,-0.0173568,-0.9943704,0,-0.1564345,0,-0.9876884,0,-0.2164396,0,-0.976296,0,-0.0436194,0,-0.9990482,0.3371452,0.0446988,0.5606716,-0.7549718,0,-0.1736482,0,-0.9848077,0,-0.0871557,0,-0.9961947,-0.0090226,0.0435558,0.006594,-0.9989885,0,-0.2079117,0,-0.9781476,0,-0.1736482,0,-0.9848077,0,-0.0348995,0,-0.9993908,0.0522085,0.0036508,0.069661,-0.9961969,0,-0.1736482,0,-0.9848077,0,-0.1045285,0,-0.9945219,0,-0.0348995,0,-0.9993908,-0.0740464,0.9969521,-0.0227449,-0.0092877,1e-7,0.0090163,2e-7,-0.9999593,0.0246332,0,2e-7,-0.9996966,0,0.7071068,-2e-7,-0.7071068,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0.0372693,0.0284231,-0.0022392,-0.9988984,0,0,0,-1,0.0319268,0.0741281,-0.0043309,-0.9967281,-1e-7,0.1045285,-1e-7,-0.9945219,0,0,0,-1,-0.0227449,-0.0092877,0.0740464,-0.9969521,1e-7,0.0090163,2e-7,-0.9999593,0.0246332,0,3e-7,-0.9996966,0,0.7071068,-2e-7,-0.7071068,0.0319268,0.0741281,-0.0043309,-0.9967281,-1e-7,0.1045285,-1e-7,-0.9945219,0.0372693,0.0284231,-0.0022392,-0.9988984,0,0,0,-1,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0.0067881,0.11322,-0.03924,-0.9927716,1e-7,0.0871557,2e-7,-0.9961947,0,0,0,-1];\n\n// 86 bone parent indices (-1 = root)\nexport const PARENTS: number[] = [-1,0,1,2,3,4,5,6,7,8,6,10,11,12,13,14,15,16,13,18,19,20,13,22,23,13,25,26,27,13,29,30,31,6,33,34,35,36,37,38,39,36,41,42,43,36,45,46,36,48,49,50,36,52,53,54,1,56,57,58,59,60,59,62,59,64,59,66,59,68,57,1,71,72,73,74,75,74,77,74,79,74,81,74,83,72];\n", "// Auto-generated canonical 441-bone skeleton data.\n// Source (out-of-tree authoring inputs, not part of this package):\n// std_male_skeleton_readable.json + _BONE_NAMES_441 from pkl_to_glb.\n// Do not edit manually.\n\nexport const NUM_BONES_441 = 441;\n\nexport const BONE_NAMES_441: string[] = [\"root\",\"pelvis\",\"spine_01\",\"spine_02\",\"spine_03\",\"spine_04\",\"spine_05\",\"neck_01\",\"neck_02\",\"head\",\"clavicle_l\",\"upperarm_l\",\"lowerarm_l\",\"hand_l\",\"pinky_metacarpal_l\",\"pinky_01_l\",\"pinky_02_l\",\"pinky_03_l\",\"ring_metacarpal_l\",\"ring_01_l\",\"ring_02_l\",\"ring_03_l\",\"thumb_01_l\",\"thumb_02_l\",\"thumb_03_l\",\"middle_metacarpal_l\",\"middle_01_l\",\"middle_02_l\",\"middle_03_l\",\"index_metacarpal_l\",\"index_01_l\",\"index_02_l\",\"index_03_l\",\"clavicle_r\",\"upperarm_r\",\"lowerarm_r\",\"hand_r\",\"pinky_metacarpal_r\",\"pinky_01_r\",\"pinky_02_r\",\"pinky_03_r\",\"ring_metacarpal_r\",\"ring_01_r\",\"ring_02_r\",\"ring_03_r\",\"thumb_01_r\",\"thumb_02_r\",\"thumb_03_r\",\"middle_metacarpal_r\",\"middle_01_r\",\"middle_02_r\",\"middle_03_r\",\"index_metacarpal_r\",\"index_01_r\",\"index_02_r\",\"index_03_r\",\"thigh_r\",\"calf_r\",\"foot_r\",\"ball_r\",\"littletoe_01_r\",\"littletoe_02_r\",\"ringtoe_01_r\",\"ringtoe_02_r\",\"middletoe_01_r\",\"middletoe_02_r\",\"bigtoe_01_r\",\"bigtoe_02_r\",\"indextoe_01_r\",\"indextoe_02_r\",\"calf_twist_01_r\",\"thigh_l\",\"calf_l\",\"foot_l\",\"ball_l\",\"indextoe_01_l\",\"indextoe_02_l\",\"bigtoe_01_l\",\"bigtoe_02_l\",\"littletoe_01_l\",\"littletoe_02_l\",\"middletoe_01_l\",\"middletoe_02_l\",\"ringtoe_01_l\",\"ringtoe_02_l\",\"calf_twist_01_l\",\"FACIAL_C_Neck2Root\",\"FACIAL_L_12IPV_NeckA1\",\"FACIAL_R_12IPV_NeckA1\",\"FACIAL_L_12IPV_NeckA3\",\"FACIAL_R_12IPV_NeckA3\",\"FACIAL_C_FacialRoot\",\"FACIAL_C_Hair3\",\"FACIAL_C_Hair4\",\"FACIAL_C_Hair5\",\"FACIAL_C_Hair6\",\"FACIAL_L_12IPV_Temple1\",\"FACIAL_R_12IPV_Temple1\",\"FACIAL_L_12IPV_Temple2\",\"FACIAL_R_12IPV_Temple2\",\"FACIAL_L_HairC1\",\"FACIAL_R_HairC1\",\"FACIAL_L_Sideburn2\",\"FACIAL_R_Sideburn2\",\"FACIAL_L_Sideburn3\",\"FACIAL_R_Sideburn3\",\"FACIAL_L_Sideburn4\",\"FACIAL_R_Sideburn4\",\"FACIAL_L_Sideburn5\",\"FACIAL_R_Sideburn5\",\"FACIAL_L_Sideburn6\",\"FACIAL_R_Sideburn6\",\"FACIAL_C_Forehead\",\"FACIAL_L_12IPV_Forehead4\",\"FACIAL_R_12IPV_Forehead4\",\"FACIAL_L_12IPV_Forehead5\",\"FACIAL_R_12IPV_Forehead5\",\"FACIAL_L_12IPV_Forehead6\",\"FACIAL_R_12IPV_Forehead6\",\"FACIAL_L_ForeheadIn\",\"FACIAL_L_12IPV_ForeheadIn2\",\"FACIAL_L_12IPV_ForeheadIn3\",\"FACIAL_L_12IPV_ForeheadIn4\",\"FACIAL_L_12IPV_ForeheadIn6\",\"FACIAL_L_12IPV_ForeheadIn7\",\"FACIAL_L_12IPV_ForeheadIn8\",\"FACIAL_L_12IPV_ForeheadIn10\",\"FACIAL_L_12IPV_ForeheadIn11\",\"FACIAL_L_12IPV_ForeheadIn12\",\"FACIAL_L_12IPV_ForeheadIn13\",\"FACIAL_L_12IPV_ForeheadIn14\",\"FACIAL_R_ForeheadIn\",\"FACIAL_R_12IPV_ForeheadIn2\",\"FACIAL_R_12IPV_ForeheadIn3\",\"FACIAL_R_12IPV_ForeheadIn4\",\"FACIAL_R_12IPV_ForeheadIn6\",\"FACIAL_R_12IPV_ForeheadIn7\",\"FACIAL_R_12IPV_ForeheadIn8\",\"FACIAL_R_12IPV_ForeheadIn10\",\"FACIAL_R_12IPV_ForeheadIn12\",\"FACIAL_R_12IPV_ForeheadIn11\",\"FACIAL_R_12IPV_ForeheadIn13\",\"FACIAL_R_12IPV_ForeheadIn14\",\"FACIAL_L_ForeheadMid\",\"FACIAL_L_12IPV_ForeheadMid16\",\"FACIAL_L_12IPV_ForeheadMid17\",\"FACIAL_L_12IPV_ForeheadMid18\",\"FACIAL_L_12IPV_ForeheadMid20\",\"FACIAL_L_12IPV_ForeheadMid21\",\"FACIAL_L_12IPV_ForeheadMid22\",\"FACIAL_R_ForeheadMid\",\"FACIAL_R_12IPV_ForeheadMid16\",\"FACIAL_R_12IPV_ForeheadMid17\",\"FACIAL_R_12IPV_ForeheadMid18\",\"FACIAL_R_12IPV_ForeheadMid20\",\"FACIAL_R_12IPV_ForeheadMid21\",\"FACIAL_R_12IPV_ForeheadMid22\",\"FACIAL_L_ForeheadOut\",\"FACIAL_L_12IPV_ForeheadOut23\",\"FACIAL_L_12IPV_ForeheadOut24\",\"FACIAL_L_12IPV_ForeheadOut25\",\"FACIAL_L_12IPV_ForeheadOut28\",\"FACIAL_L_12IPV_ForeheadOut29\",\"FACIAL_L_12IPV_ForeheadOut31\",\"FACIAL_R_ForeheadOut\",\"FACIAL_R_12IPV_ForeheadOut23\",\"FACIAL_R_12IPV_ForeheadOut24\",\"FACIAL_R_12IPV_ForeheadOut25\",\"FACIAL_R_12IPV_ForeheadOut28\",\"FACIAL_R_12IPV_ForeheadOut29\",\"FACIAL_R_12IPV_ForeheadOut31\",\"FACIAL_L_12IPV_EyesackU0\",\"FACIAL_R_12IPV_EyesackU0\",\"FACIAL_L_EyesackUpper\",\"FACIAL_L_EyesackUpper1\",\"FACIAL_L_EyesackUpper2\",\"FACIAL_L_EyesackUpper3\",\"FACIAL_R_EyesackUpper\",\"FACIAL_R_EyesackUpper1\",\"FACIAL_R_EyesackUpper2\",\"FACIAL_R_EyesackUpper3\",\"FACIAL_L_EyelidUpperFurrow\",\"FACIAL_L_EyelidUpperFurrow2\",\"FACIAL_L_EyelidUpperFurrow3\",\"FACIAL_R_EyelidUpperFurrow\",\"FACIAL_R_EyelidUpperFurrow3\",\"FACIAL_L_EyelidUpperB\",\"FACIAL_L_EyelidUpperB2\",\"FACIAL_L_EyelidUpperB3\",\"FACIAL_R_EyelidUpperB\",\"FACIAL_R_EyelidUpperB3\",\"FACIAL_L_EyelidUpperA\",\"FACIAL_L_EyelidUpperA1\",\"FACIAL_L_EyelidUpperA2\",\"FACIAL_L_EyelidUpperA3\",\"FACIAL_R_EyelidUpperA\",\"FACIAL_R_EyelidUpperA1\",\"FACIAL_R_EyelidUpperA2\",\"FACIAL_R_EyelidUpperA3\",\"FACIAL_L_Eye\",\"FACIAL_L_EyeParallel\",\"FACIAL_L_Pupil\",\"FACIAL_R_Eye\",\"FACIAL_R_EyeParallel\",\"FACIAL_R_Pupil\",\"FACIAL_L_EyelidLowerA\",\"FACIAL_L_EyelidLowerA1\",\"FACIAL_L_EyelidLowerA2\",\"FACIAL_L_EyelidLowerA3\",\"FACIAL_R_EyelidLowerA\",\"FACIAL_R_EyelidLowerA1\",\"FACIAL_R_EyelidLowerA2\",\"FACIAL_R_EyelidLowerA3\",\"FACIAL_L_EyelidLowerB\",\"FACIAL_L_EyelidLowerB3\",\"FACIAL_R_EyelidLowerB\",\"FACIAL_R_EyelidLowerB1\",\"FACIAL_R_EyelidLowerB2\",\"FACIAL_L_EyeCornerInner\",\"FACIAL_L_EyeCornerInner1\",\"FACIAL_L_EyeCornerInner2\",\"FACIAL_R_EyeCornerInner\",\"FACIAL_R_EyeCornerInner1\",\"FACIAL_R_EyeCornerInner2\",\"FACIAL_L_EyeCornerOuter\",\"FACIAL_L_EyeCornerOuter1\",\"FACIAL_L_EyeCornerOuter2\",\"FACIAL_R_EyeCornerOuter\",\"FACIAL_R_EyeCornerOuter1\",\"FACIAL_R_EyeCornerOuter2\",\"FACIAL_L_12IPV_EyeCornerO1\",\"FACIAL_R_12IPV_EyeCornerO1\",\"FACIAL_L_EyesackLower\",\"FACIAL_L_12IPV_EyesackL5\",\"FACIAL_L_12IPV_CheekOuter3\",\"FACIAL_R_12IPV_CheekOuter3\",\"FACIAL_L_12IPV_NoseBridge1\",\"FACIAL_R_12IPV_NoseBridge1\",\"FACIAL_C_12IPV_NoseBridge2\",\"FACIAL_L_12IPV_NoseBridge2\",\"FACIAL_R_12IPV_NoseBridge2\",\"FACIAL_L_NoseBridge\",\"FACIAL_R_NoseBridge\",\"FACIAL_C_12IPV_NoseUpper1\",\"FACIAL_C_12IPV_NoseUpper2\",\"FACIAL_L_12IPV_NoseUpper1\",\"FACIAL_R_12IPV_NoseUpper1\",\"FACIAL_L_12IPV_NoseUpper2\",\"FACIAL_R_12IPV_NoseUpper2\",\"FACIAL_L_12IPV_NoseUpper3\",\"FACIAL_R_12IPV_NoseUpper3\",\"FACIAL_L_12IPV_NoseUpper4\",\"FACIAL_R_12IPV_NoseUpper4\",\"FACIAL_L_NasolabialBulge\",\"FACIAL_L_12IPV_NasolabialB6\",\"FACIAL_L_12IPV_NasolabialB9\",\"FACIAL_L_12IPV_NasolabialB10\",\"FACIAL_R_NasolabialBulge\",\"FACIAL_R_12IPV_NasolabialB6\",\"FACIAL_R_12IPV_NasolabialB9\",\"FACIAL_R_12IPV_NasolabialB10\",\"FACIAL_L_12IPV_NasolabialF3\",\"FACIAL_R_12IPV_NasolabialF3\",\"FACIAL_L_CheekLower\",\"FACIAL_L_12IPV_CheekL2\",\"FACIAL_L_12IPV_CheekL4\",\"FACIAL_R_CheekLower\",\"FACIAL_R_12IPV_CheekL2\",\"FACIAL_R_12IPV_CheekL4\",\"FACIAL_L_Ear\",\"FACIAL_L_Ear1\",\"FACIAL_L_Ear4\",\"FACIAL_R_Ear\",\"FACIAL_R_Ear1\",\"FACIAL_R_Ear4\",\"FACIAL_C_Nose\",\"FACIAL_C_NoseLower\",\"FACIAL_L_NostrilThickness3\",\"FACIAL_R_NostrilThickness3\",\"FACIAL_C_12IPV_NoseL1\",\"FACIAL_C_12IPV_NoseL2\",\"FACIAL_C_NoseTip\",\"FACIAL_C_12IPV_NoseTip1\",\"FACIAL_C_12IPV_NoseTip2\",\"FACIAL_C_12IPV_NoseTip3\",\"FACIAL_R_12IPV_NoseTip1\",\"FACIAL_R_12IPV_NoseTip2\",\"FACIAL_R_12IPV_NoseTip3\",\"FACIAL_L_Nostril\",\"FACIAL_L_12IPV_Nostril8\",\"FACIAL_L_12IPV_Nostril10\",\"FACIAL_L_12IPV_Nostril11\",\"FACIAL_L_12IPV_Nostril12\",\"FACIAL_L_12IPV_Nostril14\",\"FACIAL_R_Nostril\",\"FACIAL_R_12IPV_Nostril4\",\"FACIAL_R_12IPV_Nostril6\",\"FACIAL_R_12IPV_Nostril8\",\"FACIAL_R_12IPV_Nostril10\",\"FACIAL_R_12IPV_Nostril11\",\"FACIAL_R_12IPV_Nostril12\",\"FACIAL_R_12IPV_Nostril14\",\"FACIAL_C_12IPV_LipUpperSkin1\",\"FACIAL_C_12IPV_LipUpperSkin2\",\"FACIAL_L_12IPV_LipUpperSkin\",\"FACIAL_R_12IPV_LipUpperSkin\",\"FACIAL_C_MouthUpper\",\"FACIAL_C_LipUpper\",\"FACIAL_L_12IPV_LipUpper1\",\"FACIAL_R_12IPV_LipUpper1\",\"FACIAL_L_12IPV_LipUpper2\",\"FACIAL_R_12IPV_LipUpper2\",\"FACIAL_L_12IPV_LipUpper3\",\"FACIAL_R_12IPV_LipUpper3\",\"FACIAL_L_12IPV_LipUpper4\",\"FACIAL_R_12IPV_LipUpper4\",\"FACIAL_L_LipUpper\",\"FACIAL_L_12IPV_LipUpper6\",\"FACIAL_L_12IPV_LipUpper7\",\"FACIAL_L_12IPV_LipUpper8\",\"FACIAL_L_12IPV_LipUpper9\",\"FACIAL_L_12IPV_LipUpper10\",\"FACIAL_L_12IPV_LipUpper11\",\"FACIAL_L_12IPV_LipUpper12\",\"FACIAL_L_12IPV_LipUpper14\",\"FACIAL_R_LipUpper\",\"FACIAL_R_12IPV_LipUpper6\",\"FACIAL_R_12IPV_LipUpper7\",\"FACIAL_R_12IPV_LipUpper8\",\"FACIAL_R_12IPV_LipUpper9\",\"FACIAL_R_12IPV_LipUpper10\",\"FACIAL_R_12IPV_LipUpper11\",\"FACIAL_R_12IPV_LipUpper12\",\"FACIAL_R_12IPV_LipUpper14\",\"FACIAL_L_LipUpperOuter\",\"FACIAL_L_12IPV_LipUpper16\",\"FACIAL_L_12IPV_LipUpper17\",\"FACIAL_L_12IPV_LipUpper18\",\"FACIAL_L_12IPV_LipUpper19\",\"FACIAL_L_12IPV_LipUpper20\",\"FACIAL_R_LipUpperOuter\",\"FACIAL_R_12IPV_LipUpper16\",\"FACIAL_R_12IPV_LipUpper17\",\"FACIAL_R_12IPV_LipUpper18\",\"FACIAL_R_12IPV_LipUpper19\",\"FACIAL_R_12IPV_LipUpper20\",\"FACIAL_L_LipCorner\",\"FACIAL_L_LipCorner1\",\"FACIAL_L_LipCorner2\",\"FACIAL_L_LipCorner3\",\"FACIAL_L_12IPV_LipCorner1\",\"FACIAL_L_12IPV_LipCorner2\",\"FACIAL_L_12IPV_LipCorner3\",\"FACIAL_R_LipCorner\",\"FACIAL_R_LipCorner1\",\"FACIAL_R_LipCorner2\",\"FACIAL_R_LipCorner3\",\"FACIAL_R_12IPV_LipCorner1\",\"FACIAL_R_12IPV_LipCorner2\",\"FACIAL_R_12IPV_LipCorner3\",\"FACIAL_L_JawBulge\",\"FACIAL_R_JawBulge\",\"FACIAL_L_JawRecess\",\"FACIAL_R_JawRecess\",\"FACIAL_L_Masseter\",\"FACIAL_R_Masseter\",\"FACIAL_L_12IPV_UnderChin3\",\"FACIAL_R_12IPV_UnderChin3\",\"FACIAL_L_12IPV_UnderChin5\",\"FACIAL_R_12IPV_UnderChin5\",\"FACIAL_L_12IPV_UnderChin6\",\"FACIAL_R_12IPV_UnderChin6\",\"FACIAL_C_LowerLipRotation\",\"FACIAL_C_12IPV_LipLowerSkin1\",\"FACIAL_L_12IPV_LipLowerSkin\",\"FACIAL_R_12IPV_LipLowerSkin\",\"FACIAL_L_12IPV_LipLowerOuterSkin1\",\"FACIAL_R_12IPV_LipLowerOuterSkin1\",\"FACIAL_C_MouthLower\",\"FACIAL_C_LipLower\",\"FACIAL_L_12IPV_LipLower1\",\"FACIAL_R_12IPV_LipLower1\",\"FACIAL_L_12IPV_LipLower2\",\"FACIAL_R_12IPV_LipLower2\",\"FACIAL_L_12IPV_LipLower3\",\"FACIAL_R_12IPV_LipLower3\",\"FACIAL_L_12IPV_LipLower4\",\"FACIAL_R_12IPV_LipLower4\",\"FACIAL_L_LipLower\",\"FACIAL_L_12IPV_LipLower6\",\"FACIAL_L_12IPV_LipLower7\",\"FACIAL_L_12IPV_LipLower8\",\"FACIAL_L_12IPV_LipLower9\",\"FACIAL_L_12IPV_LipLower10\",\"FACIAL_L_12IPV_LipLower11\",\"FACIAL_L_12IPV_LipLower12\",\"FACIAL_R_LipLower\",\"FACIAL_R_12IPV_LipLower6\",\"FACIAL_R_12IPV_LipLower7\",\"FACIAL_R_12IPV_LipLower8\",\"FACIAL_R_12IPV_LipLower9\",\"FACIAL_R_12IPV_LipLower10\",\"FACIAL_R_12IPV_LipLower11\",\"FACIAL_R_12IPV_LipLower12\",\"FACIAL_L_LipLowerOuter\",\"FACIAL_L_12IPV_LipLower16\",\"FACIAL_L_12IPV_LipLower17\",\"FACIAL_L_12IPV_LipLower18\",\"FACIAL_L_12IPV_LipLower19\",\"FACIAL_L_12IPV_LipLower20\",\"FACIAL_R_LipLowerOuter\",\"FACIAL_R_12IPV_LipLower16\",\"FACIAL_R_12IPV_LipLower17\",\"FACIAL_R_12IPV_LipLower18\",\"FACIAL_R_12IPV_LipLower19\",\"FACIAL_R_12IPV_LipLower20\",\"FACIAL_C_Jaw\",\"FACIAL_L_12IPV_Jawline1\",\"FACIAL_R_12IPV_Jawline1\",\"FACIAL_L_12IPV_Jawline2\",\"FACIAL_R_12IPV_Jawline2\",\"FACIAL_L_Jawline\",\"FACIAL_L_12IPV_Jawline3\",\"FACIAL_L_12IPV_Jawline4\",\"FACIAL_L_12IPV_Jawline5\",\"FACIAL_L_12IPV_Jawline6\",\"FACIAL_R_Jawline\",\"FACIAL_R_12IPV_Jawline3\",\"FACIAL_R_12IPV_Jawline4\",\"FACIAL_R_12IPV_Jawline5\",\"FACIAL_R_12IPV_Jawline6\",\"FACIAL_L_12IPV_ChinS4\",\"FACIAL_R_12IPV_ChinS4\",\"FACIAL_L_12IPV_Chin2\",\"FACIAL_R_12IPV_Chin2\",\"FACIAL_C_12IPV_Chin3\",\"FACIAL_C_12IPV_Chin4\",\"FACIAL_L_12IPV_Chin8\",\"FACIAL_L_12IPV_Chin13\",\"FACIAL_L_12IPV_Chin14\",\"FACIAL_R_12IPV_Chin14\"];\n\nexport const PARENTS_441: number[] = [-1,0,1,2,3,4,5,6,7,8,6,10,11,12,13,14,15,16,13,18,19,20,13,22,23,13,25,26,27,13,29,30,31,6,33,34,35,36,37,38,39,36,41,42,43,36,45,46,36,48,49,50,36,52,53,54,1,56,57,58,59,60,59,62,59,64,59,66,59,68,57,1,71,72,73,74,75,74,77,74,79,74,81,74,83,72,8,86,86,86,86,9,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,112,112,112,112,112,112,91,119,119,119,119,119,119,119,119,119,119,119,91,131,131,131,131,131,131,131,131,131,131,131,91,143,143,143,143,143,143,91,150,150,150,150,150,150,91,157,157,157,157,157,157,91,164,164,164,164,164,164,91,91,91,173,173,173,91,177,177,177,91,181,181,91,184,91,186,186,91,189,91,191,191,191,91,195,195,195,91,199,200,91,202,203,91,205,205,205,91,209,209,209,91,213,91,215,215,91,218,218,91,221,221,91,224,224,91,227,227,91,91,91,232,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,253,253,253,91,257,257,257,91,91,91,263,263,91,266,266,91,269,269,91,272,272,91,275,276,276,276,276,275,281,281,281,281,281,281,275,288,288,288,288,288,275,294,294,294,294,294,294,294,91,91,91,91,91,306,307,307,307,307,307,307,307,307,306,316,316,316,316,316,316,316,316,306,325,325,325,325,325,325,325,325,306,334,334,334,334,334,306,340,340,340,340,340,306,346,346,346,346,346,346,306,353,353,353,353,353,353,91,91,91,91,91,91,91,91,91,91,91,91,91,372,372,372,372,372,372,378,379,379,379,379,379,379,379,379,378,388,388,388,388,388,388,388,378,396,396,396,396,396,396,396,378,404,404,404,404,404,378,410,410,410,410,410,91,416,416,416,416,416,421,421,421,421,416,426,426,426,426,416,416,416,416,416,416,416,416,416,416];\n\nexport const REST_TRANSLATIONS_441: number[] = [0,-0,-0,0.023344,0.900783,-0,-0.001521,-0,-0.035612,-0,0,-0.063712,-0,0,-0.071221,-0,1e-06,-0.090417,-0,1e-06,-0.128666,0.005727,1e-06,-0.159028,0,1e-06,-0.052265,-3.6e-05,1e-06,-0.054106,-0.00933,-0.011471,-0.101591,1e-06,-0.001226,-0.165581,0,0,-0.271682,0,-0,-0.259356,-0.004406,0.018566,-0.027672,0,-0,-0.04638,0,0,-0.029209,0,0,-0.018704,-0.002529,0.006926,-0.0287,-0,-0,-0.049387,-0,-0,-0.040755,-0,-0,-0.031308,-0.013588,-0.022955,-0.016628,0,-0,-0.04589,0,0,-0.028047,-0.001355,-0.003889,-0.02898,0,-0,-0.054799,-0,-0,-0.046589,-0,-0,-0.029402,-0.002123,-0.020517,-0.031495,-0,-0,-0.051824,0,-0,-0.042275,0,0,-0.022987,-0.00933,0.011473,-0.101591,1e-06,0.001221,0.165582,0,0,0.271682,0,-0,0.259356,0.004406,-0.018566,0.027672,0,-0,0.04638,-0,0,0.029209,-0,0,0.018704,0.002529,-0.006926,0.0287,-0,-0,0.049387,0,-0,0.040755,-0,0,0.031308,0.013588,0.022955,0.016628,-0,-0,0.04589,0,0,0.028047,0.001355,0.003889,0.02898,0,-0,0.054799,0,0,0.046589,-0,0,0.029402,0.002123,0.020517,0.031495,-0,0,0.051824,-0,-0,0.042275,-0,-0,0.022988,0.001891,0.094935,0.010807,1e-06,-0,-0.418322,-0,-0,-0.392278,-0.139017,0.002936,-0.065634,0.005855,0.047366,-0.011031,0.001673,0.000697,0.015431,0.011036,0.032097,-0.001184,0.000361,0.003912,0.020927,0.013339,0.016396,0.005849,-0.001023,0.003598,0.02426,0.011818,-0.028687,0.009881,-0.001502,0.000777,0.031313,0.015065,-0.00248,0.007485,-0.001603,0.002936,0.03033,-2e-06,-1e-06,-0.261888,0.001891,-0.094935,0.010807,-1e-06,-0,0.418322,0,0,0.392278,0.139017,-0.002936,0.065634,-0.015065,0.00248,-0.007485,0.001603,-0.002936,-0.03033,-0.011818,0.028687,-0.009881,0.001502,-0.000776,-0.031313,-0.005855,-0.047366,0.011031,-0.001673,-0.000697,-0.015431,-0.013339,-0.016396,-0.005849,0.001023,-0.003598,-0.02426,-0.011036,-0.032097,0.001184,-0.000361,-0.003912,-0.020927,2e-06,1e-06,0.261888,0.026874,4e-06,-0.002962,0.006313,0.03091,-0.025065,0.006275,0.030867,0.025048,-0.011196,0.011833,-0.048657,-0.011328,0.011698,0.048782,-0.009899,5e-06,-0.040012,-0.11661,0.077932,-5.9e-05,-0.128862,0.048206,-1.3e-05,-0.133137,0.008422,2.1e-05,-0.121244,-0.034068,4.6e-05,-0.044079,0.083333,-0.061966,-0.044096,0.083246,0.061837,-0.036218,0.074804,-0.066002,-0.036234,0.074759,0.065998,-0.051973,0.051465,-0.073208,-0.051888,0.051468,0.073015,-0.027945,0.046024,-0.073847,-0.027937,0.046006,0.073747,-0.027355,0.025024,-0.076776,-0.027373,0.025055,0.076999,-0.004736,0.066318,-0.071697,-0.00474,0.066323,0.071715,-0.005354,0.049423,-0.074053,-0.005383,0.049457,0.073901,-0.005335,0.032464,-0.073732,-0.005363,0.032514,0.073961,-0.043356,0.110559,0.000237,0.004231,0.010024,-0.006377,0.004226,0.010127,0.005855,0.00675,0.009423,-0.006186,0.00674,0.009518,0.005672,0.013076,0.007203,-0.005153,0.013151,0.007556,0.004735,-0.044192,0.108085,-0.017441,-0.003452,0.011842,0.010352,-0.000266,0.01179,0.010523,0.008139,0.009798,0.010885,-0.003851,0.012237,0.003465,-0.000716,0.012148,0.003706,0.008262,0.010239,0.003889,-0.004805,0.011573,-0.005662,-0.001797,0.011831,-0.005203,0.006271,0.010252,-0.004264,0.014911,0.004617,0.00637,0.009354,0.007038,-0.003791,-0.04397,0.108374,0.016549,-0.003713,0.011772,-0.009511,-0.000514,0.011736,-0.009667,0.007859,0.009628,-0.010002,-0.004119,0.012189,-0.002592,-0.000955,0.012082,-0.002827,0.007851,0.009851,-0.003011,-0.005058,0.011504,0.006596,0.005891,0.010106,0.005131,-0.002037,0.011622,0.006109,0.014837,0.004686,-0.005407,0.009275,0.007089,0.004746,-0.048965,0.10091,-0.032655,0.000251,0.012773,0.004337,0.00309,0.013531,0.004935,0.010382,0.012194,0.005993,9.6e-05,0.010819,-0.005956,0.002537,0.011894,-0.005308,0.009384,0.012217,-0.003328,-0.048747,0.100187,0.031474,0.000171,0.013687,-0.003488,0.002985,0.014316,-0.004104,0.010257,0.013387,-0.005181,0.000104,0.011533,0.006665,0.00246,0.012713,0.006078,0.009311,0.01343,0.00419,-0.044651,0.092698,-0.046338,-0.005197,0.009368,0.00158,0.002266,0.01155,0.003174,0.004541,0.012468,0.003594,0.004306,0.006555,-0.00914,0.007815,0.009752,-0.004401,0.010869,0.002709,-0.015058,-0.04404,0.092692,0.045906,-0.005769,0.009416,-0.001444,0.001665,0.011667,-0.003034,0.003866,0.012614,-0.003427,0.003689,0.006894,0.009322,0.007206,0.010271,0.004653,0.010248,0.002999,0.015227,-0.027106,0.110394,-0.016668,-0.027101,0.110471,0.016676,-0.034431,0.110252,-0.034322,0.003868,0.000686,0.010512,0.000958,0.001653,-6.2e-05,0.002419,-0.001088,-0.012043,-0.034395,0.110258,0.03446,0.003862,0.000688,-0.010731,0.000904,0.001637,-8.8e-05,0.002359,-0.001079,0.011928,-0.031782,0.108184,-0.033039,0.000439,0.000866,0.000219,0.001221,-0.000103,-0.011184,-0.031718,0.108238,0.033032,0.001105,-8.6e-05,0.011223,-0.022654,0.095825,-0.031836,0.0004,0.016401,-0.001299,0.000704,0.012668,-0.010221,-0.022663,0.095706,0.031881,0.000747,0.012799,0.010162,-0.022663,0.095822,-0.03184,0.001837,0.01395,0.006634,0.000557,0.01641,-0.001307,0.001427,0.012514,-0.0097,-0.022665,0.095704,0.031888,0.001905,0.013957,-0.006721,0.000589,0.016487,0.001178,0.001377,0.012651,0.009637,-0.022666,0.095837,-0.031841,2e-06,7e-06,-3e-06,0.000437,0.012141,-0.000701,-0.022654,0.095745,0.031905,-0,0,-0,0.000388,0.012188,0.000712,-0.022656,0.095826,-0.031846,-0.001933,0.013811,0.006137,-0.001165,0.015033,-0.001647,-0.000441,0.011692,-0.009329,-0.022665,0.095704,0.031888,-0.001924,0.013866,-0.006169,-0.001165,0.015101,0.001601,-0.000481,0.011823,0.009337,-0.022666,0.095821,-0.031839,0.002146,0.013233,-0.010271,-0.022671,0.095709,0.031884,-0.000661,0.015993,-0.005946,0.00059,0.016511,0.002057,-0.018861,0.106402,-0.018159,-0.002238,0.000348,-0.001337,0.001457,0.000548,-0.00246,-0.018642,0.10623,0.018044,-0.002387,0.000508,0.001454,0.001282,0.000665,0.002586,-0.020522,0.100477,-0.045451,-0.001583,0.00183,0.001373,0.001202,0.000479,0.000282,-0.020661,0.099826,0.045568,-0.001567,0.002217,-0.001886,0.001299,0.000947,-0.000752,-0.020172,0.098095,-0.048848,-0.020234,0.098049,0.048835,-0.008836,0.1028,-0.035528,-0.001019,0.00386,-0.002949,-0.02807,0.08347,-0.062583,-0.028069,0.083439,0.062601,-0.032975,0.119318,-0.005309,-0.032931,0.119656,0.005339,-0.024691,0.120183,-4.9e-05,-0.024071,0.119121,-0.004049,-0.024084,0.119358,0.004075,-0.020829,0.109562,-0.012152,-0.020936,0.109426,0.012017,-0.019389,0.122187,-4.9e-05,-0.007826,0.129767,-8.2e-05,-0.018297,0.120549,-0.00516,-0.018311,0.120608,0.00511,-0.007032,0.128249,-0.005421,-0.007051,0.128274,0.005305,-0.015172,0.116382,-0.009218,-0.015198,0.116425,0.009224,-0.004615,0.12374,-0.009834,-0.004617,0.123792,0.009808,0.049129,0.096631,-0.03713,-0.001243,0.0073,0.014302,0.003829,0.005895,0.013934,0.018528,0.00491,0.00115,0.050119,0.097303,0.036212,-0.002115,0.007359,-0.01315,0.002932,0.005914,-0.012756,0.017608,0.004995,-8e-06,0.026135,0.114987,-0.02213,0.026266,0.115159,0.021986,0.043391,0.082007,-0.048853,0.015543,0.005661,0.006178,0.013463,0.003991,-0.009665,0.04574,0.083647,0.047902,0.013434,0.005413,-0.004009,0.011294,0.003505,0.011859,0.004762,0.009472,-0.071052,0,-0,-0,0.021144,0.011921,-0.007121,0.004829,0.009528,0.071128,0,-0,-0,0.021066,0.011921,0.007004,-0.005446,0.120997,-1.9e-05,0.031558,-0.002201,0.000108,-0.003152,-0.000407,-0.005733,-0.003213,-0.00045,0.005652,-0.001177,0.006603,-2.3e-05,0.004874,-0.000493,-6.1e-05,0.022215,0.007442,0.000502,-0.010205,0.004842,-0.000501,-0.002376,0.008496,-0.000482,0.005429,0.007026,-0.000443,-0.010055,0.000288,0.007985,-0.002922,0.002642,0.009997,0.00312,0.001051,0.010678,0.022921,-0.002186,-0.014186,-0.000107,-0.010578,-0.002407,0.003769,0.000219,-0.003097,0.005797,-0.008801,7.7e-05,0.008395,-0.002484,0.004991,0.013831,-0.005613,0.001558,0.022617,-0.001818,0.013771,-0.009532,0.007031,-0.000416,-0.002937,0.009141,0.001418,0.000283,-0.010902,0.002779,0.003949,-0.000336,0.003508,0.006058,-0.009189,0.000396,0.008584,-0.003016,-0.004644,0.014072,-0.006087,-0.001283,0.032767,0.126467,3.6e-05,0.03778,0.127802,1.7e-05,0.034508,0.123885,-0.013513,0.034433,0.123875,0.013516,0.048252,0.093357,9.4e-05,-0.005301,0.030169,-9.4e-05,-0.006138,0.005803,-0.004074,-0.006183,0.005836,0.004095,0.002511,0.005655,-0.004223,0.002502,0.005664,0.004211,0.006877,8.4e-05,-0.003463,0.00685,7.1e-05,0.003445,0.003084,-0.005263,-0.002925,0.003081,-0.005258,0.002973,-0.004195,0.026608,-0.012188,-0.006598,0.006588,0.005386,0.001817,0.006497,0.004839,-0.005083,0.005141,-0.004678,0.003424,0.004013,-0.003428,0.00621,0.00123,0.0045,0.00592,-0.000336,-0.002252,0.002751,-0.003917,0.004196,0.00228,-0.004713,-0.001789,-0.004668,0.027018,0.011648,-0.006267,0.006279,-0.004874,0.002183,0.006117,-0.004352,-0.004711,0.004705,0.005106,0.003772,0.003623,0.003893,0.006519,0.000851,-0.00401,0.00623,-0.000693,0.002734,0.003119,-0.004207,-0.003643,0.002614,-0.005007,0.00231,-0.002163,0.021478,-0.019756,-0.003344,0.00596,-0.002601,0.003905,0.003813,0.001287,0.003988,0.000731,-0.003433,0.005359,-0.000105,0.002383,0.004522,-0.00226,-0.001601,-0.002783,0.021683,0.019446,-0.002681,0.005692,0.002794,0.004446,0.003559,-0.000962,0.004601,0.000476,0.003796,0.005858,-0.000341,-0.002057,0.00509,-0.002497,0.001951,0.002965,0.014554,-0.025806,-4.7e-05,0.005676,-0.003435,-0.003501,-0.007577,-0.000567,0.004246,-0.007402,0.001802,0.000253,0.002557,0.002701,-0.001198,0.006051,0.000126,0.003126,0.004012,4e-06,0.003103,0.014129,0.02575,-0.000138,0.005992,0.003102,-0.003694,-0.007314,0.000207,0.004052,-0.007102,-0.002161,0.000274,0.002886,-0.002942,-0.001253,0.006279,-0.000463,0.003095,0.004334,-0.000224,0.037145,0.045724,-0.068915,0.037196,0.045755,0.068858,0.00945,0.036355,-0.073302,0.009485,0.036511,0.073432,0.015698,0.057461,-0.07068,0.015661,0.057466,0.070567,0.093906,0.076728,-0.024185,0.094238,0.076679,0.024255,0.077759,0.067926,-0.048138,0.077681,0.06788,0.048149,0.081184,0.047982,-0.04592,0.081197,0.047893,0.046068,0.022711,0.035839,0.000937,-0.022568,0.092507,-0.000899,-0.018216,0.091304,-0.015145,-0.018222,0.091469,0.013357,-0.021996,0.086003,-0.022726,-0.021872,0.086086,0.020952,-0.016141,0.061257,-0.00092,0.007685,0.027902,-0.000215,0.00724,0.001064,-0.004565,0.007285,0.001074,0.005022,-0.001345,0.0064,-0.004536,-0.001377,0.00644,0.005003,-0.007508,0.001178,-0.00344,-0.007551,0.001175,0.003879,-0.004332,-0.005021,-0.002724,-0.004355,-0.005042,0.003195,0.006884,0.025082,-0.009973,0.007759,0.003419,4e-05,-0.001495,0.007266,0.001074,0.007003,0.003011,-0.006975,-0.001828,0.004741,-0.005203,-0.007355,0.00228,0.001951,-0.006548,0.000798,-0.003499,-0.003938,-0.003661,0.002166,0.006949,0.025205,0.01041,0.007776,0.003108,-0.000422,-0.001621,0.007127,-0.001481,0.007071,0.002688,0.006611,-0.001908,0.004557,0.00473,-0.007454,0.002042,-0.002372,-0.006633,0.000548,0.003046,-0.004044,-0.003945,-0.002523,0.005915,0.021084,-0.017959,0.004628,0.003873,-0.003218,-0.002172,0.004193,0.000784,-0.002806,0.00152,-0.004243,-0.005573,0.001325,0.001984,-0.004517,-0.000888,-0.002442,0.006402,0.020331,0.018205,0.00412,0.004362,0.002758,-0.002794,0.00468,-0.001365,-0.003378,0.00198,0.003679,-0.00619,0.001779,-0.00256,-0.005099,-0.000441,0.001884,0.022711,0.035839,0.000937,0.009503,0.099572,-0.015498,0.009578,0.0997,0.013607,0.023235,0.08711,-0.0176,0.023355,0.087235,0.015672,0.008208,0.050305,-0.053218,-0.001654,0.007963,-0.005192,0.011921,0.012655,-8.2e-05,-0.00597,-0.020915,-0.007104,0.012227,-0.018867,-0.001766,0.00867,0.050943,0.049277,-0.002363,0.006762,0.006923,0.011216,0.011498,0.001889,-0.006728,-0.022019,0.008591,0.011292,-0.020094,0.003079,0.005563,0.091083,-0.029372,0.005616,0.091094,0.027552,-0.008111,0.102913,-0.007436,-0.008178,0.103057,0.005551,-0.002789,0.104789,-0.000974,0.00472,0.104023,-0.000986,-0.004408,0.103616,-0.010336,-0.002448,0.103151,-0.013064,0.00528,0.101868,-0.014763,0.005266,0.101768,0.012807];\n\nexport const REST_ROTATIONS_441: number[] = [0,-0,-0,-1,-0.706993,0.012667,0.012667,-0.706993,2e-06,0.095412,0,-0.995438,0,-0.063843,0,-0.99796,3e-06,-0.082862,-0,-0.996561,0,-0.074395,0,-0.997229,-0,0.013375,0,-0.999911,-0,0.200689,-0,-0.979655,-0,-0.007894,-0,-0.999969,0,-0.099543,-0,-0.995033,0.747542,0.053759,0.078301,-0.657388,0.384642,0.011175,-0.026035,-0.922631,0,0.314382,-0,-0.949297,0,-0,-0.707107,-0.707107,-0.181012,-0.087497,-0.067279,-0.977268,-0,-0.104528,0,-0.994522,0,-0.173648,-0,-0.984808,-0,-0.034899,0,-0.999391,-0.104513,0.001824,-0.017357,-0.99437,0,-0.156434,-0,-0.987688,-0,-0.21644,-0,-0.976296,-0,-0.043619,-0,-0.999048,0.337145,0.044699,0.560672,-0.754972,0,-0.173648,-0,-0.984808,0,-0.087156,0,-0.996195,-0.009023,0.043556,0.006594,-0.998989,-0,-0.207912,0,-0.978148,-0,-0.173648,0,-0.984808,-0,-0.034899,-0,-0.999391,0.052208,0.003651,0.069661,-0.996197,0,-0.173648,0,-0.984808,0,-0.104528,-0,-0.994522,-0,-0.034899,-0,-0.999391,0.078299,-0.657369,-0.747559,-0.053762,0.384628,0.01117,-0.026038,-0.922637,-0,0.314382,0,-0.949297,-0,0,-0.707107,-0.707107,-0.181012,-0.087497,-0.067279,-0.977268,0,-0.104528,0,-0.994522,-0,-0.173648,0,-0.984808,0,-0.034899,0,-0.999391,-0.104513,0.001824,-0.017357,-0.99437,0,-0.156434,-0,-0.987688,-0,-0.21644,-0,-0.976296,0,-0.043619,-0,-0.999048,0.337145,0.044699,0.560672,-0.754972,-0,-0.173648,0,-0.984808,0,-0.087156,-0,-0.996195,-0.009023,0.043556,0.006594,-0.998989,0,-0.207912,-0,-0.978148,0,-0.173648,-0,-0.984808,0,-0.034899,0,-0.999391,0.052209,0.003651,0.069661,-0.996197,0,-0.173648,0,-0.984808,-0,-0.104528,0,-0.994522,0,-0.034899,-0,-0.999391,-0.074046,0.996952,-0.022745,-0.009288,0,0.009016,0,-0.999959,0.024633,0,0,-0.999697,0,0.707107,-0,-0.707107,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0.037269,0.028423,-0.002239,-0.998898,0,-0,-0,-1,0.031927,0.074128,-0.004331,-0.996728,-0,0.104528,-0,-0.994522,0,-0,-0,-1,-0.022745,-0.009288,0.074046,-0.996952,0,0.009016,0,-0.999959,0.024633,0,0,-0.999697,0,0.707107,-0,-0.707107,0.031927,0.074128,-0.004331,-0.996728,-0,0.104528,-0,-0.994522,0.037269,0.028423,-0.002239,-0.998898,-0,-0,0,-1,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0.006788,0.11322,-0.03924,-0.992772,0,0.087156,0,-0.996195,0,-0,0,-1,0.547286,0.447743,0.447747,-0.547291,0.242088,-0.09698,0.128375,-0.956822,-0.242088,0.09698,0.128375,-0.956822,0.40361,-0.117599,0.128959,-0.898131,-0.40361,0.117599,0.128959,-0.898131,0.499997,0.499998,0.500002,-0.500003,0,-0,0.382683,-0.92388,0,-0,0.258819,-0.965926,0,-0,0.087156,-0.996195,-0,-0,-0.087156,-0.996195,-0.086551,-0.072775,0.303122,-0.946219,0.086551,0.072775,0.303122,-0.946219,-0.094233,-0.062509,0.194059,-0.974451,0.094233,0.062509,0.194059,-0.974451,-0.094233,-0.062509,0.194059,-0.974451,0.094233,0.062509,0.194059,-0.974451,-0.079983,0.007709,0.120116,-0.989503,0.079983,-0.007709,0.120116,-0.989503,-0.034866,-0.001522,0.043593,-0.99844,0.034866,0.001522,0.043593,-0.99844,-0.087126,-0.002281,0.026077,-0.995853,0.087126,0.002281,0.026077,-0.995853,0,-0,0.026177,-0.999657,0,-0,0.026177,-0.999657,0,-0,0.043619,-0.999048,0,-0,0.043619,-0.999048,-0,-0,-0.043619,-0.999048,-0,-0,0.043619,-0.999048,-0,-0,0.043619,-0.999048,0,-0,0.087156,-0.996195,0,-0,0.087156,-0.996195,0,-0,0.087156,-0.996195,0,-0,0.087156,-0.996195,0.069626,-0.004259,-0.0609,-0.995703,-0,-0,0.026177,-0.999657,-0.036644,0.01338,0.112512,-0.992884,-0.036644,0.01338,0.112512,-0.992884,-0,-0,0.026177,-0.999657,-0.036644,0.01338,0.112512,-0.992884,-0.036644,0.01338,0.112512,-0.992884,0.121753,0.005316,0.043294,-0.991601,0,-0,0.052336,-0.99863,0,0,0.207912,-0.978148,-0.081275,-0.266854,0.266854,-0.922482,-0.033411,-0.073002,0.277817,-0.957273,-0.069626,0.004259,-0.0609,-0.995703,0,0,0.026177,-0.999657,0.036644,-0.01338,0.112512,-0.992884,0.036644,-0.01338,0.112512,-0.992884,0,0,0.026177,-0.999657,0.036644,-0.01338,0.112512,-0.992884,0.036644,-0.01338,0.112512,-0.992884,-0.121753,-0.005316,0.043294,-0.991601,0,-0,0.207912,-0.978148,-0,-0,0.052336,-0.99863,0.081275,0.266854,0.266854,-0.922482,0.033411,0.073002,0.277818,-0.957273,0.175704,0.020647,-0.071179,-0.981649,0.061368,0.043004,-0.006039,-0.99717,0.061368,0.043004,-0.006039,-0.99717,0.050121,0.055707,0.21843,-0.972971,0.061368,0.043004,-0.006039,-0.99717,0.061368,0.043004,-0.006039,-0.99717,0.050121,0.055707,0.21843,-0.972971,-0.175704,-0.020647,-0.071179,-0.981649,-0.061368,-0.043004,-0.006039,-0.99717,-0.061368,-0.043004,-0.006039,-0.99717,-0.050121,-0.055707,0.21843,-0.972971,-0.061368,-0.043004,-0.006039,-0.99717,-0.061368,-0.043004,-0.006039,-0.99717,-0.050121,-0.055707,0.21843,-0.972971,0.255661,0.079231,-0.121536,-0.955818,0.04564,0.03214,-0.059434,-0.99667,0.04564,0.03214,-0.059434,-0.99667,0.102602,0.0264,0.088483,-0.990428,0.091963,0.081362,-0.053003,-0.991017,0.09618,0.095424,0.095424,-0.986173,0.09618,0.095424,0.095424,-0.986173,-0.255661,-0.079231,-0.121536,-0.955819,-0.04564,-0.03214,-0.059434,-0.99667,-0.04564,-0.03214,-0.059434,-0.99667,-0.102602,-0.0264,0.088482,-0.990428,-0.091963,-0.081362,-0.053003,-0.991017,-0.09618,-0.095424,0.095424,-0.986173,-0.09618,-0.095424,0.095424,-0.986173,-0.008996,-0.14974,0.115766,-0.981884,0.008996,0.14974,0.115766,-0.981884,0.084258,0.064553,0.048688,-0.993158,-0.078936,-0.103521,-0.000451,-0.99149,-0,-0,0,-1,0.086993,0.060816,0.005321,-0.994337,-0.084258,-0.064553,0.048688,-0.993158,0.078936,0.103521,-0.000451,-0.99149,-0,0,-0,-1,-0.086993,-0.060816,0.005321,-0.994337,0.150867,0.079694,-0.030106,-0.984877,-0.087488,-0.00412,-0.051375,-0.994831,0.071004,0.022428,-0.050367,-0.995951,-0.150867,-0.079694,-0.030106,-0.984877,-0.071004,-0.022428,-0.050367,-0.995951,-0,-0,-0.224951,-0.97437,-0,-0,-0,-1,0.165697,0.048734,-0.008553,-0.984935,-0,-0,-0.224951,-0.97437,-0.165697,-0.048734,-0.008553,-0.984935,-0,-0,-0.147809,-0.989016,-0.121406,-0.086506,0.010622,-0.988769,0,-0,-0,-1,0.165697,0.048734,-0.008553,-0.984935,-0,-0,-0.147809,-0.989016,0.121406,0.086506,0.010622,-0.988769,0,-0,-0,-1,-0.165697,-0.048734,-0.008553,-0.984935,0,-0,-0,-1,0,-0,-0,-1,-0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,-0,-0,-0,-1,0,-0,0.284015,-0.95882,-0.078459,-0,0,-0.996917,0,-0,0,-1,0.182236,0,0,-0.983255,0,-0,0.284015,-0.95882,0.078459,-0,-0,-0.996917,0,-0,0,-1,-0.182236,0,-0,-0.983255,0,-0,0.317305,-0.948324,0.182236,0,0,-0.983255,0,-0,0.317305,-0.948324,0.078459,0,0,-0.996917,-0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.382683,-0,-0,-0.92388,0,-0,-0,-1,0,-0,-0,-1,-0.382683,-0,-0,-0.92388,0,-0,-0,-1,0,-0,-0,-1,0.252684,0.209065,0.056019,-0.94303,-0.252684,-0.209065,0.056019,-0.94303,0.139756,0.022271,-0.022271,-0.989685,0.088482,-0.102602,0.008182,-0.990746,-0.215028,-0.035072,0.263565,-0.939716,0.215028,0.035072,0.263565,-0.939716,0,-0,0.043619,-0.999048,0,-0,0.043619,-0.999048,0,-0,0.043619,-0.999048,0,-0,0.043619,-0.999048,0,-0,0.043619,-0.999048,0.293995,0.122907,0.007616,-0.947841,-0.293995,-0.122906,0.007616,-0.947841,-0,-0,-0.21644,-0.976296,-0,-0,-0.21644,-0.976296,0.300095,0.066686,-0.206707,-0.928853,-0.300095,-0.066686,-0.206707,-0.928853,0.300095,0.066686,-0.206707,-0.928853,-0.300095,-0.066686,-0.206707,-0.928853,0.311524,0.099017,-0.217569,-0.91968,-0.311524,-0.099017,-0.217569,-0.91968,0.311524,0.099017,-0.217569,-0.91968,-0.311524,-0.099017,-0.217569,-0.91968,0.377418,-0.0238,0.057877,-0.923926,-0.041021,-0.057036,-0.102151,-0.992285,-0.017217,0.113333,-0.009179,-0.993365,-0.016801,0.069895,-0.009921,-0.997364,-0.377418,0.0238,0.057876,-0.923926,0.041021,0.057036,-0.102151,-0.992285,0.017217,-0.113333,-0.009179,-0.993365,0.016801,-0.069895,-0.009921,-0.997364,0.125849,0.363802,-0.033311,-0.922334,-0.125849,-0.363802,-0.033311,-0.922334,0.42696,-0.057743,0.03455,-0.901763,-0.087156,-0,0,-0.996195,0.087156,-0,-0,-0.996195,-0.42696,0.057743,0.03455,-0.901763,0.087156,-0,-0,-0.996195,-0.087156,0,-0,-0.996195,0.000685,0.026168,-0.026168,-0.999315,-0,-0,-0,-1,-0,-0,-0,-1,-0.000685,-0.026168,-0.026168,-0.999315,0,-0,-0,-1,0,-0,-0,-1,-0,-0,-0.130526,-0.991445,0,-0,0.130526,-0.991445,-0.172987,0.015134,-0.085832,-0.98106,0.172987,-0.015134,-0.085832,-0.98106,0,-0,-0,-1,0,-0,-0,-1,0,-0,0.087156,-0.996195,0,-0,-0.173648,-0.984808,0,-0,-0,-1,-0,0,0.173648,-0.984808,-0.292801,-0.053279,-0.16461,-0.94039,-0.367254,-0.038092,0.037577,-0.92858,-0.361912,-0.073116,0.126405,-0.920704,-0.130506,-0.002278,0.017303,-0.991294,0.156381,0.004095,0.025855,-0.98735,0.094592,-0.062428,-0.02319,-0.993286,0.29633,-0.082024,0.027557,-0.951158,0.29633,-0.082024,0.027557,-0.951158,0.29633,-0.082024,0.027557,-0.951158,0.130506,0.002278,0.017303,-0.991294,0.069661,-0.003651,-0.052208,-0.996197,0.069661,-0.003651,-0.052208,-0.996197,-0.156381,-0.004095,0.025855,-0.98735,-0.094592,0.062428,-0.02319,-0.993286,-0.29633,0.082024,0.027557,-0.951158,-0.29633,0.082024,0.027557,-0.951158,-0.29633,0.082024,0.027557,-0.951158,-0,-0,-0.043619,-0.999048,-0,-0,-0.043619,-0.999048,0.117487,0.061262,-0.061262,-0.989288,-0.117487,-0.061262,-0.061262,-0.989288,0,-0,-0,-1,0,-0,-0.087156,-0.996195,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.160131,0.037879,-0.077809,-0.983295,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,-0.160131,-0.037879,-0.077809,-0.983295,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,-0,-0,-0,-1,0.229385,0.098333,-0.098333,-0.96335,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,-0.229385,-0.098333,-0.098333,-0.96335,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.207912,-0,0,-0.978148,-0.087156,-0,-0,-0.996195,-0.258819,0,-0,-0.965926,-0.258819,0,-0,-0.965926,-0.258819,0,-0,-0.965926,-0.258819,0,-0,-0.965926,-0.258819,0,-0,-0.965926,-0.207912,-0,-0,-0.978148,0.087156,0,0,-0.996195,0.258819,-0,-0,-0.965926,0.258819,-0,-0,-0.965926,0.258819,-0,-0,-0.965926,0.258819,-0,-0,-0.965926,0.258819,-0,-0,-0.965926,-0.086824,-0.007596,0.086824,-0.992404,0.086824,0.007596,0.086824,-0.992404,0.017442,0.034894,0.000609,-0.999239,-0.017442,-0.034894,0.000609,-0.999239,-0.112927,-0.007897,0.069308,-0.991152,0.112928,0.007897,0.069308,-0.991152,0.256508,-0.029158,0.417475,-0.871245,-0.256508,0.029158,0.417474,-0.871245,0.354972,-0.082338,0.402471,-0.839781,-0.354972,0.082338,0.402471,-0.839781,0.354972,-0.082338,0.402471,-0.839781,-0.354972,0.082338,0.402471,-0.839781,0,-0,0.34202,-0.939693,0,-0,-0.21644,-0.976296,0.134957,-0.00034,-0.252048,-0.958258,-0.134957,0.00034,-0.252048,-0.958258,0.252897,-0.002125,-0.280862,-0.925827,-0.252897,0.002125,-0.280862,-0.925827,-0,-0,-0.34202,-0.939693,0,-0,0.087156,-0.996195,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.129488,-0.027254,0.092741,-0.986858,-0,-0,0,-1,-0,-0,0,-1,-0,-0,0,-1,-0,-0,0,-1,-0,-0,0,-1,-0,-0,0,-1,-0,-0,0,-1,-0.129488,0.027254,0.092741,-0.986858,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.232208,-0.03184,0.091272,-0.967851,-0,0,-0,-1,-0,0,-0,-1,-0,0,-0,-1,-0,0,-0,-1,-0,0,-0,-1,-0.232208,0.03184,0.091272,-0.967851,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,0.34202,-0.939693,0.095352,-0.019437,0.253917,-0.962318,-0.095353,0.019437,0.253917,-0.962318,0.056937,-0.023584,0.380197,-0.92285,-0.056937,0.023584,0.380197,-0.92285,-0.166979,-0.002604,-0.132939,-0.976954,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0,-0,-0,-1,0.166979,0.002604,-0.132939,-0.976954,-0,0,-0,-1,-0,0,-0,-1,-0,0,-0,-1,-0,0,-0,-1,0.373906,-0.049951,-0.220707,-0.899438,-0.373905,0.049951,-0.220707,-0.899438,-0,-0,-0.300706,-0.953717,-0,-0,-0.300706,-0.953717,-0,-0,0.043619,-0.999048,-0,-0,0.043619,-0.999048,0.15634,0.004979,-0.289618,-0.944275,0.145646,0.04954,0.04954,-0.986853,0.145646,0.04954,0.04954,-0.986853,-0.145646,-0.04954,0.04954,-0.986853];\n", "import {\n BONE_NAMES,\n SKELETON_1185_NAMES,\n REST_TRANSLATIONS,\n REST_ROTATIONS,\n PARENTS,\n} from './skeleton-data';\nimport {\n BONE_NAMES_441,\n PARENTS_441,\n REST_TRANSLATIONS_441,\n REST_ROTATIONS_441,\n} from './skeleton-data-441';\n\n/** @group Characters & Animation */\nexport interface SkeletonLibrary {\n boneNames?: string[];\n skeleton1185Names?: string[];\n skeleton1185StrippedNames?: string[];\n stdMaleRestTranslations?: Float32Array;\n stdMaleRestRotations?: Float32Array;\n stdMaleParents?: Int32Array;\n // Full 441-bone rig (body + facial). Used when a bin declares numBones=441.\n boneNames441?: string[];\n restTranslations441?: Float32Array;\n restRotations441?: Float32Array;\n parents441?: Int32Array;\n}\n\nconst FACIAL_PREFIX = 'FACIAL_';\n\nexport function getStripped1185Names(library: SkeletonLibrary): string[] | undefined {\n if (!library.skeleton1185Names) return undefined;\n if (!library.skeleton1185StrippedNames) {\n library.skeleton1185StrippedNames = library.skeleton1185Names.filter(\n (n) => !n.startsWith(FACIAL_PREFIX),\n );\n }\n return library.skeleton1185StrippedNames;\n}\n\n/**\n * Build the skeleton library from inlined data.\n * No network requests - all data is bundled in the engine.\n */\nexport function loadSkeletonLibrary(): SkeletonLibrary {\n return {\n boneNames: BONE_NAMES,\n skeleton1185Names: SKELETON_1185_NAMES,\n stdMaleRestTranslations: new Float32Array(REST_TRANSLATIONS),\n stdMaleRestRotations: new Float32Array(REST_ROTATIONS),\n stdMaleParents: new Int32Array(PARENTS),\n boneNames441: BONE_NAMES_441,\n restTranslations441: new Float32Array(REST_TRANSLATIONS_441),\n restRotations441: new Float32Array(REST_ROTATIONS_441),\n parents441: new Int32Array(PARENTS_441),\n };\n}\n", "import { Quat } from '../math';\nimport type { Vec3 } from '../math';\n\n/**\n * Rest pose for a rig, stored as parallel arrays indexed by bone. An empty\n * `positions` array marks an uninitialized rest pose - the rest-relative\n * conversion functions pass poses through unchanged in that case.\n */\nexport interface RestPose {\n positions: Vec3[];\n rotations: Quat[];\n scales: Vec3[];\n}\n\n/** A bone-space transform: position, rotation (as quaternion), and scale. */\nexport interface BonePose {\n position: Vec3;\n rotation: Quat;\n scale: Vec3;\n}\n\nconst _conjScratch = new Quat();\n\n/**\n * Express `pose` relative to the bone's rest transform. Writes the result\n * into `out`. Safe to call with `out === pose` (in-place).\n *\n * If `boneIndex` is out of range or `rest` is uninitialized, `pose` is copied\n * to `out` unchanged.\n */\nexport function toRestRelative(\n boneIndex: number,\n pose: BonePose,\n rest: RestPose,\n out: BonePose,\n): void {\n if (boneIndex < 0 || boneIndex >= rest.positions.length) {\n if (out !== pose) {\n out.position.copy(pose.position);\n out.rotation.copy(pose.rotation);\n out.scale.copy(pose.scale);\n }\n return;\n }\n const restPos = rest.positions[boneIndex];\n const restRot = rest.rotations[boneIndex];\n const restScale = rest.scales[boneIndex];\n\n // out.position = pose.position - restPos\n out.position.sub2(pose.position, restPos);\n // out.rotation = conj(restRot) * pose.rotation\n _conjScratch.copy(restRot).conjugate();\n out.rotation.mul2(_conjScratch, pose.rotation);\n // out.scale = pose.scale / restScale (component-wise, guarding divide-by-zero)\n out.scale.set(\n restScale.x !== 0 ? pose.scale.x / restScale.x : pose.scale.x,\n restScale.y !== 0 ? pose.scale.y / restScale.y : pose.scale.y,\n restScale.z !== 0 ? pose.scale.z / restScale.z : pose.scale.z,\n );\n}\n\n/**\n * Inverse of {@link toRestRelative}: compose a rest-relative `delta` back into\n * an absolute bone pose. Writes the result into `out`. Safe to call with\n * `out === delta` (in-place).\n */\nexport function fromRestRelative(\n boneIndex: number,\n delta: BonePose,\n rest: RestPose,\n out: BonePose,\n): void {\n if (boneIndex < 0 || boneIndex >= rest.positions.length) {\n if (out !== delta) {\n out.position.copy(delta.position);\n out.rotation.copy(delta.rotation);\n out.scale.copy(delta.scale);\n }\n return;\n }\n const restPos = rest.positions[boneIndex];\n const restRot = rest.rotations[boneIndex];\n const restScale = rest.scales[boneIndex];\n\n out.position.add2(restPos, delta.position);\n out.rotation.mul2(restRot, delta.rotation);\n out.scale.set(\n restScale.x * delta.scale.x,\n restScale.y * delta.scale.y,\n restScale.z * delta.scale.z,\n );\n}\n", "class CubicSpline {\n // control times\n times: number[];\n\n // control data: in-tangent, point, out-tangent\n knots: number[];\n\n // dimension of the knot points\n dim: number;\n\n // For looping splines built via fromPointsLooping, the original keyframe at\n // index i lives at spline segment i+2 (due to two ghost entries prepended).\n // Pass this offset to evaluateSegment when you already know the keyframe index.\n readonly keyframeOffset: number;\n\n constructor(times: number[], knots: number[], keyframeOffset = 0) {\n this.times = times;\n this.knots = knots;\n this.dim = knots.length / times.length / 3;\n this.keyframeOffset = keyframeOffset;\n }\n\n evaluate(time: number, result: number[]) {\n const { times } = this;\n const last = times.length - 1;\n\n if (time <= times[0]) {\n this.getKnot(0, result);\n } else if (time >= times[last]) {\n this.getKnot(last, result);\n } else {\n // Binary search: find largest seg where times[seg] <= time.\n let lo = 0, hi = last - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (time >= times[mid]) lo = mid;\n else hi = mid - 1;\n }\n this.evaluateSegment(\n lo,\n (time - times[lo]) / (times[lo + 1] - times[lo]),\n result,\n );\n }\n }\n\n getKnot(index: number, result: number[]) {\n const { knots, dim } = this;\n const idx = index * 3 * dim;\n for (let i = 0; i < dim; ++i) {\n result[i] = knots[idx + i * 3 + 1];\n }\n }\n\n evaluateSegment(segment: number, t: number, result: number[]) {\n const { knots, dim } = this;\n\n const t2 = t * t;\n const twot = t + t;\n const omt = 1 - t;\n const omt2 = omt * omt;\n\n let idx = segment * dim * 3;\n for (let i = 0; i < dim; ++i) {\n const p0 = knots[idx + 1];\n const m0 = knots[idx + 2];\n const m1 = knots[idx + dim * 3];\n const p1 = knots[idx + dim * 3 + 1];\n idx += 3;\n\n result[i] =\n p0 * ((1 + twot) * omt2) +\n m0 * (t * omt2) +\n p1 * (t2 * (3 - twot)) +\n m1 * (t2 * (t - 1));\n }\n }\n\n static calcKnots(times: number[], points: number[], smoothness: number) {\n const n = times.length;\n const dim = points.length / n;\n const knots: number[] = new Array(n * dim * 3);\n\n for (let i = 0; i < n; i++) {\n const t = times[i];\n\n for (let j = 0; j < dim; j++) {\n const idx = i * dim + j;\n const p = points[idx];\n\n let tangent;\n if (i === 0) {\n tangent = (points[idx + dim] - p) / (times[i + 1] - t);\n } else if (i === n - 1) {\n tangent = (p - points[idx - dim]) / (t - times[i - 1]);\n } else {\n tangent =\n (points[idx + dim] - points[idx - dim]) /\n (times[i + 1] - times[i - 1]);\n }\n\n const inScale = i > 0 ? times[i] - times[i - 1] : times[1] - times[0];\n const outScale =\n i < n - 1 ? times[i + 1] - times[i] : times[i] - times[i - 1];\n\n knots[idx * 3] = tangent * inScale * smoothness;\n knots[idx * 3 + 1] = p;\n knots[idx * 3 + 2] = tangent * outScale * smoothness;\n }\n }\n\n return knots;\n }\n\n static fromPoints(times: number[], points: number[], smoothness = 1) {\n return new CubicSpline(\n times,\n CubicSpline.calcKnots(times, points, smoothness),\n 0,\n );\n }\n\n static fromPointsLooping(\n length: number,\n times: number[],\n points: number[],\n smoothness = 1,\n ) {\n if (times.length < 2) {\n return CubicSpline.fromPoints(times, points);\n }\n\n const dim = points.length / times.length;\n const newTimes = times.slice();\n const newPoints = points.slice();\n\n newTimes.push(length + times[0], length + times[1]);\n newPoints.push(...points.slice(0, dim * 2));\n\n newTimes.splice(\n 0,\n 0,\n times[times.length - 2] - length,\n times[times.length - 1] - length,\n );\n newPoints.splice(0, 0, ...points.slice(points.length - dim * 2));\n\n // keyframeOffset=2: two ghost entries are prepended, so keyframe[i] lives\n // at spline segment i+2. Callers that know the keyframe index can skip the\n // segment search by calling evaluateSegment(i + 2, t, result) directly.\n return new CubicSpline(\n newTimes,\n CubicSpline.calcKnots(newTimes, newPoints, smoothness),\n 2,\n );\n }\n}\n\nexport { CubicSpline };\n", "import { Quat, Vec3 } from '../math';\n\nimport { toRestRelative } from './rest-relative';\nimport type { RestPose } from './rest-relative';\nimport { CubicSpline } from './spline';\n\n/** One sample on a per-bone animation curve. */\nexport interface Pose {\n frame: number;\n position: Vec3;\n rotation: Quat;\n scale: Vec3;\n}\n\n/**\n * Per-bone keyframe entry: a list of poses sorted by frame plus the cached\n * cubic spline that interpolates them. `spline` is null when there are fewer\n * than two poses (a constant-pose bone - the consumer samples `poses[0]`).\n */\nexport interface KeyframeEntryData {\n poses: Pose[];\n spline: CubicSpline | null;\n}\n\ninterface RebuildOptions {\n /** Include poses where `frame === duration`. Default `false`. */\n includeEnd?: boolean;\n /** Build a looping spline that wraps at `duration`. Default `false`. */\n looping?: boolean;\n}\n\n/**\n * Filter `poses` against `[0, duration)` (or `[0, duration]` when\n * `options.includeEnd`), sort by frame, and build the cubic spline that\n * interpolates them.\n *\n * Returns `{ poses, spline }`: a fresh sorted poses array (callers should\n * replace their original) and the spline, or `null` if fewer than two poses\n * survive the filter.\n *\n * Quaternion sign is normalized along the timeline so neighboring keys take\n * the short arc - without this the spline would interpolate the long way\n * around whenever a sample flips hemisphere.\n */\nexport function rebuildKeyframeSpline(\n poses: Pose[],\n duration: number,\n options: RebuildOptions = {},\n): { poses: Pose[]; spline: CubicSpline | null } {\n const pred = options.includeEnd\n ? (p: Pose) => p.frame <= duration\n : (p: Pose) => p.frame < duration;\n const sorted = poses.slice().filter(pred).sort((a, b) => a.frame - b.frame);\n if (sorted.length <= 1) return { poses: sorted, spline: null };\n\n const times = sorted.map((p) => p.frame);\n const points: number[] = [];\n let prevRot: Quat | null = null;\n for (const p of sorted) {\n points.push(p.position.x, p.position.y, p.position.z);\n const r = p.rotation;\n const flip = prevRot && prevRot.dot(r) < 0;\n points.push(flip ? -r.x : r.x, flip ? -r.y : r.y, flip ? -r.z : r.z, flip ? -r.w : r.w);\n points.push(p.scale.x, p.scale.y, p.scale.z);\n prevRot = r;\n }\n\n const spline = options.looping\n ? CubicSpline.fromPointsLooping(duration, times, points, 1)\n : CubicSpline.fromPoints(times, points, 1);\n return { poses: sorted, spline };\n}\n\n/**\n * Build the per-bone keyframe array an armature samples from at playback time.\n *\n * For each bone in `libraryKeyframes` whose index is below `numBones`:\n * 1. convert every pose into the bone's rest-relative space (so playback can\n * blend a delta on top of the rest pose), and\n * 2. rebuild the cubic spline, filtered+sorted by frame and wrapped for\n * looping if requested.\n *\n * Result is a sparse array of length `numBones`; bones not referenced by the\n * source map stay `null` and fall back to rest pose at evaluation time.\n *\n * If `restPose.positions` is empty (rig has no rest data), poses are emitted\n * unchanged - the rest-relative conversion no-ops.\n */\nexport function buildArmatureKeyframes(\n libraryKeyframes: Map<number, KeyframeEntryData>,\n numFrames: number,\n numBones: number,\n restPose: RestPose,\n looping: boolean,\n translationMask?: Uint8Array,\n): Array<KeyframeEntryData | null> {\n const out: Array<KeyframeEntryData | null> = new Array(numBones).fill(null);\n\n libraryKeyframes.forEach((entry, boneIdx) => {\n if (boneIdx >= numBones) return;\n // A `0` in the mask means the clip carries no MOTION for this bone, only a\n // declaration of the source rig's rest: hold the position delta at zero so\n // `fromRestRelative` reproduces the armature's own rest translation, i.e.\n // THIS character's bone length, rather than the source rig's. Absent mask =\n // every bone animates, which is what a pre-mask clip means.\n //\n // Only when there IS a rest to inherit: with no rest data `toRestRelative`\n // passes the pose through, so a zeroed position would not decode back to a\n // rest translation, it would collapse the bone onto its parent.\n const inheritsRestPosition = translationMask !== undefined\n && translationMask[boneIdx] === 0\n && boneIdx < restPose.positions.length;\n const restRelative: Pose[] = entry.poses.map((pose) => {\n const result: Pose = {\n frame: pose.frame,\n position: new Vec3(),\n rotation: new Quat(),\n scale: new Vec3(),\n };\n toRestRelative(boneIdx, pose, restPose, result);\n if (inheritsRestPosition) result.position.set(0, 0, 0);\n return result;\n });\n const built = rebuildKeyframeSpline(restRelative, numFrames, { includeEnd: true, looping });\n out[boneIdx] = { poses: built.poses, spline: built.spline };\n });\n\n return out;\n}\n\n", "import { Mat4, Quat, Vec3 } from '../math';\n\nimport { Animation } from '../animation';\nimport type { SkeletalKeyframeEntry } from '../animation';\nimport { getStripped1185Names } from '../loader/skeleton';\nimport type { SkeletonLibrary } from '../types';\n\nimport { rebuildKeyframeSpline } from './keyframe-splines';\n\n/**\n * Walk the raw 4\u00D74 bone matrices stored in `animationData.data` and produce\n * the per-bone keyframe + spline cache used at playback time.\n *\n * Idempotent - subsequent calls on the same `Animation` are no-ops (guarded\n * by `Animation.skeletalConverted`). {@link Animation.register} calls this\n * for you.\n *\n * Side effect: clears `animationData.data` once converted, since the raw\n * matrices are no longer needed and would otherwise hold ~16 floats per bone\n * per frame in memory for the lifetime of the animation.\n */\nexport function convertSkeletalAnimation(\n animationData: Animation,\n _skeletonLibrary: SkeletonLibrary,\n): void {\n if (animationData.skeletalConverted) return;\n\n if (animationData.numBones === 0 || animationData.numFrames === 0 || animationData.data.length === 0) {\n animationData.skeletalConverted = true;\n animationData.data = new Float32Array(0);\n return;\n }\n\n const store = animationData.skeletalStore ?? {\n keyframes: new Map<number, SkeletalKeyframeEntry>(),\n manualBones: new Set<number>(),\n source: 'imported',\n };\n animationData.skeletalStore = store;\n store.keyframes.clear();\n\n const floatsPerBone = 16;\n const numBones = animationData.numBones;\n const numFrames = animationData.numFrames;\n const data = animationData.data;\n const mat = new Mat4();\n const pos = new Vec3();\n const rot = new Quat();\n const scale = new Vec3();\n\n const framesToConvert = animationData.keyframeFrames?.length\n ? animationData.keyframeFrames\n : Array.from({ length: numFrames }, (_, i) => i);\n\n for (let boneIdx = 0; boneIdx < numBones; boneIdx++) {\n const poses: SkeletalKeyframeEntry['poses'] = [];\n for (const frame of framesToConvert) {\n if (frame < 0 || frame >= numFrames) continue;\n const offset = (frame * numBones + boneIdx) * floatsPerBone;\n for (let i = 0; i < 16; i++) mat.data[i] = data[offset + i];\n mat.getTranslation(pos);\n mat.getScale(scale);\n rot.setFromMat4(mat);\n rot.normalize();\n poses.push({\n frame,\n position: pos.clone(),\n rotation: rot.clone(),\n scale: scale.clone(),\n });\n }\n\n // Pass the maximum possible frame as duration so all poses survive the\n // \"in range\" filter inside rebuildKeyframeSpline - these are raw imported\n // keys, no truncation desired.\n const { spline } = rebuildKeyframeSpline(poses, Number.POSITIVE_INFINITY, { includeEnd: true });\n store.keyframes.set(boneIdx, { poses, spline });\n }\n\n animationData.skeletalConverted = true;\n animationData.data = new Float32Array(0);\n}\n\n/**\n * Return a view of `animationData` remapped to the target armature's bone\n * count, handling rig mismatches (e.g. a 1185-bone source animation played on\n * an 86-bone body rig). Target bones with no matching source bone stay at\n * rest pose during playback.\n *\n * Result is cached on the input via `Animation.filteredForBones`, so repeated\n * calls for the same target bone count reuse the filtered copy.\n */\nexport function filterAnimationForArmature(\n animationData: Animation,\n targetBoneCount: number,\n skeletonLibrary: SkeletonLibrary,\n): Animation {\n const cacheMap = animationData.filteredForBones;\n const cached = cacheMap?.get(targetBoneCount);\n if (cached) return cached;\n\n // Resolve target names from skeleton library (86-bone std male or 441-bone full rig).\n let targetNames: string[] | undefined;\n if (targetBoneCount === skeletonLibrary?.boneNames?.length) {\n targetNames = skeletonLibrary.boneNames;\n } else if (targetBoneCount === skeletonLibrary?.boneNames441?.length) {\n targetNames = skeletonLibrary.boneNames441;\n }\n if (!targetNames) return animationData;\n\n // Resolve source names by bone count: full 1185, stripped (1185 minus\n // facial), 441, or 86.\n let sourceNames: string[] | undefined;\n const fullNames = skeletonLibrary.skeleton1185Names;\n if (fullNames && animationData.numBones === fullNames.length) {\n sourceNames = fullNames;\n } else if (animationData.numBones === skeletonLibrary.boneNames441?.length) {\n sourceNames = skeletonLibrary.boneNames441;\n } else if (animationData.numBones === skeletonLibrary.boneNames?.length) {\n sourceNames = skeletonLibrary.boneNames;\n } else {\n const stripped = getStripped1185Names(skeletonLibrary);\n if (stripped && stripped.length === animationData.numBones) sourceNames = stripped;\n }\n if (!sourceNames) return animationData;\n\n // Build target \u2192 source remap (-1 when target has no matching source bone).\n const sourceByName = new Map<string, number>();\n sourceNames.forEach((n, i) => sourceByName.set(n, i));\n const mapIndices = new Int32Array(targetBoneCount);\n let identity = targetBoneCount === sourceNames.length;\n for (let i = 0; i < targetBoneCount; i++) {\n const s = sourceByName.get(targetNames[i]);\n mapIndices[i] = s === undefined ? -1 : s;\n if (identity && mapIndices[i] !== i) identity = false;\n }\n if (identity) {\n const cache = cacheMap ?? new Map<number, Animation>();\n cache.set(targetBoneCount, animationData);\n animationData.filteredForBones = cache;\n return animationData;\n }\n\n // Emit pre-converted output: only mapped target bones get keyframe entries.\n // Unmapped bones stay at rest pose at playback (see getAnimSample fallback).\n const numFrames = animationData.numFrames;\n const filtered = new Animation(new Float32Array(0), numFrames, targetBoneCount);\n const keyframes = new Map<number, SkeletalKeyframeEntry>();\n\n // Carry the translation mask across the bone remap. It is indexed by bone, so\n // it has to follow the same target->source mapping as the keyframes; losing\n // it here would silently reinstate the source rig's bone lengths. Target bones\n // with no source bone stay 0 - they have no keyframes either, so playback\n // falls back to rest regardless.\n if (animationData.translationMask) {\n const sourceMask = animationData.translationMask;\n const targetMask = new Uint8Array(targetBoneCount);\n for (let i = 0; i < targetBoneCount; i++) {\n const srcIdx = mapIndices[i];\n if (srcIdx >= 0) targetMask[i] = sourceMask[srcIdx];\n }\n filtered.translationMask = targetMask;\n }\n\n if (animationData.data.length === 0) {\n // Source is already pre-converted - copy keyframe entries under target indices.\n const sourceStore = animationData.skeletalStore;\n if (sourceStore?.keyframes) {\n for (let i = 0; i < targetBoneCount; i++) {\n const srcIdx = mapIndices[i];\n if (srcIdx < 0) continue;\n const entry = sourceStore.keyframes.get(srcIdx);\n if (!entry?.poses?.length) continue;\n const poses = entry.poses.map((pose) => ({\n frame: pose.frame,\n position: pose.position.clone(),\n rotation: pose.rotation.clone(),\n scale: pose.scale.clone(),\n }));\n keyframes.set(i, { poses, spline: null });\n }\n }\n } else {\n // Source is a raw Float32Array of 4x4 matrices - convert inline for mapped target bones only.\n const floatsPerBone = 16;\n const sourceBones = animationData.numBones;\n const data = animationData.data;\n const mat = new Mat4();\n const pos = new Vec3();\n const rot = new Quat();\n const scale = new Vec3();\n\n const framesToConvert = animationData.keyframeFrames?.length\n ? animationData.keyframeFrames\n : Array.from({ length: numFrames }, (_, i) => i);\n\n for (let i = 0; i < targetBoneCount; i++) {\n const srcIdx = mapIndices[i];\n if (srcIdx < 0) continue;\n const poses: SkeletalKeyframeEntry['poses'] = [];\n for (const frame of framesToConvert) {\n if (frame < 0 || frame >= numFrames) continue;\n const offset = (frame * sourceBones + srcIdx) * floatsPerBone;\n for (let j = 0; j < 16; j++) mat.data[j] = data[offset + j];\n mat.getTranslation(pos);\n mat.getScale(scale);\n rot.setFromMat4(mat);\n rot.normalize();\n poses.push({\n frame,\n position: pos.clone(),\n rotation: rot.clone(),\n scale: scale.clone(),\n });\n }\n const { spline } = rebuildKeyframeSpline(poses, Number.POSITIVE_INFINITY, { includeEnd: true });\n keyframes.set(i, { poses, spline });\n }\n }\n\n filtered.skeletalConverted = true;\n filtered.skeletalStore = { keyframes, manualBones: new Set<number>(), source: 'imported' };\n\n const cache = cacheMap ?? new Map<number, Animation>();\n cache.set(targetBoneCount, filtered);\n animationData.filteredForBones = cache;\n return filtered;\n}\n", "import { Mat4, Quat, Vec3 } from '../../math';\n\nimport { BONE_NAMES, SKELETON_1185_NAMES } from '../skeleton/skeleton-data';\nimport { BONE_NAMES_441 } from '../skeleton/skeleton-data-441';\n\n/**\n * Decoded contents of an *armature GLB* - a glTF 2.0 binary carrying a bone\n * hierarchy, a skin, and one animation clip. Produced by the offline MetaHuman\n * GLB exporter, and readable back after a Blender round-trip.\n *\n * @internal\n */\nexport interface ArmatureGlbAnimation {\n /** Bone matrices in {@link Animation.data} layout: `numFrames * numBones * 16`. */\n data: Float32Array;\n numFrames: number;\n numBones: number;\n /** Bone names in bone-index order (canonical rig order when recognised). */\n boneNames: string[];\n /**\n * Per bone: `1` if the clip drives that bone's translation, `0` if the bone\n * must inherit the armature's rest translation. `undefined` when every bone\n * is driven - which is what a `.anim` file means, since that format cannot\n * say anything else.\n *\n * Derived from the DATA, not from which channels exist: a translation\n * channel whose keys are all equal declares a rest pose, and a channel that\n * varies is motion. See {@link parseArmatureGlbAnimation}.\n */\n translationMask?: Uint8Array;\n /** Source frame rate derived from the main timestamp accessor. */\n frameRate: number;\n /** Clip name as stored in the GLB. */\n animationName: string;\n}\n\nconst GLB_MAGIC = 0x46546c67; // 'glTF'\nconst CHUNK_JSON = 0x4e4f534a; // 'JSON'\nconst CHUNK_BIN = 0x004e4942; // 'BIN\\0'\nconst COMPONENT_FLOAT = 5126;\nconst COMPONENT_SHORT = 5122;\nconst COMPONENTS_PER_TYPE: Record<string, number> = { SCALAR: 1, VEC3: 3, VEC4: 4 };\n/** glTF 2.0 dequantization divisor for `normalized: true` SHORT. */\nconst SHORT_SCALE = 32767;\n\n/** Minimal shape of the glTF JSON fields this reader consumes. */\ninterface Gltf {\n asset?: { version?: string };\n nodes?: Array<{ name?: string; translation?: number[] }>;\n skins?: Array<{ joints?: number[] }>;\n accessors?: Array<{\n bufferView?: number;\n byteOffset?: number;\n componentType?: number;\n normalized?: boolean;\n count?: number;\n type?: string;\n }>;\n bufferViews?: Array<{ byteOffset?: number; byteLength?: number; byteStride?: number }>;\n animations?: Array<{\n name?: string;\n samplers: Array<{ input: number; output: number; interpolation?: string }>;\n channels: Array<{ sampler: number; target: { node?: number; path: string } }>;\n }>;\n}\n\n/**\n * Split a `.glb` container into its JSON chunk and its binary chunk.\n *\n * @throws If the magic, version or chunk layout is not glTF 2.0 binary.\n */\nfunction splitGlb(buffer: ArrayBuffer): { json: Gltf; binOffset: number; binLength: number } {\n if (buffer.byteLength < 20) throw new Error('Not a GLB: file is too short');\n const view = new DataView(buffer);\n if (view.getUint32(0, true) !== GLB_MAGIC) throw new Error('Not a GLB: bad magic');\n const version = view.getUint32(4, true);\n if (version !== 2) throw new Error(`Unsupported GLB version ${version} (expected 2)`);\n\n let json: Gltf | null = null;\n let binOffset = -1;\n let binLength = 0;\n\n let offset = 12;\n while (offset + 8 <= buffer.byteLength) {\n const chunkLength = view.getUint32(offset, true);\n const chunkType = view.getUint32(offset + 4, true);\n const dataStart = offset + 8;\n if (dataStart + chunkLength > buffer.byteLength) throw new Error('Corrupt GLB: chunk overruns file');\n\n if (chunkType === CHUNK_JSON) {\n json = JSON.parse(new TextDecoder().decode(new Uint8Array(buffer, dataStart, chunkLength))) as Gltf;\n } else if (chunkType === CHUNK_BIN) {\n binOffset = dataStart;\n binLength = chunkLength;\n }\n offset = dataStart + chunkLength;\n }\n\n if (!json) throw new Error('Corrupt GLB: no JSON chunk');\n if (binOffset < 0) throw new Error('GLB has no BIN chunk - external buffers are not supported');\n return { json, binOffset, binLength };\n}\n\n/**\n * Read accessor `index` as a flat `Float32Array` of `count * components`.\n *\n * Two encodings are accepted, matching what the MetaHuman GLB exporter\n * emits: plain FLOAT, and `normalized: true` SHORT, dequantized per the glTF\n * rule `f = max(c / 32767, -1)`. Anything else throws by name rather than\n * being reinterpreted as float garbage.\n *\n * Accessors may share a bufferView and address their slice with `byteOffset`.\n * FLOAT takes a zero-copy view when 4-byte aligned (the writer guarantees it);\n * the unaligned path and every SHORT path copy.\n */\nfunction readFloatAccessor(\n json: Gltf,\n buffer: ArrayBuffer,\n binOffset: number,\n index: number,\n expectedType: string,\n): Float32Array {\n const accessor = json.accessors?.[index];\n if (!accessor) throw new Error(`GLB accessor ${index} is missing`);\n if (accessor.type !== expectedType) {\n throw new Error(`GLB accessor ${index} must be ${expectedType} (got ${accessor.type})`);\n }\n if (accessor.bufferView === undefined) {\n throw new Error(`GLB accessor ${index} has no bufferView - sparse accessors are not supported`);\n }\n const bufferView = json.bufferViews?.[accessor.bufferView];\n if (!bufferView) throw new Error(`GLB bufferView ${accessor.bufferView} is missing`);\n if (bufferView.byteStride !== undefined && bufferView.byteStride !== 0) {\n throw new Error('Interleaved (byteStride) animation accessors are not supported');\n }\n\n const components = COMPONENTS_PER_TYPE[expectedType];\n const count = accessor.count ?? 0;\n const length = count * components;\n const start = binOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n\n if (accessor.componentType === COMPONENT_SHORT) {\n if (!accessor.normalized) {\n throw new Error(`GLB accessor ${index} is SHORT but not normalized - refusing to guess a scale`);\n }\n if (start + length * 2 > buffer.byteLength) {\n throw new Error(`GLB accessor ${index} overruns the BIN chunk`);\n }\n const raw = (start & 1) === 0\n ? new Int16Array(buffer, start, length)\n : new Int16Array(buffer.slice(start, start + length * 2));\n const out = new Float32Array(length);\n for (let i = 0; i < length; i++) out[i] = Math.max(raw[i] / SHORT_SCALE, -1);\n return out;\n }\n\n if (accessor.componentType !== COMPONENT_FLOAT) {\n throw new Error(\n `GLB accessor ${index} must be FLOAT or normalized SHORT (got componentType ${accessor.componentType})`,\n );\n }\n if (start + length * 4 > buffer.byteLength) {\n throw new Error(`GLB accessor ${index} overruns the BIN chunk`);\n }\n if ((start & 3) === 0) return new Float32Array(buffer, start, length);\n // Unaligned: copy into a fresh buffer so the typed-array view is legal.\n return new Float32Array(buffer.slice(start, start + length * 4));\n}\n\n/** Rigs the engine knows by name. Order inside each table IS the bone order. */\nconst KNOWN_RIGS: readonly (readonly string[])[] = [BONE_NAMES, BONE_NAMES_441, SKELETON_1185_NAMES];\n\n/**\n * If `jointNames` is one of the engine's known rigs, return the permutation\n * that puts it in that rig's canonical order (`order[bone]` indexes\n * `jointNames`). Returns `null` when no rig matches, in which case the file's\n * own joint order stands.\n *\n * This matters because downstream `filterAnimationForArmature` resolves rigs by\n * NAME but assumes source bone index order matches the engine's table. A\n * Blender round-trip is free to reorder joints, so index order cannot be\n * trusted - the name set can.\n */\nfunction canonicalBoneOrder(jointNames: string[]): number[] | null {\n const indexByName = new Map<string, number>();\n for (let i = 0; i < jointNames.length; i++) indexByName.set(jointNames[i], i);\n if (indexByName.size !== jointNames.length) return null; // duplicate names\n\n for (const table of KNOWN_RIGS) {\n if (table.length !== jointNames.length) continue;\n const order: number[] = [];\n for (const name of table) {\n const i = indexByName.get(name);\n if (i === undefined) break;\n order.push(i);\n }\n if (order.length === table.length) return order;\n }\n return null;\n}\n\n/**\n * How a sampler's output is laid out, per its interpolation mode.\n *\n * CUBICSPLINE stores `[inTangent, value, outTangent]` per keyframe. The Hermite\n * spline passes exactly through `value` at the key's own time, and this reader\n * samples only at key times, so taking the middle element is exact rather than\n * an approximation. Reading it as LINEAR would consume tangents as poses and\n * produce a plausible-but-wrong result, which is why the mode is resolved\n * explicitly and anything unrecognised throws.\n */\nfunction samplerLayout(\n interpolation: string | undefined,\n label: string,\n): { stride: number; offset: number; step: boolean } {\n switch (interpolation ?? 'LINEAR') {\n case 'LINEAR':\n return { stride: 1, offset: 0, step: false };\n case 'STEP':\n return { stride: 1, offset: 0, step: true };\n case 'CUBICSPLINE':\n return { stride: 3, offset: 1, step: false };\n default:\n throw new Error(`${label} uses unsupported interpolation \"${interpolation}\"`);\n }\n}\n\n/** One decoded animation channel, with its own timeline. */\ninterface DecodedChannel {\n values: Float32Array;\n times: Float32Array;\n keys: number;\n stride: number;\n offset: number;\n comps: number;\n step: boolean;\n /** True when key `i` is exactly frame `i` of the main timeline. */\n aligned: boolean;\n}\n\n/** Component `c` of keyframe `k`. */\nfunction keyValue(ch: DecodedChannel, k: number, c: number): number {\n return ch.values[(k * ch.stride + ch.offset) * ch.comps + c];\n}\n\n/**\n * How far a translation channel may wander and still count as a declaration of\n * rest rather than motion: 10 \u00B5m.\n *\n * The distinction cannot be drawn from channel *presence*, because a\n * conformant writer emits a channel for every bone and Blender re-exports\n * dense channels for everything it imports. It is drawn from the values, which\n * survive that round trip: a constant track stays constant however densely it\n * is written.\n *\n * The bound is empirical and has room on both sides. Below it: a Blender\n * 4.2.18 import\u2192export of our own files re-derives every bone through its own\n * matrix pipeline and perturbs a constant translation by at most 7.96e-7 m,\n * 12x under this. Above it: the smallest genuinely moving channel in the same\n * files drifts 3.06e-4 m, 30x over. The writer's own collapse threshold\n * (the exporter's own `TRANSLATION_EPS`, 1e-6 m) sits inside\n * that gap too, so everything it calls constant still reads as constant here,\n * before and after a round trip.\n *\n * Shared with the `.anim` reader ({@link Animation.parse}), which asks the same\n * question of the same quantity, so one number keeps the two formats from ever\n * disagreeing about what \"constant\" means. It has even more room there: a v3\n * `.anim` stores float16, whose decode is deterministic, so a constant track\n * comes back bit-identical (deviation exactly 0) while the smallest moving bone\n * across `test_full` / `test_stripped` / `test_blend_*` drifts 2.69e-4 m. Motion\n * finer than this bound is not representable at bone-offset magnitudes in\n * float16 anyway (one ulp at 0.4 m is 2.4e-4 m), so it has already been\n * quantized flat before the test sees it.\n *\n * @internal\n */\nexport const CONSTANT_TRANSLATION_EPS = 1e-5;\n\n/**\n * The same test for scale, which is dimensionless, so the tolerance stands\n * against the identity it is being compared with. 1e-4 is far above float32\n * noise - Blender writes a scale channel for every bone it exports and ours\n * come back within 3.6e-7 of `1,1,1` - and far below any scale a rig author\n * would notice.\n */\nconst CONSTANT_SCALE_EPS = 1e-4;\n\n/**\n * True when every key of `ch` sits within `eps` of the first - i.e. the channel\n * holds one value for the whole clip.\n *\n * For CUBICSPLINE the tangents are checked too: equal values with a non-zero\n * tangent still bulge between keys, so that is motion, not a constant.\n */\nfunction isConstantChannel(ch: DecodedChannel, eps: number): boolean {\n for (let c = 0; c < ch.comps; c++) {\n const first = keyValue(ch, 0, c);\n for (let k = 1; k < ch.keys; k++) {\n if (Math.abs(keyValue(ch, k, c) - first) > eps) return false;\n }\n }\n if (ch.stride === 3) {\n for (let k = 0; k < ch.keys; k++) {\n for (let c = 0; c < ch.comps; c++) {\n if (Math.abs(ch.values[(k * 3) * ch.comps + c]) > eps) return false; // inTangent\n if (Math.abs(ch.values[(k * 3 + 2) * ch.comps + c]) > eps) return false; // outTangent\n }\n }\n }\n return true;\n}\n\n/**\n * Evaluate a channel at time `t` into `out`.\n *\n * Needed because a channel is not obliged to share the main timeline: Blender\n * collapses a constant track to two STEP keys on a two-entry timeline of its\n * own, and hand-authored files may key anything anywhere. Resampling here is\n * what lets frame `f` mean one instant across every bone downstream.\n */\nfunction evalChannel(ch: DecodedChannel, t: number, out: Float32Array): void {\n const n = ch.keys;\n if (n === 1 || t <= ch.times[0]) {\n for (let c = 0; c < ch.comps; c++) out[c] = keyValue(ch, 0, c);\n return;\n }\n if (t >= ch.times[n - 1]) {\n for (let c = 0; c < ch.comps; c++) out[c] = keyValue(ch, n - 1, c);\n return;\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1;\n if (ch.times[mid] <= t) lo = mid; else hi = mid;\n }\n const t0 = ch.times[lo];\n const t1 = ch.times[lo + 1];\n const dt = t1 - t0;\n const u = dt > 0 ? (t - t0) / dt : 0;\n\n if (ch.stride === 3) {\n // CUBICSPLINE: Hermite between the two keys, using key `lo`'s outTangent\n // and key `lo+1`'s inTangent. Tangents are stored scaled by 1/dt.\n const u2 = u * u;\n const u3 = u2 * u;\n const h00 = 2 * u3 - 3 * u2 + 1;\n const h10 = u3 - 2 * u2 + u;\n const h01 = -2 * u3 + 3 * u2;\n const h11 = u3 - u2;\n for (let c = 0; c < ch.comps; c++) {\n const p0 = ch.values[(lo * 3 + 1) * ch.comps + c];\n const m0 = ch.values[(lo * 3 + 2) * ch.comps + c] * dt;\n const p1 = ch.values[((lo + 1) * 3 + 1) * ch.comps + c];\n const m1 = ch.values[((lo + 1) * 3) * ch.comps + c] * dt;\n out[c] = h00 * p0 + h10 * m0 + h01 * p1 + h11 * m1;\n }\n return;\n }\n if (ch.step) {\n for (let c = 0; c < ch.comps; c++) out[c] = keyValue(ch, lo, c);\n return;\n }\n // LINEAR. Quaternions get a sign fix so the short way round is taken; the\n // caller renormalizes, which turns this into an nlerp.\n let sign = 1;\n if (ch.comps === 4) {\n let dot = 0;\n for (let c = 0; c < 4; c++) dot += keyValue(ch, lo, c) * keyValue(ch, lo + 1, c);\n if (dot < 0) sign = -1;\n }\n for (let c = 0; c < ch.comps; c++) {\n const a = keyValue(ch, lo, c);\n const b = keyValue(ch, lo + 1, c) * sign;\n out[c] = a + (b - a) * u;\n }\n}\n\nfunction decodeChannel(\n json: Gltf,\n buffer: ArrayBuffer,\n binOffset: number,\n sampler: { input: number; output: number; interpolation?: string },\n type: 'VEC3' | 'VEC4',\n label: string,\n mainInput: number,\n numFrames: number,\n): DecodedChannel {\n const { stride, offset, step } = samplerLayout(sampler.interpolation, label);\n const comps = COMPONENTS_PER_TYPE[type];\n const values = readFloatAccessor(json, buffer, binOffset, sampler.output, type);\n const times = readFloatAccessor(json, buffer, binOffset, sampler.input, 'SCALAR');\n const keys = values.length / comps / stride;\n if (!Number.isInteger(keys) || keys !== times.length) {\n throw new Error(\n `${label} has ${values.length / comps} output elements for ${times.length} timestamps `\n + `(interpolation ${sampler.interpolation ?? 'LINEAR'})`,\n );\n }\n if (keys === 0) throw new Error(`${label} has no keyframes`);\n const aligned = sampler.input === mainInput && keys === numFrames;\n return { values, times, keys, stride, offset, comps, step, aligned };\n}\n\n/**\n * Parse an armature GLB into the flat bone-matrix form that {@link Animation}\n * holds after {@link Animation.parse}.\n *\n * **Bones are resolved by NAME, never by node index.** The joint set comes from\n * `skins[0].joints` when a skin is present (files we write, and anything\n * Blender exports), falling back to \"every node is a bone\" for older files\n * that carried no skin. If the joint names match one of the engine's known rigs the bones are\n * re-ordered into that rig's canonical order; otherwise the file's joint order\n * stands. Nodes that are not joints - the armature parent, mesh nodes, cameras,\n * anything a DCC tool adds - are ignored, and so are channels targeting them.\n *\n * What it accepts:\n *\n * - `translation`, `rotation` and `scale` channels; `weights` is ignored,\n * there being no morph targets on an armature.\n * - Rotations as FLOAT or `normalized: true` SHORT (dequantized + renormalized).\n * - `LINEAR`, `STEP` and `CUBICSPLINE` samplers. Other modes throw by name.\n * - Per-channel timelines: each sampler rides either the main timeline - the\n * longest, so frame `f` is the same instant for every bone - or a one-key\n * timeline of its own, meaning a constant channel held for the whole clip.\n * - Accessors sharing one bufferView via `byteOffset`, and absent `min`/`max`.\n *\n * What it requires: exactly one rotation channel per bone, timestamps on a\n * uniform grid (the engine indexes animations by frame, so key `i` must be\n * frame `i`), and no duplicate channels.\n *\n * **Constant translation is a rest declaration, not motion.** A translation\n * channel whose keys are all equal (within {@link CONSTANT_TRANSLATION_EPS})\n * states the rig's own bone length; a channel that varies is real motion -\n * root motion at the pelvis, and the face, which is translation-driven. The\n * former is reported through {@link ArmatureGlbAnimation.translationMask} as a\n * `0`, so playback keeps the TARGET character's rest translation and its limbs\n * do not resize mid-clip. On our own clips that lands on 85 of 441 bones\n * without a single bone name being mentioned anywhere.\n *\n * The test reads the data rather than the channel list on purpose. Absence\n * could carry the same message, but only in a file nobody has touched: a\n * conformant reader is entitled to use `nodes[b].translation` when a channel\n * is missing, and Blender re-exports dense channels for every bone, which\n * erases the distinction. Constancy survives both. Files that genuinely omit\n * the channel - everything written before 2026-08 - are still read the old\n * way, as `0`.\n *\n * Scale gets the same treatment, and resolves at parse time: a constant scale\n * is a rest declaration, and every rig this engine builds rests at scale\n * `1,1,1`, so a constant channel simply resolves to identity here and needs no\n * mask of its own. A varying scale is honoured. Our writers emit no scale\n * channels at all, so this only ever fires for a bone somebody scaled by hand\n * in a DCC tool.\n *\n * @throws If the container, the layout, or an accessor is invalid.\n * @internal\n */\nexport function parseArmatureGlbAnimation(\n buffer: ArrayBuffer,\n animationName?: string,\n): ArmatureGlbAnimation {\n const { json, binOffset } = splitGlb(buffer);\n\n const declaredVersion = json.asset?.version;\n if (declaredVersion !== undefined && !declaredVersion.startsWith('2')) {\n throw new Error(`Unsupported glTF asset version \"${declaredVersion}\"`);\n }\n\n const nodes = json.nodes ?? [];\n if (nodes.length === 0) throw new Error('Armature GLB has no nodes');\n\n // Joint set: the skin when there is one, otherwise every node (the skinless\n // layout this loader shipped with, before the skin was added for Blender).\n const skin = json.skins?.[0];\n let jointNodes = skin?.joints;\n if (jointNodes === undefined) {\n jointNodes = Array.from({ length: nodes.length }, (_, i) => i);\n }\n if (jointNodes.length === 0) throw new Error('Armature GLB skin has no joints');\n for (const node of jointNodes) {\n if (node < 0 || node >= nodes.length) throw new Error(`Skin references node ${node}, out of range`);\n }\n\n const jointNames = jointNodes.map((node, i) => nodes[node].name ?? `#${i}`);\n const order = canonicalBoneOrder(jointNames);\n const boneToNode = order\n ? order.map((jointIdx) => jointNodes[jointIdx])\n : jointNodes.slice();\n const numBones = boneToNode.length;\n // Bone order, which is canonical order when the rig was recognised.\n const boneNames = boneToNode.map((node, i) => nodes[node].name ?? `#${i}`);\n const nodeToBone = new Map<number, number>();\n boneToNode.forEach((node, bone) => nodeToBone.set(node, bone));\n\n const animations = json.animations ?? [];\n if (animations.length === 0) throw new Error('Armature GLB has no animations');\n const animation = animationName === undefined\n ? animations[0]\n : animations.find((a) => a.name === animationName);\n if (!animation) {\n const available = animations.map((a) => a.name ?? '<unnamed>').join(', ');\n throw new Error(`Animation \"${animationName}\" not found in GLB (have: ${available})`);\n }\n\n // Resolve channels by target. Channels aimed at non-joint nodes are skipped,\n // not fatal - a DCC tool may animate the armature object or a camera.\n const translationOf = new Int32Array(numBones).fill(-1);\n const rotationOf = new Int32Array(numBones).fill(-1);\n const scaleOf = new Int32Array(numBones).fill(-1);\n for (const channel of animation.channels) {\n const node = channel.target.node;\n if (node === undefined) continue;\n const bone = nodeToBone.get(node);\n if (bone === undefined) continue;\n const sampler = animation.samplers[channel.sampler];\n if (!sampler) throw new Error(`Animation channel references missing sampler ${channel.sampler}`);\n const slot = channel.target.path === 'translation' ? translationOf\n : channel.target.path === 'rotation' ? rotationOf\n : channel.target.path === 'scale' ? scaleOf\n : null; // 'weights' ignored - no morph targets here\n if (slot === null) continue;\n if (slot[bone] >= 0) {\n throw new Error(`Bone ${bone} (\"${boneNames[bone]}\") has two ${channel.target.path} channels`);\n }\n slot[bone] = channel.sampler;\n }\n\n // A rotation channel is mandatory; translation and scale are not. The mask is\n // filled in below, once each channel has been decoded and can be asked\n // whether it varies - absence is only one of the two ways a bone ends up\n // inheriting its rest translation.\n const translationMask = new Uint8Array(numBones);\n let restBones = 0;\n for (let bone = 0; bone < numBones; bone++) {\n if (rotationOf[bone] < 0) {\n throw new Error(`Bone ${bone} (\"${boneNames[bone]}\") is missing a rotation channel`);\n }\n }\n\n // The main timeline is the longest sampler input. Constant channels ride a\n // one-key timeline of their own; anything else would make frame `f` mean\n // different instants for different bones.\n let timeAccessor = -1;\n let numFrames = 0;\n for (const sampler of animation.samplers) {\n const count = json.accessors?.[sampler.input]?.count ?? 0;\n if (count > numFrames) {\n numFrames = count;\n timeAccessor = sampler.input;\n }\n }\n if (timeAccessor < 0 || numFrames === 0) throw new Error('Animation has no keyframes');\n\n const times = readFloatAccessor(json, buffer, binOffset, timeAccessor, 'SCALAR');\n const span = numFrames > 1 ? times[numFrames - 1] - times[0] : 0;\n const frameRate = span > 0 ? (numFrames - 1) / span : 30;\n\n // Playback is frame-indexed: key `i` must BE frame `i`. A non-uniform grid\n // would still load, but every frame after the first irregular key would sit\n // at the wrong instant, so refuse it instead.\n if (numFrames > 2 && span > 0) {\n const step = span / (numFrames - 1);\n let worst = 0;\n for (let i = 0; i < numFrames; i++) {\n worst = Math.max(worst, Math.abs(times[i] - (times[0] + i * step)));\n }\n if (worst > step * 0.5) {\n throw new Error(\n `Animation timestamps are not on a uniform grid (off by up to ${worst.toFixed(4)}s `\n + `against a ${step.toFixed(4)}s step); resampling is not supported`,\n );\n }\n }\n\n // Pack absolute parent-local TRS into 4x4 matrices, matching the element\n // layout `.anim` uses (translation at indices 12..14). convertSkeletalAnimation\n // decomposes these straight back to TRS, so the round-trip is lossless.\n const data = new Float32Array(numFrames * numBones * 16);\n const matrix = new Mat4();\n const position = new Vec3();\n const rotation = new Quat();\n const scale = new Vec3(1, 1, 1);\n const scratch3 = new Float32Array(3);\n const scratch3b = new Float32Array(3);\n const scratch4 = new Float32Array(4);\n\n for (let bone = 0; bone < numBones; bone++) {\n const name = boneNames[bone];\n const rot = decodeChannel(\n json, buffer, binOffset, animation.samplers[rotationOf[bone]], 'VEC4',\n `Bone ${bone} (\"${name}\") rotation`, timeAccessor, numFrames,\n );\n const trans = translationOf[bone] >= 0\n ? decodeChannel(\n json, buffer, binOffset, animation.samplers[translationOf[bone]], 'VEC3',\n `Bone ${bone} (\"${name}\") translation`, timeAccessor, numFrames,\n )\n : null;\n let scaleCh = scaleOf[bone] >= 0\n ? decodeChannel(\n json, buffer, binOffset, animation.samplers[scaleOf[bone]], 'VEC3',\n `Bone ${bone} (\"${name}\") scale`, timeAccessor, numFrames,\n )\n : null;\n\n // Here is the whole decision. A channel that varies drives the bone; a\n // channel that holds still is stating the source rig's rest, which the\n // target character's own rest must override.\n if (trans !== null && !isConstantChannel(trans, CONSTANT_TRANSLATION_EPS)) {\n translationMask[bone] = 1;\n } else {\n restBones++;\n }\n // A constant scale resolves to identity right here rather than to a mask:\n // every rig the engine builds rests at scale 1,1,1 (see `Skeleton.restPose`),\n // so there is no per-character value to defer to and nothing to carry.\n if (scaleCh !== null && isConstantChannel(scaleCh, CONSTANT_SCALE_EPS)) scaleCh = null;\n\n // The packed matrix still needs *a* translation to stay a geometrically\n // valid local transform for anything that walks `data` directly (debug FK,\n // tooling). When the channel is present its value is used verbatim, which\n // is what a conformant glTF reader does and what `translationMask` then\n // overrides at playback. When it is absent - a pre-2026-08 file - the node\n // rest stands in.\n const rest = nodes[boneToNode[bone]].translation;\n const restX = rest?.[0] ?? 0;\n const restY = rest?.[1] ?? 0;\n const restZ = rest?.[2] ?? 0;\n\n for (let frame = 0; frame < numFrames; frame++) {\n const t = times[frame];\n if (!trans) {\n position.set(restX, restY, restZ);\n } else if (trans.aligned) {\n const i = (frame * trans.stride + trans.offset) * trans.comps;\n position.set(trans.values[i], trans.values[i + 1], trans.values[i + 2]);\n } else {\n evalChannel(trans, t, scratch3);\n position.set(scratch3[0], scratch3[1], scratch3[2]);\n }\n\n if (!scaleCh) {\n scale.set(1, 1, 1);\n } else if (scaleCh.aligned) {\n const i = (frame * scaleCh.stride + scaleCh.offset) * scaleCh.comps;\n scale.set(scaleCh.values[i], scaleCh.values[i + 1], scaleCh.values[i + 2]);\n } else {\n evalChannel(scaleCh, t, scratch3b);\n scale.set(scratch3b[0], scratch3b[1], scratch3b[2]);\n }\n\n // glTF stores quaternions xyzw, the same order as `Quat`.\n // Dequantized int16 and interpolated values sit slightly off the unit\n // sphere and setTRS assumes unit - renormalize. A no-op for an\n // already-unit FLOAT quaternion read straight off an aligned key.\n if (rot.aligned) {\n const j = (frame * rot.stride + rot.offset) * rot.comps;\n rotation.set(rot.values[j], rot.values[j + 1], rot.values[j + 2], rot.values[j + 3]);\n } else {\n evalChannel(rot, t, scratch4);\n rotation.set(scratch4[0], scratch4[1], scratch4[2], scratch4[3]);\n }\n rotation.normalize();\n matrix.setTRS(position, rotation, scale);\n data.set(matrix.data, (frame * numBones + bone) * 16);\n }\n }\n\n return {\n data,\n numFrames,\n numBones,\n boneNames,\n // Every bone genuinely translates: say nothing, which is what `.anim` means\n // and what every consumer already treats as \"drive them all\".\n translationMask: restBones === 0 ? undefined : translationMask,\n frameRate,\n animationName: animation.name ?? '<unnamed>',\n };\n}\n", "const CACHE_NAME = 'viggle-asset-cache';\nconst MAX_TTL_MS = 60 * 60 * 1000;\nconst EXPIRES_HEADER = 'X-Viggle-Cache-Expires';\n\n// Extensions that must never be persisted (bypass all caching). Empty now that\n// `.ply` character/map splats are cached like `.spz` - kept as the hook for any\n// future no-store asset type.\nconst NO_STORE_EXTENSIONS = new Set<string>([]);\n\n// Extensions whose assets share one cache entry across rotating CDN URLs (e.g.\n// Cloudflare query-string cache busters): for these, a signed URL's query\n// string is dropped from the cache key, so the same bytes re-signed under a\n// fresh token still hit. Anything else is cached under its full URL including\n// query string.\nconst PATH_NORMALIZED_EXTENSIONS = new Set([\n '.anim',\n '.bin',\n '.glb',\n '.gltf',\n '.jpg',\n '.jpeg',\n '.mp3',\n '.ogg',\n '.opus',\n '.ply',\n '.png',\n '.spz',\n // VIGGCHAR v1 character bundles. Without this a signed `.vsplat` URL is\n // keyed on its rotating token, so the Cache API never hits AND (see the\n // store gate below) the bytes are never persisted at all - every reload\n // re-downloads a multi-MB character.\n '.vsplat',\n '.webp',\n]);\n\nlet cachePromise: Promise<Cache | null> | null = null;\n\nfunction getCache(): Promise<Cache | null> {\n if (!cachePromise) {\n cachePromise = (typeof caches !== 'undefined')\n ? caches.open(CACHE_NAME).catch(() => null)\n : Promise.resolve(null);\n }\n return cachePromise;\n}\n\nfunction getPathname(url: string): string {\n return (() => {\n try {\n return new URL(url, globalThis.location?.href).pathname;\n } catch {\n return url.split(/[?#]/, 1)[0] ?? url;\n }\n })().toLowerCase();\n}\n\nfunction hasExtension(url: string, extensions: Set<string>): boolean {\n const pathname = getPathname(url);\n for (const ext of extensions) {\n if (pathname.endsWith(ext)) return true;\n }\n return false;\n}\n\nfunction isNoStoreAsset(url: string): boolean {\n return hasExtension(url, NO_STORE_EXTENSIONS);\n}\n\n/** Detect signed CDN URLs that rotate tokens (Cloudflare ?verify=, AWS S3 ?X-Amz-). */\nfunction hasSignedQueryParams(url: string): boolean {\n const q = url.indexOf('?');\n if (q === -1) return false;\n const query = url.slice(q + 1).toLowerCase();\n return query.includes('verify=') || query.includes('x-amz-');\n}\n\nfunction cacheKeyFor(url: string): string {\n const pathname = getPathname(url);\n // Only strip query params for signed CDN URLs with rotating tokens\n const isSignedUrl = hasSignedQueryParams(url);\n const normalize = isSignedUrl && hasExtension(pathname, PATH_NORMALIZED_EXTENSIONS);\n if (normalize && typeof globalThis.location !== 'undefined') {\n return new URL(`/__viggle_asset_cache__${pathname}`, globalThis.location.href).href;\n }\n return url;\n}\n\nfunction stripCacheControlHeaders(init?: RequestInit): Headers {\n const headers = new Headers(init?.headers);\n headers.delete('If-None-Match');\n headers.delete('If-Modified-Since');\n headers.set('Cache-Control', 'no-store');\n headers.set('Pragma', 'no-cache');\n return headers;\n}\n\n/**\n * Absolute ms timestamp when a freshly-fetched response should expire.\n * Honors positive `Cache-Control: max-age=N` and `Expires:` values from the\n * server, capped at 1 hour. Returns 0 only for `no-store` (the server\n * explicitly forbids persisting the bytes anywhere) - never persisted.\n *\n * `no-cache` is deliberately NOT treated the same as `no-store`: per HTTP\n * semantics it means \"store this, but revalidate with the server before\n * reusing it\", not \"don't store it\". This loader is an app-owned asset\n * byte-cache, not an HTTP-spec-compliant shared cache, and every asset it\n * handles is immutable (a given URL's bytes never change), so revalidation\n * has no purpose here - the default 1-hour TTL is safe to apply instead of\n * refusing to cache at all. This matters in practice: dev servers (e.g.\n * Vite's static middleware) commonly send `Cache-Control: no-cache` on\n * every asset, which - before this fix - meant a cache-presence check could\n * never return true and any \"reload finer detail once cached\" flow was\n * permanently a no-op in local dev, regardless of how many times the same\n * URL was fetched.\n *\n * CDN asset URLs sometimes send `private,max-age=0`; those are also safe to\n * keep in our app-owned Cache API store for the default TTL, and already\n * fall through to it below (ageMs=0 skips the max-age branch).\n */\nfunction computeExpiryMs(res: Response): number {\n const cc = res.headers.get('cache-control') ?? '';\n const lower = cc.toLowerCase();\n if (lower.includes('no-store')) return 0;\n\n const maxAgeMatch = /(?:^|,)\\s*max-age\\s*=\\s*(\\d+)/i.exec(cc);\n if (maxAgeMatch) {\n const ageMs = Number(maxAgeMatch[1]) * 1000;\n if (ageMs > 0) return Date.now() + Math.min(ageMs, MAX_TTL_MS);\n }\n\n const expires = res.headers.get('expires');\n if (expires) {\n const t = Date.parse(expires);\n if (Number.isFinite(t)) {\n const ttl = t - Date.now();\n if (ttl <= 0) return 0;\n return Date.now() + Math.min(ttl, MAX_TTL_MS);\n }\n }\n\n return Date.now() + MAX_TTL_MS;\n}\n\nasync function stampWithExpiry(res: Response, expiry: number): Promise<Response> {\n const headers = new Headers(res.headers);\n headers.set(EXPIRES_HEADER, String(expiry));\n const body = await res.arrayBuffer();\n return new Response(body, {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n}\n\nfunction isExpired(cached: Response): boolean {\n const stamp = Number(cached.headers.get(EXPIRES_HEADER) ?? 0);\n if (!stamp) return true;\n return Date.now() >= stamp;\n}\n\n/**\n * Fetch through a persistent Cache API layer with a 1-hour TTL.\n * - Assets with cacheable extensions (.bin, .vsplat, .anim, .ply, \u2026) \u2192\n * cached in Cache API\n * - Signed URLs (with ?verify= or ?X-Amz-) \u2192 query stripped for cache key\n * - No-store assets \u2192 never persisted. `NO_STORE_EXTENSIONS` is empty\n * today, so nothing takes this branch; see its declaration.\n * Server `Cache-Control: max-age` and `Expires` headers are honored as a cap\n * when they provide a positive TTL.\n * On network error, a stale cached copy is returned in preference to throwing.\n */\nasync function cachedFetch(url: string, init?: RequestInit): Promise<Response> {\n // No-store assets bypass all caching\n if (isNoStoreAsset(url)) {\n return fetch(url, {\n ...init,\n cache: 'no-store',\n headers: stripCacheControlHeaders(init),\n });\n }\n\n // Only cache assets with known cacheable extensions\n if (!hasExtension(url, PATH_NORMALIZED_EXTENSIONS)) {\n return fetch(url, init);\n }\n\n // Cache API with query-stripped key for signed URLs, full URL otherwise\n const cacheKey = cacheKeyFor(url);\n const cache = await getCache();\n\n if (!cache) {\n return fetch(url, init);\n }\n\n const cached = await cache.match(cacheKey);\n if (cached && !isExpired(cached)) return cached;\n\n let res: Response;\n try {\n res = await fetch(url, init);\n } catch (err) {\n if (cached) return cached;\n throw err;\n }\n\n if (res.ok) {\n const expiry = computeExpiryMs(res);\n if (expiry > 0) {\n stampWithExpiry(res.clone(), expiry)\n .then((stamped) => cache.put(cacheKey, stamped))\n .catch(() => {});\n } else if (cached) {\n cache.delete(cacheKey).catch(() => {});\n }\n }\n return res;\n}\n\n/**\n * Sweep the persistent cache and delete every entry whose stamp is in the\n * past. Intended to run once per app boot, non-blocking, to keep the Cache\n * API store from accumulating dead entries across sessions.\n */\nasync function evictExpired(): Promise<number> {\n const cache = await getCache();\n if (!cache) return 0;\n const keys = await cache.keys();\n let removed = 0;\n await Promise.all(keys.map(async (req) => {\n const res = await cache.match(req);\n if (res && isExpired(res)) {\n const ok = await cache.delete(req);\n if (ok) removed++;\n }\n }));\n return removed;\n}\n\nexport { cachedFetch, evictExpired };\n", "import type { Quat, Vec3 } from './math';\n\nimport { convertSkeletalAnimation } from './anim/animation-conversion';\nimport type { CubicSpline } from './anim/spline';\nimport { CONSTANT_TRANSLATION_EPS, parseArmatureGlbAnimation } from './loader/animation/animation-glb';\nimport { cachedFetch } from './loader/shared/bin-cache';\nimport type { SplatEngine } from './engine';\n\n/**\n * A frame-aligned event attached to an {@link Animation}. Events are fired by\n * {@link AnimationPlayer} as `animTime` crosses each `frame`, dispatched\n * through {@link Armature.onAnimEvent} / {@link Character.onAnimEvent}.\n *\n * The engine treats `name` and `payload` as opaque - games define their own\n * vocabulary (e.g. `'footstep'`, `'hit-impact'`, `'screen-shake'`) and route\n * via the listener.\n *\n * @group Characters & Animation\n */\nexport interface AnimationEvent {\n /** Frame index (integer, `0 .. numFrames-1`). */\n frame: number;\n /** Game-defined event name. */\n name: string;\n /** Optional game-defined payload, opaque to the engine. */\n payload?: unknown;\n}\n\n/**\n * Per-bone keyframe entry inside a {@link SkeletalStore}.\n * @internal\n */\nexport interface SkeletalKeyframeEntry {\n poses: Array<{ frame: number; position: Vec3; rotation: Quat; scale: Vec3 }>;\n spline: CubicSpline | null;\n}\n\n/**\n * Engine-private cache attached to an {@link Animation} after\n * {@link convertSkeletalAnimation} processes the raw matrices into\n * per-bone keyframes + splines. Subsequent registrations and playback reads\n * go through this store rather than re-walking the raw `Float32Array`.\n *\n * @internal\n */\nexport interface SkeletalStore {\n keyframes: Map<number, SkeletalKeyframeEntry>;\n manualBones: Set<number>;\n source: string;\n}\n\n/**\n * Expand Float16 (IEEE 754 half-precision) stored as Uint16 into Float32.\n */\nfunction float16ToFloat32(u16: Uint16Array): Float32Array {\n const out = new Float32Array(u16.length);\n for (let i = 0; i < u16.length; i++) {\n const h = u16[i];\n const sign = (h >>> 15) & 0x1;\n const exp = (h >>> 10) & 0x1f;\n const mant = h & 0x3ff;\n\n let val: number;\n if (exp === 0) {\n val = mant === 0 ? 0 : 5.960464477539063e-8 * mant;\n } else if (exp === 31) {\n val = mant === 0 ? Infinity : NaN;\n } else {\n val = Math.pow(2, exp - 15) * (1 + mant / 1024);\n }\n out[i] = sign ? -val : val;\n }\n return out;\n}\n\n/**\n * Element offset of the translation inside one packed column-major 4x4 bone\n * matrix: the layout `convertSkeletalAnimation` reads back with\n * `Mat4.getTranslation`, which is `data[12..14]`.\n */\nconst MATRIX_TRANSLATION = 12;\n\n/**\n * Derive {@link Animation.translationMask} from decoded `.anim` matrices.\n *\n * Same question the armature-GLB reader asks of its translation channels, asked\n * of the same quantity in its other storage form: does this bone's translation\n * *move* over the clip? A track that holds still is not motion, it is the source\n * rig stating its own bone length, and the target character's rest must win.\n *\n * A `.anim` frame carries a full local matrix per bone, so every bone always has\n * a translation and the \"channel absent\" half of the GLB test has no analogue\n * here, so constancy is the whole test. On our own clips it lands on the pelvis\n * alone for a body rig, and on the pelvis plus the translation-driven face for a\n * facial rig, without naming a single bone.\n *\n * Sparse clips are scanned on `keyframeFrames` only, matching the frames\n * `convertSkeletalAnimation` converts; the gaps between keyframes hold nothing\n * anyone reads.\n *\n * Degenerate clips fall out of the same rule rather than being special-cased: a\n * single-frame clip, or one where nothing translates at all, has no evidence of\n * motion anywhere, so every bone reads as a rest declaration and the whole mask\n * is `0`. The pose still plays, and every bone length comes from the character.\n * Returns `undefined` when every bone genuinely translates, which is the \"drive\n * them all\" the mask's absence has always meant.\n */\nfunction deriveTranslationMask(\n data: Float32Array,\n numFrames: number,\n numBones: number,\n keyframeFrames?: number[],\n): Uint8Array | undefined {\n const frames = keyframeFrames?.length\n ? keyframeFrames.filter((f) => f >= 0 && f < numFrames)\n : Array.from({ length: numFrames }, (_, i) => i);\n if (numBones === 0 || frames.length === 0) return undefined;\n // A pre-converted clip carries its poses in `skeletalStore` and an EMPTY data\n // array (`filterAnimationForArmature`). Reading it would compare `undefined`s,\n // every comparison would be false, and the clip would come back \"nothing\n // translates\" - freezing every bone at rest. No data means no evidence, which\n // is `undefined`, not an all-rest mask.\n if (data.length === 0) return undefined;\n\n const mask = new Uint8Array(numBones);\n let restBones = 0;\n for (let bone = 0; bone < numBones; bone++) {\n const first = (frames[0] * numBones + bone) * 16 + MATRIX_TRANSLATION;\n const x = data[first];\n const y = data[first + 1];\n const z = data[first + 2];\n let varies = false;\n for (let i = 1; i < frames.length; i++) {\n const o = (frames[i] * numBones + bone) * 16 + MATRIX_TRANSLATION;\n if (Math.abs(data[o] - x) > CONSTANT_TRANSLATION_EPS\n || Math.abs(data[o + 1] - y) > CONSTANT_TRANSLATION_EPS\n || Math.abs(data[o + 2] - z) > CONSTANT_TRANSLATION_EPS) {\n varies = true;\n break;\n }\n }\n if (varies) mask[bone] = 1;\n else restBones++;\n }\n return restBones === 0 ? undefined : mask;\n}\n\n/**\n * Parsed skeletal animation data.\n *\n * An `Animation` is the deserialized form of one clip, whatever it was\n * authored as. It holds a flat `Float32Array` of per-bone 4\u00D74 matrices indexed\n * by frame and bone. Once registered on an engine under a name, characters can play\n * it via {@link Character.playAnimation} / {@link Character.crossfadeTo}.\n *\n * The primary entry point is {@link Animation.loadGlb}, which fetches a\n * MetaHuman GLB, parses and registers it in one call. For custom fetch\n * pipelines, use {@link Animation.fromGlb} on an already-fetched\n * `ArrayBuffer`, then {@link Animation#register} to attach it to the engine.\n * The `.anim` container is still read, by {@link Animation.load} and\n * {@link Animation.parse}.\n *\n * @group Characters & Animation\n */\nexport class Animation {\n /** Column-major bone matrices (translation at `[12..14]`, the layout\n * `THREE.Matrix4.elements` uses), length `numFrames * numBones * 16`. */\n data: Float32Array;\n /** Number of animation frames. */\n numFrames: number;\n /** Number of bones per frame. */\n numBones: number;\n /** Optional sparse keyframe indices. If present, frames between keyframes are interpolated. */\n keyframeFrames?: number[];\n /**\n * Per bone: `1` if this clip drives the bone's translation, `0` if the bone\n * must keep the armature's own rest translation.\n *\n * A constant translation track is not motion - it is the source rig's bone\n * length. Applied to a character whose skeleton differs, it silently replaces\n * that character's bone lengths mid-clip while the bind pose keeps the\n * originals, which compresses the skin. Both readers are built with that in\n * mind and set a `0` for every bone whose translation holds still, judged from\n * the decoded data: {@link Animation.fromGlb} per channel, {@link Animation.parse}\n * across the per-frame matrices. `undefined` means every bone genuinely\n * translates, and every bone drives its own translation.\n *\n * Set once, at parse time, and never mutated afterwards. Playback caches\n * keyframes per `Animation` object, so a mask that could change would go stale\n * inside them. `filterAnimationForArmature` remaps rather than edits, onto a\n * new `Animation` that is its own cache key.\n *\n * Consumed by `buildArmatureKeyframes`, which zeroes the position delta for\n * masked bones so `fromRestRelative` yields `pose.position = restPosition`.\n */\n translationMask?: Uint8Array;\n /**\n * Frame-aligned events fired as `animTime` advances. Set by\n * {@link Animation.parse} from the `.anim` header's optional `events` array,\n * or assigned directly by game code before {@link Animation.register}.\n */\n events?: AnimationEvent[];\n /** @internal Set by convertSkeletalAnimation on first registration. */\n /** The clip's own name, where its file gave one. Not the name it is registered under. */\n name = '';\n /** Frames per second the clip was authored at. `30` unless the file says otherwise. */\n frameRate = 30;\n /** The name of the most recent {@link Animation.register}, if any. */\n registeredName?: string;\n private _registeredIn: SplatEngine | null = null;\n\n /** Length in seconds at the authored frame rate. */\n get duration(): number {\n return this.frameRate > 0 ? this.numFrames / this.frameRate : 0;\n }\n\n skeletalConverted = false;\n /** @internal Per-bone keyframe cache produced by convertSkeletalAnimation. */\n skeletalStore?: SkeletalStore;\n /** @internal Per-target-bone-count cache of `filterAnimationForArmature` outputs. */\n filteredForBones?: Map<number, Animation>;\n\n constructor(data: Float32Array, numFrames: number, numBones: number, keyframeFrames?: number[]) {\n this.data = data;\n this.numFrames = numFrames;\n this.numBones = numBones;\n this.keyframeFrames = keyframeFrames;\n // Derived HERE, not at each call site, so \"an Animation knows which bones it\n // actually drives\" holds by construction. It was previously set only by\n // `parse` and `fromGlb`, which left the `.bin`-embedded clip built in\n // `Character._buildFromLoadResult` with no mask at all - under\n // `restSource: 'bundled'` that clip silently reimposed the canonical bone\n // lengths on a character whose bind is its own.\n //\n // Callers that know better still override on the next line: `fromGlb` has\n // the real glTF channel list (a channel that is absent differs from one\n // whose keys happen to be equal), and `filterAnimationForArmature` remaps\n // the source mask through its bone mapping. Both assign unconditionally, so\n // this pass is at worst redundant for them, never wrong.\n this.translationMask = deriveTranslationMask(data, numFrames, numBones, keyframeFrames);\n }\n\n /**\n * Parse an in-memory `.anim` buffer.\n *\n * Accepts both v2 (float32) and v3 (float16) data encodings. Use this when\n * fetching through a custom pipeline; pair with {@link Animation#register}\n * to make the result playable. Otherwise prefer {@link Animation.load}, the\n * fetching wrapper around this one. For a MetaHuman GLB, the current\n * container, the pair is {@link Animation.fromGlb} / {@link Animation.loadGlb}.\n *\n * Also derives {@link Animation#translationMask} from the decoded matrices, so\n * bones whose translation never moves keep the *target* character's bone\n * lengths instead of the source rig's.\n *\n * @throws If the header is missing, malformed, or not of type `skeletal_animation`.\n */\n static parse(buffer: ArrayBuffer): Animation {\n const view = new DataView(buffer);\n const headerLength = view.getUint32(0, true);\n\n if (headerLength > 10000 || headerLength > buffer.byteLength - 4) {\n throw new Error(`Invalid animation file: header length ${headerLength} out of range`);\n }\n\n const headerBytes = new Uint8Array(buffer, 4, headerLength);\n const headerJson = new TextDecoder().decode(headerBytes);\n\n let header: {\n type?: string;\n version?: number;\n numFrames: number;\n numBones: number;\n dataType?: string;\n keyframeFrames?: number[];\n events?: AnimationEvent[];\n };\n try {\n header = JSON.parse(headerJson);\n } catch {\n throw new Error('Invalid animation file: header is not valid JSON');\n }\n\n if (header.type !== 'skeletal_animation') {\n throw new Error(`Invalid animation type: '${header.type}'`);\n }\n\n const dataOffset = 4 + headerLength;\n const dataLength = buffer.byteLength - dataOffset;\n if (dataLength <= 0) throw new Error('Animation file has no data');\n\n const dataBytes = new Uint8Array(buffer, dataOffset, dataLength);\n const alignedBuffer = new ArrayBuffer(dataLength);\n new Uint8Array(alignedBuffer).set(dataBytes);\n\n let animData: Float32Array;\n if (header.dataType === 'float16') {\n animData = float16ToFloat32(new Uint16Array(alignedBuffer));\n } else {\n animData = new Float32Array(alignedBuffer);\n }\n\n // The constructor derives `translationMask` from exactly these arguments.\n const anim = new Animation(animData, header.numFrames, header.numBones, header.keyframeFrames);\n if (Array.isArray(header.events) && header.events.length > 0) {\n anim.events = header.events;\n }\n return anim;\n }\n\n /**\n * Parse an in-memory *MetaHuman GLB* - a glTF 2.0 binary holding a bone\n * hierarchy and one animation clip, carrying no real geometry (as produced\n * by the offline MetaHuman GLB exporter).\n *\n * The result is indistinguishable from {@link Animation.parse} output: the\n * clip's absolute parent-local TRS is packed into the same flat 4x4 bone\n * matrices, so every downstream stage - `convertSkeletalAnimation`,\n * `filterAnimationForArmature`, `AnimationPlayer` - behaves exactly as it\n * does for a `.anim`.\n *\n * `animationName` selects a clip by name when the GLB holds more than one;\n * omitted, the first clip is used. Pair with {@link Animation#register} to\n * make the result playable, or use {@link Animation.loadGlb}.\n *\n * @throws If the container is not GLB 2.0, or the clip does not supply a\n * translation and a rotation channel for every bone on one shared timeline.\n */\n static fromGlb(buffer: ArrayBuffer, animationName?: string): Animation {\n const animation = Animation.parseGlb(buffer, animationName);\n if (Math.abs(animation.frameRate - 30) > 0.5) {\n console.warn(\n `[Animation] GLB \"${animation.name}\" is authored at ${animation.frameRate.toFixed(2)} fps; ` +\n 'playback is frame-indexed and defaults to 30 - set `armature.frameRate` to match.',\n );\n }\n return animation;\n }\n\n /**\n * {@link Animation.fromGlb} without the frame-rate warning: the clip's own\n * rate is recorded on {@link Animation.frameRate} for a caller that applies it.\n * @internal\n */\n static parseGlb(buffer: ArrayBuffer, animationName?: string): Animation {\n const parsed = parseArmatureGlbAnimation(buffer, animationName);\n const animation = new Animation(parsed.data, parsed.numFrames, parsed.numBones);\n animation.translationMask = parsed.translationMask;\n // Key times are float32 seconds, so 30 fps comes back as 29.999998. Snap\n // to the whole rate the clip was plainly authored at.\n const whole = Math.round(parsed.frameRate);\n animation.frameRate = Math.abs(parsed.frameRate - whole) < 0.01 ? whole : parsed.frameRate;\n animation.name = parsed.animationName;\n return animation;\n }\n\n /**\n * Fetch, parse, and register a `.anim` file on the engine under `name`.\n *\n * After this resolves, characters can play it via\n * `character.playAnimation(name)` / `character.crossfadeTo(name)`.\n *\n * @throws If the network request fails or the file is not a valid animation.\n * @example\n * ```ts\n * await Animation.load(engine, '/assets/idle.anim', 'idle');\n * character.playAnimation('idle', { loop: true });\n * ```\n */\n static async load(engine: SplatEngine, url: string, name: string): Promise<Animation> {\n const buffer = await Animation._fetchBuffer(url);\n const animation = Animation.parse(buffer);\n animation.register(engine, name);\n return animation;\n }\n\n /**\n * Fetch, parse, and register a MetaHuman GLB on the engine under `name`.\n * The GLB counterpart of {@link Animation.load}.\n *\n * `animationName` selects a clip inside the GLB by name; omitted, the first\n * clip is used. After this resolves, characters can play it via\n * `character.playAnimation(name)` / `character.crossfadeTo(name)` - the\n * source format is invisible from that point on.\n *\n * @throws If the network request fails or the GLB is not a valid armature clip.\n * @example\n * ```ts\n * await Animation.loadGlb(engine, '/assets/metahuman_full.glb', 'walk');\n * character.playAnimation('walk', { loop: true });\n * ```\n */\n static async loadGlb(\n engine: SplatEngine,\n url: string,\n name: string,\n animationName?: string,\n ): Promise<Animation> {\n const buffer = await Animation._fetchBuffer(url);\n const animation = Animation.fromGlb(buffer, animationName);\n animation.register(engine, name);\n return animation;\n }\n\n /**\n * Process-wide ArrayBuffer cache for .anim URLs. Each `SplatEngine` still\n * gets its own parsed `Animation` (storage arrays are mutated by the\n * skeletal converter so they're not safely shareable across scenes),\n * but the network bytes are shared. Avoids re-downloading the same\n * idle/walk clips every time the app swaps one engine for another.\n */\n private static _bufferCache = new Map<string, ArrayBuffer>();\n private static _bufferLoading = new Map<string, Promise<ArrayBuffer>>();\n\n private static async _fetchBuffer(url: string): Promise<ArrayBuffer> {\n // Strip query for in-memory cache key (signed CDN URLs rotate tokens)\n const key = url.indexOf('?') === -1 ? url : url.slice(0, url.indexOf('?'));\n\n const cached = Animation._bufferCache.get(key);\n if (cached) return cached;\n const inflight = Animation._bufferLoading.get(key);\n if (inflight) return inflight;\n\n // Use cachedFetch for persistent caching (Cache API), then store in-memory\n const promise = cachedFetch(url).then(async (res) => {\n if (!res.ok) throw new Error(`Failed to fetch animation: ${res.statusText}`);\n const buf = await res.arrayBuffer();\n Animation._bufferCache.set(key, buf);\n return buf;\n }).finally(() => {\n Animation._bufferLoading.delete(key);\n });\n Animation._bufferLoading.set(key, promise);\n return promise;\n }\n\n /**\n * Convert the animation data against the engine's skeleton library and\n * register it under `name` so characters can play it.\n *\n * Must be called before {@link Character.playAnimation} / {@link Character.crossfadeTo}\n * reference this animation.\n */\n register(engine: SplatEngine, name: string): void {\n convertSkeletalAnimation(this, engine.skeletonLibrary);\n engine.skeletalAnimationLibrary.set(name, this);\n this.registeredName = name;\n this._registeredIn = engine;\n }\n\n /**\n * Remove the clip from the engine it is registered with, so it can be\n * garbage-collected once nothing is playing it. A character already playing\n * the clip keeps playing; starting it again registers it afresh.\n */\n dispose(): void {\n if (this._registeredIn && this.registeredName !== undefined) {\n this._registeredIn.skeletalAnimationLibrary.delete(this.registeredName);\n }\n this._registeredIn = null;\n this.registeredName = undefined;\n }\n}\n", "import { Group } from 'three';\nimport type { Frustum } from 'three';\n\nimport { Mat4, Quat, Vec3 } from './math';\n\nimport {\n convertSkeletalAnimation,\n filterAnimationForArmature,\n} from './anim/animation-conversion';\nimport type { SplatEngine } from './engine';\nimport { AnimationPlayer } from './skeletal/animation-player';\nimport type { AnimEventCallback, AnimationProvider } from './skeletal/animation-player';\nimport type { BoneMask } from './skeletal/bone-mask';\nimport { computeBoneStretch } from './skeletal/bone-stretch';\nimport type { BoneScaleInput } from './skeletal/bone-stretch';\nimport { Pose } from './skeletal/pose';\nimport { Skeleton } from './skeletal/skeleton';\nimport { SplatSkinning } from './skeletal/splat-skinning';\nimport type { Splat } from './splat/splat';\nimport type { ArmatureData } from './types';\n\n/**\n * Distance-based animation-LOD knobs. Used as the engine-wide preset\n * (`SplatEngine.animLodPreset`) and as the per-armature override shape in\n * {@link Armature.setAnimationLod}.\n */\nexport interface AnimLodPreset {\n /** World-space distance (m) below which the armature animates full rate. */\n nearDist?: number;\n /** World-space distance (m) beyond which `farStride` applies. */\n farDist?: number;\n /** Frames-per-update between `nearDist` and `farDist`. 1 = every frame. */\n nearStride?: number;\n /** Frames-per-update beyond `farDist`. */\n farStride?: number;\n}\n\n/** Built-in fallback used by `setAnimationLod()` (no-arg) when the engine\n * has no `animLodPreset`. Full rate \u226412 m, every-2nd \u226424 m, every-4th\n * beyond. */\nconst DEFAULT_ANIM_LOD_PRESET: AnimLodPreset = {\n nearDist: 12,\n farDist: 24,\n nearStride: 2,\n farStride: 4,\n};\n\n/**\n * Pluggable override that drives the per-frame pose in place of\n * animation. The Armature has no knowledge of what's on the other end -\n * ragdoll physics, an IK solver, an AI behavior tree's pose output, a\n * network-replicated remote character - they all attach the same way.\n *\n * When `armature.poseProvider` is non-null, the Armature's animation\n * player is **not advanced** that frame; the provider has total control\n * of the pose. The Armature still owns the skinning pipeline (LOD,\n * frustum cull, world-transform composition, GPU palette upload), so a\n * provider only needs to fill `pose`.\n *\n * Implementations: {@link Ragdoll}.\n *\n * @group Characters & Animation\n */\nexport interface PoseProvider {\n /**\n * Fill `pose` (per-bone TRS in armature-local bone space) for this\n * frame. The Armature runs this between its LOD/frustum gate and the\n * `Skeleton.applyLocal` composition step. To restore animation,\n * detach by setting `armature.poseProvider = null`.\n */\n writePose(pose: Pose, armature: Armature, dt: number): void;\n\n /**\n * Optional teardown hook fired when the Armature is destroyed (or\n * when a new provider replaces this one). Use to release external\n * resources - e.g. ragdoll physics bodies.\n */\n onDetach?(): void;\n}\n\n/**\n * How the armature handles the pelvis X/Z motion extracted from the active\n * animation.\n *\n * - `'off'` - Pelvis X/Z is clamped to bind in bone space. The character\n * looks \"in-place\" regardless of whether the underlying clip is\n * locomotive. The pivot is not touched by animation. **Default.**\n * - `'apply'` - The pivot tracks the pelvis as an absolute offset from a captured\n * baseline: `object3D.position = baseline + (pelvis_pose \u2212 bind)` each\n * frame. Switching `off \u2192 apply` captures the current pivot position as\n * the baseline; switching `apply \u2192 off` snaps the pivot back to the\n * baseline. Best for toggling-on/off demos and in-place looping animations\n * (pelvis returns to bind at loop end \u2192 no teleport). Locomotive clips\n * visibly snap at loop wrap; use `'extract'` for those.\n * - `'extract'` - Engine computes the per-frame pelvis \u0394\n * (`pelvis(t) \u2212 pelvis(t \u2212 dt)`) and accumulates it into an internal\n * buffer; the caller reads it via {@link Armature.consumeRootMotionDelta}\n * and feeds it to a motor / physics body / network layer. Unity-style\n * `OnAnimatorMove` pattern. The engine does **not** write to the pivot in\n * this mode. Loop wraps and hard `play` calls suppress the resulting\n * pelvis discontinuity so the next \u0394 is `0`.\n *\n * In every mode the pelvis bone itself is clamped to bind X/Z in bone space -\n * the motion lives on the pivot (or in the consumed delta), never on the\n * bone.\n *\n * @group Characters & Animation\n */\nexport type RootMotionMode = 'off' | 'apply' | 'extract';\n\n/**\n * Composition root for one character: holds the three.js pivot object and\n * wires together a {@link Skeleton}, an {@link AnimationPlayer}, a working\n * {@link Pose}, and a {@link SplatSkinning} unit.\n *\n * Thin facade - `playAnimation` / `crossfadeTo` / `stop` / `update` delegate\n * to the underlying modules. The rig-convention rules (pelvis X/Z clamp,\n * pelvis-Y lock, root-bone clamp, root-motion extraction) live here, because\n * they're a *character-setup* concern, not a pose-evaluation concern.\n *\n * Most users won't construct this directly - {@link Character.load} builds\n * one automatically. It's exported for custom pipelines that need direct\n * control over skeletal evaluation.\n *\n * @group Characters & Animation\n */\nexport class Armature {\n /** Pivot object; all linked splats become children of this. */\n object3D: Group;\n /** Rig data (bone count, rest translations/rotations, parents). */\n armatureData: ArmatureData;\n /** Number of bones in the rig. */\n numBones: number;\n\n private readonly _skeleton: Skeleton;\n private readonly _currentPose: Pose;\n private readonly _snapshotPose: Pose;\n private readonly _worldTransforms: Mat4[] = [];\n\n private _engine: SplatEngine | null = null;\n private readonly _worldMatrix = new Mat4();\n private _player: AnimationPlayer | null = null;\n private _skinning: SplatSkinning | null = null;\n private _provider: AnimationProvider | null = null;\n private readonly _layers = new Map<string, AnimationLayer>();\n private readonly _layerTmpQ = new Quat();\n\n /**\n * Optional override that drives the pose in place of animation.\n * Setting this to a non-null value skips animation evaluation; the\n * provider has full control of `_currentPose`. Setting back to `null`\n * resumes animation immediately. See {@link PoseProvider}.\n *\n * Replacing the provider (set non-null while another is attached)\n * fires the outgoing provider's `onDetach()` first.\n */\n get poseProvider(): PoseProvider | null { return this._poseProvider; }\n set poseProvider(p: PoseProvider | null) {\n if (p === this._poseProvider) return;\n const prev = this._poseProvider;\n this._poseProvider = p;\n try { prev?.onDetach?.(); } catch { /* keep going */ }\n }\n private _poseProvider: PoseProvider | null = null;\n\n // Rig-convention bone indices. `-2` = unresolved, `-1` = absent in rig.\n private _rootBoneIndex = -2;\n private _pelvisBoneIndex = -2;\n\n\n /**\n * When true, {@link update} advances the animation player (so timers,\n * crossfade, and event callbacks still fire) but skips pose evaluation\n * and the skinning push. The previous frame's pose stays on the GPU\n * palette and the splat keeps rendering at its last bone state.\n *\n * Use for dynamic animation LOD - e.g. when fps drops, set true on\n * every other (or every Nth) frame to halve the per-frame skeletal\n * cost. Cleared when fps recovers.\n */\n skipPose = false;\n\n /**\n * When true, {@link update} still pushes bone transforms to the GPU\n * palette (so items, hitboxes, and outlines tracking bones still move\n * correctly) but skips the CPU-side `splat.updatePositions(...)` call\n * that recomputes sort centers from the deformed mesh. The depth-sort\n * order lags one frame behind the visual pose.\n *\n * Use for alternate-frame throttling - `updatePositions` is the heavy\n * call (full center buffer re-upload to the sort worker), and most\n * frames don't visibly need a fresh sort.\n */\n skipPositions = false;\n\n /**\n * Update rate divider. `1` = pose evaluation runs on every {@link update}\n * call (default - one pose update per `engine.update()`).\n * Set to N>1 to advance the animation player every call but only do the\n * heavy pose-eval + skinning push every Nth call.\n *\n * `dt` from skipped frames is accumulated and passed to the next\n * evaluated frame, so animation time stays correct - only the GPU\n * palette refresh rate drops.\n *\n * Typical use: set to `2` on background characters so the per-character\n * armature cost halves while the engine still ticks at 30 Hz.\n */\n updateInterval = 1;\n\n private _updateCounter = 0;\n private _updateAccumDt = 0;\n\n // Pelvis-lock state.\n private _lockPelvisY = false;\n\n // Root motion.\n private _rootMotionMode: RootMotionMode = 'off';\n // 'apply' mode: baseline pivot position captured on off \u2192 apply.\n private _baseLocalPosition = new Vec3();\n // 'extract' mode: delta tracker for Unity-style per-frame \u0394.\n private _lastPelvisPos = new Vec3();\n private _hasLastPelvis = false;\n private _rootMotionAccumDx = 0;\n private _rootMotionAccumDz = 0;\n\n // \u2500\u2500 Distance-based animation LOD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Throttle skinning updates by distance from the camera: near\n // characters update every frame, far ones every Nth. `tick(dt)` still\n // advances animation time every frame (so clip timing stays correct);\n // only the expensive pose-evaluate + skinning push is skipped on\n // throttled frames, freezing the rendered pose until the next update.\n //\n // OFF BY DEFAULT - distances start at Infinity so `_lodStride()` always\n // returns 1 (full rate). Opt in per-armature via `setAnimationLod()`\n // (no-arg form pulls the engine's `animLodPreset`), or set the engine\n // preset once and call `setAnimationLod()` on each character you want\n // throttled. Player / important characters: just never opt in.\n private _lodNearDist = Infinity;\n private _lodFarDist = Infinity;\n private _lodNearStride = 2; // frames-per-update between near and far\n private _lodFarStride = 4; // frames-per-update beyond far\n private _lodFrameCounter = 0;\n\n // \u2500\u2500 Distance-based SORT LOD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Complement to animation LOD. Throttles ONLY the CPU-side sort center\n // re-upload (`splat.updatePositions`, ~88% of per-character CPU at high\n // counts) by setting `skipPositions=true` on throttled frames. The GPU\n // palette still uploads, so the visible pose is correct - only the\n // depth-sort order lags one frame.\n //\n // Composes with anim LOD: on frames where anim LOD throttles, the whole\n // block returns and sort LOD is irrelevant. On frames where anim LOD\n // evaluates, sort LOD can still decide to skip the positions push.\n // Typical setup: tight bands so even mid-distance characters skip sort\n // most frames, while pose stays at full rate.\n //\n // OFF BY DEFAULT - opt in per-armature via `setSortLod()`.\n private _sortLodNearDist = Infinity;\n private _sortLodFarDist = Infinity;\n private _sortLodNearStride = 2;\n private _sortLodFarStride = 4;\n private _sortLodFrameCounter = 0;\n\n constructor(name: string, armatureData: ArmatureData) {\n this.armatureData = armatureData;\n this.numBones = armatureData.numBones;\n this.object3D = new Group();\n this.object3D.name = name;\n this._skeleton = new Skeleton(armatureData);\n this._currentPose = new Pose(this.numBones);\n this._snapshotPose = new Pose(this.numBones);\n this._currentPose.setToBind(this._skeleton.bindT, this._skeleton.bindR);\n }\n\n /** Splats currently being driven by this armature. */\n get linkedSplats(): Set<Splat> {\n if (this._skinning) return this._skinning.linkedSplats;\n return _EMPTY_SET;\n }\n\n /**\n * Detach the armature from its engine and remove its pivot object. Splats\n * still linked at the time of destroy are also destroyed so they stop\n * holding GPU resources alive. The armature itself is not safe to\n * reuse after this call.\n *\n * Use {@link Character.destroy} instead if you have the owning\n * {@link Character} - it disposes both the armature and its primary splat.\n */\n destroy(): void {\n try { this._poseProvider?.onDetach?.(); } catch { /* keep tearing down */ }\n this._poseProvider = null;\n if (this._skinning) {\n for (const splat of Array.from(this._skinning.linkedSplats)) {\n try { splat.destroy(); } catch { /* ignore cleanup errors */ }\n }\n }\n this.object3D.removeFromParent();\n this._engine = null;\n this._skinning = null;\n this._player = null;\n this._provider = null;\n this._layers.clear();\n }\n\n // \u2500\u2500 Engine integration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Attach this armature to an engine. Required before playback. Adds the\n * armature pivot as a child of `engine.contentRoot` and wires up the\n * animation provider + splat skinning.\n */\n addToScene(engine: SplatEngine): void {\n this._engine = engine;\n engine.contentRoot.add(this.object3D);\n\n const provider: AnimationProvider = (name: string) => {\n let anim = engine.skeletalAnimationLibrary.get(name);\n if (!anim) return null;\n anim = filterAnimationForArmature(anim, this.numBones, engine.skeletonLibrary);\n engine.skeletalAnimationLibrary.set(name, anim);\n convertSkeletalAnimation(anim, engine.skeletonLibrary);\n return anim;\n };\n this._provider = provider;\n\n this._player = new AnimationPlayer({\n skeleton: this._skeleton,\n animationProvider: provider,\n snapshotPose: this._snapshotPose,\n });\n this._skinning = new SplatSkinning(this._skeleton, engine.skeletonLibrary);\n\n this._pushPose();\n }\n\n /**\n * Register a {@link Splat} to be driven by this armature.\n *\n * Reparents the splat under the armature's pivot and pushes the current\n * bone transforms so the splat appears in the correct pose immediately.\n */\n linkSplat(splat: Splat): void {\n if (!this._skinning) return;\n this._skinning.link(splat);\n splat.linkedArmature = this;\n\n this.object3D.add(splat.object3D);\n\n this._pushPose();\n }\n\n /**\n * Stop driving the given splat. The splat is not destroyed; it just no\n * longer receives bone transform updates.\n */\n unlinkSplat(splat: Splat): void {\n this._skinning?.unlink(splat);\n if (splat.linkedArmature === this) {\n splat.linkedArmature = null;\n }\n }\n\n /**\n * Apply any combination of position, rotation, and scale to the armature\n * pivot. All linked splats are requested to re-sort.\n */\n move(position?: Vec3, rotation?: Quat, scale?: Vec3): void {\n if (position) {\n this._baseLocalPosition.copy(position);\n this.object3D.position.set(position.x, position.y, position.z);\n }\n if (rotation) this.object3D.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);\n if (scale) this.object3D.scale.set(scale.x, scale.y, scale.z);\n this._skinning?.requestSortAll();\n }\n\n // \u2500\u2500 Root motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * How pelvis X/Z motion is routed each frame. See {@link RootMotionMode}.\n * Default `'off'`.\n *\n * Transitions are coordinated so toggling is well-behaved:\n *\n * - `off \u2192 apply` captures the current pivot position as the baseline.\n * The pivot then tracks `baseline + (pelvis \u2212 bind)` each frame.\n * - `apply \u2192 off` (or `apply \u2192 extract`) snaps the pivot back to the\n * baseline so the apply-mode offset doesn't leak into the next mode.\n * This is what prevents the toggle-ratchet bug.\n * - `* \u2192 extract` resets the per-frame \u0394 tracker so the next \u0394 is `0`.\n */\n get rootMotionMode(): RootMotionMode { return this._rootMotionMode; }\n set rootMotionMode(m: RootMotionMode) {\n if (m === this._rootMotionMode) return;\n const prev = this._rootMotionMode;\n if (prev === 'apply') {\n this.object3D.position.set(this._baseLocalPosition.x, this._baseLocalPosition.y, this._baseLocalPosition.z);\n this._skinning?.requestSortAll();\n }\n if (m === 'apply') {\n const p = this.object3D.position;\n this._baseLocalPosition.set(p.x, p.y, p.z);\n }\n this._hasLastPelvis = false;\n this._rootMotionAccumDx = 0;\n this._rootMotionAccumDz = 0;\n this._rootMotionMode = m;\n }\n\n /**\n * Convenience boolean alias for {@link rootMotionMode}.\n * `true` \u21D4 `'apply'`, `false` \u21D4 `'off'`. To use `'extract'`, set\n * {@link rootMotionMode} directly.\n */\n get rootMotion(): boolean { return this._rootMotionMode === 'apply'; }\n set rootMotion(v: boolean) { this.rootMotionMode = v ? 'apply' : 'off'; }\n\n /**\n * Return the pelvis X/Z delta accumulated since the previous call (or since\n * the armature was created / `rootMotionMode` was changed), and reset the\n * accumulator. The delta is in the pivot's parent space - feed it directly\n * to a motor's velocity input or to a physics body.\n *\n * Returns `{ dx: 0, dz: 0 }` in `'off'` or `'apply'` modes. In `'apply'`\n * mode the delta has already been written to {@link object3D}, so consumers\n * shouldn't read and re-apply it.\n */\n consumeRootMotionDelta(): { dx: number; dz: number } {\n const dx = this._rootMotionAccumDx;\n const dz = this._rootMotionAccumDz;\n this._rootMotionAccumDx = 0;\n this._rootMotionAccumDz = 0;\n return { dx, dz };\n }\n\n /**\n * When `true`, clamp the pelvis bone's Y translation to bind each frame.\n * Use for in-place idle / gesture captures where vertical bob would push\n * the character out of a tightly-framed thumbnail.\n */\n get lockPelvisY(): boolean { return this._lockPelvisY; }\n set lockPelvisY(v: boolean) { this._lockPelvisY = v; }\n\n // \u2500\u2500 Playback accessors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n get isPlaying(): boolean { return this._player?.isPlaying ?? false; }\n get isFinished(): boolean { return this._player?.isFinished ?? false; }\n\n get paused(): boolean { return this._player?.paused ?? false; }\n set paused(v: boolean) { if (this._player) this._player.paused = v; }\n\n get animationTime(): number { return this._player?.animationTime ?? 0; }\n set animationTime(v: number) { if (this._player) this._player.animationTime = v; }\n\n get animationDuration(): number { return this._player?.animationDuration ?? 0; }\n\n /**\n * Crossfade progress in `[0, 1]`. `0` when no crossfade is active; `1`\n * once the active crossfade has fully blended into the target animation.\n */\n get crossfadeProgress(): number { return this._player?.crossfadeProgress ?? 0; }\n\n get frameRate(): number { return this._player?.frameRate ?? 30; }\n set frameRate(v: number) { if (this._player) this._player.frameRate = v; }\n\n /** Playback-speed multiplier (`1` = author speed). Scales how fast the\n * active clip advances without touching its authored frame rate or\n * crossfade timing. See {@link AnimationPlayer.playbackSpeed}. */\n get playbackSpeed(): number { return this._player?.playbackSpeed ?? 1; }\n set playbackSpeed(v: number) { if (this._player) this._player.playbackSpeed = v; }\n\n hasAnimation(animName: string): boolean {\n return !!this._engine?.skeletalAnimationLibrary.get(animName);\n }\n\n /**\n * Bone names from the attached engine's skeleton library, or an empty array\n * if the armature isn't bound yet. Consumers that need bone-name lookup\n * (bone-tracked colliders, attachments, debug overlays) read from here\n * instead of reaching into private armature state.\n */\n get boneNames(): readonly string[] {\n return this._engine?.skeletonLibrary?.boneNames ?? [];\n }\n\n /**\n * Bone names matching THIS armature's rig size. {@link boneNames} always\n * returns the 86-bone std-male list; the 441-bone facial rig has its own\n * name table (`boneNames441`). Name-keyed per-bone features (bone stretch,\n * body-part classification) must use this accessor or they silently\n * misclassify every bone on the large rig.\n */\n get rigBoneNames(): readonly string[] {\n const lib = this._engine?.skeletonLibrary;\n if (this.numBones === 441 && lib?.boneNames441) return lib.boneNames441;\n return lib?.boneNames ?? [];\n }\n\n /** The engine this armature is attached to, or `null` if not yet attached. */\n get engine(): SplatEngine | null { return this._engine; }\n\n /** The skeleton owned by this armature (rest pose, parents, bind data). */\n get skeleton(): Skeleton { return this._skeleton; }\n\n /**\n * Live reference to the per-bone world-transform array filled in by\n * the most recent {@link update}. Same Mat4 instances are reused\n * across frames - callers may hold the array reference and re-read,\n * or call {@link getBoneWorldMatrix} for a single bone. Empty until\n * the first update.\n */\n get boneWorldMatrices(): readonly Mat4[] { return this._worldTransforms; }\n\n /**\n * Snap any active crossfade to its terminal state (target pose fully\n * applied) on the next {@link Armature.update}. Useful when scrubbing\n * through animation frames for precompute, where the per-frame pose\n * needs to be the pure animation evaluation without crossfade blend.\n */\n endCrossfade(): void {\n this._player?.endCrossfade();\n }\n\n /**\n * Return the world-space transform of bone `boneIdx` as computed by the\n * most recent {@link Armature.update}. Returns a live reference into the\n * armature's internal array - callers must not mutate it; copy first if\n * you need to retain.\n *\n * Returns `null` if `boneIdx` is out of range, or if the bone transform\n * array has not been populated yet (no `update()` has run, or the armature\n * isn't attached to an engine).\n *\n * Used by per-bone attachments - bone-tracked colliders, weapon GLBs\n * mounted to a bone, particle emitters following a bone, etc.\n */\n getBoneWorldMatrix(boneIdx: number): Mat4 | null {\n if (boneIdx < 0 || boneIdx >= this.numBones) return null;\n return this._worldTransforms[boneIdx] ?? null;\n }\n\n /**\n * Name of the currently-playing animation, or `null` if no animation is\n * active. Mirrors {@link AnimationPlayer.currentAnimationName}.\n */\n get currentAnimationName(): string | null {\n return this._player?.currentAnimationName ?? null;\n }\n\n /**\n * Subscribe to frame-aligned {@link AnimationEvent}s on the currently-\n * playing animation. Events come from the active animation's\n * {@link Animation.events} array; the engine doesn't interpret `name` or\n * `payload` - games define their own vocabulary and route inside the\n * callback.\n *\n * Listeners are kept across animation switches; one subscription is enough\n * for the armature's lifetime. Returns an unsubscribe handle.\n */\n onAnimEvent(cb: AnimEventCallback): () => void {\n return this._player?.onAnimEvent(cb) ?? (() => {});\n }\n\n // \u2500\u2500 Playback verbs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Start playing an animation immediately (no crossfade). Restarts from\n * frame 0. Returns `false` if not registered, or if the armature isn't\n * attached to an engine yet.\n *\n * Passing `rootMotion: true` sets {@link rootMotionMode} to `'apply'`;\n * passing `false` sets it to `'off'`. For `'extract'`, set the mode\n * separately and pass `rootMotion: false` (or omit) here - the per-clip\n * flag is just a convenience shortcut for the common case.\n */\n playAnimation(animName: string, rootMotion = false, loop = true): boolean {\n if (!this._player) return false;\n this.rootMotion = rootMotion;\n this._hasLastPelvis = false; // hard switch - pelvis pose discontinuity\n return this._player.play(animName, { loop });\n }\n\n /**\n * Crossfade from the current pose to a new animation over `opts.duration`\n * seconds. Snapshots current bone poses, then blends toward the new\n * animation target. Pelvis motion stays continuous across the blend.\n *\n * `opts.rootMotion` is mapped to {@link rootMotionMode} the same way as\n * {@link playAnimation}.\n */\n crossfadeTo(\n animName: string,\n opts?: { duration?: number; rootMotion?: boolean; loop?: boolean; preserveTime?: boolean },\n ): boolean {\n if (!this._player) return false;\n this.rootMotion = opts?.rootMotion ?? false;\n // Crossfade is a smooth pose blend - _hasLastPelvis stays valid, so the\n // pelvis delta on the first cross-fade frame is the small differential\n // between the snapshot pelvis and the (blended) target pelvis.\n return this._player.crossfadeTo(animName, this._currentPose, opts);\n }\n\n // \u2500\u2500 Animation layers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Play `animName` on the named overlay layer, gated to `mask`'s bone set.\n * Layers compose on top of the base animation in {@link update} - for each\n * bone in the mask, the current pose is interpolated toward the overlay's\n * pose by the layer weight.\n *\n * Creates the layer lazily on first use (allocates a per-layer\n * {@link AnimationPlayer} sharing the same skeleton and animation provider\n * as the base). Subsequent calls reuse the same player.\n */\n playLayerAnimation(\n layerName: string,\n animName: string,\n mask: BoneMask,\n opts?: { loop?: boolean; crossfade?: number; weight?: number },\n ): boolean {\n if (!this._provider) return false;\n let layer = this._layers.get(layerName);\n if (!layer) {\n const snapshot = new Pose(this.numBones);\n snapshot.setToBind(this._skeleton.bindT, this._skeleton.bindR);\n const player = new AnimationPlayer({\n skeleton: this._skeleton,\n animationProvider: this._provider,\n snapshotPose: snapshot,\n });\n const pose = new Pose(this.numBones);\n pose.setToBind(this._skeleton.bindT, this._skeleton.bindR);\n layer = { player, mask: mask.boneIndices, pose, snapshot, weight: opts?.weight ?? 1 };\n this._layers.set(layerName, layer);\n } else {\n layer.mask = mask.boneIndices;\n if (opts?.weight !== undefined) layer.weight = opts.weight;\n layer.fadingOut = undefined;\n }\n const loop = opts?.loop ?? true;\n const xf = opts?.crossfade ?? 0;\n return xf > 0\n ? layer.player.crossfadeTo(animName, layer.pose, { duration: xf, loop })\n : layer.player.play(animName, { loop });\n }\n\n /** Set the overlay weight for a layer in `[0, 1]`. No-op if the layer doesn't exist. */\n setLayerWeight(layerName: string, weight: number): void {\n const l = this._layers.get(layerName);\n if (l) {\n l.weight = Math.max(0, Math.min(1, weight));\n l.fadingOut = undefined;\n }\n }\n\n /**\n * Pause or resume every active overlay layer. The base animation is\n * controlled separately via {@link paused}. Useful so a single play/pause\n * toggle in an editor or pause menu freezes the whole stack together.\n */\n setAllLayersPaused(paused: boolean): void {\n for (const layer of this._layers.values()) {\n layer.player.paused = paused;\n }\n }\n\n /**\n * Stop and remove the named layer. With `fadeDuration > 0`, ramps the\n * layer weight to zero over `fadeDuration` seconds before tearing down.\n */\n stopLayer(layerName: string, fadeDuration = 0): void {\n const l = this._layers.get(layerName);\n if (!l) return;\n if (fadeDuration <= 0) {\n this._layers.delete(layerName);\n return;\n }\n l.fadingOut = { from: l.weight, t: 0, duration: fadeDuration };\n }\n\n /** Stop with optional crossfade back to rest pose. */\n stop(fadeDuration = 0): void {\n if (!this._player) return;\n if (fadeDuration > 0 && this._player.isPlaying) {\n this._player.stop(this._currentPose, fadeDuration);\n return;\n }\n this._player.stop(this._currentPose, 0);\n this._currentPose.setToBind(this._skeleton.bindT, this._skeleton.bindR);\n this._hasLastPelvis = false; // hard stop - pelvis snaps to bind\n this._pushPose();\n }\n\n // \u2500\u2500 Per-frame update \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Advance animation time by `dt` seconds, evaluate pose, and push bone\n * transforms to linked splats. Called for you by `engine.update()` unless auto-update is detached.\n */\n update(dt: number): void {\n if (!this._player || !this._skinning) return;\n\n // External pose-provider path: animation is fully replaced. The\n // provider writes the pose; the skinning pipeline (LOD's frustum\n // cull, applyLocal, push-transforms) is unchanged. Animation-LOD\n // strides and the player tick are bypassed - providers handle\n // their own throttling if they need to.\n if (this._poseProvider) {\n if (!this._skinning.anyVisible(this._cameraFrustum())) return;\n this._poseProvider.writePose(this._currentPose, this, dt);\n this._skeleton.applyLocal(\n this._currentPose,\n this._worldTransform(),\n this._worldTransforms,\n );\n this._skinning.pushTransforms(\n this._worldTransforms,\n this._worldTransform(),\n this.skipPositions,\n );\n return;\n }\n\n // Always advance animation time so clip timing / events stay correct\n // even on LOD-throttled frames.\n const { wrapped } = this._player.tick(dt);\n if (wrapped) this._hasLastPelvis = false;\n\n // Four layered throttles, cheapest-first, each an early-out. Animation\n // time already advanced above, so every skip just freezes the rendered\n // pose at its last evaluated value - clip timing / events stay correct.\n //\n // 1. Manual escape hatch: caller-driven hard skip (fps-adaptive, etc).\n if (this.skipPose) return;\n\n // 2. Manual rate divider: do the heavy work every Nth call only.\n if (this.updateInterval > 1) {\n this._updateAccumDt += dt;\n if (++this._updateCounter < this.updateInterval) return;\n this._updateCounter = 0;\n this._updateAccumDt = 0;\n }\n\n // 3. Off-screen: skip skinning entirely (frustum gate).\n if (!this._skinning.anyVisible(this._cameraFrustum())) return;\n\n // 4. Distance LOD: throttle by camera distance (off by default; armature\n // opts in via setAnimationLod). On throttled frames the pose stays\n // frozen until the next due frame.\n this._lodFrameCounter++;\n const stride = this._lodStride();\n if (stride > 1 && this._lodFrameCounter % stride !== 0) return;\n\n // Reaching here means this frame survived every anim-LOD throttle above:\n // the pose is actually being re-evaluated and pushed. Stamp the engine's\n // frame marker so pose-mirroring consumers (PixelartEffect's mask camera)\n // know a character moved this frame and a mask rebuild is warranted. On\n // throttled (frame-dropped) frames we return early above and never stamp,\n // so the mask consumer can skip its rebuild entirely.\n if (this._engine) this._engine.characterPoseUpdatedFrame = this._engine.frame;\n\n this._resolveRigIndices();\n this._player.evaluate(this._currentPose);\n if (this._layers.size > 0) this._evaluateLayers(dt);\n this._applyRigPostClamps();\n this._skeleton.applyLocal(this._currentPose, this._worldTransform(), this._worldTransforms);\n\n // Sort LOD: independent of anim LOD, decides per-frame whether to skip\n // the expensive CPU sort re-upload. ORs with the manual `skipPositions`\n // flag so callers can hard-force a skip regardless of LOD bands.\n const skipPos = this.skipPositions || this._sortLodSkipThisFrame();\n this._skinning.pushTransforms(this._worldTransforms, this._worldTransform(), skipPos);\n }\n\n // \u2500\u2500 Internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve named rig conventions once skeleton library is available.\n * If `boneNames` is present, looks up \"root\" and any name containing\n * \"pelvis\"; otherwise falls back to bone index 0 as root.\n */\n private _resolveRigIndices(): void {\n if (this._pelvisBoneIndex !== -2) return;\n this._rootBoneIndex = -1;\n this._pelvisBoneIndex = -1;\n const boneNames = this._engine?.skeletonLibrary?.boneNames;\n if (boneNames && boneNames.length > 0) {\n for (let i = 0; i < this.numBones; i++) {\n const name = boneNames[i]?.toLowerCase();\n if (!name) continue;\n if (name === 'root') this._rootBoneIndex = i;\n if (name.includes('pelvis')) this._pelvisBoneIndex = i;\n }\n } else {\n this._rootBoneIndex = 0;\n }\n }\n\n /**\n * Compose overlay layers onto `_currentPose`. Each layer ticks its own\n * player, evaluates a full pose into a scratch buffer, then per masked\n * bone interpolates the current pose toward the overlay by the layer\n * weight. Runs before `_applyRigPostClamps` so pelvis/root clamps stay\n * authoritative.\n */\n private _evaluateLayers(dt: number): void {\n const out = this._currentPose;\n const lp = out.positions, lr = out.rotations, ls = out.scales;\n const tmpQ = this._layerTmpQ;\n for (const [name, layer] of this._layers) {\n layer.player.tick(dt);\n layer.player.evaluate(layer.pose);\n\n if (layer.fadingOut) {\n layer.fadingOut.t += dt;\n const k = Math.min(1, layer.fadingOut.t / layer.fadingOut.duration);\n layer.weight = layer.fadingOut.from * (1 - k);\n if (k >= 1) { this._layers.delete(name); continue; }\n }\n const w = layer.weight;\n if (w <= 0) continue;\n\n const op = layer.pose.positions, or = layer.pose.rotations, os = layer.pose.scales;\n const mask = layer.mask;\n for (let i = 0; i < mask.length; i++) {\n const bi = mask[i];\n lp[bi].lerp(lp[bi], op[bi], w);\n tmpQ.copy(or[bi]);\n if (lr[bi].dot(tmpQ) < 0) tmpQ.mulScalar(-1);\n lr[bi].slerp(lr[bi], tmpQ, w);\n ls[bi].lerp(ls[bi], os[bi], w);\n }\n }\n }\n\n /**\n * Apply rig-convention rules to the freshly-evaluated pose:\n * - root-motion routing - `'apply'` writes `baseline + (pelvis \u2212 bind)`\n * to the pivot; `'extract'` accumulates the per-frame pelvis \u0394;\n * `'off'` does nothing.\n * - pelvis X/Z clamp to bind in bone space (always - the motion lives on\n * the pivot / in the consumed delta, not on the bone).\n * - pelvis-Y lock to bind (when {@link lockPelvisY} is set).\n * - root-bone full clamp to bind.\n */\n private _applyRigPostClamps(): void {\n const bindT = this._skeleton.bindT;\n const bindR = this._skeleton.bindR;\n const pose = this._currentPose;\n const pelvisIdx = this._pelvisBoneIndex;\n const rootIdx = this._rootBoneIndex;\n\n if (pelvisIdx >= 0) {\n const pelvisPos = pose.positions[pelvisIdx];\n\n if (this._rootMotionMode === 'apply') {\n const base = this._baseLocalPosition;\n const ox = pelvisPos.x - bindT[pelvisIdx * 3];\n const oz = pelvisPos.z - bindT[pelvisIdx * 3 + 2];\n const cur = this.object3D.position;\n cur.set(base.x + ox, cur.y, base.z + oz);\n } else if (this._rootMotionMode === 'extract') {\n if (this._hasLastPelvis) {\n this._rootMotionAccumDx += pelvisPos.x - this._lastPelvisPos.x;\n this._rootMotionAccumDz += pelvisPos.z - this._lastPelvisPos.z;\n }\n this._lastPelvisPos.copy(pelvisPos);\n this._hasLastPelvis = true;\n }\n\n pelvisPos.x = bindT[pelvisIdx * 3];\n pelvisPos.z = bindT[pelvisIdx * 3 + 2];\n if (this._lockPelvisY) pelvisPos.y = bindT[pelvisIdx * 3 + 1];\n }\n\n if (rootIdx >= 0) {\n pose.positions[rootIdx].set(bindT[rootIdx * 3], bindT[rootIdx * 3 + 1], bindT[rootIdx * 3 + 2]);\n pose.rotations[rootIdx].set(bindR[rootIdx * 4], bindR[rootIdx * 4 + 1], bindR[rootIdx * 4 + 2], bindR[rootIdx * 4 + 3]);\n pose.scales[rootIdx].set(1, 1, 1);\n }\n }\n\n /**\n * Apply runtime bone scaling. Each entry scales a bone's flesh + segment in\n * its own frame - `{ along, width, thickness }` (each defaulting to `1`), or\n * a bare number for uniform scale. e.g. `{ thigh_l: { along: 1.3 }, calf_l:\n * { along: 1.3 } }` \u2192 a 1.3\u00D7 longer left leg; `{ upperarm_l: { width: 1.4,\n * thickness: 1.4 } }` \u2192 a beefier arm. Bones not listed stay at `1`. Pass\n * `null` to clear. Works for any bone set (limbs, spine, \u2026); see\n * {@link computeBoneStretch} for the model. Recompute only when factors\n * change - the result is applied every frame by the skeleton + skinning.\n */\n setBoneStretch(factors: Record<string, BoneScaleInput> | null): void {\n if (!factors) {\n this._skeleton.lengthScale = null;\n this._skinning?.setCovStretch(null);\n return;\n }\n const { lengthScale, covStretch, any } = computeBoneStretch(\n this._skeleton,\n this.rigBoneNames,\n factors,\n );\n this._skeleton.lengthScale = any ? lengthScale : null;\n this._skinning?.setCovStretch(any ? covStretch : null);\n }\n\n /** Push the current pose through skeleton + skinning. Called at link time. */\n private _pushPose(): void {\n if (!this._skinning) return;\n this._skeleton.applyLocal(this._currentPose, this._worldTransform(), this._worldTransforms);\n this._skinning.pushTransforms(this._worldTransforms, this._worldTransform());\n }\n\n private _cameraFrustum(): Frustum | undefined {\n return this._engine?.cameraFrustum;\n }\n\n /**\n * The pivot's world matrix in the skeletal core's own matrix type. Refreshes\n * the three.js world matrix first, so a transform set this frame is seen\n * this frame.\n */\n private _worldTransform(): Mat4 {\n this.object3D.updateWorldMatrix(true, false);\n return this._worldMatrix.setFromArray(this.object3D.matrixWorld.elements);\n }\n\n /**\n * Squared distance from the pivot's world origin to the engine camera, or\n * `null` when the engine has no camera. Drives the distance-LOD bands.\n * @internal\n */\n cameraDistanceSq(): number | null {\n const camPos = this._engine?.cameraWorldPosition;\n if (!camPos) return null;\n this.object3D.updateWorldMatrix(true, false);\n const e = this.object3D.matrixWorld.elements;\n const dx = e[12] - camPos.x;\n const dy = e[13] - camPos.y;\n const dz = e[14] - camPos.z;\n return dx * dx + dy * dy + dz * dz;\n }\n\n /**\n * Enable / configure distance-based animation LOD for THIS armature.\n * LOD is off by default (full rate); calling this is the opt-in.\n *\n * - **No args**: pull the engine's `animLodPreset` (set via\n * `SplatEngine.animLodPreset`). If the engine has no preset, fall back to a\n * built-in default (full rate \u226412 m, every-2nd \u226424 m, every-4th\n * beyond). Typical gameplay use: set the preset once, then call\n * `armature.setAnimationLod()` on each throttle-able character.\n * - **Partial opts**: tweak individual knobs on top of current values.\n *\n * `nearDist` / `farDist` are world-space distances (m) from the camera;\n * `nearStride` / `farStride` are frames-per-update in the mid / far\n * bands. A stride of 1 means every frame.\n */\n setAnimationLod(opts?: {\n nearDist?: number;\n farDist?: number;\n nearStride?: number;\n farStride?: number;\n }): void {\n // No-arg form: seed from the engine preset (or the built-in fallback),\n // then continue so any explicit knobs below can still override.\n const resolved = opts ?? this._engine?.animLodPreset ?? DEFAULT_ANIM_LOD_PRESET;\n if (resolved.nearDist !== undefined) this._lodNearDist = resolved.nearDist;\n if (resolved.farDist !== undefined) this._lodFarDist = resolved.farDist;\n if (resolved.nearStride !== undefined) this._lodNearStride = Math.max(1, Math.floor(resolved.nearStride));\n if (resolved.farStride !== undefined) this._lodFarStride = Math.max(1, Math.floor(resolved.farStride));\n }\n\n /** Disable LOD throttling - every character animates at full rate\n * regardless of distance (frustum cull still applies). */\n disableAnimationLod(): void {\n this._lodNearDist = Infinity;\n this._lodFarDist = Infinity;\n }\n\n /**\n * Enable / configure distance-based SORT LOD for THIS armature.\n *\n * Throttles only the CPU-side `splat.updatePositions` call (the dominant\n * cost - ~88% of per-character CPU at high counts) without freezing the\n * rendered pose. On throttled frames the GPU palette still uploads, so\n * animation looks correct; only the depth-sort order lags one frame.\n *\n * Composes with {@link setAnimationLod} - when anim LOD throttles a\n * frame, sort LOD is moot for that frame; when anim LOD evaluates, sort\n * LOD can independently decide to skip the positions push.\n *\n * Typical use: tighter near band than anim LOD (e.g. 5\u201310 m) so even\n * mid-distance characters skip the sort re-upload most frames.\n *\n * - **No args**: enable with a built-in default\n * (nearDist=5, farDist=15, nearStride=2, farStride=4).\n * - **Partial opts**: tweak individual knobs on top of current values.\n */\n setSortLod(opts?: {\n nearDist?: number;\n farDist?: number;\n nearStride?: number;\n farStride?: number;\n }): void {\n const defaults = { nearDist: 5, farDist: 15, nearStride: 2, farStride: 4 };\n const resolved = opts ?? defaults;\n if (resolved.nearDist !== undefined) this._sortLodNearDist = resolved.nearDist;\n if (resolved.farDist !== undefined) this._sortLodFarDist = resolved.farDist;\n if (resolved.nearStride !== undefined) this._sortLodNearStride = Math.max(1, Math.floor(resolved.nearStride));\n if (resolved.farStride !== undefined) this._sortLodFarStride = Math.max(1, Math.floor(resolved.farStride));\n }\n\n /** Disable sort LOD - every character does the full updatePositions\n * every frame (still gated by `skipPositions` and anim LOD). */\n disableSortLod(): void {\n this._sortLodNearDist = Infinity;\n this._sortLodFarDist = Infinity;\n }\n\n /** Frames-per-update for this armature this frame, based on camera\n * distance. 1 = full rate. Returns 1 when no camera is available so\n * we never freeze a character due to missing engine state. */\n private _lodStride(): number {\n // The pivot's world origin is a good-enough \"where is this body\" proxy for\n // a distance bucket - no need for the AABB center.\n const distSq = this.cameraDistanceSq();\n if (distSq === null) return 1;\n if (distSq >= this._lodFarDist * this._lodFarDist) return this._lodFarStride;\n if (distSq >= this._lodNearDist * this._lodNearDist) return this._lodNearStride;\n return 1;\n }\n\n /** True when sort LOD says \"skip the CPU positions re-upload this frame\".\n * Uses the same camera-distance bands shape as anim LOD, but a separate\n * counter so the two strides don't lock-step. */\n private _sortLodSkipThisFrame(): boolean {\n const distSq = this.cameraDistanceSq();\n if (distSq === null) return false;\n let stride = 1;\n if (distSq >= this._sortLodFarDist * this._sortLodFarDist) stride = this._sortLodFarStride;\n else if (distSq >= this._sortLodNearDist * this._sortLodNearDist) stride = this._sortLodNearStride;\n if (stride <= 1) return false;\n this._sortLodFrameCounter++;\n return this._sortLodFrameCounter % stride !== 0;\n }\n}\n\nconst _EMPTY_SET: Set<Splat> = new Set();\n\ninterface AnimationLayer {\n player: AnimationPlayer;\n mask: Int32Array;\n pose: Pose;\n snapshot: Pose;\n weight: number;\n fadingOut?: { from: number; t: number; duration: number };\n}\n", "import { Quat, Vec3 } from '../math';\n\nimport { buildArmatureKeyframes } from '../anim/keyframe-splines';\nimport { fromRestRelative } from '../anim/rest-relative';\nimport type { BonePose } from '../anim/rest-relative';\nimport type { Animation, AnimationEvent, SkeletalKeyframeEntry } from '../animation';\n\nimport type { Pose } from './pose';\nimport type { Skeleton } from './skeleton';\n\ntype KeyframeEntry = SkeletalKeyframeEntry | null;\n\n// Global shared keyframe cache. buildArmatureKeyframes is pure and deterministic\n// for a given (filtered Animation object, numBones, loop, REST POSE) tuple - all\n// enemies on the same rig playing the same animation produce identical output, so\n// we allocate once and share the arrays across every AnimationPlayer.\n// WeakMap on the Animation object means entries are GC'd automatically when\n// the animation is removed from the engine's library.\n//\n// The rest pose is part of the key because the keyframes it builds are\n// REST-RELATIVE (`toRestRelative`): a bone's stored delta is measured against\n// the rest that was current at build time. Two characters can now disagree on\n// that rest - `LoadCharacterOptions.restSource: 'bundled'` swaps in the\n// per-character joints - so keying on bone count alone would hand a character\n// deltas encoded against somebody else's rest, and `fromRestRelative` would\n// decode them into a pose that is neither rig's. Identity, not contents: rest\n// arrays are built once per armature and never mutated in place.\nconst _sharedKeyframeCache = new WeakMap<Animation, Map<string, Array<KeyframeEntry | null>>>();\n\n// Stable per-rest-pose id, so the cache key can name a rest pose without\n// hashing its arrays on every play() call.\nlet _nextRestPoseId = 0;\nconst _restPoseIds = new WeakMap<object, number>();\nfunction restPoseId(rest: object | null | undefined): number {\n if (!rest) return -1;\n let id = _restPoseIds.get(rest);\n if (id === undefined) {\n id = _nextRestPoseId++;\n _restPoseIds.set(rest, id);\n }\n return id;\n}\n\n/**\n * Resolves an animation by name and returns an already-filtered/converted\n * {@link Animation}, or `null` if not registered. Lets {@link AnimationPlayer}\n * stay free of `SplatEngine` and `SkeletonLibrary`.\n *\n * @group Characters & Animation\n */\nexport type AnimationProvider = (name: string) => Animation | null;\n\n/**\n * Options for {@link AnimationPlayer.crossfadeTo}.\n *\n * @group Characters & Animation\n */\nexport interface CrossfadeOptions {\n /** Blend duration in seconds. Defaults to `defaultCrossfadeDuration`. */\n duration?: number;\n /** Loop the target animation. Default `true`. */\n loop?: boolean;\n /**\n * Preserve the current animation's normalized phase\n * (`animTime / numFrames`) when crossfading. Useful for \"style change\"\n * crossfades where the new looping animation should start at the same\n * cycle position as the outgoing one (e.g. switching idle variants\n * mid-cycle without a snap). Default `false` - new anim starts at\n * frame 0.\n */\n preserveTime?: boolean;\n}\n\n/**\n * Callback fired when {@link AnimationPlayer.tick} crosses a frame that has\n * one or more {@link AnimationEvent}s on the active animation.\n *\n * @group Characters & Animation\n */\nexport type AnimEventCallback = (event: AnimationEvent) => void;\n\n/**\n * Skeletal animation state machine. Owns playback state (current animation,\n * time, loop flag, crossfade window) and writes the per-bone target pose into\n * a caller-owned {@link Pose} each `update`.\n *\n * Knows nothing about splats, entities, or bone names. Output is a raw\n * crossfaded pose; rig-convention clamps (pelvis X/Z lock, root-bone clamp,\n * root-motion extraction onto the armature pivot) are the\n * {@link Armature} facade's job.\n *\n * @group Characters & Animation\n */\nexport class AnimationPlayer {\n /** Default crossfade duration when {@link CrossfadeOptions.duration} is omitted. */\n defaultCrossfadeDuration = 0.08;\n /** Frame rate used to convert `dt` (seconds) to frame time. Default `30`. */\n frameRate = 30;\n /**\n * Playback-speed multiplier applied to `dt` in {@link tick}. `1` = author\n * speed, `2` = double speed, `0.5` = half. Unlike {@link frameRate} this\n * scales only how fast time advances - the clip's authored frame rate (and\n * thus event-frame mapping) is unchanged. Lets a game tie a locomotion\n * clip's speed to the pivot's actual movement speed. Crossfade blending is\n * deliberately NOT sped up (it runs on real `dt`), so style swaps stay\n * smooth regardless of playback speed.\n */\n playbackSpeed = 1;\n\n private readonly _skeleton: Skeleton;\n private readonly _provider: AnimationProvider;\n\n private _active = false;\n private _animName: string | null = null;\n private _animData: Animation | null = null;\n private _keyframes: Array<KeyframeEntry | null> = [];\n private _keyframesReady = false;\n private _animTime = 0;\n private _loop = true;\n private _paused = false;\n private _blendToRest = false;\n\n private _crossfadeTime = 0;\n private _crossfadeDuration = 0;\n private readonly _snapshot: Pose;\n\n private _lastTickFrame = -1;\n private readonly _eventListeners = new Set<AnimEventCallback>();\n\n // Per-instance cache removed - keyframes are now shared globally via\n // _sharedKeyframeCache; see _prepareKeyframes.\n\n // Scratch\n private readonly _tmpPos = new Vec3();\n private readonly _tmpRot = new Quat();\n private readonly _tmpScale = new Vec3();\n private readonly _tmpSlerpRot = new Quat();\n private readonly _tmpToRot = new Quat();\n private readonly _restIn: BonePose = { position: new Vec3(), rotation: new Quat(), scale: new Vec3() };\n private readonly _restOut: BonePose = { position: new Vec3(), rotation: new Quat(), scale: new Vec3() };\n private readonly _splineValues: number[] = [];\n\n constructor(opts: { skeleton: Skeleton; animationProvider: AnimationProvider; snapshotPose: Pose }) {\n this._skeleton = opts.skeleton;\n this._provider = opts.animationProvider;\n this._snapshot = opts.snapshotPose;\n }\n\n // \u2500\u2500 State accessors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n get isPlaying(): boolean {\n return this._active;\n }\n\n get isFinished(): boolean {\n if (!this._active || !this._animData || this._loop || this._blendToRest) return false;\n const nf = this._animData.numFrames;\n return nf > 0 && this._animTime >= nf - 0.01;\n }\n\n get paused(): boolean {\n return this._paused;\n }\n set paused(v: boolean) {\n this._paused = v;\n }\n\n get animationTime(): number {\n return this._animTime;\n }\n set animationTime(v: number) {\n this._animTime = v;\n if (this._animData) {\n const nf = this._animData.numFrames;\n if (nf > 0) {\n if (this._loop) {\n while (this._animTime >= nf) this._animTime -= nf;\n while (this._animTime < 0) this._animTime += nf;\n } else {\n this._animTime = Math.max(0, Math.min(this._animTime, nf - 0.001));\n }\n }\n }\n }\n\n get animationDuration(): number {\n return this._animData?.numFrames ?? 0;\n }\n\n /**\n * Crossfade alpha in `[0, 1]`. `0` when no crossfade is active or one just\n * started; `1` when the in-progress crossfade has reached its terminal\n * blend. Useful for games that want to gate logic on \"the rig has fully\n * committed to the new pose\" without reaching into player internals.\n */\n get crossfadeProgress(): number {\n if (this._crossfadeDuration <= 0) return 0;\n return Math.min(1, this._crossfadeTime / this._crossfadeDuration);\n }\n\n /**\n * Name of the currently-playing animation, or `null` if no animation is\n * active (after {@link AnimationPlayer.stop} with `fadeDuration: 0`, or\n * before the first {@link AnimationPlayer.play}).\n */\n get currentAnimationName(): string | null {\n return this._animName;\n }\n\n // \u2500\u2500 Event dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Subscribe to frame-aligned {@link AnimationEvent}s on the currently-\n * playing animation. The callback fires once per crossed frame, after the\n * `tick` advances `animTime`.\n *\n * @returns an unsubscribe handle.\n */\n onAnimEvent(cb: AnimEventCallback): () => void {\n this._eventListeners.add(cb);\n return () => { this._eventListeners.delete(cb); };\n }\n\n private _dispatchEventsForFrameTransition(prevFrame: number, curFrame: number, wrapped: boolean, nf: number): void {\n if (this._eventListeners.size === 0) return;\n const events = this._animData?.events;\n if (!events || events.length === 0) return;\n if (curFrame === prevFrame) return;\n\n if (wrapped) {\n // Looping anim wrapped: fire events from prevFrame+1..nf-1, then 0..curFrame.\n for (const e of events) if (e.frame > prevFrame && e.frame < nf) this._fireEvent(e);\n for (const e of events) if (e.frame >= 0 && e.frame <= curFrame) this._fireEvent(e);\n } else if (curFrame > prevFrame) {\n // Normal forward step.\n for (const e of events) if (e.frame > prevFrame && e.frame <= curFrame) this._fireEvent(e);\n }\n }\n\n private _fireEvent(e: AnimationEvent): void {\n for (const cb of this._eventListeners) {\n try { cb(e); } catch (err) {\n // Don't let one listener's throw stop the rest.\n // eslint-disable-next-line no-console\n console.error('[AnimationPlayer] event listener threw:', err);\n }\n }\n }\n\n // \u2500\u2500 Playback verbs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Start an animation immediately (no crossfade). Restarts from frame 0.\n * Returns `false` if `name` isn't resolvable through the provider.\n */\n play(name: string, opts?: { loop?: boolean }): boolean {\n const loop = opts?.loop ?? true;\n\n if (this._active && !this._blendToRest && this._animName === name && this._loop === loop) {\n return true;\n }\n\n const kf = this._prepareKeyframes(name, loop);\n if (!kf) return false;\n\n this._activate(name, kf, loop, 0);\n this._crossfadeTime = 0;\n this._crossfadeDuration = 0;\n return true;\n }\n\n /**\n * Crossfade from `currentPose` to `name` over `opts.duration` seconds. The\n * current pose is captured into the internal snapshot - caller can keep\n * mutating `currentPose` after the call returns.\n */\n crossfadeTo(name: string, currentPose: Pose, opts?: CrossfadeOptions): boolean {\n const duration = opts?.duration ?? this.defaultCrossfadeDuration;\n const loop = opts?.loop ?? true;\n const preserveTime = opts?.preserveTime ?? false;\n\n if (this._active && !this._blendToRest && this._animName === name && this._loop === loop) {\n return true;\n }\n\n const kf = this._prepareKeyframes(name, loop);\n if (!kf) return false;\n\n let startTime = 0;\n if (preserveTime && this._active && !this._blendToRest && this._animData && this._loop) {\n const prevNf = this._animData.numFrames;\n const newAnim = this._provider(name);\n if (prevNf > 0 && newAnim && newAnim.numFrames > 0) {\n const phase = (this._animTime % prevNf) / prevNf;\n startTime = phase * newAnim.numFrames;\n }\n }\n\n this._snapshot.copyFrom(currentPose);\n this._crossfadeTime = 0;\n this._crossfadeDuration = duration;\n this._activate(name, kf, loop, startTime);\n return true;\n }\n\n /**\n * Snap any active crossfade to its terminal state (alpha = 1, target pose\n * fully applied) on the next {@link AnimationPlayer.evaluate}. No-op if no\n * crossfade is active. Useful when a game scrubs through animation frames\n * for precompute and wants per-frame poses without the blend artefacts of\n * a still-in-progress crossfade.\n */\n endCrossfade(): void {\n if (this._crossfadeDuration > 0) {\n this._crossfadeTime = this._crossfadeDuration;\n }\n }\n\n /**\n * Stop playback. With `fadeDuration > 0`, snapshots `currentPose` and\n * crossfades back to bind over `fadeDuration` seconds. With `0`, deactivates\n * immediately (the caller is expected to reset the pose to bind).\n */\n stop(currentPose: Pose, fadeDuration = 0): void {\n if (fadeDuration > 0 && this._active) {\n this._snapshot.copyFrom(currentPose);\n this._crossfadeTime = 0;\n this._crossfadeDuration = fadeDuration;\n this._blendToRest = true;\n return;\n }\n this._deactivate();\n }\n\n // \u2500\u2500 Per-frame update \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Advance animation time by `dt` seconds. Always cheap - call every frame\n * even for off-screen characters so they resume at the correct frame when\n * the camera pans back. Does **not** write to any `Pose`.\n *\n * Returns `wrapped: true` if `animTime` rolled past the end of a looping\n * animation on this tick. The facade uses that signal to suppress the\n * end-to-start pelvis discontinuity when extracting root motion.\n */\n tick(dt: number): { wrapped: boolean } {\n let wrapped = false;\n if (this._active && !this._paused && !this._blendToRest && this._animData && this._keyframesReady) {\n const prevFrame = this._lastTickFrame;\n this._animTime += dt * this.frameRate * this.playbackSpeed;\n const nf = this._animData.numFrames;\n if (nf > 0) {\n if (this._loop) {\n while (this._animTime >= nf) {\n this._animTime -= nf;\n wrapped = true;\n }\n } else if (this._animTime >= nf) {\n this._animTime = nf - 0.001;\n }\n }\n const curFrame = Math.floor(this._animTime);\n this._dispatchEventsForFrameTransition(prevFrame, curFrame, wrapped, nf);\n this._lastTickFrame = curFrame;\n }\n this._crossfadeTime += dt;\n return { wrapped };\n }\n\n /**\n * Evaluate the current pose at the current `animTime` into `outPose`,\n * applying the crossfade blend with the internal snapshot if one is active.\n *\n * Returns `blendToRestComplete: true` once on the tick a previously-\n * scheduled `stop(_, fade > 0)` reaches alpha 1 - the facade uses that to\n * snap pose to bind and reset rootMotion baseline.\n *\n * Skip this call when the character is off-screen; `tick` keeps time\n * advancing in the meantime, so the next on-screen frame evaluates straight\n * to the correct pose with no visible pop.\n */\n evaluate(outPose: Pose): { blendToRestComplete: boolean } {\n const alpha = this._crossfadeDuration > 0\n ? Math.min(1, this._crossfadeTime / this._crossfadeDuration)\n : 1;\n const inCrossfade = alpha < 1;\n\n const numBones = this._skeleton.numBones;\n const bindT = this._skeleton.bindT;\n const bindR = this._skeleton.bindR;\n const lp = outPose.positions;\n const lr = outPose.rotations;\n const ls = outPose.scales;\n const fp = this._snapshot.positions;\n const fr = this._snapshot.rotations;\n const fs = this._snapshot.scales;\n const tPos = this._tmpPos;\n const tRot = this._tmpRot;\n const tScale = this._tmpScale;\n const toRot = this._tmpToRot;\n\n if (inCrossfade) {\n for (let bi = 0; bi < numBones; bi++) {\n this._evalTargetPose(bi, bindT, bindR, tPos, tRot, tScale);\n lp[bi].lerp(fp[bi], tPos, alpha);\n toRot.copy(tRot);\n if (fr[bi].dot(toRot) < 0) toRot.mulScalar(-1);\n lr[bi].slerp(fr[bi], toRot, alpha);\n ls[bi].lerp(fs[bi], tScale, alpha);\n }\n } else {\n for (let bi = 0; bi < numBones; bi++) {\n this._evalTargetPose(bi, bindT, bindR, lp[bi], lr[bi], ls[bi]);\n }\n }\n\n const blendToRestComplete = this._blendToRest && alpha >= 1;\n if (blendToRestComplete) this._deactivate();\n return { blendToRestComplete };\n }\n\n // \u2500\u2500 Internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private _activate(name: string, kf: KeyframeEntry[], loop: boolean, startTime = 0): void {\n this._active = true;\n this._blendToRest = false;\n this._animName = name;\n this._animData = this._provider(name);\n this._keyframes = kf;\n this._keyframesReady = true;\n this._animTime = startTime;\n this._loop = loop;\n // Frame transition tracking restarts at the activation frame so the first\n // tick after activation doesn't fire all events from frame 0 in one go.\n this._lastTickFrame = Math.floor(startTime);\n }\n\n private _deactivate(): void {\n this._active = false;\n this._blendToRest = false;\n this._animName = null;\n this._animData = null;\n this._keyframesReady = false;\n this._animTime = 0;\n this._lastTickFrame = -1;\n }\n\n private _prepareKeyframes(name: string, loop: boolean): Array<KeyframeEntry | null> | null {\n const animData = this._provider(name);\n if (!animData) {\n console.warn(`[AnimationPlayer] Animation \"${name}\" not found`);\n return null;\n }\n const store = animData.skeletalStore;\n if (!store) {\n console.warn(`[AnimationPlayer] Animation \"${name}\" has no keyframes`);\n return null;\n }\n\n // Global cache: all players on the same filtered Animation object + same\n // bone count produce identical buildArmatureKeyframes output, so one build\n // is shared across every enemy of the same rig type.\n const innerKey = `${this._skeleton.numBones}:${loop ? 1 : 0}:${restPoseId(this._skeleton.restPose)}`;\n let perAnim = _sharedKeyframeCache.get(animData);\n if (!perAnim) {\n perAnim = new Map();\n _sharedKeyframeCache.set(animData, perAnim);\n }\n let kf = perAnim.get(innerKey);\n if (!kf) {\n // `translationMask` needs no place in `innerKey`: the cache is keyed by\n // the Animation object itself, and an Animation's mask is set once at\n // parse time and never mutated, so one object can never present two\n // different masks. `filterAnimationForArmature` produces a *new*\n // Animation with its own remapped mask, which is a different cache key.\n kf = buildArmatureKeyframes(\n store.keyframes,\n animData.numFrames,\n this._skeleton.numBones,\n this._skeleton.restPose,\n loop,\n animData.translationMask,\n );\n perAnim.set(innerKey, kf);\n }\n return kf;\n }\n\n private _evalTargetPose(\n boneIdx: number,\n bindT: Float32Array,\n bindR: Float32Array,\n outPos: Vec3,\n outRot: Quat,\n outScale: Vec3,\n ): void {\n if (!this._active || !this._keyframesReady || this._blendToRest) {\n outPos.set(bindT[boneIdx * 3], bindT[boneIdx * 3 + 1], bindT[boneIdx * 3 + 2]);\n outRot.set(bindR[boneIdx * 4], bindR[boneIdx * 4 + 1], bindR[boneIdx * 4 + 2], bindR[boneIdx * 4 + 3]);\n outScale.set(1, 1, 1);\n return;\n }\n\n const entry = this._keyframes[boneIdx];\n if (entry && entry.poses.length > 1) {\n this._evaluateSpline(entry, this._animTime, outPos, outRot, outScale);\n this._applyFromRest(boneIdx, outPos, outRot, outScale, outPos, outRot, outScale);\n } else if (entry && entry.poses.length === 1) {\n const p = entry.poses[0];\n this._applyFromRest(boneIdx, p.position, p.rotation, p.scale, outPos, outRot, outScale);\n } else {\n outPos.set(bindT[boneIdx * 3], bindT[boneIdx * 3 + 1], bindT[boneIdx * 3 + 2]);\n outRot.set(bindR[boneIdx * 4], bindR[boneIdx * 4 + 1], bindR[boneIdx * 4 + 2], bindR[boneIdx * 4 + 3]);\n outScale.set(1, 1, 1);\n }\n }\n\n private _evaluateSpline(\n entry: NonNullable<KeyframeEntry>,\n frameTime: number,\n outPos: Vec3,\n outRot: Quat,\n outScale: Vec3,\n ): void {\n const poses = entry.poses;\n\n let low = 0;\n let high = poses.length - 1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (poses[mid].frame === frameTime) {\n outPos.copy(poses[mid].position);\n outRot.copy(poses[mid].rotation);\n outScale.copy(poses[mid].scale);\n return;\n }\n if (poses[mid].frame < frameTime) low = mid + 1;\n else high = mid - 1;\n }\n\n const i1 = Math.min(Math.max(low, 1), poses.length - 1);\n const i0 = i1 - 1;\n const p0 = poses[i0];\n const p1 = poses[i1];\n const span = Math.max(1e-5, p1.frame - p0.frame);\n const t = Math.min(Math.max((frameTime - p0.frame) / span, 0), 1);\n\n const sr = this._tmpSlerpRot;\n sr.copy(p1.rotation);\n if (p0.rotation.dot(sr) < 0) sr.mulScalar(-1);\n outRot.slerp(p0.rotation, sr, t);\n\n if (entry.spline) {\n // i0 indexes the same keyframe in the spline's times array (plus any\n // ghost-entry offset for looping splines). Skip the spline's own segment\n // search - we already found the segment above.\n entry.spline.evaluateSegment(i0 + entry.spline.keyframeOffset, t, this._splineValues);\n const v = this._splineValues;\n const cl = (val: number, a: number, b: number) =>\n Math.min(Math.max(val, Math.min(a, b)), Math.max(a, b));\n outPos.set(\n cl(v[0], p0.position.x, p1.position.x),\n cl(v[1], p0.position.y, p1.position.y),\n cl(v[2], p0.position.z, p1.position.z),\n );\n outScale.set(\n cl(v[7], p0.scale.x, p1.scale.x),\n cl(v[8], p0.scale.y, p1.scale.y),\n cl(v[9], p0.scale.z, p1.scale.z),\n );\n return;\n }\n outPos.lerp(p0.position, p1.position, t);\n outScale.lerp(p0.scale, p1.scale, t);\n }\n\n private _applyFromRest(\n boneIdx: number,\n srcPos: Vec3, srcRot: Quat, srcScale: Vec3,\n outPos: Vec3, outRot: Quat, outScale: Vec3,\n ): void {\n this._restIn.position = srcPos;\n this._restIn.rotation = srcRot;\n this._restIn.scale = srcScale;\n this._restOut.position = outPos;\n this._restOut.rotation = outRot;\n this._restOut.scale = outScale;\n fromRestRelative(boneIdx, this._restIn, this._skeleton.restPose, this._restOut);\n }\n}\n", "import { Mat4, Vec3 } from '../math';\n\nimport type { Skeleton } from './skeleton';\n\n/**\n * Per-axis scale for a single bone, in a frame aligned to the bone:\n * - `along` - scale down the bone's own axis (lengthen / shorten),\n * - `width` / `thickness` - scale across the bone (the two cross-section axes;\n * their world orientation is bone-dependent, so treat them as \"the two\n * perpendicular directions\" rather than a fixed front/side).\n *\n * Each defaults to `1`. A bare `number` is shorthand for a uniform scale on all\n * three axes.\n *\n * @group Characters & Animation\n */\nexport interface BoneScale {\n along: number;\n width: number;\n thickness: number;\n}\n\n/** A bone scale, or a number meaning uniform scale on all three axes. */\nexport type BoneScaleInput = Partial<BoneScale> | number;\n\n/**\n * Per-bone data that realizes a set of bone scales. Produced by\n * {@link computeBoneStretch}, consumed by {@link Skeleton} (lengthening) and\n * {@link SplatSkinning} (flesh/covariance stretch).\n *\n * @group Characters & Animation\n */\nexport interface BoneStretch {\n /**\n * Per-bone multiplier on the local rest translation. A bone's local\n * translation is its offset from its parent (the parent segment's vector),\n * so scaling it lengthens that segment by the parent's `along` factor.\n * Translation-only \u2192 never inflates covariance, never compounds down a\n * chain. Indexed by bone; `1` = unchanged.\n */\n lengthScale: Float32Array;\n /**\n * Per-bone local stretch matrix (`F\u00B7diag(along,width,thickness)\u00B7F\u1D40` in the\n * bone-aligned frame `F`), folded into the skinning palette so the bone's\n * Gaussians scale on all three axes and their covariances follow. Identity\n * for unscaled bones. Indexed by bone.\n */\n covStretch: Mat4[];\n /** True when at least one bone is actually scaled. */\n any: boolean;\n}\n\nconst IDENT: BoneScale = { along: 1, width: 1, thickness: 1 };\n\nfunction normalize(v: BoneScaleInput): BoneScale {\n if (typeof v === 'number') return { along: v, width: v, thickness: v };\n return {\n along: v.along ?? 1,\n width: v.width ?? 1,\n thickness: v.thickness ?? 1,\n };\n}\n\nfunction isIdentity(s: BoneScale): boolean {\n return s.along === 1 && s.width === 1 && s.thickness === 1;\n}\n\n/**\n * Translate a map of per-bone scales into the {@link BoneStretch} arrays.\n * `factors[boneName]` scales that bone's flesh + segment (e.g.\n * `{ thigh_l: { along: 1.3 }, calf_l: { along: 1.3 } }` \u2192 a 1.3\u00D7 longer left\n * leg; `{ upperarm_l: { width: 1.4, thickness: 1.4 } }` \u2192 a beefier arm).\n * Bones not listed stay at `1`.\n *\n * Correct for arbitrary bone sets (limbs, spine, \u2026) with no boundary\n * compensation: lengthening lives in per-segment translations (no cumulative\n * scale), and the flesh scale is per-bone in the palette (non-propagating).\n * Each bone scales in ITS OWN frame, so bones at any orientation scale\n * correctly.\n *\n * @param skeleton Rig to read the rest pose / hierarchy from.\n * @param boneNames Bone names in index order (from the armature).\n * @param factors Per-bone scales keyed by bone name.\n */\nexport function computeBoneStretch(\n skeleton: Skeleton,\n boneNames: readonly string[],\n factors: Record<string, BoneScaleInput>,\n): BoneStretch {\n const n = skeleton.numBones;\n const parents = skeleton.parents;\n const restT = skeleton.restPose.positions; // local rest translations (per bone)\n\n const scaleOf: BoneScale[] = new Array(n);\n for (let i = 0; i < n; i++) scaleOf[i] = IDENT;\n let any = false;\n for (const name in factors) {\n const s = normalize(factors[name]);\n if (isIdentity(s)) continue;\n const idx = boneNames.indexOf(name);\n if (idx >= 0) {\n scaleOf[idx] = s;\n any = true;\n }\n }\n\n const children = buildChildren(parents, n);\n\n // Lengthening: a parent's `along` scale lengthens the offsets of its children.\n const lengthScale = new Float32Array(n).fill(1);\n for (let i = 0; i < n; i++) {\n const p = parents[i];\n if (p >= 0 && p < n) lengthScale[i] = scaleOf[p].along;\n }\n\n // Flesh stretch: per-bone 3-axis scale in a frame aligned to the bone.\n const covStretch: Mat4[] = Array.from({ length: n }, () => new Mat4());\n const e0 = new Vec3();\n const e1 = new Vec3();\n const e2 = new Vec3();\n for (let b = 0; b < n; b++) {\n const s = scaleOf[b];\n if (isIdentity(s)) continue;\n if (!boneAxis(b, children, scaleOf, restT, e0)) continue; // no axis \u2192 skip\n perpendicularFrame(e0, e1, e2);\n setFrameScale(covStretch[b], e0, e1, e2, s);\n }\n\n return { lengthScale, covStretch, any };\n}\n\nfunction buildChildren(parents: Int32Array, n: number): number[][] {\n const children: number[][] = Array.from({ length: n }, () => []);\n for (let i = 0; i < n; i++) {\n const p = parents[i];\n if (p >= 0 && p < n) children[p].push(i);\n }\n return children;\n}\n\n/**\n * Write the bone's local axis (the \"along\" direction) into `out`. A bone spans\n * from its joint to its child's, so the axis is the (primary) child's offset;\n * for a leaf bone, fall back to the bone's own offset from its parent. Returns\n * false if neither yields a usable direction.\n */\nfunction boneAxis(\n b: number,\n children: number[][],\n scaleOf: BoneScale[],\n restT: { x: number; y: number; z: number }[],\n out: Vec3,\n): boolean {\n const child = primaryChild(b, children, scaleOf, restT);\n const off = child >= 0 ? restT[child] : restT[b];\n out.set(off.x, off.y, off.z);\n if (out.length() < 1e-6) return false;\n out.normalize();\n return true;\n}\n\n/**\n * Pick the child that defines a bone's axis. Single-child bones are\n * unambiguous; for a branch (e.g. the top spine bone, parent of both clavicles\n * and the neck) prefer a scaled child (the region's continuation), else the\n * child with the longest offset.\n */\nfunction primaryChild(\n b: number,\n children: number[][],\n scaleOf: BoneScale[],\n restT: { x: number; y: number; z: number }[],\n): number {\n const kids = children[b];\n if (kids.length === 0) return -1;\n if (kids.length === 1) return kids[0];\n let best = -1;\n let bestLen = -1;\n for (const c of kids) {\n if (!isIdentity(scaleOf[c])) return c;\n const o = restT[c];\n const len = o.x * o.x + o.y * o.y + o.z * o.z;\n if (len > bestLen) {\n bestLen = len;\n best = c;\n }\n }\n return best;\n}\n\n/** Complete `e0` to an orthonormal basis (e1, e2) with a stable seed choice. */\nfunction perpendicularFrame(e0: Vec3, e1: Vec3, e2: Vec3): void {\n // Seed with whichever cardinal axis is least parallel to e0, then Gram-Schmidt.\n if (Math.abs(e0.x) <= Math.abs(e0.y) && Math.abs(e0.x) <= Math.abs(e0.z)) {\n e1.set(1, 0, 0);\n } else if (Math.abs(e0.y) <= Math.abs(e0.z)) {\n e1.set(0, 1, 0);\n } else {\n e1.set(0, 0, 1);\n }\n const d = e1.dot(e0);\n e1.set(e1.x - d * e0.x, e1.y - d * e0.y, e1.z - d * e0.z).normalize();\n e2.cross(e0, e1); // already unit (e0, e1 orthonormal)\n}\n\n/** In-place: m's 3\u00D73 = F\u00B7diag(along,width,thickness)\u00B7F\u1D40, F = [e0 e1 e2]. */\nfunction setFrameScale(\n m: Mat4,\n e0: Vec3,\n e1: Vec3,\n e2: Vec3,\n s: BoneScale,\n): void {\n const { along: a, width: w, thickness: t } = s;\n const d = m.data; // identity to start (column-major; the matrix is symmetric)\n for (let i = 0; i < 3; i++) {\n const c0 = i === 0 ? e0.x : i === 1 ? e0.y : e0.z;\n const c1 = i === 0 ? e1.x : i === 1 ? e1.y : e1.z;\n const c2 = i === 0 ? e2.x : i === 1 ? e2.y : e2.z;\n for (let j = 0; j < 3; j++) {\n const r0 = j === 0 ? e0.x : j === 1 ? e0.y : e0.z;\n const r1 = j === 0 ? e1.x : j === 1 ? e1.y : e1.z;\n const r2 = j === 0 ? e2.x : j === 1 ? e2.y : e2.z;\n d[i * 4 + j] = a * c0 * r0 + w * c1 * r1 + t * c2 * r2;\n }\n }\n}\n", "import { Quat, Vec3 } from '../math';\n\n/**\n * Per-bone local TRS for a whole rig. The seam between\n * {@link AnimationPlayer} (which writes pose values) and\n * {@link Skeleton} (which composes them into world transforms).\n *\n * Three parallel arrays of length `numBones`. Values live in armature-local\n * bone space - absolute, not rest-relative. Allocation happens once;\n * AnimationPlayer mutates entries in place each frame.\n *\n * @group Characters & Animation\n */\nexport class Pose {\n readonly positions: Vec3[];\n readonly rotations: Quat[];\n readonly scales: Vec3[];\n\n constructor(numBones: number) {\n this.positions = new Array(numBones);\n this.rotations = new Array(numBones);\n this.scales = new Array(numBones);\n for (let i = 0; i < numBones; i++) {\n this.positions[i] = new Vec3();\n this.rotations[i] = new Quat();\n this.scales[i] = new Vec3(1, 1, 1);\n }\n }\n\n get numBones(): number {\n return this.positions.length;\n }\n\n /** Copy every bone from `other` into this pose. */\n copyFrom(other: Pose): void {\n const n = this.positions.length;\n for (let i = 0; i < n; i++) {\n this.positions[i].copy(other.positions[i]);\n this.rotations[i].copy(other.rotations[i]);\n this.scales[i].copy(other.scales[i]);\n }\n }\n\n /**\n * Reset every bone to the bind-pose values held in `bindT` (flat\n * `[x,y,z]*numBones`) and `bindR` (flat `[x,y,z,w]*numBones`). Scales reset\n * to unit.\n */\n setToBind(bindT: Float32Array, bindR: Float32Array): void {\n const n = this.positions.length;\n for (let i = 0; i < n; i++) {\n this.positions[i].set(bindT[i * 3], bindT[i * 3 + 1], bindT[i * 3 + 2]);\n this.rotations[i].set(bindR[i * 4], bindR[i * 4 + 1], bindR[i * 4 + 2], bindR[i * 4 + 3]);\n this.scales[i].set(1, 1, 1);\n }\n }\n}\n", "import { Mat4, Quat, Vec3 } from '../math';\n\n/**\n * Walk the rig's rest pose to produce world-space bind-pose matrices, one per\n * bone. Parents are expected to come before their children in index order (the\n * skeleton library's bone arrays satisfy this).\n *\n * Returns `null` if any of the three arrays is missing - the armature's\n * `armatureData` carries them as optional fields.\n */\nexport function computeBindPoseTransforms(\n numBones: number,\n restTranslations: Float32Array,\n restRotations: Float32Array,\n parents: Int32Array,\n): Mat4[] {\n const wt = new Array<Mat4>(numBones);\n for (let i = 0; i < numBones; i++) wt[i] = new Mat4();\n\n const tmpPos = new Vec3();\n const tmpRot = new Quat();\n const tmpScale = new Vec3(1, 1, 1);\n const tmpLocal = new Mat4();\n\n for (let i = 0; i < numBones; i++) {\n tmpPos.set(restTranslations[i * 3], restTranslations[i * 3 + 1], restTranslations[i * 3 + 2]);\n tmpRot.set(restRotations[i * 4], restRotations[i * 4 + 1], restRotations[i * 4 + 2], restRotations[i * 4 + 3]);\n tmpLocal.setTRS(tmpPos, tmpRot, tmpScale);\n\n const pi = parents[i];\n if (pi >= 0 && pi < numBones) {\n wt[i].mul2(wt[pi], tmpLocal);\n } else {\n wt[i].copy(tmpLocal);\n }\n }\n return wt;\n}\n\n/**\n * Compute the inverse of each matrix in `bindPose`. Returns a new array; the\n * input is left untouched.\n */\nexport function invertBindPose(bindPose: Mat4[]): Mat4[] {\n return bindPose.map((m) => {\n const inv = new Mat4();\n inv.copy(m);\n inv.invert();\n return inv;\n });\n}\n", "import { Mat4, Quat, Vec3 } from '../math';\n\nimport { computeBindPoseTransforms, invertBindPose } from '../anim/bind-pose';\nimport type { RestPose } from '../anim/rest-relative';\nimport type { ArmatureData } from '../types';\n\nimport type { Pose } from './pose';\n\n/**\n * Rig data and skeletal math for one character. Owns the bone hierarchy, the\n * rest pose, and the (lazy) inverse-bind pose. Composes per-bone local\n * transforms into world-space matrices.\n *\n * Pure data + math - no three.js object, no `SplatEngine`, no `Splat`. Safe to\n * construct in tests with a fixture rig.\n *\n * @group Characters & Animation\n */\nexport class Skeleton {\n readonly numBones: number;\n /** Parent bone index per bone. `-1` for root bones. */\n readonly parents: Int32Array;\n /** Flat bind-pose translations: `[x,y,z]*numBones`. */\n readonly bindT: Float32Array;\n /** Flat bind-pose rotations (quaternions): `[x,y,z,w]*numBones`. */\n readonly bindR: Float32Array;\n /** Rest pose as parallel `Vec3`/`Quat` arrays. */\n readonly restPose: RestPose;\n\n /**\n * Optional per-bone multiplier on the local rest translation, applied during\n * FK. A bone's local translation is its offset from its parent, so scaling\n * it lengthens that segment - this is the lengthening half of bone-length\n * scaling (see {@link computeBoneStretch}). It deliberately affects only the\n * translation, not the bone's orientation/scale, so it never inflates\n * Gaussian covariance and never compounds down a chain. `null` = unscaled\n * (the normal path). The bind/inverse-bind are intentionally NOT rescaled,\n * so the palette carries the standard\u2192stretched delta.\n */\n lengthScale: Float32Array | null = null;\n\n private readonly _children: number[][];\n private readonly _rootBones: number[];\n private _inverseBindPose: Mat4[] | null = null;\n private readonly _tmpLocalMat = new Mat4();\n private readonly _tmpPos = new Vec3();\n private readonly _kfStack: number[] = [];\n\n constructor(armatureData: ArmatureData) {\n const { stdMaleRestTranslations: bt, stdMaleRestRotations: br, stdMaleParents: parents } = armatureData;\n if (!bt || !br || !parents) {\n throw new Error('Skeleton requires stdMaleRestTranslations/Rotations/Parents on ArmatureData');\n }\n\n this.numBones = armatureData.numBones;\n this.bindT = bt;\n this.bindR = br;\n this.parents = parents;\n\n // Hierarchy\n const children: number[][] = new Array(this.numBones);\n for (let i = 0; i < this.numBones; i++) children[i] = [];\n const roots: number[] = [];\n for (let i = 0; i < this.numBones; i++) {\n const pi = parents[i];\n if (pi >= 0 && pi < this.numBones) {\n children[pi].push(i);\n } else {\n roots.push(i);\n }\n }\n if (roots.length === 0) roots.push(0);\n this._children = children;\n this._rootBones = roots;\n\n // Rest pose (decomposed bind for rest-relative animation evaluation).\n const positions: Vec3[] = [];\n const rotations: Quat[] = [];\n const scales: Vec3[] = [];\n for (let i = 0; i < this.numBones; i++) {\n positions.push(new Vec3(bt[i * 3], bt[i * 3 + 1], bt[i * 3 + 2]));\n rotations.push(new Quat(br[i * 4], br[i * 4 + 1], br[i * 4 + 2], br[i * 4 + 3]));\n scales.push(new Vec3(1, 1, 1));\n }\n this.restPose = { positions, rotations, scales };\n }\n\n /**\n * World-space inverse-bind pose, one matrix per bone. Lazy - bind pose is\n * only needed once splat skinning starts pushing transforms.\n */\n get inverseBindPose(): Mat4[] {\n if (!this._inverseBindPose) {\n const bindPose = computeBindPoseTransforms(this.numBones, this.bindT, this.bindR, this.parents);\n this._inverseBindPose = invertBindPose(bindPose);\n }\n return this._inverseBindPose;\n }\n\n /**\n * Compose local-space `pose` into world-space matrices, prefixed by\n * `entityWorldTransform`. Walks the hierarchy parent-first so child world\n * transforms read the freshly-written parent.\n *\n * `out` is reused - entries are created lazily if missing, but the caller\n * owns the buffer (no per-frame allocation).\n */\n applyLocal(pose: Pose, entityWorldTransform: Mat4, out: Mat4[]): void {\n const numBones = this.numBones;\n for (let i = out.length; i < numBones; i++) out[i] = new Mat4();\n\n const localMat = this._tmpLocalMat;\n const stack = this._kfStack;\n const parents = this.parents;\n const positions = pose.positions;\n const rotations = pose.rotations;\n const scales = pose.scales;\n\n for (const rootIdx of this._rootBones) {\n stack.length = 0;\n stack.push(rootIdx);\n while (stack.length > 0) {\n const bi = stack.pop()!;\n const ls = this.lengthScale;\n if (ls && ls[bi] !== 1) {\n // Lengthen this bone's segment: scale only its local translation.\n const p = positions[bi];\n const f = ls[bi];\n this._tmpPos.set(p.x * f, p.y * f, p.z * f);\n localMat.setTRS(this._tmpPos, rotations[bi], scales[bi]);\n } else {\n localMat.setTRS(positions[bi], rotations[bi], scales[bi]);\n }\n const pi = parents[bi];\n if (pi < 0 || pi >= numBones) {\n out[bi].mul2(entityWorldTransform, localMat);\n } else {\n out[bi].mul2(out[pi], localMat);\n }\n const kids = this._children[bi];\n for (let ci = 0; ci < kids.length; ci++) stack.push(kids[ci]);\n }\n }\n }\n}\n", "import { getStripped1185Names } from '../loader/skeleton';\nimport type { SkeletonLibrary } from '../types';\n\nimport type { Splat } from './splat';\n\n/**\n * Build the source\u2192target bone remap when the splat's `.bin` bundle was\n * authored against a wider skeleton than the armature uses (e.g. a 1185-bone\n * source on the 86-bone std-male rig, or a 441-bone full body+facial source\n * on the 86-bone body rig).\n *\n * Returns `null` when no remap is needed (source and target bone counts\n * match) or when the skeleton library doesn't carry enough naming metadata to\n * resolve the mapping. Unmapped bones in the result are `-1`, except facial\n * bones (`FACIAL_*`), which fall back to the `head` bone so the splats track\n * head motion rather than snapping to root.\n */\nexport function buildSourceBoneRemap(\n splat: Splat,\n numBones: number,\n skeletonLibrary: SkeletonLibrary | undefined,\n): Int32Array | null {\n const sourceCount = splat.sourceBoneCount;\n if (!sourceCount || sourceCount === numBones) return null;\n if (!skeletonLibrary) return null;\n\n let targetNames: string[] | undefined;\n if (skeletonLibrary.boneNames?.length === numBones) targetNames = skeletonLibrary.boneNames;\n else if (skeletonLibrary.boneNames441?.length === numBones) targetNames = skeletonLibrary.boneNames441;\n if (!targetNames) return null;\n\n let sourceNames: string[] | undefined;\n const fullNames = skeletonLibrary.skeleton1185Names;\n if (fullNames && sourceCount === fullNames.length) {\n sourceNames = fullNames;\n } else if (fullNames && sourceCount === fullNames.length - 1 && fullNames[0] === 'joints_grp') {\n sourceNames = fullNames.slice(1);\n } else if (sourceCount === skeletonLibrary.boneNames441?.length) {\n sourceNames = skeletonLibrary.boneNames441;\n } else if (sourceCount === skeletonLibrary.boneNames?.length) {\n sourceNames = skeletonLibrary.boneNames;\n } else {\n const stripped = getStripped1185Names(skeletonLibrary);\n if (stripped && stripped.length === sourceCount) sourceNames = stripped;\n }\n if (!sourceNames) return null;\n\n const targetByName = new Map<string, number>();\n targetNames.forEach((n, i) => targetByName.set(n, i));\n\n // Fallback target for facial bones when target armature has no facial\n // bones (e.g. 86-bone std male rig loaded with a 441-bone full bin) -\n // facial splats track head motion rather than snapping to root.\n const facialFallback = targetByName.get('head') ?? -1;\n\n const remap = new Int32Array(sourceCount);\n for (let i = 0; i < sourceCount; i++) {\n const name = sourceNames[i];\n const t = targetByName.get(name);\n if (t !== undefined) {\n remap[i] = t;\n } else if (name.startsWith('FACIAL_')) {\n remap[i] = facialFallback;\n } else {\n remap[i] = -1;\n }\n }\n return remap;\n}\n\n/**\n * Allocate the splat's slice of the shared transform palette and rewrite its\n * bone-index texture so each splat's K influences point at the palette slots\n * the armature will write into.\n *\n * Splats with no resolvable target bone (typically facial influences on a\n * body-only rig that can't fall back to `head`) get weight 0 - they stay at\n * rest instead of snapping to bone 0.\n *\n * Returns the first palette index allocated for this splat's bone block.\n * Palette slot for bone `i` is always `firstIdx + i`.\n */\nexport function initializeSplatBoneMapping(\n splat: Splat,\n numBones: number,\n skeletonLibrary: SkeletonLibrary | undefined,\n): number {\n const weights = splat.splatWeights;\n if (!weights) throw new Error('No weights data');\n\n const boneIndices = weights.indices;\n const boneWeights = weights.weights;\n const numSplats = boneIndices.length / 4;\n const palette = splat.transformPalette;\n const firstIdx = palette.alloc(numBones);\n\n const srcToTarget = buildSourceBoneRemap(splat, numBones, skeletonLibrary);\n\n const indicesData = splat.boneIndicesData;\n const weightsData = splat.boneWeightsData;\n if (!indicesData || !weightsData) {\n throw new Error('Bone textures not initialized');\n }\n\n for (let s = 0; s < numSplats; s++) {\n for (let j = 0; j < 4; j++) {\n const rawIdx = boneIndices[s * 4 + j];\n const targetIdx = srcToTarget ? srcToTarget[rawIdx] ?? -1 : rawIdx;\n if (targetIdx < 0 || targetIdx >= numBones) {\n indicesData[s * 4 + j] = firstIdx;\n weightsData[s * 4 + j] = 0;\n } else {\n indicesData[s * 4 + j] = firstIdx + targetIdx;\n weightsData[s * 4 + j] = boneWeights[s * 4 + j];\n }\n }\n }\n\n splat.markBoneTexturesDirty();\n\n return firstIdx;\n}\n\n/**\n * Walk the splat's per-influence bone-index buffer and return the sorted list\n * of distinct bone indices it actually references. Used to skip palette writes\n * for bones no splat influences (e.g. a 441-bone rig where ~half the bones are\n * facial and the splat has no facial weights).\n *\n * Returns an empty `Int32Array` when the splat has no weights data - callers\n * treat that as \"fall back to walking every bone.\"\n */\nexport function buildSplatBoneIndexList(splat: Splat, numBones: number): Int32Array {\n const weights = splat.splatWeights;\n if (!weights) return new Int32Array(0);\n const used = new Uint8Array(numBones);\n for (let i = 0; i < weights.indices.length; i++) {\n const idx = weights.indices[i] | 0;\n if (idx >= 0 && idx < numBones) used[idx] = 1;\n }\n let count = 0;\n for (let i = 0; i < numBones; i++) if (used[i]) count++;\n const list = new Int32Array(count);\n let j = 0;\n for (let i = 0; i < numBones; i++) if (used[i]) list[j++] = i;\n return list;\n}\n", "import type { Frustum } from 'three';\n\nimport { Mat4 } from '../math';\nimport {\n buildSplatBoneIndexList,\n initializeSplatBoneMapping,\n} from '../splat/bone-binding';\nimport type { Splat } from '../splat/splat';\nimport type { SkeletonLibrary } from '../types';\n\nimport type { Skeleton } from './skeleton';\n\n/**\n * Per-character splat skinning coordinator. Owns the set of {@link Splat}s\n * driven by an armature, their palette-slot maps, and the GPU push that\n * uploads bone matrices each frame.\n *\n * Also owns the frustum-visibility gate: the armature can skip the expensive\n * pose-eval + skinning path when no linked splat is on-screen.\n *\n * @group Characters & Animation\n */\nexport class SplatSkinning {\n /** Splats currently driven by this skinning unit. */\n readonly linkedSplats = new Set<Splat>();\n\n /**\n * Optional per-bone local stretch matrices (the covariance half of\n * bone-length scaling - see {@link computeBoneStretch}). When set, each\n * bone's palette entry gets this stretch folded in, the per-bone scale is\n * NOT normalized out of the palette, and linked splats render with the\n * `USE_NONRIGID_COV` shader path so Gaussian covariances follow the stretch.\n * `null` = rigid skinning (the normal path). Set via {@link setCovStretch}.\n */\n covStretch: Mat4[] | null = null;\n\n private readonly _skeleton: Skeleton;\n private readonly _skeletonLibrary: SkeletonLibrary | undefined;\n\n // firstPaletteIdx[splat] - palette slot for bone i is firstIdx + i (linear, no Map lookup needed)\n private readonly _bonePaletteFirstIdx = new Map<Splat, number>();\n private readonly _boneIndexLists = new Map<Splat, Int32Array>();\n\n private readonly _finalBoneTransforms: Mat4[];\n private readonly _armatureWorldToLocal = new Mat4();\n\n constructor(skeleton: Skeleton, skeletonLibrary: SkeletonLibrary | undefined) {\n this._skeleton = skeleton;\n this._skeletonLibrary = skeletonLibrary;\n const n = skeleton.numBones;\n this._finalBoneTransforms = Array.from({ length: n }, () => new Mat4());\n }\n\n link(splat: Splat): void {\n this.linkedSplats.add(splat);\n }\n\n unlink(splat: Splat): void {\n this.linkedSplats.delete(splat);\n this._bonePaletteFirstIdx.delete(splat);\n this._boneIndexLists.delete(splat);\n }\n\n /**\n * Set (or clear with `null`) the per-bone covariance-stretch matrices for\n * bone-length scaling. Also flips the `USE_NONRIGID_COV` shader path on every\n * linked splat so covariances follow the stretch. Pass `null` to return to\n * rigid skinning.\n */\n setCovStretch(mats: Mat4[] | null): void {\n this.covStretch = mats;\n for (const splat of this.linkedSplats) splat.setNonRigidCovariance(!!mats);\n }\n\n /**\n * Returns `true` when at least one linked splat's bounding sphere intersects\n * the camera frustum. Used by the armature to short-circuit the per-frame\n * skinning math for off-screen characters.\n *\n * When `frustum` is missing (e.g. before the first `engine.update()`) returns `true` -\n * the conservative choice is to do the extra work rather than freeze a\n * character's pose.\n */\n anyVisible(frustum: Frustum | undefined): boolean {\n if (this.linkedSplats.size === 0) return false;\n if (!frustum) return true;\n for (const splat of this.linkedSplats) {\n if (splat.isInFrustum(frustum)) return true;\n }\n return false;\n }\n\n /**\n * Compose `worldTransforms` (one per bone) with the pivot's inverse world\n * transform and the inverse-bind pose, then upload the resulting palette to\n * every linked splat. `worldTransforms[i]` is the i-th bone's matrix in\n * world space, as produced by {@link Skeleton.applyLocal}.\n *\n * Strips scale from the per-bone linear part before composing with the\n * inverse bind. Without this, any net scale (from `splat.object3D` world scale\n * or animated bone scale) inflates Gaussian sigmas on the GPU via the\n * palette's column lengths - visible as radial streaks on hands/fists, and\n * desyncs CPU-computed centers from GPU-rendered positions.\n */\n pushTransforms(worldTransforms: Mat4[], entityWorldTransform: Mat4, skipPositions = false): void {\n if (this.linkedSplats.size === 0) return;\n\n const inverseBindPose = this._skeleton.inverseBindPose;\n if (inverseBindPose.length === 0) return;\n\n const armatureWorldToLocal = this._armatureWorldToLocal;\n // Fast inverse for TRS matrices (no shear). Transpose the 3\u00D73 rotation\n // block after normalizing out scale, then compute the rotated-negated\n // translation. ~2\u00D7 fewer ops than the general Mat4 cofactor expansion.\n {\n const ed = entityWorldTransform.data;\n const ad = armatureWorldToLocal.data;\n const sx2 = 1 / Math.max(ed[0]*ed[0] + ed[1]*ed[1] + ed[2]*ed[2], 1e-16);\n const sy2 = 1 / Math.max(ed[4]*ed[4] + ed[5]*ed[5] + ed[6]*ed[6], 1e-16);\n const sz2 = 1 / Math.max(ed[8]*ed[8] + ed[9]*ed[9] + ed[10]*ed[10], 1e-16);\n ad[0] = ed[0]*sx2; ad[1] = ed[4]*sy2; ad[2] = ed[8]*sz2; ad[3] = 0;\n ad[4] = ed[1]*sx2; ad[5] = ed[5]*sy2; ad[6] = ed[9]*sz2; ad[7] = 0;\n ad[8] = ed[2]*sx2; ad[9] = ed[6]*sy2; ad[10] = ed[10]*sz2; ad[11] = 0;\n const tx = ed[12], ty = ed[13], tz = ed[14];\n ad[12] = -(ad[0]*tx + ad[4]*ty + ad[8]*tz);\n ad[13] = -(ad[1]*tx + ad[5]*ty + ad[9]*tz);\n ad[14] = -(ad[2]*tx + ad[6]*ty + ad[10]*tz);\n ad[15] = 1;\n }\n\n const numBones = this._skeleton.numBones;\n const finalBoneTransforms = this._finalBoneTransforms;\n for (let boneIdx = 0; boneIdx < numBones; boneIdx++) {\n const ft = finalBoneTransforms[boneIdx];\n ft.mul2(armatureWorldToLocal, worldTransforms[boneIdx]);\n\n const ld = ft.data;\n // Bone-length scaling: when covStretch is set we WANT the scale\n // preserved (the deformation IS a stretch), so skip the normalization.\n if (!this.covStretch) {\n // Inline sqrt - Math.hypot is variadic and ~3-4\u00D7 slower than the\n // inline Math.sqrt(x*x+y*y+z*z) form. Called numBones \u00D7 3 per\n // character per frame; the spread shows up in CPU profiles.\n const l0 = ld[0] * ld[0] + ld[1] * ld[1] + ld[2] * ld[2];\n const l1 = ld[4] * ld[4] + ld[5] * ld[5] + ld[6] * ld[6];\n const l2 = ld[8] * ld[8] + ld[9] * ld[9] + ld[10] * ld[10];\n const il0 = 1 / Math.max(Math.sqrt(l0), 1e-8);\n const il1 = 1 / Math.max(Math.sqrt(l1), 1e-8);\n const il2 = 1 / Math.max(Math.sqrt(l2), 1e-8);\n ld[0] *= il0; ld[1] *= il0; ld[2] *= il0;\n ld[4] *= il1; ld[5] *= il1; ld[6] *= il1;\n ld[8] *= il2; ld[9] *= il2; ld[10] *= il2;\n }\n\n // Bone-length scaling: fold in this bone's local along-axis stretch\n // (between the world transform and the inverse bind, so it acts in the\n // bone's own frame and affects only this bone's Gaussians).\n if (this.covStretch) ft.mul(this.covStretch[boneIdx]);\n\n // In-place: ft = ft * inverseBindPose[boneIdx]\n ft.mul(inverseBindPose[boneIdx]);\n }\n\n for (const splat of this.linkedSplats) {\n if (!splat.splatWeights) continue;\n // Skip inactive LODs entirely - for a multi-level character only one\n // linked splat is enabled at a time. Saves the dominant CPU cost\n // (palette upload + updatePositions) on hidden levels.\n if (!splat.renderingEnabled) continue;\n\n let firstPaletteIdx = this._bonePaletteFirstIdx.get(splat);\n if (firstPaletteIdx === undefined) {\n firstPaletteIdx = initializeSplatBoneMapping(splat, numBones, this._skeletonLibrary);\n this._bonePaletteFirstIdx.set(splat, firstPaletteIdx);\n }\n let boneIndexList = this._boneIndexLists.get(splat);\n if (!boneIndexList) {\n boneIndexList = buildSplatBoneIndexList(splat, numBones);\n this._boneIndexLists.set(splat, boneIndexList);\n }\n\n const palette = splat.transformPalette;\n if (boneIndexList.length > 0) {\n for (let j = 0; j < boneIndexList.length; j++) {\n const boneIdx = boneIndexList[j];\n palette.setTransform(firstPaletteIdx + boneIdx, finalBoneTransforms[boneIdx]);\n }\n } else {\n for (let boneIdx = 0; boneIdx < numBones; boneIdx++) {\n palette.setTransform(firstPaletteIdx + boneIdx, finalBoneTransforms[boneIdx]);\n }\n }\n\n const uploaded = palette.upload();\n if (uploaded) {\n // skipPositions: the GPU palette is still uploaded (so the visible\n // pose is current), but the CPU re-skin of the centres is skipped.\n // The depth-sort order lags until the next full update.\n if (!skipPositions) {\n splat.updatePositions(this._finalBoneTransforms);\n }\n }\n }\n }\n\n /** Request a re-sort on every linked splat (e.g. after a transform change). */\n requestSortAll(): void {\n for (const splat of this.linkedSplats) splat.requestSort();\n }\n}\n", "import {\n ClampToEdgeWrapping,\n DataTexture,\n FloatType,\n Frustum,\n Group,\n Matrix4,\n NearestFilter,\n RGBAFormat,\n Vector3,\n} from 'three';\nimport type { Camera, IUniform, Object3D } from 'three';\n\nimport type { Animation } from './animation';\nimport type { AnimLodPreset } from './armature';\nimport type { PointLight } from './lighting/point-light';\nimport type { SkyLight } from './lighting/sky-light';\nimport type { SunLight } from './lighting/sun-light';\nimport { loadSkeletonLibrary } from './loader/skeleton';\nimport type { SkeletonLibrary } from './loader/skeleton';\nimport type { SplatBackend } from './splat/backend';\n\n/**\n * Lights that splats respond to. Splats carry baked colour, so this is a\n * multiplier on that colour rather than a shading model: ambient plus sun plus\n * distance-attenuated point lights, evaluated at each splat's centre.\n *\n * With no sun and no sky the factor is exactly 1 and splats render as authored.\n *\n * @group Lighting\n */\nexport interface SceneLighting {\n sun: SunLight | null;\n sky: SkyLight | null;\n points: PointLight[];\n}\n\n/** @group Engine */\nexport interface SplatEngineOptions {\n /**\n * Parent for everything the engine creates. When given, the engine's\n * {@link SplatEngine.contentRoot} is added to it, so loaded characters and\n * environments appear without a further `scene.add`.\n */\n scene?: Object3D;\n /** Camera used for visibility gating and distance LOD. Can also be passed to {@link SplatEngine.update}. */\n camera?: Camera;\n /**\n * Force a particular splat backend. Leave unset: each splat then picks the\n * backend matching the renderer that first draws it.\n */\n backend?: SplatBackend;\n}\n\nfunction createPointLightTexture(capacity: number): DataTexture {\n const w = Math.max(capacity, 1);\n const texture = new DataTexture(new Float32Array(w * 2 * 4), w, 2, RGBAFormat, FloatType);\n texture.name = 'lightingPointLights';\n texture.minFilter = NearestFilter;\n texture.magFilter = NearestFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * Shared state for a set of splat characters and environments: the skeleton\n * library, the registry of named animation clips, the lights, and the\n * per-frame update that advances every character.\n *\n * This is the three.js counterpart of the PlayCanvas build's `Scene`, minus\n * everything three.js already owns. It creates no renderer, canvas or camera:\n * you keep your own `WebGLRenderer`, `Scene` and render loop, and call\n * {@link SplatEngine.update} once per frame before rendering.\n *\n * ```ts\n * const engine = new SplatEngine({ scene, camera });\n * const character = await Character.load(engine, '/assets/hero.vsplat');\n * await Animation.loadGlb(engine, '/assets/idle.glb', 'idle');\n * character.playAnimation('idle', { loop: true });\n *\n * renderer.setAnimationLoop(() => {\n * engine.update(clock.getDelta());\n * renderer.render(scene, camera);\n * });\n * ```\n *\n * @group Engine\n */\nexport class SplatEngine {\n /** Parent of every character and environment loaded through this engine. */\n readonly contentRoot: Group;\n /** A forced splat backend, or `null` to pick per renderer (the default). */\n readonly backend: SplatBackend | null;\n readonly skeletonLibrary: SkeletonLibrary;\n /** Clips by name. Populated by {@link Animation.register} and the `Animation.load*` helpers. */\n readonly skeletalAnimationLibrary = new Map<string, Animation>();\n readonly lighting: SceneLighting = { sun: null, sky: null, points: [] };\n\n /** Camera used for visibility gating and distance LOD. `null` disables both. */\n camera: Camera | null;\n /** Default animation-LOD bands for `Armature.setAnimationLod()` called with no arguments. */\n animLodPreset?: AnimLodPreset;\n /** Number of {@link SplatEngine.update} calls so far. */\n frame = 0;\n /** {@link SplatEngine.frame} of the most recent character pose evaluation. */\n characterPoseUpdatedFrame = -1;\n\n /**\n * Lighting uniforms shared by every splat material this engine creates.\n * Refreshed by {@link SplatEngine.syncLighting}.\n * @internal\n */\n readonly lightingUniforms: {\n uSunColor: IUniform<Vector3>;\n uSunIntensity: IUniform<number>;\n uAmbientColor: IUniform<Vector3>;\n uPointLightCount: IUniform<number>;\n uPointLightTex: IUniform<DataTexture>;\n };\n\n private readonly _updaters = new Set<(dt: number) => void>();\n private readonly _frustum = new Frustum();\n private readonly _projScreen = new Matrix4();\n private readonly _cameraPosition = new Vector3();\n private _frustumValid = false;\n private _pointLightCapacity = 1;\n private _destroyed = false;\n\n constructor(opts?: SplatEngineOptions) {\n this.contentRoot = new Group();\n this.contentRoot.name = 'splatEngineContent';\n opts?.scene?.add(this.contentRoot);\n this.camera = opts?.camera ?? null;\n this.backend = opts?.backend ?? null;\n this.skeletonLibrary = loadSkeletonLibrary();\n this.lightingUniforms = {\n uSunColor: { value: new Vector3(0, 0, 0) },\n uSunIntensity: { value: 0 },\n uAmbientColor: { value: new Vector3(1, 1, 1) },\n uPointLightCount: { value: 0 },\n uPointLightTex: { value: createPointLightTexture(this._pointLightCapacity) },\n };\n }\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n private static _shared: SplatEngine | null = null;\n\n /**\n * The engine the loaders use when none is given: one shared skeleton\n * library, animation registry and set of lights for the whole page. Created\n * on first use, attached to no scene.\n */\n static get shared(): SplatEngine {\n if (!SplatEngine._shared || SplatEngine._shared.destroyed) SplatEngine._shared = new SplatEngine();\n return SplatEngine._shared;\n }\n\n /**\n * Advance every auto-updating character by `dt` seconds. Call once per\n * frame, before rendering.\n *\n * @param camera - Optional; replaces {@link SplatEngine.camera} when given.\n */\n update(dt: number, camera?: Camera): void {\n if (this._destroyed) return;\n if (camera) this.camera = camera;\n this.frame++;\n\n const cam = this.camera;\n if (cam) {\n cam.updateMatrixWorld();\n this._projScreen.multiplyMatrices(cam.projectionMatrix, cam.matrixWorldInverse);\n this._frustum.setFromProjectionMatrix(this._projScreen, cam.coordinateSystem, cam.reversedDepth);\n this._cameraPosition.setFromMatrixPosition(cam.matrixWorld);\n this._frustumValid = true;\n } else {\n this._frustumValid = false;\n }\n\n for (const fn of this._updaters) fn(dt);\n }\n\n /**\n * Register a per-frame callback run by {@link SplatEngine.update}.\n * @returns A function that removes it.\n * @internal\n */\n addUpdater(fn: (dt: number) => void): () => void {\n this._updaters.add(fn);\n return () => this._updaters.delete(fn);\n }\n\n /** @internal */\n removeUpdater(fn: (dt: number) => void): void {\n this._updaters.delete(fn);\n }\n\n /**\n * The camera frustum as of the last {@link SplatEngine.update}, or\n * `undefined` when no camera is set - callers treat that as \"visible\".\n * @internal\n */\n get cameraFrustum(): Frustum | undefined {\n return this._frustumValid ? this._frustum : undefined;\n }\n\n /**\n * World-space camera position as of the last {@link SplatEngine.update}, or\n * `null` when no camera is set.\n * @internal\n */\n get cameraWorldPosition(): Vector3 | null {\n return this._frustumValid ? this._cameraPosition : null;\n }\n\n /**\n * Incremented whenever {@link SplatEngine.syncLighting} finds the lights\n * changed. Lets a backend skip work that depends on lighting.\n * @internal\n */\n lightingVersion = 0;\n\n /**\n * Copy {@link SplatEngine.lighting} into the shared uniforms. Called per\n * draw, so it only compares numbers and writes on change.\n * @internal\n */\n syncLighting(): void {\n const { sun, sky, points } = this.lighting;\n const u = this.lightingUniforms;\n const sunActive = !!sun && sun.enabled;\n const skyActive = !!sky && sky.enabled;\n let changed = false;\n\n const sunR = sunActive ? sun!.color.r : 0;\n const sunG = sunActive ? sun!.color.g : 0;\n const sunB = sunActive ? sun!.color.b : 0;\n const sunI = sunActive ? sun!.intensity : 0;\n const sunColor = u.uSunColor.value;\n if (sunColor.x !== sunR || sunColor.y !== sunG || sunColor.z !== sunB || u.uSunIntensity.value !== sunI) {\n sunColor.set(sunR, sunG, sunB);\n u.uSunIntensity.value = sunI;\n changed = true;\n }\n\n // No lights at all means \"render as authored\", not \"render black\".\n let ambR = 0, ambG = 0, ambB = 0;\n if (skyActive) {\n ambR = sky!.color.r * sky!.intensity;\n ambG = sky!.color.g * sky!.intensity;\n ambB = sky!.color.b * sky!.intensity;\n } else if (!sunActive) {\n ambR = ambG = ambB = 1;\n }\n const ambient = u.uAmbientColor.value;\n if (ambient.x !== ambR || ambient.y !== ambG || ambient.z !== ambB) {\n ambient.set(ambR, ambG, ambB);\n changed = true;\n }\n\n let count = 0;\n for (let i = 0; i < points.length; i++) if (points[i].enabled) count++;\n if (count > this._pointLightCapacity) {\n this._pointLightCapacity = Math.max(this._pointLightCapacity * 2, count);\n u.uPointLightTex.value.dispose();\n u.uPointLightTex.value = createPointLightTexture(this._pointLightCapacity);\n changed = true;\n }\n if (count !== u.uPointLightCount.value) {\n u.uPointLightCount.value = count;\n changed = true;\n }\n\n // Row 0: position + range. Row 1: colour + intensity.\n const texture = u.uPointLightTex.value;\n const data = texture.image.data as Float32Array;\n const row1 = this._pointLightCapacity * 4;\n let textureChanged = false;\n let w = 0;\n for (let i = 0; i < points.length; i++) {\n const p = points[i];\n if (!p.enabled) continue;\n const a = w * 4;\n const b = row1 + w * 4;\n if (\n data[a] !== p.position.x || data[a + 1] !== p.position.y || data[a + 2] !== p.position.z || data[a + 3] !== p.range ||\n data[b] !== p.color.r || data[b + 1] !== p.color.g || data[b + 2] !== p.color.b || data[b + 3] !== p.intensity\n ) {\n data[a] = p.position.x;\n data[a + 1] = p.position.y;\n data[a + 2] = p.position.z;\n data[a + 3] = p.range;\n data[b] = p.color.r;\n data[b + 1] = p.color.g;\n data[b + 2] = p.color.b;\n data[b + 3] = p.intensity;\n textureChanged = true;\n }\n w++;\n }\n if (textureChanged) {\n texture.needsUpdate = true;\n changed = true;\n }\n\n if (changed) this.lightingVersion++;\n }\n\n /**\n * Detach the engine's content from the scene and stop updating. Characters\n * and environments are not destroyed for you - destroy them first if you\n * want their GPU resources released.\n */\n dispose(): void {\n if (this._destroyed) return;\n this._destroyed = true;\n this._updaters.clear();\n this.contentRoot.removeFromParent();\n this.lightingUniforms.uPointLightTex.value.dispose();\n }\n}\n\n/**\n * Thrown when an asset finishes loading onto an engine that has already been\n * disposed.\n *\n * This is a CANCELLATION, not a failure: the bytes were fine and the engine is\n * simply gone. It exists as its own type so a caller can tell the two apart.\n *\n * @group Engine\n */\nexport class EngineDisposedError extends Error {\n constructor(what: string) {\n super(`${what}: the engine was disposed while the asset was loading`);\n this.name = 'EngineDisposedError';\n }\n}\n", "import { DataUtils } from 'three';\n\nimport type { SplatAttributes } from '../loader/character/types';\n\nconst SH_C0 = 0.28209479177387814;\n\n/**\n * Splat attributes packed into the three texel streams the shaders read.\n *\n * Renderer-agnostic on purpose: these are plain typed arrays laid out as\n * `width x height` RGBA texels, so the WebGL and WebGPU backends wrap the same\n * bytes in their own texture objects.\n *\n * The layout is 32 bytes per splat:\n *\n * - `color` RGBA16F - `rgb` display-referred colour, `a` opacity (post-sigmoid).\n * - `transformA` RGBA32UI - `xyz` the centre as raw float32 bits, `w` two packed\n * half floats: rotation `x` (low 16) and `y` (high 16).\n * - `transformB` RGBA16F - `xyz` linear scale, `w` rotation `z`.\n *\n * Rotation `w` is not stored: quaternions are normalised and flipped to\n * `w >= 0` here, so the shader recovers it as `sqrt(1 - |xyz|^2)`.\n */\nexport interface PackedSplats {\n numSplats: number;\n width: number;\n height: number;\n color: Uint16Array;\n transformA: Uint32Array;\n transformB: Uint16Array;\n /** Rest-pose centres, flat `[x,y,z] * numSplats`. The depth sort reads these. */\n centers: Float32Array;\n boundsMin: [number, number, number];\n boundsMax: [number, number, number];\n}\n\n/** Texture dimensions for `count` texels: near-square, wide enough to hold every row. */\nexport function textureSizeFor(count: number): { width: number; height: number } {\n const width = Math.max(1, Math.ceil(Math.sqrt(count)));\n const height = Math.max(1, Math.ceil(count / width));\n return { width, height };\n}\n\nexport function packSplats(numSplats: number, s: SplatAttributes): PackedSplats {\n const { width, height } = textureSizeFor(numSplats);\n const texels = width * height;\n const color = new Uint16Array(texels * 4);\n const transformA = new Uint32Array(texels * 4);\n const transformAFloat = new Float32Array(transformA.buffer);\n const transformB = new Uint16Array(texels * 4);\n const centers = new Float32Array(numSplats * 3);\n const toHalf = DataUtils.toHalfFloat;\n\n let minX = Infinity, minY = Infinity, minZ = Infinity;\n let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;\n\n for (let i = 0; i < numSplats; i++) {\n const o = i * 4;\n\n color[o] = toHalf(s.f_dc_0[i] * SH_C0 + 0.5);\n color[o + 1] = toHalf(s.f_dc_1[i] * SH_C0 + 0.5);\n color[o + 2] = toHalf(s.f_dc_2[i] * SH_C0 + 0.5);\n color[o + 3] = toHalf(1 / (1 + Math.exp(-s.opacity[i])));\n\n const x = s.x[i], y = s.y[i], z = s.z[i];\n transformAFloat[o] = x;\n transformAFloat[o + 1] = y;\n transformAFloat[o + 2] = z;\n centers[i * 3] = x;\n centers[i * 3 + 1] = y;\n centers[i * 3 + 2] = z;\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n if (z < minZ) minZ = z;\n if (z > maxZ) maxZ = z;\n\n // Source order is wxyz. Normalise, then flip onto the w >= 0 hemisphere so\n // w is recoverable from xyz alone.\n let qw = s.rot_0[i], qx = s.rot_1[i], qy = s.rot_2[i], qz = s.rot_3[i];\n const len = Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw);\n if (len === 0) {\n qx = qy = qz = 0;\n qw = 1;\n } else {\n const inv = (qw < 0 ? -1 : 1) / len;\n qx *= inv;\n qy *= inv;\n qz *= inv;\n }\n transformA[o + 3] = (toHalf(qx) | (toHalf(qy) << 16)) >>> 0;\n\n transformB[o] = toHalf(Math.exp(s.scale_0[i]));\n transformB[o + 1] = toHalf(Math.exp(s.scale_1[i]));\n transformB[o + 2] = toHalf(Math.exp(s.scale_2[i]));\n transformB[o + 3] = toHalf(qz);\n }\n\n if (numSplats === 0) {\n minX = minY = minZ = maxX = maxY = maxZ = 0;\n }\n\n return {\n numSplats,\n width,\n height,\n color,\n transformA,\n transformB,\n centers,\n boundsMin: [minX, minY, minZ],\n boundsMax: [maxX, maxY, maxZ],\n };\n}\n", "/**\n * The one interface every character-bundle version handler satisfies, and the\n * one error type they all fail with.\n *\n * This module is version-agnostic on purpose and holds no knowledge of any\n * particular version: it is the boundary that lets `index.ts` treat `v1/` and\n * `legacy/` as interchangeable, and the reason adding version N+1 costs exactly\n * one module and one registry entry\n * (character-bundle format spec, R2/R3).\n */\n\n/**\n * Error categories, from the spec's `Errors` table.\n *\n * A caller distinguishes \"not our file\" (`WrongMagic`) from \"our file, broken\"\n * (everything else) without parsing a message string.\n */\ntype BundleErrorCategory =\n | 'WrongMagic'\n | 'UnknownVersion'\n | 'Truncated'\n | 'MalformedHeader'\n | 'UnalignedPayload'\n | 'MissingField'\n | 'UnexpectedField'\n | 'BadFieldValue'\n | 'BlockSizeMismatch'\n | 'InconsistentHeader';\n\n/**\n * A rejection carrying its category.\n *\n * The category travels over the worker boundary alongside the message, so the\n * main thread can tell a foreign file from a corrupt one without re-reading the\n * bytes. The message names the offending block or field and reports the value\n * found next to the value expected.\n */\nclass CharacterBundleError extends Error {\n readonly category: BundleErrorCategory;\n\n constructor(category: BundleErrorCategory, message: string) {\n super(`[${category}] ${message}`);\n this.name = 'CharacterBundleError';\n this.category = category;\n }\n}\n\n/** The 14 Float32 attribute arrays the GPU pipeline consumes, one per column. */\ninterface SplatAttributes {\n x: Float32Array;\n y: Float32Array;\n z: Float32Array;\n scale_0: Float32Array;\n scale_1: Float32Array;\n scale_2: Float32Array;\n /** Quaternion `w`. The engine wants `wxyz`, whatever order the file stores. */\n rot_0: Float32Array;\n rot_1: Float32Array;\n rot_2: Float32Array;\n rot_3: Float32Array;\n f_dc_0: Float32Array;\n f_dc_1: Float32Array;\n f_dc_2: Float32Array;\n /** The LOGIT, not the alpha. */\n opacity: Float32Array;\n}\n\n/**\n * The version-independent decode output. Every handler returns this shape and a\n * caller cannot tell from it which handler ran.\n *\n * Three of these fields exist because the answer differs per version and the\n * QUESTION does not, so asking it downstream would put a per-version branch\n * outside the handlers - the one thing R2 forbids:\n *\n * - `rigBoneCount` - the legacy containers spell the rig's size three\n * different ways across two magics; version 1 has no header key for it at all\n * and derives it from `blocks.joints.count`.\n * - `corrected` - the legacy containers carry a correction receipt, in either\n * of two spellings, and files exist both with and without it. Version 1 needs\n * no receipt: the version itself means corrected, and the spec forbids a\n * reader from looking for a signal.\n * - `bundledRestIsPerCharacter` - whether `jointsArray` is this character's own\n * vetted rest pose, i.e. whether a consumer may pose the splats against it\n * instead of against the shared canonical tables.\n */\ninterface DecodedBundle {\n /** The version's own header, verbatim. Diagnostics; nothing dispatches on it. */\n header: unknown;\n numSplats: number;\n splats: SplatAttributes;\n /** `numSplats * K` global rig indices, or `null` when unskinned. */\n boneIndices: Uint16Array | null;\n /** `numSplats * K` weights, matching `boneIndices`, or `null`. */\n boneWeights: Float32Array | null;\n animationArray: Float32Array | null;\n animNumFrames: number;\n animNumBones: number;\n /** Flat `[x,y,z] * rigBoneCount` rest translations, or `null` when no rig. */\n jointsArray: Float32Array | null;\n /** Bones in the rig this bundle poses. `0` when it carries no rig. */\n rigBoneCount: number;\n /** Whether the geometric corrections are baked into the splats and joints. */\n corrected: boolean;\n /**\n * Whether `jointsArray` is this character's OWN rest pose, vetted against the\n * gaussians it ships with - i.e. whether posing the splats from it (rather\n * than from the shared canonical rest tables) is correct.\n *\n * A separate question from `corrected`, and deliberately not derived from it.\n * `corrected` answers \"did the correction pipeline run\", which some legacy\n * files answer yes to and others no, from the same generation of writer;\n * this one answers \"is the joints block authoritative\", which is a property\n * of the CONTAINER:\n *\n * - version 1 - yes, by definition. The joint canonicalisation, the ankle\n * pitch bake and the ground shift are all baked into the gaussians AND\n * into this block, so the two agree and nothing else does.\n * - legacy - no. Those joints were written for diagnostics, were never\n * vetted as a posing rest, and the shipped characters render today against\n * the canonical tables.\n *\n * Read by `Character`'s ground-convention shim, which must be able to tell\n * a v1 bundle from a legacy one WITHOUT keying on `corrected` - some legacy\n * bundles carry a receipt, and moving those would move already-shipped\n * characters. See `Character.bakedGroundShiftY`.\n */\n bundledRestIsPerCharacter: boolean;\n}\n\n/**\n * What a handler hands back: the bundle, plus the buffers the worker may\n * transfer instead of copying.\n */\ninterface DecodeResult {\n result: DecodedBundle;\n transferables: ArrayBuffer[];\n}\n\n/**\n * One payload version's reader.\n *\n * Given the whole file, the offset its payload begins at, and how long that\n * payload is. A handler is total over its own version, never learns that\n * another version exists, and never re-checks the magic or the version - the\n * dispatcher owns both.\n */\ntype VersionHandler = (\n file: ArrayBuffer,\n payloadOffset: number,\n payloadLength: number,\n) => Promise<DecodeResult>;\n\nexport { CharacterBundleError };\nexport type {\n BundleErrorCategory,\n DecodeResult,\n DecodedBundle,\n SplatAttributes,\n VersionHandler,\n};\n", "/**\n * Interleaved character-splat decoder - the payload half of `VFCHARB1`.\n *\n * MOVED, NOT REWRITTEN. This is `binary-gsplat-worker.ts`'s `parseBinaryGsplat`\n * verbatim, lifted out of the worker glue so the legacy readers sit behind one\n * door (`../index.ts`). It decodes files that are already in storage and will\n * stay there - there is no backfill - so any behaviour change here is a\n * regression, and it keeps its own vocabulary: this container talks about\n * CHUNKS, where the planar one talks about PLANES and `VIGGCHAR` talks about\n * BLOCKS.\n *\n * `version` here numbers one global bundle lineage across both legacy magics\n * (1 = fp32 interleaved, 2 = fp16 interleaved, 3 = planar), which is exactly the\n * accretion `VIGGCHAR` was shaped to end.\n */\n\n/** The interleaved container: per-splat records, v1 (fp32) and v2 (fp16). */\nconst CHARACTER_BUNDLE_MAGIC = 'VFCHARB1';\n\n/**\n * First `version` of the PLANAR container, which the interleaved reader below\n * must never attempt. `version` numbers one global bundle lineage across both\n * magics (1 = fp32 interleaved, 2 = fp16 interleaved, 3 = planar), so\n * `version >= 3` under the interleaved magic is a mislabelled file, not a\n * newer interleaved one - and `encoding.precision === 'fp16'` would happily\n * accept it and decode planes as records.\n */\nconst FIRST_PLANAR_VERSION = 3;\n\nconst SH_C0 = 0.28209479177387814;\n\ninterface BundleChunk {\n offset: number;\n length: number;\n stride?: number;\n}\n\ninterface AssetHeader {\n format: string;\n version: number;\n numSplats: number;\n numBones: number;\n bounds: { min: number[]; max: number[] };\n encoding?: {\n /**\n * Bundle-wide field precision. `'fp16'` means pos/scale/rot/opacity and\n * the weights chunk's per-splat weights are stored as IEEE 754 half-floats\n * (read 2 bytes / value, expanded to Float32 on parse). `'fp32'` or\n * missing = legacy raw float32 (the v1 layout). RGB stays uint8 and bone\n * indices stay uint16 either way. Bumps the file size by ~42%; expanding\n * to Float32 here means GPU memory is unchanged.\n */\n precision?: 'fp16' | 'fp32';\n weights?: { topK: number; indexType: string; weightType: string; stride: number };\n color?: { format: string; levels: number };\n };\n chunks: {\n splats: BundleChunk;\n weights?: BundleChunk;\n joints?: BundleChunk;\n animation?: BundleChunk;\n };\n animation?: {\n format: string;\n numFrames: number;\n numBones: number;\n shape: number[];\n stride: number;\n };\n joints?: {\n count: number;\n format: string;\n stride: number;\n };\n}\n\n// IEEE 754 half-float \u2192 single-float, branch-light. Used to expand the v2\n// quantized fields back into the Float32Arrays the GPU pipeline expects.\n// Subnormals are handled correctly (rare in our data - opacity 0 / unused\n// channels). Speed matters: this runs numSplats \u00D7 ~12 times per asset load.\nconst _f16Buf = new ArrayBuffer(4);\nconst _f16U32 = new Uint32Array(_f16Buf);\nconst _f16F32 = new Float32Array(_f16Buf);\nfunction f16ToF32(h: number): number {\n const sign = (h & 0x8000) << 16;\n const exp = (h & 0x7c00) >> 10;\n const frac = h & 0x03ff;\n let bits: number;\n if (exp === 0) {\n if (frac === 0) {\n bits = sign;\n } else {\n // Subnormal - normalize the mantissa into f32 representation.\n let e = -14;\n let m = frac;\n while ((m & 0x400) === 0) {\n m <<= 1;\n e--;\n }\n m &= 0x3ff;\n bits = sign | ((e + 127) << 23) | (m << 13);\n }\n } else if (exp === 31) {\n bits = sign | 0x7f800000 | (frac << 13);\n } else {\n bits = sign | ((exp - 15 + 127) << 23) | (frac << 13);\n }\n _f16U32[0] = bits;\n return _f16F32[0];\n}\n\nfunction parseBinaryGsplat(bundleBuffer: ArrayBuffer) {\n if (bundleBuffer.byteLength < 12) {\n throw new Error('Character bundle too small');\n }\n\n const bundleView = new DataView(bundleBuffer);\n const magic = new TextDecoder().decode(new Uint8Array(bundleBuffer, 0, CHARACTER_BUNDLE_MAGIC.length));\n if (magic !== CHARACTER_BUNDLE_MAGIC) {\n throw new Error(`Invalid character bundle magic: ${magic}`);\n }\n\n const headerLength = bundleView.getUint32(CHARACTER_BUNDLE_MAGIC.length, true);\n const headerStart = CHARACTER_BUNDLE_MAGIC.length + 4;\n const headerEnd = headerStart + headerLength;\n if (headerEnd > bundleBuffer.byteLength) {\n throw new Error('Character bundle header length out of range');\n }\n\n const headerText = new TextDecoder().decode(new Uint8Array(bundleBuffer, headerStart, headerLength));\n const header: AssetHeader = JSON.parse(headerText);\n if (header.format !== 'vfa3d-charbin') {\n throw new Error(`Unsupported character bundle format: ${header.format}`);\n }\n // Both `format` and `version` are checked, not just one: this reader used to\n // decide layout from `encoding.precision` alone, which cannot tell a planar\n // payload from an interleaved fp16 one. A file that gets this far is claiming\n // to be interleaved under two independent fields.\n if (header.version >= FIRST_PLANAR_VERSION) {\n throw new Error(\n `Character bundle declares version ${header.version} under the ${CHARACTER_BUNDLE_MAGIC} ` +\n 'magic; planar payloads must be published as VFCHARB2',\n );\n }\n\n const payloadStart = headerEnd;\n const chunkBuffer = (chunk: BundleChunk | undefined): ArrayBuffer | null => {\n if (!chunk) return null;\n const start = payloadStart + chunk.offset;\n const end = start + chunk.length;\n if (start < payloadStart || end > bundleBuffer.byteLength || start > end) {\n throw new Error('Character bundle chunk range out of bounds');\n }\n return bundleBuffer.slice(start, end);\n };\n\n const numSplats = header.numSplats;\n\n // Parse splats\n const splatsBuffer = chunkBuffer(header.chunks.splats);\n if (!splatsBuffer) throw new Error('Missing splats chunk');\n const splatData = new DataView(splatsBuffer);\n\n const storage_x = new Float32Array(numSplats);\n const storage_y = new Float32Array(numSplats);\n const storage_z = new Float32Array(numSplats);\n const storage_scale_0 = new Float32Array(numSplats);\n const storage_scale_1 = new Float32Array(numSplats);\n const storage_scale_2 = new Float32Array(numSplats);\n const storage_rot_0 = new Float32Array(numSplats);\n const storage_rot_1 = new Float32Array(numSplats);\n const storage_rot_2 = new Float32Array(numSplats);\n const storage_rot_3 = new Float32Array(numSplats);\n const storage_f_dc_0 = new Float32Array(numSplats);\n const storage_f_dc_1 = new Float32Array(numSplats);\n const storage_f_dc_2 = new Float32Array(numSplats);\n const storage_opacity = new Float32Array(numSplats);\n\n const isFp16 = header.encoding?.precision === 'fp16';\n let offset = 0;\n if (isFp16) {\n // v2 layout: pos/scale/rot/opacity stored as fp16. RGB+pad still 4B, no\n // padding after opacity. Per-splat stride = 6 + 6 + 8 + 4 + 2 = 26 B.\n for (let i = 0; i < numSplats; i++) {\n storage_x[i] = f16ToF32(splatData.getUint16(offset + 0, true));\n storage_y[i] = f16ToF32(splatData.getUint16(offset + 2, true));\n storage_z[i] = f16ToF32(splatData.getUint16(offset + 4, true));\n offset += 6;\n\n const scaleX = f16ToF32(splatData.getUint16(offset + 0, true));\n const scaleY = f16ToF32(splatData.getUint16(offset + 2, true));\n const scaleZ = f16ToF32(splatData.getUint16(offset + 4, true));\n storage_scale_0[i] = Math.log(Math.max(scaleX, 1e-8));\n storage_scale_1[i] = Math.log(Math.max(scaleY, 1e-8));\n storage_scale_2[i] = Math.log(Math.max(scaleZ, 1e-8));\n offset += 6;\n\n const qx = f16ToF32(splatData.getUint16(offset + 0, true));\n const qy = f16ToF32(splatData.getUint16(offset + 2, true));\n const qz = f16ToF32(splatData.getUint16(offset + 4, true));\n const qw = f16ToF32(splatData.getUint16(offset + 6, true));\n storage_rot_0[i] = qw;\n storage_rot_1[i] = qx;\n storage_rot_2[i] = qy;\n storage_rot_3[i] = qz;\n offset += 8;\n\n const r = splatData.getUint8(offset + 0);\n const g = splatData.getUint8(offset + 1);\n const b = splatData.getUint8(offset + 2);\n storage_f_dc_0[i] = (r / 255 - 0.5) / SH_C0;\n storage_f_dc_1[i] = (g / 255 - 0.5) / SH_C0;\n storage_f_dc_2[i] = (b / 255 - 0.5) / SH_C0;\n offset += 4;\n\n const opacity = f16ToF32(splatData.getUint16(offset + 0, true));\n const clampedOpacity = Math.max(0.0001, Math.min(0.9999, opacity));\n storage_opacity[i] = -Math.log(1 / clampedOpacity - 1);\n offset += 2;\n }\n } else {\n // v1 layout: all float32. Per-splat stride 48 B.\n for (let i = 0; i < numSplats; i++) {\n storage_x[i] = splatData.getFloat32(offset + 0, true);\n storage_y[i] = splatData.getFloat32(offset + 4, true);\n storage_z[i] = splatData.getFloat32(offset + 8, true);\n offset += 12;\n\n const scaleX = splatData.getFloat32(offset + 0, true);\n const scaleY = splatData.getFloat32(offset + 4, true);\n const scaleZ = splatData.getFloat32(offset + 8, true);\n storage_scale_0[i] = Math.log(Math.max(scaleX, 1e-8));\n storage_scale_1[i] = Math.log(Math.max(scaleY, 1e-8));\n storage_scale_2[i] = Math.log(Math.max(scaleZ, 1e-8));\n offset += 12;\n\n const qx = splatData.getFloat32(offset + 0, true);\n const qy = splatData.getFloat32(offset + 4, true);\n const qz = splatData.getFloat32(offset + 8, true);\n const qw = splatData.getFloat32(offset + 12, true);\n storage_rot_0[i] = qw;\n storage_rot_1[i] = qx;\n storage_rot_2[i] = qy;\n storage_rot_3[i] = qz;\n offset += 16;\n\n const r = splatData.getUint8(offset + 0);\n const g = splatData.getUint8(offset + 1);\n const b = splatData.getUint8(offset + 2);\n storage_f_dc_0[i] = (r / 255 - 0.5) / SH_C0;\n storage_f_dc_1[i] = (g / 255 - 0.5) / SH_C0;\n storage_f_dc_2[i] = (b / 255 - 0.5) / SH_C0;\n offset += 4;\n\n const opacity = splatData.getFloat32(offset + 0, true);\n const clampedOpacity = Math.max(0.0001, Math.min(0.9999, opacity));\n storage_opacity[i] = -Math.log(1 / clampedOpacity - 1);\n offset += 4;\n }\n }\n\n // Parse weights\n let boneIndices: Uint16Array | undefined;\n let boneWeights: Float32Array | undefined;\n const weightsBuffer = chunkBuffer(header.chunks.weights);\n if (weightsBuffer) {\n const topK = Math.max(1, header.encoding?.weights?.topK ?? 4);\n const indexBytes = 2;\n // v1 stores per-splat weights as float32; v2 stores them as fp16. Indices\n // stay uint16 either way (capacity for the 441-bone full rig).\n const weightBytes = isFp16 ? 2 : 4;\n const weightsData = new DataView(weightsBuffer);\n boneIndices = new Uint16Array(numSplats * topK);\n boneWeights = new Float32Array(numSplats * topK);\n let wOffset = 0;\n for (let i = 0; i < numSplats; i++) {\n for (let j = 0; j < topK; j++) {\n boneIndices[i * topK + j] = weightsData.getUint16(wOffset + j * 2, true);\n }\n wOffset += topK * indexBytes;\n if (isFp16) {\n for (let j = 0; j < topK; j++) {\n boneWeights[i * topK + j] = f16ToF32(weightsData.getUint16(wOffset + j * 2, true));\n }\n } else {\n for (let j = 0; j < topK; j++) {\n boneWeights[i * topK + j] = weightsData.getFloat32(wOffset + j * 4, true);\n }\n }\n wOffset += topK * weightBytes;\n }\n }\n\n // Parse animation\n let animationArray: Float32Array | undefined;\n let animNumFrames = 0;\n let animNumBones = 0;\n if (header.animation && header.animation.numFrames > 0 && header.animation.numBones > 0) {\n const animationBuffer = chunkBuffer(header.chunks.animation);\n if (animationBuffer) {\n const FLOATS_PER_BONE = 16;\n animNumBones = header.animation.numBones;\n animNumFrames = header.animation.numFrames;\n const expectedSize = animNumFrames * animNumBones * FLOATS_PER_BONE * 4;\n if (animationBuffer.byteLength !== expectedSize) {\n const actualBoneCount = animationBuffer.byteLength / 4 / (animNumFrames * FLOATS_PER_BONE);\n if (Number.isInteger(actualBoneCount) && actualBoneCount > 0) {\n animNumBones = actualBoneCount;\n }\n }\n animationArray = new Float32Array(animationBuffer);\n }\n }\n\n // Parse joints\n let jointsArray: Float32Array | undefined;\n const headerAny = header as any;\n if (headerAny.joints) {\n const jointsBuffer = chunkBuffer(header.chunks.joints);\n if (jointsBuffer) {\n const FLOATS_PER_JOINT = 3;\n const expectedJointsSize = headerAny.joints.count * FLOATS_PER_JOINT * 4;\n if (jointsBuffer.byteLength === expectedJointsSize) {\n jointsArray = new Float32Array(jointsBuffer);\n }\n }\n }\n\n // Collect all transferable buffers\n const transferables: ArrayBuffer[] = [\n storage_x.buffer as ArrayBuffer, storage_y.buffer as ArrayBuffer, storage_z.buffer as ArrayBuffer,\n storage_scale_0.buffer as ArrayBuffer, storage_scale_1.buffer as ArrayBuffer, storage_scale_2.buffer as ArrayBuffer,\n storage_rot_0.buffer as ArrayBuffer, storage_rot_1.buffer as ArrayBuffer, storage_rot_2.buffer as ArrayBuffer, storage_rot_3.buffer as ArrayBuffer,\n storage_f_dc_0.buffer as ArrayBuffer, storage_f_dc_1.buffer as ArrayBuffer, storage_f_dc_2.buffer as ArrayBuffer,\n storage_opacity.buffer as ArrayBuffer,\n ];\n if (boneIndices) transferables.push(boneIndices.buffer as ArrayBuffer);\n if (boneWeights) transferables.push(boneWeights.buffer as ArrayBuffer);\n if (animationArray) transferables.push(animationArray.buffer as ArrayBuffer);\n if (jointsArray) transferables.push(jointsArray.buffer as ArrayBuffer);\n\n const result = {\n header,\n numSplats,\n splats: {\n x: storage_x, y: storage_y, z: storage_z,\n scale_0: storage_scale_0, scale_1: storage_scale_1, scale_2: storage_scale_2,\n rot_0: storage_rot_0, rot_1: storage_rot_1, rot_2: storage_rot_2, rot_3: storage_rot_3,\n f_dc_0: storage_f_dc_0, f_dc_1: storage_f_dc_1, f_dc_2: storage_f_dc_2,\n opacity: storage_opacity,\n },\n boneIndices: boneIndices ?? null,\n boneWeights: boneWeights ?? null,\n animationArray: animationArray ?? null,\n animNumFrames,\n animNumBones,\n jointsArray: jointsArray ?? null,\n };\n\n return { result, transferables };\n}\n\nexport { parseBinaryGsplat, CHARACTER_BUNDLE_MAGIC };\n", "/**\n * Planar character-splat decoder - the payload half of `VFCHARB2`.\n *\n * A planar container stores one contiguous, component-major byte plane per\n * attribute (all x, then all y, then all z) instead of the per-splat records\n * `VFCHARB1` uses. Two precision modes share the one layout:\n *\n * `fp16` - the same half-float values the shipping v2 `VFCHARB1` bundle\n * carries, only re-laid-out. It decodes bit-identically to the v2\n * path, which is what makes it the control when judging q23.\n * `q23` - ~23 B/gaussian: u16 position against per-file bounds, u8 rotation\n * (w derived), u8 log-scale, u8 logit-opacity, u8 weights (the last\n * one derived), bone indices through a per-file palette.\n *\n * This module is deliberately free of Worker glue so it can be driven directly\n * (from `binary-gsplat-worker.ts`, and from a plain Node process when the\n * decode is being compared against the Python reference implementation).\n */\n\nconst SH_C0 = 0.28209479177387814;\n\n// Mirrors the decoder clamp in the interleaved path in binary-gsplat-worker.ts.\n// q23 opacity is already quantized inside this band by the encoder, so the\n// clamp costs nothing there.\nconst OPACITY_CLAMP_LO = 0.0001;\nconst OPACITY_CLAMP_HI = 0.9999;\nconst MIN_SCALE = 1e-8;\n\n/**\n * Magic -> the `format` string a file under that magic must declare.\n *\n * The MAGIC is the container generation and the one field this decoder refuses\n * to guess at: a planar payload published under `VFCHARB1` would sail past\n * every version check in the interleaved reader and decode to silent garbage.\n * `format` is then checked as well - dispatching on `version` alone is exactly\n * how a file can be misparsed without anything throwing.\n *\n * `VSPLAT01` is the pre-release prototype of the same layout. It is kept\n * readable so the `.vsplat` LOD/quantisation A/B rig keeps working, and because\n * routing it through this same decoder means the prototype exercises the\n * production code path rather than a copy of it.\n */\nconst PLANAR_CONTAINERS: Record<string, string> = {\n VFCHARB2: 'vfa3d-charb2',\n VSPLAT01: 'vsplat-planar',\n};\n\n/** First planar `version`. `1` = fp32 interleaved, `2` = fp16 interleaved. */\nconst FIRST_PLANAR_VERSION = 3;\n\ntype PlaneDtype = 'f32' | 'f16' | 'u16' | 'u8';\n\n/**\n * Per-plane compression codec, as written in the header.\n *\n * WHY DEFLATE AND NOT BROTLI OR ZSTD, which both compress ~10% better: these\n * three are the only formats `DecompressionStream` accepts, and the equivalents\n * (`GZipStream` / `DeflateStream`) are in the .NET base library, so a file with\n * compressed planes decodes on both targets with ZERO shipped decoder. Browsers\n * expose brotli and zstd only to the HTTP layer, never to script, so choosing\n * either would put a WASM decoder on the critical path of every character load.\n *\n * In-file compression is for platforms with no HTTP layer (Unity\n * StreamingAssets, AssetBundles, local files). On the web the file is served\n * flat with `Content-Encoding: br` instead, which is free and compresses\n * better. This decoder honours whichever the file declares.\n */\ntype PlaneCodec = 'gzip' | 'deflate' | 'deflate-raw';\n\nconst PLANE_CODECS: readonly string[] = ['gzip', 'deflate', 'deflate-raw'];\n\ninterface PlaneInfo {\n offset: number;\n /** Bytes IN THE FILE - the compressed size when `compression` is set. */\n length: number;\n dtype: PlaneDtype;\n /** Values per splat. Stored COMPONENT-major: all c0, then all c1, ... */\n components: number;\n count: number;\n compression?: PlaneCodec;\n /** Bytes after inflation. Normative when `compression` is set. */\n uncompressedLength?: number;\n}\n\n/** A plane's bytes, wherever they ended up: in the file, or in an inflated copy. */\ninterface ResolvedPlane extends PlaneInfo {\n buf: ArrayBuffer;\n /** Byte offset of component 0 within `buf`. */\n base: number;\n}\n\ninterface PlanarHeader {\n format: string;\n version: number;\n precision: 'fp16' | 'q23';\n numSplats: number;\n numBones: number;\n topK: number;\n bounds: { min: number[]; max: number[] };\n /** q23 only - normative, positions cannot be reconstructed without them. */\n logScale?: { min: number[]; max: number[] };\n logitOpacity?: { min: number; max: number };\n bonePalette?: number[];\n joints?: { count: number };\n /** Free-form; informational. The plane table is what the decoder obeys. */\n encoding?: { planeCompression?: PlaneCodec | null };\n planes: Record<string, PlaneInfo>;\n}\n\nconst BYTES_PER_ELEMENT: Record<PlaneDtype, number> = { f32: 4, f16: 2, u16: 2, u8: 1 };\n\n// Float16Array landed in browsers only recently (Chrome 135+/Safari 26+), so\n// the manual expansion below stays as the fallback. Where it exists it is the\n// whole point of the planar layout: a component plane converts into its\n// Float32Array destination in one `set()` instead of a per-splat DataView walk.\nconst NativeFloat16Array = (globalThis as unknown as {\n Float16Array?: new (buffer: ArrayBuffer, byteOffset?: number, length?: number) => ArrayLike<number>;\n}).Float16Array;\n\n// IEEE 754 half-float -> single-float. Identical to the one in\n// binary-gsplat-worker.ts; the two decoders stay independent files so the\n// interleaved path has no import edge into the planar one.\nconst _f16Buf = new ArrayBuffer(4);\nconst _f16U32 = new Uint32Array(_f16Buf);\nconst _f16F32 = new Float32Array(_f16Buf);\nfunction f16ToF32(h: number): number {\n const sign = (h & 0x8000) << 16;\n const exp = (h & 0x7c00) >> 10;\n const frac = h & 0x03ff;\n let bits: number;\n if (exp === 0) {\n if (frac === 0) {\n bits = sign;\n } else {\n let e = -14;\n let m = frac;\n while ((m & 0x400) === 0) {\n m <<= 1;\n e--;\n }\n m &= 0x3ff;\n bits = sign | ((e + 127) << 23) | (m << 13);\n }\n } else if (exp === 31) {\n bits = sign | 0x7f800000 | (frac << 13);\n } else {\n bits = sign | ((exp - 15 + 127) << 23) | (frac << 13);\n }\n _f16U32[0] = bits;\n return _f16F32[0];\n}\n\n/** The 8-byte ASCII magic, or `''` when the buffer is too short to have one. */\nfunction readMagic(buffer: ArrayBuffer): string {\n if (buffer.byteLength < 12) return '';\n return new TextDecoder().decode(new Uint8Array(buffer, 0, 8));\n}\n\n/** True when `magic` names a planar container this module can decode. */\nfunction isPlanarMagic(magic: string): boolean {\n return Object.prototype.hasOwnProperty.call(PLANAR_CONTAINERS, magic);\n}\n\n/** Inflate one plane into its own exactly-sized ArrayBuffer. */\nasync function inflate(src: Uint8Array, codec: PlaneCodec): Promise<ArrayBuffer> {\n const stream = new Blob([src as unknown as BlobPart])\n .stream()\n .pipeThrough(new DecompressionStream(codec));\n return await new Response(stream).arrayBuffer();\n}\n\n/**\n * Resolve every plane to a buffer + offset, inflating the compressed ones.\n *\n * This is the whole cost of supporting compressed planes: a decompressed plane\n * lands at offset 0 of a fresh buffer (so every typed-array view below stays\n * aligned), an uncompressed one is still a view straight into the file with no\n * copy at all. Everything downstream reads `p.buf` / `p.base` and no longer\n * cares which mode the file was written in.\n */\nasync function resolvePlanes(\n buffer: ArrayBuffer,\n header: PlanarHeader,\n planeStart: number,\n): Promise<Record<string, ResolvedPlane>> {\n const out: Record<string, ResolvedPlane> = {};\n for (const [name, p] of Object.entries(header.planes)) {\n const start = planeStart + p.offset;\n if (start + p.length > buffer.byteLength) {\n throw new Error(`Planar plane out of bounds: ${name}`);\n }\n const expected = p.components * p.count * BYTES_PER_ELEMENT[p.dtype];\n if (p.compression) {\n if (!PLANE_CODECS.includes(p.compression)) {\n throw new Error(`Planar plane ${name}: unsupported compression ${p.compression}`);\n }\n const buf = await inflate(new Uint8Array(buffer, start, p.length), p.compression);\n // The header's uncompressedLength is what a native decoder would have\n // used to size its destination, so a disagreement means the file lies\n // about itself - fail rather than render half a character.\n if (buf.byteLength !== (p.uncompressedLength ?? expected)) {\n throw new Error(\n `Planar plane ${name}: inflated to ${buf.byteLength} B, header says ` +\n `${p.uncompressedLength ?? expected} B`,\n );\n }\n if (buf.byteLength !== expected) {\n throw new Error(`Planar plane ${name}: ${buf.byteLength} B, expected ${expected} B`);\n }\n out[name] = { ...p, buf, base: 0 };\n } else {\n if (p.length !== expected) {\n throw new Error(`Planar plane ${name}: ${p.length} B, expected ${expected} B`);\n }\n out[name] = { ...p, buf: buffer, base: start };\n }\n }\n return out;\n}\n\n/**\n * Decode a planar character bundle into the Float32 arrays the GPU pipeline\n * expects, plus the skinning and joint data.\n *\n * Returns the same shape `parseBinaryGsplat` returns for the interleaved\n * container (minus the animation chunk, which planar files do not carry - clips\n * are registered separately), so both feed one `loadBinaryGsplat`.\n */\nasync function parsePlanarSplats(buffer: ArrayBuffer) {\n const magic = readMagic(buffer);\n const expectedFormat = PLANAR_CONTAINERS[magic];\n if (!expectedFormat) {\n throw new Error(`Invalid planar character bundle magic: ${magic}`);\n }\n\n const view = new DataView(buffer);\n const headerLength = view.getUint32(8, true);\n const headerStart = 12;\n const planeStart = headerStart + headerLength;\n if (planeStart > buffer.byteLength) throw new Error('Planar header length out of range');\n\n const header: PlanarHeader = JSON.parse(\n new TextDecoder().decode(new Uint8Array(buffer, headerStart, headerLength)),\n );\n if (header.format !== expectedFormat) {\n throw new Error(\n `Planar bundle ${magic} declares format '${header.format}', expected '${expectedFormat}'`,\n );\n }\n // The magic is the container generation, so a version below the planar line\n // under a planar magic means the file mislabels itself - the one thing this\n // reader must never shrug off. A LATER version is accepted: the format's own\n // rule is that a breaking layout change bumps the magic, not the version.\n if (!(header.version >= FIRST_PLANAR_VERSION)) {\n throw new Error(\n `Planar bundle ${magic} declares version ${header.version}, expected >= ${FIRST_PLANAR_VERSION}`,\n );\n }\n if (header.precision !== 'fp16' && header.precision !== 'q23') {\n throw new Error(`Unsupported planar precision: ${header.precision}`);\n }\n if (!header.planes) throw new Error('Planar bundle has no plane table');\n // The encoder pads the header so the plane block is 4-byte aligned; without\n // that every typed-array view below would be a coin flip. (Inflated planes\n // start at offset 0 of their own buffer and are aligned for free.)\n if (planeStart % 4 !== 0) throw new Error('Planar plane block is not 4-byte aligned');\n\n const numSplats = header.numSplats;\n const topK = header.topK ?? 4;\n const isQ23 = header.precision === 'q23';\n\n const resolved = await resolvePlanes(buffer, header, planeStart);\n\n const plane = (name: string): ResolvedPlane => {\n const p = resolved[name];\n if (!p) throw new Error(`Planar bundle missing plane: ${name}`);\n return p;\n };\n\n const componentOffset = (p: ResolvedPlane, c: number): number =>\n p.base + c * p.count * BYTES_PER_ELEMENT[p.dtype];\n\n /** Expand one f16 component plane into `out`, natively where possible. */\n const readF16 = (p: ResolvedPlane, c: number, out: Float32Array): Float32Array => {\n const off = componentOffset(p, c);\n if (NativeFloat16Array) {\n out.set(new NativeFloat16Array(p.buf, off, p.count) as unknown as ArrayLike<number>);\n return out;\n }\n const dv = new DataView(p.buf, off, p.count * 2);\n for (let i = 0; i < p.count; i++) out[i] = f16ToF32(dv.getUint16(i * 2, true));\n return out;\n };\n\n const readU8 = (p: ResolvedPlane, c: number) => new Uint8Array(p.buf, componentOffset(p, c), p.count);\n const readU16 = (p: ResolvedPlane, c: number) => new Uint16Array(p.buf, componentOffset(p, c), p.count);\n const readUint = (p: ResolvedPlane, c: number): Uint8Array | Uint16Array =>\n p.dtype === 'u8' ? readU8(p, c) : readU16(p, c);\n\n const storage_x = new Float32Array(numSplats);\n const storage_y = new Float32Array(numSplats);\n const storage_z = new Float32Array(numSplats);\n const storage_scale_0 = new Float32Array(numSplats);\n const storage_scale_1 = new Float32Array(numSplats);\n const storage_scale_2 = new Float32Array(numSplats);\n const storage_rot_0 = new Float32Array(numSplats);\n const storage_rot_1 = new Float32Array(numSplats);\n const storage_rot_2 = new Float32Array(numSplats);\n const storage_rot_3 = new Float32Array(numSplats);\n const storage_f_dc_0 = new Float32Array(numSplats);\n const storage_f_dc_1 = new Float32Array(numSplats);\n const storage_f_dc_2 = new Float32Array(numSplats);\n const storage_opacity = new Float32Array(numSplats);\n\n const posPlane = plane('position');\n const scalePlane = plane('scale');\n const rotPlane = plane('rotation');\n const colorPlane = plane('color');\n const opacityPlane = plane('opacity');\n\n // \u2500\u2500 position \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const posOut = [storage_x, storage_y, storage_z];\n if (isQ23) {\n const bmin = header.bounds.min;\n const bmax = header.bounds.max;\n for (let c = 0; c < 3; c++) {\n const q = readU16(posPlane, c);\n const lo = bmin[c];\n const step = (bmax[c] - lo) / 65535;\n const out = posOut[c];\n for (let i = 0; i < numSplats; i++) out[i] = lo + q[i] * step;\n }\n } else {\n for (let c = 0; c < 3; c++) readF16(posPlane, c, posOut[c]);\n }\n\n // \u2500\u2500 scale \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The engine consumes LOG scale. q23 already stores log scale, so its decode\n // is a multiply-add; fp16 stores the linear value the v2 .bin stores and pays\n // the same log() the v2 path pays.\n const scaleOut = [storage_scale_0, storage_scale_1, storage_scale_2];\n if (isQ23) {\n const lsMin = header.logScale!.min;\n const lsMax = header.logScale!.max;\n for (let c = 0; c < 3; c++) {\n const q = readU8(scalePlane, c);\n const lo = lsMin[c];\n const step = (lsMax[c] - lo) / 255;\n const out = scaleOut[c];\n for (let i = 0; i < numSplats; i++) out[i] = lo + q[i] * step;\n }\n } else {\n for (let c = 0; c < 3; c++) {\n const out = readF16(scalePlane, c, scaleOut[c]);\n for (let i = 0; i < numSplats; i++) out[i] = Math.log(Math.max(out[i], MIN_SCALE));\n }\n }\n\n // \u2500\u2500 rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Stored xyzw; the engine wants wxyz (rot_0 = w).\n if (isQ23) {\n const qx = readU8(rotPlane, 0);\n const qy = readU8(rotPlane, 1);\n const qz = readU8(rotPlane, 2);\n for (let i = 0; i < numSplats; i++) {\n const x = (qx[i] / 255) * 2 - 1;\n const y = (qy[i] / 255) * 2 - 1;\n const z = (qz[i] / 255) * 2 - 1;\n // The encoder forced w >= 0, which is what makes this branch valid.\n storage_rot_0[i] = Math.sqrt(Math.max(0, 1 - x * x - y * y - z * z));\n storage_rot_1[i] = x;\n storage_rot_2[i] = y;\n storage_rot_3[i] = z;\n }\n } else {\n readF16(rotPlane, 0, storage_rot_1);\n readF16(rotPlane, 1, storage_rot_2);\n readF16(rotPlane, 2, storage_rot_3);\n readF16(rotPlane, 3, storage_rot_0);\n }\n\n // \u2500\u2500 colour \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const dcOut = [storage_f_dc_0, storage_f_dc_1, storage_f_dc_2];\n for (let c = 0; c < 3; c++) {\n const src = readU8(colorPlane, c);\n const out = dcOut[c];\n for (let i = 0; i < numSplats; i++) out[i] = (src[i] / 255 - 0.5) / SH_C0;\n }\n\n // \u2500\u2500 opacity \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The engine consumes the LOGIT. Same trade as scale: q23 stores it already\n // in logit space, fp16 stores the post-sigmoid value the v2 .bin stores.\n if (isQ23) {\n const lo = header.logitOpacity!.min;\n const step = (header.logitOpacity!.max - lo) / 255;\n const q = readU8(opacityPlane, 0);\n for (let i = 0; i < numSplats; i++) storage_opacity[i] = lo + q[i] * step;\n } else {\n readF16(opacityPlane, 0, storage_opacity);\n for (let i = 0; i < numSplats; i++) {\n const a = Math.max(OPACITY_CLAMP_LO, Math.min(OPACITY_CLAMP_HI, storage_opacity[i]));\n storage_opacity[i] = -Math.log(1 / a - 1);\n }\n }\n\n // \u2500\u2500 skinning \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n let boneIndices: Uint16Array | undefined;\n let boneWeights: Float32Array | undefined;\n if (header.planes.boneIndex && header.planes.boneWeight) {\n const idxPlane = plane('boneIndex');\n const wPlane = plane('boneWeight');\n boneIndices = new Uint16Array(numSplats * topK);\n boneWeights = new Float32Array(numSplats * topK);\n\n // q23 indexes a per-file palette so the plane can be a byte wide; the\n // encoder widens it to u16 when a character touches more than 256 bones,\n // which the plane dtype records.\n const palette = header.bonePalette;\n for (let j = 0; j < topK; j++) {\n const src = readUint(idxPlane, j);\n if (palette) {\n for (let i = 0; i < numSplats; i++) boneIndices[i * topK + j] = palette[src[i]];\n } else {\n for (let i = 0; i < numSplats; i++) boneIndices[i * topK + j] = src[i];\n }\n }\n\n if (isQ23) {\n // Slots 0..2 are stored; the last one is whatever is left, which is what\n // makes the decoded quartet sum to exactly 1.\n const scratch = new Float32Array(numSplats);\n for (let j = 0; j < wPlane.components; j++) {\n const src = readU8(wPlane, j);\n for (let i = 0; i < numSplats; i++) {\n const w = src[i] / 255;\n boneWeights[i * topK + j] = w;\n scratch[i] += w;\n }\n }\n for (let i = 0; i < numSplats; i++) {\n boneWeights[i * topK + (topK - 1)] = Math.max(0, 1 - scratch[i]);\n }\n } else {\n const col = new Float32Array(numSplats);\n for (let j = 0; j < topK; j++) {\n readF16(wPlane, j, col);\n for (let i = 0; i < numSplats; i++) boneWeights[i * topK + j] = col[i];\n }\n }\n }\n\n // \u2500\u2500 joints \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Component-major like every other plane, unlike the interleaved container's\n // joints chunk, which is float3 records.\n let jointsArray: Float32Array | undefined;\n if (header.planes.joints) {\n const jp = plane('joints');\n jointsArray = new Float32Array(jp.count * 3);\n for (let c = 0; c < 3; c++) {\n const src = new Float32Array(jp.buf, componentOffset(jp, c), jp.count);\n for (let i = 0; i < jp.count; i++) jointsArray[i * 3 + c] = src[i];\n }\n }\n\n const transferables: ArrayBuffer[] = [\n storage_x.buffer as ArrayBuffer, storage_y.buffer as ArrayBuffer, storage_z.buffer as ArrayBuffer,\n storage_scale_0.buffer as ArrayBuffer, storage_scale_1.buffer as ArrayBuffer, storage_scale_2.buffer as ArrayBuffer,\n storage_rot_0.buffer as ArrayBuffer, storage_rot_1.buffer as ArrayBuffer, storage_rot_2.buffer as ArrayBuffer, storage_rot_3.buffer as ArrayBuffer,\n storage_f_dc_0.buffer as ArrayBuffer, storage_f_dc_1.buffer as ArrayBuffer, storage_f_dc_2.buffer as ArrayBuffer,\n storage_opacity.buffer as ArrayBuffer,\n ];\n if (boneIndices) transferables.push(boneIndices.buffer as ArrayBuffer);\n if (boneWeights) transferables.push(boneWeights.buffer as ArrayBuffer);\n if (jointsArray) transferables.push(jointsArray.buffer as ArrayBuffer);\n\n const result = {\n header,\n numSplats,\n splats: {\n x: storage_x, y: storage_y, z: storage_z,\n scale_0: storage_scale_0, scale_1: storage_scale_1, scale_2: storage_scale_2,\n rot_0: storage_rot_0, rot_1: storage_rot_1, rot_2: storage_rot_2, rot_3: storage_rot_3,\n f_dc_0: storage_f_dc_0, f_dc_1: storage_f_dc_1, f_dc_2: storage_f_dc_2,\n opacity: storage_opacity,\n },\n boneIndices: boneIndices ?? null,\n boneWeights: boneWeights ?? null,\n // Planar files carry no animation chunk; the fields exist so both\n // containers hand `loadBinaryGsplat` the same shape.\n animationArray: null as Float32Array | null,\n animNumFrames: 0,\n animNumBones: 0,\n jointsArray: jointsArray ?? null,\n nativeFloat16: !!NativeFloat16Array,\n planeCompression: header.encoding?.planeCompression ?? null,\n };\n\n return { result, transferables };\n}\n\nexport { parsePlanarSplats, readMagic, isPlanarMagic, PLANAR_CONTAINERS, FIRST_PLANAR_VERSION };\nexport type { PlanarHeader, PlaneInfo, PlaneCodec, PlaneDtype };\n", "/**\n * The legacy door.\n *\n * Everything whose first 8 bytes are not `VIGGCHAR` arrives here, and nothing\n * else does. Behind it are the two container generations that shipped before\n * the format was respecified:\n *\n * `VFCHARB1` -> interleaved per-splat records (v1 fp32, v2 fp16)\n * `VFCHARB2` -> planar byte planes (v3; fp16 or q23 precision)\n * `VSPLAT01` -> the pre-release prototype of the planar layout\n *\n * These readers are PERMANENT, not migration scaffolding. Files already in\n * storage keep their old magic forever - there is no backfill - so this module\n * is kept indefinitely and its decoders are moved, never improved. What it is\n * NOT is entangled: it is one branch of one top-level `if`, it imports nothing\n * from `../v1/`, and `../v1/` imports nothing from it.\n *\n * These containers spell `version` as one global lineage across two magics,\n * which is precisely the accretion `VIGGCHAR` exists to end. Nothing about that\n * lineage leaks past this file: the dispatcher upstream never reads it, and the\n * bundle handed back is the same version-independent shape `v1/` returns.\n */\n\nimport { CharacterBundleError } from '../types';\nimport type { DecodeResult, DecodedBundle } from '../types';\nimport { CHARACTER_BUNDLE_MAGIC, parseBinaryGsplat } from './interleaved-splat';\nimport { isPlanarMagic, parsePlanarSplats, readMagic } from './planar-splat';\n\n/**\n * Did this bundle go through the character-correction pipeline?\n *\n * A LEGACY question with a legacy answer. The old writers agree on the meaning\n * and disagree on the spelling, so both are accepted:\n *\n * - `corrections` - the production encoder, which stamps this header ONLY\n * when the corrections ran. That makes presence an exact test: with the\n * corrections switched off the encoder is byte-identical to its\n * pre-correction self, receipt included.\n * - `ankleCorrection` - the offline authoring writer, which writes the ankle\n * block at the top level and no `corrections` key at all.\n *\n * `groundOffset` and `visibleBounds` are deliberately NOT accepted: the writer\n * emits them unconditionally, so they say \"written recently\", not \"corrected\".\n *\n * Two spellings for one fact is exactly how a gate like this rots, and it is\n * why `VIGGCHAR` version 1 carries no receipt at all - the version means\n * corrected, so there is no question left to ask. Nothing here is shared with\n * that path; a receipt is a property of these containers only.\n */\nfunction hasCorrectionReceipt(header: any): boolean {\n return header?.corrections != null || header?.ankleCorrection != null;\n}\n\n/**\n * How many bones the rig this bundle poses has, by the legacy rules.\n *\n * Three header keys can answer, in a fixed order of trust, and `0` means the\n * bundle carries no rig. This is lifted verbatim out of `binary-gsplat.ts`,\n * where it used to run downstream of the worker on a header only these\n * containers produce; it belongs to them, so it moved in with them.\n */\nfunction legacyRigBoneCount(header: any, animNumFrames: number, animNumBones: number): number {\n if (!header?.joints && !header?.skeleton) return 0;\n let numBones = animNumFrames > 0 && animNumBones > 0 ? animNumBones : 0;\n if (numBones === 0 && header.skeleton) numBones = header.skeleton.count;\n if (numBones === 0 && header.joints) numBones = header.joints.count;\n return numBones > 0 ? numBones : 0;\n}\n\n/**\n * Decode a bundle in one of the pre-`VIGGCHAR` containers.\n *\n * The container is identified by SNIFFING THE 8-BYTE MAGIC and never by the\n * filename or a header key - both generations arrive through the same URLs,\n * with no out-of-band type information, so the bytes are the only honest\n * answer. Anything this door does not recognise throws with the magic it\n * actually found.\n */\nasync function decodeLegacyBundle(file: ArrayBuffer): Promise<DecodeResult> {\n if (file.byteLength < 12) {\n throw new CharacterBundleError(\n 'WrongMagic',\n `character bundle is ${file.byteLength} B, too small to carry a magic`,\n );\n }\n const magic = readMagic(file);\n\n let decoded: { result: any; transferables: ArrayBuffer[] };\n if (isPlanarMagic(magic)) {\n decoded = await parsePlanarSplats(file);\n } else if (magic === CHARACTER_BUNDLE_MAGIC) {\n decoded = parseBinaryGsplat(file);\n } else {\n throw new CharacterBundleError(\n 'WrongMagic',\n `unrecognised character bundle magic '${magic}'`,\n );\n }\n\n const { result, transferables } = decoded;\n // The decoders above are untouched, so the two version-independent answers\n // are computed here from what they returned. Cast because the legacy planar\n // reader also carries `nativeFloat16` / `planeCompression` diagnostics on the\n // worker message, which predate this interface and are kept for the A/B rig.\n const bundle: DecodedBundle = {\n ...result,\n rigBoneCount: legacyRigBoneCount(result.header, result.animNumFrames, result.animNumBones),\n corrected: hasCorrectionReceipt(result.header),\n // Never. A legacy joints block is diagnostics: it was not vetted as a\n // posing rest, and every shipped legacy character renders against the\n // canonical tables. Independent of the receipt above on purpose.\n bundledRestIsPerCharacter: false,\n } as DecodedBundle;\n\n return { result: bundle, transferables };\n}\n\nexport { decodeLegacyBundle };\n", "/**\n * `VIGGCHAR` version 1 - the quantised block payload.\n *\n * Written from the character-bundle format spec and from nothing else.\n * A JSON header with exactly two keys, `numSplats` and `blocks`, followed by\n * the blocks it lists. Each block holds one attribute for every gaussian,\n * stored component-major, and each block's entry carries everything needed to\n * decode THAT block - its dequantisation bounds, its palette. There is no\n * top-level decoding parameter and no file-wide precision mode.\n *\n * This handler is total over version 1 and knows that no other version exists.\n * It never re-checks the magic or the version: the dispatcher owns both.\n *\n * Vocabulary note: this format says BLOCKS. The legacy containers next door say\n * planes and chunks. The difference is deliberate - a block is self-describing\n * in a way a plane was not, and keeping the words apart keeps the two readers\n * from being read as one.\n */\n\nimport { CharacterBundleError } from '../types';\nimport type { DecodeResult, DecodedBundle } from '../types';\n\n/** Spherical-harmonic DC coefficient. A constant of version 1. */\nconst SH_C0 = 0.28209479177387814;\n\n/** Position quantisation levels: stored values run `0..65535`. */\nconst POSITION_LEVELS = 65536;\n\n/** Scale and opacity quantisation levels: stored values run `0..255`. */\nconst BYTE_LEVELS = 256;\n\ntype BlockDtype = 'f32' | 'u16' | 'u8';\n\nconst BYTES_PER_ELEMENT: Record<BlockDtype, number> = { f32: 4, u16: 2, u8: 1 };\n\n/** The five keys required on every block entry. */\nconst COMMON_KEYS = ['offset', 'length', 'dtype', 'components', 'count'] as const;\n\n/**\n * Every block this version defines, with the shape its entry must declare.\n *\n * `components: null` means \"whatever the entry says\" - `boneIndex` carries `K`\n * and `boneWeight` carries `K - 1`, and `K` is per-file. A block name that is\n * not in here is ignored: the manifest is what the file contains, and a name\n * this version does not define contributes nothing to the decode.\n */\nconst BLOCK_SHAPES: Record<string, { dtypes: BlockDtype[]; components: number | null }> = {\n position: { dtypes: ['u16'], components: 3 },\n scale: { dtypes: ['u8'], components: 3 },\n rotation: { dtypes: ['u8'], components: 3 },\n color: { dtypes: ['u8'], components: 3 },\n opacity: { dtypes: ['u8'], components: 1 },\n boneIndex: { dtypes: ['u8', 'u16'], components: null },\n boneWeight: { dtypes: ['u8'], components: null },\n joints: { dtypes: ['f32'], components: 3 },\n};\n\n/** The five blocks every conforming file carries. A missing one is rejected by name. */\nconst UNCONDITIONAL_BLOCKS = ['position', 'scale', 'rotation', 'color', 'opacity'] as const;\n\n/**\n * The blocks quantised against a range measured from this file's data.\n *\n * These and only these carry `min` / `max`. `rotation`, `boneWeight` and\n * `color` do not, because their range is a property of their type rather than\n * of this character, and there is nothing per-file to record.\n */\nconst BOUNDED_BLOCKS = ['position', 'scale', 'opacity'] as const;\n\ninterface BlockEntry {\n offset: number;\n /** Bytes in the file, and the only length a block has. */\n length: number;\n dtype: BlockDtype;\n /** Values per row, stored component-major: all c0, then all c1, ... */\n components: number;\n count: number;\n /** Per-component dequantisation bounds. Present on `BOUNDED_BLOCKS` only. */\n min?: number[];\n max?: number[];\n /** Stored index -> global rig bone index. Present on `boneIndex` only. */\n palette?: number[];\n}\n\ninterface V1Header {\n numSplats: number;\n blocks: Record<string, BlockEntry>;\n}\n\n/** A block entry with its bytes located: `base` is where component 0 begins. */\ninterface ResolvedBlock extends BlockEntry {\n /** Absolute byte offset of component 0 in the file: `blockStart + offset`. */\n base: number;\n}\n\n// A `function` declaration rather than a `const` arrow, deliberately: TypeScript\n// only narrows control flow through a never-returning call when the callee is a\n// function declaration or an explicitly-annotated variable. As a `const` arrow\n// this returned `never` and still left every `if (x === undefined) fail(...)`\n// guard invisible to the compiler, so the code after it saw `x` as possibly\n// undefined even though the guard had already thrown.\nfunction fail(\n category: ConstructorParameters<typeof CharacterBundleError>[0],\n message: string,\n): never {\n throw new CharacterBundleError(category, message);\n}\n\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\n\nconst isUint = (v: unknown): v is number =>\n typeof v === 'number' && Number.isInteger(v) && v >= 0;\n\n/**\n * Check the five common keys and the arithmetic that ties them together.\n *\n * Everything here is a property of ONE block entry, which is the point: no\n * check reaches into a sibling key, so a block decodes from its own entry plus\n * the constants of this version.\n */\nfunction validateCommonKeys(name: string, entry: unknown, blockStart: number, totalLength: number) {\n if (!isPlainObject(entry)) {\n fail('BadFieldValue', `block '${name}': entry is ${JSON.stringify(entry)}, expected an object`);\n }\n const e = entry as Record<string, unknown>;\n for (const key of COMMON_KEYS) {\n if (e[key] === undefined || e[key] === null) {\n fail('MissingField', `block '${name}': missing required key '${key}'`);\n }\n }\n for (const key of ['offset', 'length', 'components', 'count'] as const) {\n if (!isUint(e[key])) {\n fail('BadFieldValue', `block '${name}': '${key}' is ${JSON.stringify(e[key])}, expected a non-negative integer`);\n }\n }\n if (!Object.prototype.hasOwnProperty.call(BYTES_PER_ELEMENT, e.dtype as string)) {\n fail(\n 'BadFieldValue',\n `block '${name}': dtype ${JSON.stringify(e.dtype)}, expected one of ${Object.keys(BYTES_PER_ELEMENT).join(', ')}`,\n );\n }\n\n const p = e as unknown as BlockEntry;\n // A u16 or f32 block at an odd offset otherwise fails deep inside the decode,\n // where the cause is no longer visible.\n if (p.offset % 4 !== 0) {\n fail('UnalignedPayload', `block '${name}': offset ${p.offset} is not a multiple of 4`);\n }\n const end = blockStart + p.offset + p.length;\n if (end > totalLength) {\n fail(\n 'Truncated',\n `block '${name}': bytes [${blockStart + p.offset}, ${end}) run past the file's ${totalLength} B`,\n );\n }\n // The block's bytes are the decoded bytes, so its stored length is the size\n // its own shape asks for. A disagreement is the file describing itself wrong,\n // and it is caught here rather than as a short read deep inside the decode.\n const decoded = p.components * p.count * BYTES_PER_ELEMENT[p.dtype];\n if (p.length !== decoded) {\n fail(\n 'BlockSizeMismatch',\n `block '${name}': length ${p.length} B, but ` +\n `${p.components} components x ${p.count} rows x ${BYTES_PER_ELEMENT[p.dtype]} B (${p.dtype}) = ${decoded} B`,\n );\n }\n}\n\n/**\n * Check the manifest as a whole: which blocks are present, and what their\n * entries must then say about each other.\n *\n * The block table is the ONE place this reader learns what the file contains.\n * Nothing below probes the payload, guesses from a size, or reads meaning into\n * a block's absence beyond the presence rules the spec states outright.\n */\nfunction validateManifest(header: V1Header, blocks: Record<string, BlockEntry>) {\n for (const name of UNCONDITIONAL_BLOCKS) {\n if (!blocks[name]) fail('MissingField', `manifest is missing the required block '${name}'`);\n }\n\n for (const [name, p] of Object.entries(blocks)) {\n const shape = BLOCK_SHAPES[name];\n if (!shape) continue;\n if (!shape.dtypes.includes(p.dtype)) {\n fail(\n 'InconsistentHeader',\n `block '${name}': dtype '${p.dtype}', expected ${shape.dtypes.map((d) => `'${d}'`).join(' or ')}`,\n );\n }\n if (shape.components !== null && p.components !== shape.components) {\n fail(\n 'InconsistentHeader',\n `block '${name}': ${p.components} components, expected exactly ${shape.components}`,\n );\n }\n if (name !== 'joints' && p.count !== header.numSplats) {\n fail(\n 'InconsistentHeader',\n `block '${name}': count ${p.count}, expected numSplats ${header.numSplats}`,\n );\n }\n }\n\n // Checked before anything reads the rig's size: an empty rig is not a rig,\n // and a `joints.count` of 0 would otherwise surface as every palette entry\n // being out of range.\n if (blocks.joints && blocks.joints.count === 0) {\n fail('UnexpectedField', `block 'joints': count 0, and an empty rig is not a rig`);\n }\n\n // Bounds live in the entry of the block they decode, and nowhere else. A\n // block that carries them where it should not is as wrong as one that omits\n // them: both mean a decoder cannot tell from an entry how to read it.\n for (const [name, p] of Object.entries(blocks)) {\n if (!BLOCK_SHAPES[name]) continue;\n const bounded = (BOUNDED_BLOCKS as readonly string[]).includes(name);\n for (const key of ['min', 'max'] as const) {\n const v = p[key];\n if (!bounded) {\n if (v !== undefined) {\n fail('UnexpectedField', `block '${name}': carries '${key}', but its range is fixed by its type`);\n }\n continue;\n }\n if (v === undefined) {\n fail('MissingField', `block '${name}': missing dequantisation bound '${key}'`);\n }\n if (!Array.isArray(v) || v.length !== p.components || !v.every((n) => typeof n === 'number' && Number.isFinite(n))) {\n fail(\n 'BadFieldValue',\n `block '${name}': '${key}' is ${JSON.stringify(v)}, expected an array of ${p.components} finite numbers`,\n );\n }\n }\n if (bounded) {\n for (let c = 0; c < p.components; c++) {\n if (p.max![c] < p.min![c]) {\n fail(\n 'BadFieldValue',\n `block '${name}': component ${c} has max ${p.max![c]} below min ${p.min![c]}, an inverted span`,\n );\n }\n }\n }\n if (name !== 'boneIndex' && p.palette !== undefined) {\n fail('UnexpectedField', `block '${name}': carries a 'palette', which only 'boneIndex' takes`);\n }\n }\n\n // Skinning is one fact in two blocks. A bundle with one of them has no\n // defined meaning, so neither half is guessed at from the other's absence.\n const hasIndex = !!blocks.boneIndex;\n const hasWeight = !!blocks.boneWeight;\n if (hasIndex && !hasWeight) {\n fail('MissingField', `manifest has 'boneIndex' but not 'boneWeight'; skinning needs both`);\n }\n if (hasWeight && !hasIndex) {\n fail('UnexpectedField', `manifest has 'boneWeight' but not 'boneIndex'; skinning needs both`);\n }\n if (hasIndex) {\n const idx = blocks.boneIndex;\n const w = blocks.boneWeight;\n if (w.components !== idx.components - 1) {\n fail(\n 'InconsistentHeader',\n `block 'boneWeight': ${w.components} components, expected boneIndex.components - 1 = ${idx.components - 1}`,\n );\n }\n if (idx.palette === undefined) {\n fail('MissingField', `block 'boneIndex': missing 'palette'`);\n }\n if (!Array.isArray(idx.palette) || !idx.palette.every(isUint)) {\n fail(\n 'BadFieldValue',\n `block 'boneIndex': 'palette' is ${JSON.stringify(idx.palette)?.slice(0, 80)}, expected an array of rig indices`,\n );\n }\n // A palette entry is a global rig index, so the rig - when the file carries\n // one - is what says which indices exist.\n const rigBones = blocks.joints?.count;\n if (rigBones !== undefined) {\n for (let i = 0; i < idx.palette.length; i++) {\n if (idx.palette[i] >= rigBones) {\n fail(\n 'InconsistentHeader',\n `block 'boneIndex': palette[${i}] is ${idx.palette[i]}, outside the ${rigBones}-bone rig`,\n );\n }\n }\n }\n }\n\n}\n\n/**\n * Locate every block: `base` is where its component 0 begins in the file.\n *\n * A block is read in place - no copy at all. `blockStart` and every `offset`\n * are multiples of 4, so every typed-array view below is aligned by the\n * layout's own rules and nothing has to be moved to make it so.\n */\nfunction resolveBlocks(\n blocks: Record<string, BlockEntry>,\n blockStart: number,\n): Record<string, ResolvedBlock> {\n const out: Record<string, ResolvedBlock> = {};\n for (const [name, p] of Object.entries(blocks)) {\n if (!BLOCK_SHAPES[name]) continue;\n out[name] = { ...p, base: blockStart + p.offset };\n }\n return out;\n}\n\n/**\n * Decode a `VIGGCHAR` version 1 payload.\n *\n * Version 1 means CORRECTED: the ankle pitch bake and then the ground shift are\n * already in the gaussians and in the `joints` block, and the character stands\n * on `y = 0` by construction. There is no in-file signal about that and nothing\n * below looks for one - the version answered it.\n *\n * The decode is straight-line and never yields; it is declared `async` only\n * because `VersionHandler` is promise-shaped for the handlers that must be.\n */\nasync function decodeV1(\n file: ArrayBuffer,\n payloadOffset: number,\n payloadLength: number,\n): Promise<DecodeResult> {\n const totalLength = payloadOffset + payloadLength;\n\n if (payloadLength < 4) {\n fail('Truncated', `payload is ${payloadLength} B, too small to carry a header length`);\n }\n const headerLength = new DataView(file).getUint32(payloadOffset, true);\n const headerStart = payloadOffset + 4;\n const blockStart = headerStart + headerLength;\n if (blockStart > totalLength) {\n fail(\n 'Truncated',\n `header claims ${headerLength} B, which ends at ${blockStart}, past the file's ${totalLength} B`,\n );\n }\n // The writer pads the JSON with spaces until this holds. Block offsets are\n // relative to `blockStart`, so a misaligned base makes every typed-array view\n // in the payload invalid - and a `u16` block would fail far from the cause.\n if (headerLength % 4 !== 0) {\n fail('UnalignedPayload', `headerLength ${headerLength} is not a multiple of 4`);\n }\n\n let header: V1Header;\n try {\n const text = new TextDecoder('utf-8', { fatal: true }).decode(\n new Uint8Array(file, headerStart, headerLength),\n );\n header = JSON.parse(text);\n } catch (err) {\n return fail('MalformedHeader', `header is not valid UTF-8 JSON (${(err as Error)?.message ?? String(err)})`);\n }\n if (!isPlainObject(header)) {\n return fail('MalformedHeader', `header is ${JSON.stringify(header)}, expected a JSON object`);\n }\n\n if (header.numSplats === undefined || header.numSplats === null) {\n fail('MissingField', `header is missing 'numSplats'`);\n }\n if (!isUint(header.numSplats)) {\n fail('BadFieldValue', `header 'numSplats' is ${JSON.stringify(header.numSplats)}, expected a non-negative integer`);\n }\n if (header.blocks === undefined || header.blocks === null) {\n fail('MissingField', `header is missing 'blocks', the block table`);\n }\n if (!isPlainObject(header.blocks)) {\n fail('BadFieldValue', `header 'blocks' is ${JSON.stringify(header.blocks)}, expected an object`);\n }\n\n const numSplats = header.numSplats;\n // A name this version does not define contributes nothing to the decode, so\n // it is ignored whole rather than validated against rules written for other\n // blocks. Everything past this point works from `blocks`.\n const blocks: Record<string, BlockEntry> = {};\n for (const [name, entry] of Object.entries(header.blocks)) {\n if (!BLOCK_SHAPES[name]) continue;\n validateCommonKeys(name, entry, blockStart, totalLength);\n blocks[name] = entry as BlockEntry;\n }\n validateManifest(header, blocks);\n\n const resolved = resolveBlocks(blocks, blockStart);\n const block = (name: string): ResolvedBlock => resolved[name];\n\n const componentOffset = (p: ResolvedBlock, c: number): number =>\n p.base + c * p.count * BYTES_PER_ELEMENT[p.dtype];\n\n const readU8 = (p: ResolvedBlock, c: number) => new Uint8Array(file, componentOffset(p, c), p.count);\n const readU16 = (p: ResolvedBlock, c: number) => new Uint16Array(file, componentOffset(p, c), p.count);\n const readUint = (p: ResolvedBlock, c: number): Uint8Array | Uint16Array =>\n p.dtype === 'u8' ? readU8(p, c) : readU16(p, c);\n\n const storage_x = new Float32Array(numSplats);\n const storage_y = new Float32Array(numSplats);\n const storage_z = new Float32Array(numSplats);\n const storage_scale_0 = new Float32Array(numSplats);\n const storage_scale_1 = new Float32Array(numSplats);\n const storage_scale_2 = new Float32Array(numSplats);\n const storage_rot_0 = new Float32Array(numSplats);\n const storage_rot_1 = new Float32Array(numSplats);\n const storage_rot_2 = new Float32Array(numSplats);\n const storage_rot_3 = new Float32Array(numSplats);\n const storage_f_dc_0 = new Float32Array(numSplats);\n const storage_f_dc_1 = new Float32Array(numSplats);\n const storage_f_dc_2 = new Float32Array(numSplats);\n const storage_opacity = new Float32Array(numSplats);\n\n // \u2500\u2500 position, scale, opacity \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // One decode, `min[c] + q * (max[c] - min[c]) / (levels - 1)`, over the\n // component index of whichever block is being read. Nothing distinguishes\n // the single-component block from the three-component ones, which is why\n // opacity's bounds are one-element arrays like everybody else's.\n const dequantise = (p: ResolvedBlock, levels: number, out: Float32Array[]) => {\n for (let c = 0; c < out.length; c++) {\n const q = levels === POSITION_LEVELS ? readU16(p, c) : readU8(p, c);\n const lo = p.min![c];\n const step = (p.max![c] - lo) / (levels - 1);\n const dst = out[c];\n for (let i = 0; i < numSplats; i++) dst[i] = lo + q[i] * step;\n }\n };\n\n dequantise(block('position'), POSITION_LEVELS, [storage_x, storage_y, storage_z]);\n // Log-space per-axis standard deviations, which is the space the engine\n // consumes, so the decode is a multiply-add and nothing pays a `log` per\n // gaussian.\n dequantise(block('scale'), BYTE_LEVELS, [storage_scale_0, storage_scale_1, storage_scale_2]);\n // The LOGIT, not an alpha. Same trade as scale.\n dequantise(block('opacity'), BYTE_LEVELS, [storage_opacity]);\n\n // \u2500\u2500 rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Three components, not four: the writer negated any quaternion with w < 0\n // before quantising, which is what makes w recoverable from xyz. Stored\n // xyzw; the engine wants wxyz, so rot_0 is w.\n {\n const p = block('rotation');\n const qx = readU8(p, 0);\n const qy = readU8(p, 1);\n const qz = readU8(p, 2);\n for (let i = 0; i < numSplats; i++) {\n const x = (qx[i] / 255) * 2 - 1;\n const y = (qy[i] / 255) * 2 - 1;\n const z = (qz[i] / 255) * 2 - 1;\n storage_rot_0[i] = Math.sqrt(Math.max(0, 1 - x * x - y * y - z * z));\n storage_rot_1[i] = x;\n storage_rot_2[i] = y;\n storage_rot_3[i] = z;\n }\n }\n\n // \u2500\u2500 colour \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The spherical-harmonic DC term. There is no higher band; characters are\n // lit flat.\n {\n const p = block('color');\n const dcOut = [storage_f_dc_0, storage_f_dc_1, storage_f_dc_2];\n for (let c = 0; c < 3; c++) {\n const src = readU8(p, c);\n const dst = dcOut[c];\n for (let i = 0; i < numSplats; i++) dst[i] = (src[i] / 255 - 0.5) / SH_C0;\n }\n }\n\n // \u2500\u2500 skinning \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n let boneIndices: Uint16Array | undefined;\n let boneWeights: Float32Array | undefined;\n if (resolved.boneIndex) {\n const idxBlock = block('boneIndex');\n const wBlock = block('boneWeight');\n const palette = idxBlock.palette!;\n const K = idxBlock.components;\n boneIndices = new Uint16Array(numSplats * K);\n boneWeights = new Float32Array(numSplats * K);\n\n // The palette is what lets a narrow character on a 441-bone rig store its\n // indices in a byte. It is required even when it is the identity mapping,\n // so there is only ever one index space to read.\n for (let j = 0; j < K; j++) {\n const src = readUint(idxBlock, j);\n for (let i = 0; i < numSplats; i++) {\n const q = src[i];\n if (q >= palette.length) {\n fail(\n 'InconsistentHeader',\n `block 'boneIndex': gaussian ${i} slot ${j} stores index ${q}, ` +\n `outside its ${palette.length}-entry palette`,\n );\n }\n boneIndices[i * K + j] = palette[q];\n }\n }\n\n // K - 1 slots are stored; the last is whatever is left, which is what makes\n // the decoded influences sum to exactly 1. The writer allocated the K byte\n // weights by largest remainder so they total 255, so summing the BYTES and\n // dividing once evaluates `1 - sum(q / 255)` with no rounding drift.\n const stored = new Uint32Array(numSplats);\n for (let j = 0; j < wBlock.components; j++) {\n const src = readU8(wBlock, j);\n for (let i = 0; i < numSplats; i++) {\n boneWeights[i * K + j] = src[i] / 255;\n stored[i] += src[i];\n }\n }\n for (let i = 0; i < numSplats; i++) {\n boneWeights[i * K + (K - 1)] = Math.max(0, 255 - stored[i]) / 255;\n }\n }\n\n // \u2500\u2500 joints \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Rest positions only - no rotations, no names, no hierarchy. Row i is the\n // rest position of global rig bone i, the same index space a decoded\n // `boneIndex` lands in. Component-major like every other block.\n let jointsArray: Float32Array | undefined;\n let rigBoneCount = 0;\n if (resolved.joints) {\n const p = block('joints');\n rigBoneCount = p.count;\n jointsArray = new Float32Array(p.count * 3);\n for (let c = 0; c < 3; c++) {\n const src = new Float32Array(file, componentOffset(p, c), p.count);\n for (let i = 0; i < p.count; i++) jointsArray[i * 3 + c] = src[i];\n }\n }\n\n const transferables: ArrayBuffer[] = [\n storage_x.buffer as ArrayBuffer, storage_y.buffer as ArrayBuffer, storage_z.buffer as ArrayBuffer,\n storage_scale_0.buffer as ArrayBuffer, storage_scale_1.buffer as ArrayBuffer, storage_scale_2.buffer as ArrayBuffer,\n storage_rot_0.buffer as ArrayBuffer, storage_rot_1.buffer as ArrayBuffer, storage_rot_2.buffer as ArrayBuffer, storage_rot_3.buffer as ArrayBuffer,\n storage_f_dc_0.buffer as ArrayBuffer, storage_f_dc_1.buffer as ArrayBuffer, storage_f_dc_2.buffer as ArrayBuffer,\n storage_opacity.buffer as ArrayBuffer,\n ];\n if (boneIndices) transferables.push(boneIndices.buffer as ArrayBuffer);\n if (boneWeights) transferables.push(boneWeights.buffer as ArrayBuffer);\n if (jointsArray) transferables.push(jointsArray.buffer as ArrayBuffer);\n\n const result: DecodedBundle = {\n header,\n numSplats,\n splats: {\n x: storage_x, y: storage_y, z: storage_z,\n scale_0: storage_scale_0, scale_1: storage_scale_1, scale_2: storage_scale_2,\n rot_0: storage_rot_0, rot_1: storage_rot_1, rot_2: storage_rot_2, rot_3: storage_rot_3,\n f_dc_0: storage_f_dc_0, f_dc_1: storage_f_dc_1, f_dc_2: storage_f_dc_2,\n opacity: storage_opacity,\n },\n boneIndices: boneIndices ?? null,\n boneWeights: boneWeights ?? null,\n // This format carries no animation. Clips are separate files, registered\n // separately; the fields exist so every version hands back one shape.\n animationArray: null,\n animNumFrames: 0,\n animNumBones: 0,\n jointsArray: jointsArray ?? null,\n rigBoneCount,\n // Version 1 means corrected. There is no field to read and no receipt to\n // find, and a reader is forbidden from looking for one.\n corrected: true,\n // Always. The corrections are baked into the gaussians AND into the joints\n // block, so this rest is the character's own and the two agree.\n bundledRestIsPerCharacter: true,\n };\n\n return { result, transferables };\n}\n\nexport { decodeV1 };\n", "/**\n * Character-bundle reader: the dispatch table and the public entry point.\n *\n * ONE top-level branch, and legacy behind one door:\n *\n * magic == VIGGCHAR -> look `version` up in VERSION_HANDLERS\n * otherwise -> legacy/\n *\n * That is the whole structure, and it is the point of it: adding version N+1\n * costs one module under `vN/` and one line in the table below, and removing a\n * version costs deleting exactly those two things. If a change to support a new\n * version has to touch an existing handler, the decomposition is not real.\n * (Character-bundle format spec, \"Reader architecture\", R1-R5.)\n *\n * The only bytes read before dispatch are the 16 container bytes. Nothing here\n * sniffs the payload, peeks at the header, tries a parse, or consults the\n * filename, the extension, the URL or the MIME type - the `.vsplat` extension\n * is advisory and says nothing this reader may act on.\n */\n\nimport { CharacterBundleError } from './types';\nimport type { DecodeResult, VersionHandler } from './types';\nimport { decodeLegacyBundle } from './legacy';\nimport { decodeV1 } from './v1/decode';\n\n/**\n * The format tag, compared as 8 bytes and never decoded as an integer.\n *\n * Loading it as one or two integers would make the comparison depend on byte\n * order, and a magic whose numeric spelling differs per platform is a magic\n * that fails on one of them.\n */\nconst VIGGCHAR_MAGIC = new Uint8Array([0x56, 0x49, 0x47, 0x47, 0x43, 0x48, 0x41, 0x52]); // 'VIGGCHAR'\n\n/** Bytes of container: `magic` (8) + `version` (4) + `totalLength` (4). */\nconst CONTAINER_BYTES = 16;\n\n/**\n * The dispatch table: payload version -> the one handler that decodes it.\n *\n * A SET of versions, not a range. There is no ordering relation here - a\n * higher version is not \"newer and probably compatible\", it is unknown, and\n * unknown is a hard failure.\n */\nconst VERSION_HANDLERS: ReadonlyMap<number, VersionHandler> = new Map([\n [1, decodeV1],\n]);\n\n/** True when the first 8 bytes are exactly `VIGGCHAR`. */\nfunction hasViggcharMagic(file: ArrayBuffer): boolean {\n if (file.byteLength < VIGGCHAR_MAGIC.length) return false;\n const bytes = new Uint8Array(file, 0, VIGGCHAR_MAGIC.length);\n for (let i = 0; i < VIGGCHAR_MAGIC.length; i++) {\n if (bytes[i] !== VIGGCHAR_MAGIC[i]) return false;\n }\n return true;\n}\n\n/**\n * Read a character bundle of any container this reader implements.\n *\n * @param file - the whole file as a read-only byte buffer.\n * @returns the decoded bundle in the version-independent output type, plus the\n * buffers a worker may transfer rather than copy. A caller cannot tell from the\n * result which handler ran.\n * @throws {CharacterBundleError} carrying the spec's error category.\n */\nasync function parseCharacterBundle(file: ArrayBuffer): Promise<DecodeResult> {\n // Not our file. A caller may reasonably try another format - which is why\n // this is the one branch that leaves, rather than rejecting outright.\n if (!hasViggcharMagic(file)) {\n return await decodeLegacyBundle(file);\n }\n\n if (file.byteLength < CONTAINER_BYTES) {\n throw new CharacterBundleError(\n 'Truncated',\n `file is ${file.byteLength} B, shorter than the ${CONTAINER_BYTES} B container`,\n );\n }\n\n const view = new DataView(file);\n const version = view.getUint32(8, true);\n const handler = VERSION_HANDLERS.get(version);\n if (!handler) {\n // No fallback, no \"probably compatible\", no speculative parse, no partial\n // decode. The supported set is reported so the caller knows what to do.\n throw new CharacterBundleError(\n 'UnknownVersion',\n `file declares version ${version}; this reader implements ` +\n `${[...VERSION_HANDLERS.keys()].sort((a, b) => a - b).join(', ')}`,\n );\n }\n\n // Carried rather than taken from the transport: a truncated download or a\n // clipped upload otherwise arrives with an intact header and a short last\n // block, and surfaces as a broken character instead of an error. Trailing\n // bytes beyond it are ignored, so the container can be embedded in a larger\n // stream.\n const totalLength = view.getUint32(12, true);\n if (totalLength < CONTAINER_BYTES) {\n throw new CharacterBundleError(\n 'Truncated',\n `header declares totalLength ${totalLength} B, below the ${CONTAINER_BYTES} B container`,\n );\n }\n if (file.byteLength < totalLength) {\n throw new CharacterBundleError(\n 'Truncated',\n `header declares totalLength ${totalLength} B, but the file is ${file.byteLength} B`,\n );\n }\n\n return await handler(file, CONTAINER_BYTES, totalLength - CONTAINER_BYTES);\n}\n\nexport { parseCharacterBundle, CharacterBundleError };\nexport type { DecodeResult };\n", "import { packSplats } from '../../splat/packed-splats';\nimport type { SplatSource } from '../../splat/splat';\nimport type { ArmatureData } from '../../types';\nimport { cachedFetch } from '../shared/bin-cache';\n\nimport { parseCharacterBundle } from './index';\n\n/** A clip embedded in a legacy character bundle: per-frame, per-bone 4x4 matrices. */\nexport interface RawAnimationData {\n data: Float32Array;\n numFrames: number;\n numBones: number;\n keyframeFrames?: number[];\n}\n\n/** A decoded character bundle, ready to become a {@link Splat} and an {@link Armature}. */\nexport interface CharacterBundle {\n source: SplatSource;\n armatureData?: ArmatureData;\n animationData?: RawAnimationData;\n}\n\n// Raw bytes by URL (query string dropped, so a re-signed URL still hits). Lets\n// a second character from the same file skip the network; each load still\n// decodes its own copy because splats own and mutate their buffers.\nconst _bufferCache = new Map<string, ArrayBuffer>();\nconst _bufferLoading = new Map<string, Promise<ArrayBuffer>>();\n\nfunction cacheKeyFor(url: string): string {\n const q = url.indexOf('?');\n return q === -1 ? url : url.slice(0, q);\n}\n\nasync function fetchBundleBuffer(url: string): Promise<ArrayBuffer> {\n const key = cacheKeyFor(url);\n const cached = _bufferCache.get(key);\n if (cached) return cached;\n const inflight = _bufferLoading.get(key);\n if (inflight) return inflight;\n const promise = cachedFetch(url)\n .then(async (res) => {\n if (!res.ok) throw new Error(`[loadCharacterBundle] fetch failed (${res.status}): ${url}`);\n const buf = await res.arrayBuffer();\n _bufferCache.set(key, buf);\n return buf;\n })\n .finally(() => {\n _bufferLoading.delete(key);\n });\n _bufferLoading.set(key, promise);\n return promise;\n}\n\n/**\n * Decode a character bundle held in memory.\n *\n * Accepts every container the reader implements - `VIGGCHAR` (`.vsplat`) and\n * the legacy `.bin` layouts - and dispatches on the file's own magic, never on\n * a filename.\n *\n * Decoding runs on the calling thread. A bundle is a few megabytes and decodes\n * in single-digit milliseconds, which does not earn the packaging cost of a\n * separate worker file.\n *\n * @throws {CharacterBundleError} carrying the format spec's error category.\n */\nexport async function decodeCharacterBundle(file: ArrayBuffer): Promise<CharacterBundle> {\n const { result } = await parseCharacterBundle(file);\n\n let armatureData: ArmatureData | undefined;\n if (result.rigBoneCount > 0) {\n armatureData = { numBones: result.rigBoneCount };\n if (result.jointsArray) {\n armatureData.joints = result.jointsArray;\n armatureData.corrected = result.corrected;\n armatureData.restIsPerCharacter = result.bundledRestIsPerCharacter;\n }\n }\n\n let animationData: RawAnimationData | undefined;\n if (result.animationArray && result.animNumFrames > 0 && result.animNumBones > 0) {\n animationData = {\n data: result.animationArray,\n numFrames: result.animNumFrames,\n numBones: result.animNumBones,\n };\n }\n\n const header = result.header as { numBones?: number } | null | undefined;\n\n return {\n source: {\n packed: packSplats(result.numSplats, result.splats),\n splatWeights:\n result.boneIndices && result.boneWeights\n ? { indices: result.boneIndices, weights: result.boneWeights }\n : undefined,\n sourceBoneCount: header?.numBones ?? armatureData?.numBones,\n },\n armatureData,\n animationData,\n };\n}\n\n/** Fetch and decode a character bundle. */\nexport async function loadCharacterBundle(url: string): Promise<CharacterBundle> {\n return decodeCharacterBundle(await fetchBundleBuffer(url));\n}\n\n/** Decode a character bundle from bytes already in memory. */\nexport async function loadCharacterBundleFromBytes(bytes: Uint8Array): Promise<CharacterBundle> {\n // The decoders build aligned typed-array views straight onto the buffer, so\n // a view that starts mid-buffer has to be copied out first.\n const aligned =\n bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength\n ? (bytes.buffer as ArrayBuffer)\n : (bytes.slice().buffer as ArrayBuffer);\n return decodeCharacterBundle(aligned);\n}\n", "/**\n * Bone-mask utilities for layered animation. A {@link BoneMask} selects a\n * subset of an armature's bones by index; the {@link Armature} layer system\n * uses it to gate an overlay animation to (e.g.) just the upper body while a\n * base full-body clip drives the rest.\n *\n * Built-in regions ({@link UPPER_BODY_BONE_NAMES} / {@link LOWER_BODY_BONE_NAMES})\n * follow the canonical 86-bone rig naming. The split bone is the pelvis:\n * - UPPER covers everything from `spine_01` up (spine 01-05, neck, head,\n * clavicles, arms, hands, all fingers) so the overlay fully replaces\n * the torso without leak from the base's spine rotation.\n * - LOWER covers `pelvis` plus the leg chain (thighs, calves, calf\n * twists, feet, ball, all toes). Including pelvis means an overlay's\n * pelvis Y motion drives the rig and routes through `rootMotionMode`,\n * so the lower-body overlay owns root motion when active.\n *\n * @group Characters & Animation\n */\n\nexport const UPPER_BODY_BONE_NAMES = [\n 'spine_01', 'spine_02', 'spine_03', 'spine_04', 'spine_05',\n 'neck_01', 'neck_02',\n 'head',\n 'clavicle_l', 'clavicle_r',\n 'upperarm_l', 'upperarm_r',\n 'lowerarm_l', 'lowerarm_r',\n 'hand_l', 'hand_r',\n // Fingers - so the overlay fully owns hand pose.\n 'thumb_01_l', 'thumb_02_l', 'thumb_03_l',\n 'index_metacarpal_l', 'index_01_l', 'index_02_l', 'index_03_l',\n 'middle_metacarpal_l', 'middle_01_l', 'middle_02_l', 'middle_03_l',\n 'ring_metacarpal_l', 'ring_01_l', 'ring_02_l', 'ring_03_l',\n 'pinky_metacarpal_l', 'pinky_01_l', 'pinky_02_l', 'pinky_03_l',\n 'thumb_01_r', 'thumb_02_r', 'thumb_03_r',\n 'index_metacarpal_r', 'index_01_r', 'index_02_r', 'index_03_r',\n 'middle_metacarpal_r', 'middle_01_r', 'middle_02_r', 'middle_03_r',\n 'ring_metacarpal_r', 'ring_01_r', 'ring_02_r', 'ring_03_r',\n 'pinky_metacarpal_r', 'pinky_01_r', 'pinky_02_r', 'pinky_03_r',\n] as const;\n\nexport const LOWER_BODY_BONE_NAMES = [\n 'pelvis',\n 'thigh_l', 'thigh_r',\n 'calf_l', 'calf_r',\n 'calf_twist_01_l', 'calf_twist_01_r',\n 'foot_l', 'foot_r',\n 'ball_l', 'ball_r',\n 'bigtoe_01_l', 'bigtoe_02_l',\n 'indextoe_01_l', 'indextoe_02_l',\n 'middletoe_01_l', 'middletoe_02_l',\n 'ringtoe_01_l', 'ringtoe_02_l',\n 'littletoe_01_l', 'littletoe_02_l',\n 'bigtoe_01_r', 'bigtoe_02_r',\n 'indextoe_01_r', 'indextoe_02_r',\n 'middletoe_01_r', 'middletoe_02_r',\n 'ringtoe_01_r', 'ringtoe_02_r',\n 'littletoe_01_r', 'littletoe_02_r',\n] as const;\n\nexport interface BoneMask {\n name: string;\n boneIndices: Int32Array;\n}\n\nexport function resolveBoneIndices(\n allBoneNames: readonly string[],\n maskNames: readonly string[],\n): Int32Array {\n const out: number[] = [];\n for (const n of maskNames) {\n const i = allBoneNames.indexOf(n);\n if (i >= 0) out.push(i);\n }\n return Int32Array.from(out);\n}\n\nexport type BodyRegion = 'upperBody' | 'lowerBody';\n\nexport function makeRegionMask(\n region: BodyRegion,\n allBoneNames: readonly string[],\n): BoneMask {\n const names = region === 'upperBody' ? UPPER_BODY_BONE_NAMES : LOWER_BODY_BONE_NAMES;\n return { name: region, boneIndices: resolveBoneIndices(allBoneNames, names) };\n}\n", "import {\n Box3,\n ClampToEdgeWrapping,\n DataTexture,\n FloatType,\n HalfFloatType,\n NearestFilter,\n RedFormat,\n RGBAFormat,\n RGBAIntegerFormat,\n Sphere,\n UnsignedIntType,\n Vector2,\n Vector3,\n Vector4,\n} from 'three';\nimport type { Frustum, PixelFormat, TextureDataType } from 'three';\n\nimport type { SplatEngine } from '../engine';\nimport type { Mat4 } from '../math';\nimport type { SplatWeights } from '../types';\n\nimport type { PackedSplats } from './packed-splats';\nimport { SplatMesh } from './splat-mesh';\nimport { TransformPalette } from './transform-palette';\n\nconst WHITE_TINT = { r: 1, g: 1, b: 1 };\n\n/** Bones in the widest rig the skeleton library knows: the palette size for a bundle that does not say. */\nconst MAX_RIG_BONES = 1185;\n\nfunction dataTexture(\n name: string,\n data: ArrayBufferView,\n width: number,\n height: number,\n format: PixelFormat,\n type: TextureDataType,\n): DataTexture {\n const texture = new DataTexture(data as never, width, height, format, type);\n texture.name = name;\n texture.minFilter = NearestFilter;\n texture.magFilter = NearestFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\n/** What a {@link Splat} is built from: packed gaussians, plus skinning data for characters. */\nexport interface SplatSource {\n packed: PackedSplats;\n /** Present for skinned splats. Any `K` influences per splat; the top four are used. */\n splatWeights?: SplatWeights;\n /** Bone count of the rig the weights index into, when it differs from the armature's. */\n sourceBoneCount?: number;\n}\n\n/** @group Splats */\nexport interface SplatOptions {\n /**\n * Depth-sort in a worker instead of synchronously. Default: `true` for\n * unskinned splats, `false` for skinned ones (whose order must track the pose).\n */\n asyncSort?: boolean;\n}\n\n/**\n * Gaussian splat renderer.\n *\n * Owns the splat data textures, the bone index/weight textures used for\n * skeletal deformation, the transform palette written to by the linked\n * {@link Armature}, and the three.js mesh that draws it all. Skinning runs on\n * the GPU when the splat has weights; unskinned splats (environments) take the\n * same path with the identity transform.\n *\n * {@link Character.load} and {@link Environment.load} construct this\n * internally. Direct construction is only needed for custom loading pipelines.\n *\n * @group Splats\n */\nexport class Splat {\n readonly numSplats: number;\n /** The packed gaussian data backing the textures. */\n readonly packed: PackedSplats;\n /** The three.js object that draws this splat. Parent it; do not replace it. */\n readonly object3D: SplatMesh;\n\n readonly colorTexture: DataTexture;\n readonly transformATexture: DataTexture;\n readonly transformBTexture: DataTexture;\n\n /** Per-splat palette slot indices, four per splat. Rewritten when an armature binds. */\n boneIndicesData?: Float32Array;\n boneWeightsData?: Float32Array;\n boneIndicesTexture?: DataTexture;\n boneWeightsTexture?: DataTexture;\n\n groupIdsTexture?: DataTexture;\n variantMaskTexture?: DataTexture;\n variantMask?: Float32Array;\n groupIds?: Uint8Array;\n /** Bumped whenever the group ids or the variant mask change. */\n variantMaskVersion = 0;\n\n transformPalette: TransformPalette;\n /** rgb tint colour, w tint amount. Shared with the material by reference. */\n readonly tint = new Vector4(1, 1, 1, 0);\n /** x contrast, y saturation. Shared with the material by reference. */\n readonly grade = new Vector2(1, 1);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n linkedArmature: any = null;\n\n /** Skinning influences normalised to exactly four slots per splat. */\n splatWeights?: SplatWeights;\n sourceBoneCount?: number;\n\n /**\n * Splat centres in local space: the rest pose until the first skinning\n * update, the skinned pose after.\n *\n * Only kept current when the renderer sorts on the CPU (WebGL). Under WebGPU\n * this lags the pose; call {@link Splat.ensureCenters} before reading it.\n */\n centers: Float32Array;\n /** Bumped whenever {@link Splat.centers} changes. */\n centersVersion = 0;\n /**\n * Local-space bounds used for culling and visibility tests. With CPU\n * centres these track the pose exactly; without, they are the rest bounds\n * padded generously enough to contain any pose.\n */\n readonly localBounds = new Box3();\n\n /** Discard splats smaller than this many pixels on screen. `0` draws everything. */\n minPixelSize = 0;\n\n private readonly _mesh: SplatMesh;\n private _cpuInfluences: Float32Array | null = null;\n private _pendingBoneTransforms: Mat4[] | null = null;\n private _flatBones: Float32Array | null = null;\n private _variantMaskEnabled = false;\n private _nonRigidCov = false;\n private _antiAlias = false;\n private _destroyed = false;\n private readonly _worldBounds = new Box3();\n private readonly _worldSphere = new Sphere();\n private readonly _groundHist = new Int32Array(256);\n\n constructor(engine: SplatEngine, source: SplatSource, opts?: SplatOptions) {\n const { packed } = source;\n this.packed = packed;\n this.numSplats = packed.numSplats;\n this.sourceBoneCount = source.sourceBoneCount;\n\n const { width, height } = packed;\n this.colorTexture = dataTexture('splatColor', packed.color, width, height, RGBAFormat, HalfFloatType);\n this.transformATexture = dataTexture('transformA', packed.transformA, width, height, RGBAIntegerFormat, UnsignedIntType);\n this.transformATexture.internalFormat = 'RGBA32UI';\n this.transformBTexture = dataTexture('transformB', packed.transformB, width, height, RGBAFormat, HalfFloatType);\n\n this.localBounds.min.fromArray(packed.boundsMin);\n this.localBounds.max.fromArray(packed.boundsMax);\n\n if (source.splatWeights) {\n this.splatWeights = this._normalizeWeights(source.splatWeights);\n this.boneIndicesData = new Float32Array(width * height * 4);\n this.boneWeightsData = new Float32Array(width * height * 4);\n // Raw rig indices for now; an armature rewrites them as palette slots when it binds.\n this.boneIndicesData.set(this.splatWeights.indices);\n this.boneWeightsData.set(this.splatWeights.weights);\n this.boneIndicesTexture = dataTexture('boneIndices', this.boneIndicesData, width, height, RGBAFormat, FloatType);\n this.boneWeightsTexture = dataTexture('boneWeights', this.boneWeightsData, width, height, RGBAFormat, FloatType);\n this._bakeInfluences();\n // Skinning moves centres every frame, so they need their own buffer.\n this.centers = new Float32Array(packed.centers);\n } else {\n this.centers = packed.centers;\n }\n\n // Sized to the bundle's own rig (plus the identity slot) so the per-frame\n // upload is no larger than it has to be. Binding to a bigger armature\n // grows it, which the backends handle.\n this.transformPalette = new TransformPalette(\n this.splatWeights ? (this.sourceBoneCount ?? MAX_RIG_BONES) + 1 : 1,\n );\n\n if (this.splatWeights) {\n // Until CPU-skinned centres exist (and under WebGPU they never do),\n // nothing tracks the pose, so pad the rest bounds by the character's own\n // half-size: room for a raised arm, a kick, or a jump.\n const size = this.localBounds.getSize(_size);\n this.localBounds.expandByScalar(0.5 * Math.max(size.x, size.y, size.z));\n }\n\n const asyncSort = opts?.asyncSort ?? !this.splatWeights;\n this._mesh = new SplatMesh(this, engine, asyncSort);\n this.object3D = this._mesh;\n\n Splat._liveInstances.add(this);\n }\n\n /**\n * A new, independent splat over the same packed data, carrying this one's\n * render options. For unskinned splats only.\n * @internal\n */\n cloneStatic(engine: SplatEngine, asyncSort: boolean): Splat {\n const copy = new Splat(engine, { packed: this.packed }, { asyncSort });\n copy.tint.copy(this.tint);\n copy.grade.copy(this.grade);\n copy.minPixelSize = this.minPixelSize;\n copy.antiAlias = this.antiAlias;\n return copy;\n }\n\n /** Top-4 influences per splat, zero-padded. The shader and the CPU path both assume four. */\n private _normalizeWeights(src: SplatWeights): SplatWeights {\n const n = this.numSplats;\n const k = n > 0 ? Math.max(1, Math.floor(src.indices.length / n)) : 4;\n if (k === 4) return { indices: src.indices, weights: src.weights };\n const indices = new Uint16Array(n * 4);\n const weights = new Float32Array(n * 4);\n const take = Math.min(k, 4);\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < take; j++) {\n indices[i * 4 + j] = src.indices[i * k + j];\n weights[i * 4 + j] = src.weights[i * k + j];\n }\n }\n return { indices, weights };\n }\n\n /** Re-upload the bone index/weight textures after editing their data arrays. */\n markBoneTexturesDirty(): void {\n this._mesh.syncBoneData();\n }\n\n get variantMaskEnabled(): boolean {\n return this._variantMaskEnabled;\n }\n\n get nonRigidCovariance(): boolean {\n return this._nonRigidCov;\n }\n\n /**\n * Toggle the non-rigid covariance shader path. When on, the palette's\n * per-axis scale stretches each gaussian's covariance; the palette must then\n * actually carry that scale (see `SplatSkinning.covStretch`). Off is the\n * rigid path, where palette scale is treated as unit. Switching recompiles\n * the shader, so toggle it rarely.\n */\n setNonRigidCovariance(on: boolean): void {\n if (this._nonRigidCov === on) return;\n this._nonRigidCov = on;\n this._mesh.syncDefines();\n }\n\n /**\n * Compensate each splat's opacity for the screen-space dilation applied to\n * keep sub-pixel splats visible. Off by default; turn on for assets trained\n * with anti-aliasing (e.g. Mip-Splatting).\n */\n get antiAlias(): boolean {\n return this._antiAlias;\n }\n\n set antiAlias(on: boolean) {\n if (this._antiAlias === on) return;\n this._antiAlias = on;\n this._mesh.syncDefines();\n }\n\n /**\n * Blend every splat's colour toward `color` by `intensity` (0..1).\n * `intensity = 0` restores the authored colour.\n */\n setTint(intensity: number, color: { r: number; g: number; b: number } = WHITE_TINT): void {\n this.tint.set(color.r, color.g, color.b, intensity);\n }\n\n /** Per-splat colour grade. `(1, 1)` is a true no-op. */\n setGrade(contrast: number, saturation: number): void {\n this.grade.set(contrast, saturation);\n }\n\n /**\n * Assign each splat to a group and enable per-group visibility. All groups\n * start visible; toggle them with {@link Splat.setVariantMask}.\n */\n setSplatGroups(groupIds: Uint8Array, numGroups: number): void {\n if (groupIds.length !== this.numSplats) {\n throw new Error(\n `Splat.setSplatGroups: groupIds length ${groupIds.length} != numSplats ${this.numSplats}`,\n );\n }\n if (numGroups < 1) throw new Error('Splat.setSplatGroups: numGroups must be \u22651');\n this.groupIds = groupIds;\n\n const { width, height } = this.packed;\n if (!this.groupIdsTexture) {\n this.groupIdsTexture = dataTexture('splatGroupIds', new Float32Array(width * height), width, height, RedFormat, FloatType);\n }\n const gidData = this.groupIdsTexture.image.data as Float32Array;\n for (let i = 0; i < this.numSplats; i++) gidData[i] = groupIds[i];\n this.groupIdsTexture.needsUpdate = true;\n\n if (!this.variantMaskTexture || this.variantMaskTexture.image.width !== numGroups) {\n this.variantMaskTexture?.dispose();\n this.variantMask = new Float32Array(numGroups);\n this.variantMaskTexture = dataTexture('splatVariantMask', this.variantMask, numGroups, 1, RedFormat, FloatType);\n }\n this.variantMask!.fill(1);\n this.variantMaskTexture.needsUpdate = true;\n this.variantMaskVersion++;\n\n if (!this._variantMaskEnabled) {\n this._variantMaskEnabled = true;\n this._mesh.syncDefines();\n } else {\n this._mesh.syncVariantGroups();\n }\n }\n\n /** Per-group visibility, one entry per group: `>= 0.5` shows the group. */\n setVariantMask(mask: ArrayLike<number>): void {\n if (!this.variantMaskTexture || !this.variantMask) return;\n const n = Math.min(this.variantMask.length, mask.length);\n for (let i = 0; i < n; i++) this.variantMask[i] = mask[i];\n this.variantMaskTexture.needsUpdate = true;\n this.variantMaskVersion++;\n }\n\n /** Whether the splat's world-space bounding sphere touches `frustum`. */\n isInFrustum(frustum: Frustum): boolean {\n this.object3D.updateWorldMatrix(true, false);\n this._worldBounds.copy(this.localBounds).applyMatrix4(this.object3D.matrixWorld);\n this._worldBounds.getBoundingSphere(this._worldSphere);\n return frustum.intersectsSphere(this._worldSphere);\n }\n\n /** World-space bounds of the splat in its current pose. */\n getWorldAabb(out: Box3 = new Box3()): Box3 {\n this.object3D.updateWorldMatrix(true, false);\n return out.copy(this.localBounds).applyMatrix4(this.object3D.matrixWorld);\n }\n\n /** World-space Y of the lowest corner of the current bounds. */\n getWorldMinY(): number {\n return this.getWorldAabb(this._worldBounds).min.y;\n }\n\n /**\n * World-space Y of the splat's ground contact: the height below which only\n * `quantile` of the splats lie. More robust than the bounds minimum, which a\n * single stray gaussian can drag down.\n */\n getGroundWorldY(quantile = 0.005): number {\n const n = this.numSplats;\n if (n === 0 || !this.splatWeights) return this.getWorldMinY();\n this.ensureCenters();\n const centers = this.centers;\n\n let lo = Infinity, hi = -Infinity;\n for (let i = 0; i < n; i++) {\n const y = centers[i * 3 + 1];\n if (y < lo) lo = y;\n if (y > hi) hi = y;\n }\n this.object3D.updateWorldMatrix(true, false);\n const worldOffsetY = this.object3D.matrixWorld.elements[13];\n if (!(hi > lo)) return lo + worldOffsetY;\n\n const BUCKETS = 256;\n const counts = this._groundHist;\n counts.fill(0);\n const scale = BUCKETS / (hi - lo);\n for (let i = 0; i < n; i++) {\n const y = centers[i * 3 + 1];\n let b = ((y - lo) * scale) | 0;\n if (b >= BUCKETS) b = BUCKETS - 1;\n if (b < 0) b = 0;\n counts[b]++;\n }\n const threshold = Math.max(1, Math.floor(n * quantile));\n let cum = 0;\n let boundary = lo;\n for (let b = 0; b < BUCKETS; b++) {\n cum += counts[b];\n if (cum >= threshold) { boundary = lo + (b + 1) / scale; break; }\n }\n return boundary + worldOffsetY;\n }\n\n /**\n * Flatten rest centres and influences into one interleaved buffer for the\n * per-frame CPU skinning pass: `[x, y, z, w0, b0, w1, b1, w2, b2, w3, b3]`.\n */\n private _bakeInfluences(): void {\n if (!this.splatWeights) return;\n const rest = this.packed.centers;\n const { indices, weights } = this.splatWeights;\n const STRIDE = 11;\n const buf = new Float32Array(this.numSplats * STRIDE);\n for (let i = 0, base = 0; i < this.numSplats; i++, base += STRIDE) {\n buf[base] = rest[i * 3];\n buf[base + 1] = rest[i * 3 + 1];\n buf[base + 2] = rest[i * 3 + 2];\n const src = i * 4;\n for (let j = 0; j < 4; j++) {\n buf[base + 3 + j * 2] = weights[src + j];\n buf[base + 4 + j * 2] = indices[src + j];\n }\n }\n this._cpuInfluences = buf;\n }\n\n /**\n * Tell the splat its bone matrices changed. When the renderer sorts on the\n * CPU the centres are re-skinned immediately; otherwise the work is deferred\n * until something asks for them ({@link Splat.ensureCenters}).\n */\n updatePositions(boneTransforms: Mat4[]): void {\n if (!this.splatWeights || !boneTransforms.length) return;\n this._pendingBoneTransforms = boneTransforms;\n if (this._mesh.needsCpuCenters) this.ensureCenters();\n }\n\n /** Bring {@link Splat.centers} up to date with the latest bone matrices. */\n ensureCenters(): void {\n const boneTransforms = this._pendingBoneTransforms;\n if (!boneTransforms) return;\n this._pendingBoneTransforms = null;\n this._skinCenters(boneTransforms);\n }\n\n /**\n * Skin the splat centres on the CPU with the same matrices the GPU uses.\n * This is the dominant per-character CPU cost, which is why it only runs\n * when something needs the result.\n */\n private _skinCenters(boneTransforms: Mat4[]): void {\n const packed = this._cpuInfluences;\n if (!packed) return;\n\n // Copy the affine 3x4 of every bone into one flat array first. The inner\n // loop then reads plain typed-array slots instead of chasing a Mat4 object\n // per influence, which is worth a large constant factor over ~50k splats.\n const numBones = boneTransforms.length;\n let bones = this._flatBones;\n if (!bones || bones.length !== numBones * 12) {\n bones = this._flatBones = new Float32Array(numBones * 12);\n }\n for (let b = 0, o = 0; b < numBones; b++, o += 12) {\n const m = boneTransforms[b].data;\n bones[o] = m[0]; bones[o + 1] = m[4]; bones[o + 2] = m[8]; bones[o + 3] = m[12];\n bones[o + 4] = m[1]; bones[o + 5] = m[5]; bones[o + 6] = m[9]; bones[o + 7] = m[13];\n bones[o + 8] = m[2]; bones[o + 9] = m[6]; bones[o + 10] = m[10]; bones[o + 11] = m[14];\n }\n\n const centers = this.centers;\n const count = this.numSplats;\n let minX = Infinity, minY = Infinity, minZ = Infinity;\n let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;\n\n for (let i = 0, base = 0, ci = 0; i < count; i++, base += 11, ci += 3) {\n const rx = packed[base];\n const ry = packed[base + 1];\n const rz = packed[base + 2];\n\n let outX = 0, outY = 0, outZ = 0, totalWeight = 0;\n for (let k = 0; k < 4; k++) {\n const w = packed[base + 3 + k * 2];\n if (w < 0.001) continue;\n const b = packed[base + 4 + k * 2] | 0;\n if (b >= numBones) continue;\n const o = b * 12;\n outX += (rx * bones[o] + ry * bones[o + 1] + rz * bones[o + 2] + bones[o + 3]) * w;\n outY += (rx * bones[o + 4] + ry * bones[o + 5] + rz * bones[o + 6] + bones[o + 7]) * w;\n outZ += (rx * bones[o + 8] + ry * bones[o + 9] + rz * bones[o + 10] + bones[o + 11]) * w;\n totalWeight += w;\n }\n\n let cx: number, cy: number, cz: number;\n if (totalWeight > 0.001) {\n const inv = 1 / totalWeight;\n cx = outX * inv;\n cy = outY * inv;\n cz = outZ * inv;\n } else {\n cx = rx;\n cy = ry;\n cz = rz;\n }\n\n centers[ci] = cx;\n centers[ci + 1] = cy;\n centers[ci + 2] = cz;\n\n if (cx < minX) minX = cx;\n if (cx > maxX) maxX = cx;\n if (cy < minY) minY = cy;\n if (cy > maxY) maxY = cy;\n if (cz < minZ) minZ = cz;\n if (cz > maxZ) maxZ = cz;\n }\n\n this.centersVersion++;\n // Exact bounds are only authoritative when centres are kept current;\n // otherwise the padded rest bounds stay in force.\n if (this._mesh.needsCpuCenters) {\n this.localBounds.min.set(minX, minY, minZ);\n this.localBounds.max.set(maxX, maxY, maxZ);\n this._mesh.syncBounds();\n }\n }\n\n /** Force a re-sort on the next render. */\n requestSort(): void {\n this._mesh.requestSort();\n }\n\n /** True while an asynchronous sort is outstanding, i.e. the drawn order is stale or absent. */\n get sortPending(): boolean {\n return this._mesh.sortPending;\n }\n\n /** Show or hide the splat without disturbing its bindings. */\n setRenderingEnabled(enabled: boolean): void {\n this.object3D.visible = enabled;\n }\n\n get renderingEnabled(): boolean {\n return this.object3D.visible;\n }\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n /** Remove from the scene graph and release every GPU resource. */\n destroy(): void {\n if (this._destroyed) return;\n this._destroyed = true;\n Splat._liveInstances.delete(this);\n this.object3D.removeFromParent();\n this._mesh.dispose();\n this.colorTexture.dispose();\n this.transformATexture.dispose();\n this.transformBTexture.dispose();\n this.boneIndicesTexture?.dispose();\n this.boneWeightsTexture?.dispose();\n this.groupIdsTexture?.dispose();\n this.variantMaskTexture?.dispose();\n this.transformPalette.dispose();\n }\n\n /** @internal */\n static _liveInstances = new Set<Splat>();\n}\n\nconst _size = new Vector3();\n", "import { BufferAttribute, BufferGeometry, Mesh, MeshBasicMaterial } from 'three';\nimport type { Camera } from 'three';\n\nimport type { SplatEngine } from '../engine';\n\nimport type { SplatBackend, SplatRenderImpl } from './backend';\nimport type { Splat } from './splat';\nimport { WebGLSplatBackend } from './webgl/backend';\n\n// What a splat mesh holds until a renderer has drawn it once: one degenerate\n// triangle that writes nothing. Any three.js renderer accepts it, and drawing\n// it is what gets `onBeforeRender` called so the real implementation can attach.\nconst PLACEHOLDER_GEOMETRY = new BufferGeometry();\nPLACEHOLDER_GEOMETRY.setAttribute('position', new BufferAttribute(new Float32Array(9), 3));\nconst PLACEHOLDER_MATERIAL = new MeshBasicMaterial({ colorWrite: false, depthWrite: false, depthTest: false });\n\nconst webglBackend = new WebGLSplatBackend();\nlet webgpuBackend: SplatBackend | null = null;\nconst warned = new Set<string>();\n\nfunction warnOnce(message: string): void {\n if (warned.has(message)) return;\n warned.add(message);\n console.error(`[splat-engine-three] ${message}`);\n}\n\n/**\n * Make the WebGPU backend available to every {@link SplatMesh}. Called by the\n * `@viggle/splat-engine-three/webgpu` entry point when it is imported; the\n * default entry point leaves it out so WebGL applications never load\n * `three/webgpu`.\n *\n * @internal\n */\nexport function registerWebGPUBackend(backend: SplatBackend): void {\n webgpuBackend = backend;\n}\n\n/** The backend that can draw with `renderer`, or `null` (after saying why) when none can. */\nfunction backendFor(renderer: unknown): SplatBackend | null {\n const r = renderer as { isWebGPURenderer?: boolean; backend?: { isWebGPUBackend?: boolean } };\n if (r.isWebGPURenderer !== true) return webglBackend;\n if (r.backend?.isWebGPUBackend !== true) {\n warnOnce(\n 'WebGPURenderer is running on its WebGL2 fallback, which has no compute shaders, so splats cannot be drawn. ' +\n 'Use THREE.WebGLRenderer on devices without WebGPU.',\n );\n return null;\n }\n if (!webgpuBackend) {\n warnOnce(\n \"Splats are being drawn by a WebGPURenderer, but the WebGPU backend is not loaded. \" +\n \"Import from '@viggle/splat-engine-three/webgpu' instead of '@viggle/splat-engine-three'.\",\n );\n return null;\n }\n return webgpuBackend;\n}\n\n/**\n * The object that draws one {@link Splat}: an ordinary `THREE.Mesh` in your\n * scene graph, so `visible`, `renderOrder`, `layers` and parent transforms all\n * work as they do for any mesh.\n *\n * It works with both `THREE.WebGLRenderer` and `WebGPURenderer`. Which one is\n * not known until something renders it, so the renderer-specific geometry and\n * material are attached the first time it is drawn; the mesh shows from the\n * following frame.\n *\n * @group Splats\n */\nexport class SplatMesh extends Mesh {\n /** Type flag, in the three.js manner. */\n readonly isSplatMesh = true;\n\n /** The splat this mesh draws: its data, tint, grade and render options. */\n readonly splat: Splat;\n\n private readonly _engine: SplatEngine;\n private readonly _asyncSort: boolean;\n private _impl: SplatRenderImpl | null = null;\n\n /**\n * @param asyncSort - See {@link SplatBackend.createImpl}.\n * @internal Construct a {@link Splat} instead; it creates its own mesh.\n */\n constructor(splat: Splat, engine: SplatEngine, asyncSort: boolean) {\n super(PLACEHOLDER_GEOMETRY, PLACEHOLDER_MATERIAL);\n this.name = 'splat';\n this.splat = splat;\n this._engine = engine;\n this._asyncSort = asyncSort;\n // The placeholder has no extent to cull against, and must be drawn for the\n // real implementation to attach.\n this.frustumCulled = false;\n if (engine.backend) this._attach(engine.backend);\n }\n\n private _attach(backend: SplatBackend): void {\n const impl = backend.createImpl(this, this.splat, this._engine, this._asyncSort);\n this._impl = impl;\n this.geometry = impl.geometry;\n this.material = impl.material;\n this.frustumCulled = true;\n }\n\n /** See {@link SplatRenderImpl.needsCpuCenters}. False until a renderer has drawn this mesh. */\n get needsCpuCenters(): boolean {\n return this._impl?.needsCpuCenters ?? false;\n }\n\n /** True while the drawn order is stale or absent, including before the first draw. */\n get sortPending(): boolean {\n return this._impl ? this._impl.sortPending : true;\n }\n\n requestSort(): void {\n this._impl?.requestSort();\n }\n\n syncDefines(): void {\n this._impl?.syncDefines();\n }\n\n syncBounds(): void {\n this._impl?.syncBounds();\n }\n\n syncBoneData(): void {\n this._impl?.syncBoneData();\n }\n\n syncVariantGroups(): void {\n this._impl?.syncVariantGroups();\n }\n\n override onBeforeRender(renderer: unknown, _scene: unknown, camera: Camera): void {\n if (!this._impl) {\n const backend = backendFor(renderer);\n // This draw still uses the placeholder; the real mesh shows next frame.\n if (backend) this._attach(backend);\n return;\n }\n this._impl.beforeRender(renderer, camera);\n }\n\n /**\n * A second mesh drawing the same splat data, at the same transform. The\n * decoded data is shared; the GPU copy of it is not.\n *\n * Only for static splats. A mesh that belongs to a character is driven by\n * that character's rig and cannot stand alone - clone the `SplatCharacter`.\n */\n override clone(): this {\n const source = this.splat;\n if (source.splatWeights) {\n throw new Error('SplatMesh.clone: this mesh is part of a character; clone the SplatCharacter instead');\n }\n const copy = source.cloneStatic(this._engine, this._asyncSort).object3D;\n copy.name = this.name;\n copy.position.copy(this.position);\n copy.quaternion.copy(this.quaternion);\n copy.scale.copy(this.scale);\n copy.visible = this.visible;\n copy.renderOrder = this.renderOrder;\n copy.layers.mask = this.layers.mask;\n copy.userData = { ...this.userData };\n return copy as this;\n }\n\n /**\n * Splats are not pickable. The inherited implementation would test the ray\n * against this mesh's own geometry, which is a single proxy quad at the\n * local origin - every instance is positioned in the shader - and report\n * hits that have nothing to do with where the splats are drawn.\n */\n override raycast(): void {}\n\n /**\n * Release every GPU resource behind this mesh - the splat's data textures as\n * well as the renderer-specific buffers - and remove it from its parent.\n */\n override dispose(): void {\n // The splat owns the teardown order; it calls back here once it has begun.\n if (!this.splat.destroyed) {\n this.splat.destroy();\n return;\n }\n this._impl?.dispose();\n this._impl = null;\n this.geometry = PLACEHOLDER_GEOMETRY;\n this.material = PLACEHOLDER_MATERIAL;\n super.dispose();\n }\n}\n", "import {\n BufferAttribute,\n ColorManagement,\n CustomBlending,\n DoubleSide,\n DynamicDrawUsage,\n GLSL3,\n InstancedBufferAttribute,\n InstancedBufferGeometry,\n LinearTransfer,\n OneFactor,\n OneMinusSrcAlphaFactor,\n Quaternion,\n RawShaderMaterial,\n Sphere,\n Vector2,\n Vector3,\n Vector4,\n} from 'three';\nimport type { Camera, Mesh, WebGLRenderer } from 'three';\n\nimport type { SplatEngine } from '../../engine';\nimport type { SplatRenderImpl } from '../backend';\nimport { AsyncDepthSorter, DepthSorter, projectBoundsOnDirection } from '../depth-sort';\nimport type { Splat } from '../splat';\n\nimport { SPLAT_FRAGMENT_GLSL, SPLAT_VERTEX_GLSL } from './shaders';\n\nconst _position = new Vector3();\nconst _quaternion = new Quaternion();\nconst _scale = new Vector3();\nconst _viewport = new Vector4();\n\n/**\n * How one {@link Splat} is drawn under `WebGLRenderer`: one instanced quad per\n * gaussian, drawn back-to-front with premultiplied alpha.\n *\n * The instance attribute holds splat indices in draw order, so sorting only\n * ever rewrites that one buffer; all splat data stays put in textures.\n *\n * @internal\n */\nexport class WebGLSplatImpl implements SplatRenderImpl {\n readonly geometry: InstancedBufferGeometry;\n readonly material: RawShaderMaterial;\n /** The depth sort runs on the CPU, so it needs CPU-side centres. */\n readonly needsCpuCenters = true;\n\n private readonly _host: Mesh;\n private readonly _splat: Splat;\n private readonly _engine: SplatEngine;\n private readonly _order: InstancedBufferAttribute;\n private readonly _syncSorter: DepthSorter | null;\n private readonly _asyncSorter: AsyncDepthSorter | null;\n\n private _sortedVersion = -1;\n private _sortRequested = true;\n private _lastDx = NaN;\n private _lastDy = NaN;\n private _lastDz = NaN;\n\n /**\n * @param asyncSort - Sort in a worker and keep drawing the previous order\n * meanwhile. Right for large static splats; wrong for skinned ones, whose\n * order would lag the pose.\n */\n constructor(host: Mesh, splat: Splat, engine: SplatEngine, asyncSort: boolean) {\n const geometry = new InstancedBufferGeometry();\n geometry.setAttribute(\n 'position',\n new BufferAttribute(new Float32Array([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0]), 3),\n );\n geometry.setIndex([0, 1, 2, 0, 2, 3]);\n\n const order = new InstancedBufferAttribute(new Uint32Array(splat.numSplats), 1);\n order.setUsage(DynamicDrawUsage);\n geometry.setAttribute('splatOrder', order);\n geometry.boundingSphere = new Sphere();\n\n const lighting = engine.lightingUniforms;\n const material = new RawShaderMaterial({\n name: 'SplatMaterial',\n glslVersion: GLSL3,\n vertexShader: SPLAT_VERTEX_GLSL,\n fragmentShader: SPLAT_FRAGMENT_GLSL,\n uniforms: {\n tTransformA: { value: splat.transformATexture },\n tTransformB: { value: splat.transformBTexture },\n tColor: { value: splat.colorTexture },\n uTexWidth: { value: splat.packed.width },\n uViewport: { value: new Vector2(1, 1) },\n uMinPixelSize: { value: 0 },\n uModelRotation: { value: new Vector4(0, 0, 0, 1) },\n uModelScale: { value: new Vector3(1, 1, 1) },\n uTint: { value: splat.tint },\n uGrade: { value: splat.grade },\n uOutputLinear: { value: 0 },\n transformPalette: { value: splat.transformPalette.texture },\n boneIndices: { value: splat.boneIndicesTexture ?? null },\n boneWeights: { value: splat.boneWeightsTexture ?? null },\n splatGroupIds: { value: null },\n splatVariantMask: { value: null },\n // Shared objects: one write in the engine reaches every splat material.\n uSunColor: lighting.uSunColor,\n uSunIntensity: lighting.uSunIntensity,\n uAmbientColor: lighting.uAmbientColor,\n uPointLightCount: lighting.uPointLightCount,\n uPointLightTex: lighting.uPointLightTex,\n },\n // The ellipse axes can mirror the quad, so its winding is not fixed.\n side: DoubleSide,\n transparent: true,\n depthTest: true,\n depthWrite: false,\n premultipliedAlpha: true,\n blending: CustomBlending,\n blendSrc: OneFactor,\n blendDst: OneMinusSrcAlphaFactor,\n blendSrcAlpha: OneFactor,\n blendDstAlpha: OneMinusSrcAlphaFactor,\n });\n\n this.geometry = geometry;\n this.material = material;\n this._host = host;\n this._splat = splat;\n this._engine = engine;\n this._order = order;\n\n if (asyncSort) {\n this._syncSorter = null;\n // Nothing is drawn until the first order arrives.\n geometry.instanceCount = 0;\n this._asyncSorter = new AsyncDepthSorter(splat.centers, splat.numSplats, (sorted) => {\n (order.array as Uint32Array).set(sorted);\n order.needsUpdate = true;\n geometry.instanceCount = splat.numSplats;\n });\n } else {\n this._asyncSorter = null;\n this._syncSorter = new DepthSorter();\n geometry.instanceCount = splat.numSplats;\n }\n\n this.syncDefines();\n this.syncBounds();\n }\n\n /** True while a worker sort is in flight (always false for synchronous sorting). */\n get sortPending(): boolean {\n return this._asyncSorter ? this._asyncSorter.busy || this.geometry.instanceCount === 0 : false;\n }\n\n /** Force a re-sort on the next render even if the view direction is unchanged. */\n requestSort(): void {\n this._sortRequested = true;\n }\n\n /** Rebuild the shader variant after a feature toggle on the splat. */\n syncDefines(): void {\n const splat = this._splat;\n const defines: Record<string, string> = {};\n if (splat.splatWeights) defines.USE_BONE_BLENDING = '';\n if (splat.variantMaskEnabled) defines.USE_VARIANT_MASK = '';\n if (splat.nonRigidCovariance) defines.USE_NONRIGID_COV = '';\n if (splat.antiAlias) defines.USE_ANTIALIAS = '';\n this.material.defines = defines;\n this.material.needsUpdate = true;\n }\n\n /** The bone textures are the splat's own; flagging them is all there is to do. */\n syncBoneData(): void {\n const splat = this._splat;\n if (splat.boneIndicesTexture) splat.boneIndicesTexture.needsUpdate = true;\n if (splat.boneWeightsTexture) splat.boneWeightsTexture.needsUpdate = true;\n }\n\n /** Group ids live in the splat's own texture, which it flags itself. */\n syncVariantGroups(): void {}\n\n /** Refresh the culling sphere from the splat's current local bounds. */\n syncBounds(): void {\n const box = this._splat.localBounds;\n box.getBoundingSphere(this.geometry.boundingSphere!);\n }\n\n beforeRender(renderer: unknown, camera: Camera): void {\n const gl = renderer as WebGLRenderer;\n const splat = this._splat;\n const u = this.material.uniforms;\n\n gl.getCurrentViewport(_viewport);\n u.uViewport.value.set(_viewport.z, _viewport.w);\n\n // Splat colours are display-referred. Decode them only when the target\n // wants linear values (a post-processing chain); drawing straight to an\n // sRGB canvas passes them through untouched.\n const target = gl.getRenderTarget();\n const outputColorSpace = target ? target.texture.colorSpace : gl.outputColorSpace;\n u.uOutputLinear.value = ColorManagement.getTransfer(outputColorSpace) === LinearTransfer ? 1 : 0;\n\n this._host.matrixWorld.decompose(_position, _quaternion, _scale);\n u.uModelRotation.value.set(_quaternion.x, _quaternion.y, _quaternion.z, _quaternion.w);\n u.uModelScale.value.copy(_scale);\n\n u.uMinPixelSize.value = splat.minPixelSize;\n u.transformPalette.value = splat.transformPalette.texture;\n u.splatGroupIds.value = splat.groupIdsTexture ?? null;\n u.splatVariantMask.value = splat.variantMaskTexture ?? null;\n this._engine.syncLighting();\n\n this._sortFor(camera);\n }\n\n private _sortFor(camera: Camera): void {\n const splat = this._splat;\n const count = splat.numSplats;\n if (count === 0) return;\n // Centres may be waiting on a pose pushed before this implementation existed.\n splat.ensureCenters();\n\n // Camera forward (-Z of its world matrix) carried into splat-local space.\n // Depth along it is dot(M^T f, p) + const, so M^T f orders local centres\n // exactly as view depth orders world ones - for any affine M.\n const ce = camera.matrixWorld.elements;\n const fx = -ce[8], fy = -ce[9], fz = -ce[10];\n const me = this._host.matrixWorld.elements;\n const dx = me[0] * fx + me[1] * fy + me[2] * fz;\n const dy = me[4] * fx + me[5] * fy + me[6] * fz;\n const dz = me[8] * fx + me[9] * fy + me[10] * fz;\n\n const dirChanged = dx !== this._lastDx || dy !== this._lastDy || dz !== this._lastDz;\n const dataChanged = splat.centersVersion !== this._sortedVersion;\n if (!dirChanged && !dataChanged && !this._sortRequested) return;\n\n this._lastDx = dx;\n this._lastDy = dy;\n this._lastDz = dz;\n this._sortedVersion = splat.centersVersion;\n this._sortRequested = false;\n\n const box = splat.localBounds;\n const { depthMin, depthMax } = projectBoundsOnDirection(\n [box.min.x, box.min.y, box.min.z],\n [box.max.x, box.max.y, box.max.z],\n dx, dy, dz,\n );\n\n if (this._asyncSorter) {\n this._asyncSorter.request({ dx, dy, dz, depthMin, depthMax });\n } else {\n this._syncSorter!.sort(splat.centers, count, dx, dy, dz, depthMin, depthMax, this._order.array as Uint32Array);\n this._order.needsUpdate = true;\n }\n }\n\n dispose(): void {\n this._asyncSorter?.dispose();\n this.geometry.dispose();\n this.material.dispose();\n }\n}\n", "/**\n * Back-to-front depth ordering for splats: a counting sort over quantised\n * distance along the view direction.\n *\n * The same routine runs in two places. Skinned characters are small and move\n * every frame, so they sort synchronously on the main thread and never show a\n * stale order. Environments are large and only need a new order when the camera\n * moves, so they sort in a worker ({@link AsyncDepthSorter}) and keep drawing\n * the previous order until the new one lands.\n */\n\ninterface SortScratch {\n keys: Uint32Array | null;\n counts: Uint32Array | null;\n}\n\n/**\n * Write into `order` the indices `[0, count)` sorted far-to-near along\n * `(dx, dy, dz)`, which must be the view direction expressed in the same space\n * as `centers`.\n *\n * `depthMin` / `depthMax` bound `dot(center, dir)` over the splats; a\n * conservative bound (from an AABB) is fine and avoids a pass over the data.\n *\n * Written to be self-contained - no closures over module state - because its\n * source text is also what the worker runs.\n */\nfunction countingSortByDepth(\n centers: Float32Array,\n count: number,\n dx: number,\n dy: number,\n dz: number,\n depthMin: number,\n depthMax: number,\n order: Uint32Array,\n scratch: SortScratch,\n): void {\n if (count === 0) return;\n\n // Bucket resolution tracks the splat count: ~4 splats per bucket, clamped to\n // [2^10, 2^20]. More buckets than that costs cache misses for no visible gain.\n const bits = Math.max(10, Math.min(20, Math.round(Math.log2(count / 4))));\n const bucketCount = 1 << bits;\n\n if (!scratch.keys || scratch.keys.length < count) scratch.keys = new Uint32Array(count);\n if (!scratch.counts || scratch.counts.length !== bucketCount) scratch.counts = new Uint32Array(bucketCount);\n const keys = scratch.keys;\n const counts = scratch.counts;\n counts.fill(0);\n\n const range = depthMax - depthMin;\n const scale = range > 1e-12 ? (bucketCount - 1) / range : 0;\n const last = bucketCount - 1;\n\n // Key 0 is the farthest splat, so ascending key order is back-to-front.\n for (let i = 0, c = 0; i < count; i++, c += 3) {\n const depth = centers[c] * dx + centers[c + 1] * dy + centers[c + 2] * dz;\n let key = ((depthMax - depth) * scale) | 0;\n if (key < 0) key = 0;\n else if (key > last) key = last;\n keys[i] = key;\n counts[key]++;\n }\n\n for (let i = 1; i < bucketCount; i++) counts[i] += counts[i - 1];\n\n for (let i = count - 1; i >= 0; i--) {\n order[--counts[keys[i]]] = i;\n }\n}\n\n/**\n * Range of `dot(p, dir)` over an axis-aligned box - the projection of the box\n * onto the view direction.\n */\nexport function projectBoundsOnDirection(\n min: ArrayLike<number>,\n max: ArrayLike<number>,\n dx: number,\n dy: number,\n dz: number,\n): { depthMin: number; depthMax: number } {\n const depthMin =\n (dx >= 0 ? min[0] : max[0]) * dx + (dy >= 0 ? min[1] : max[1]) * dy + (dz >= 0 ? min[2] : max[2]) * dz;\n const depthMax =\n (dx >= 0 ? max[0] : min[0]) * dx + (dy >= 0 ? max[1] : min[1]) * dy + (dz >= 0 ? max[2] : min[2]) * dz;\n return { depthMin, depthMax };\n}\n\n/** Synchronous sorter with its own scratch buffers. One per splat. */\nexport class DepthSorter {\n private readonly _scratch: SortScratch = { keys: null, counts: null };\n\n sort(\n centers: Float32Array,\n count: number,\n dx: number,\n dy: number,\n dz: number,\n depthMin: number,\n depthMax: number,\n order: Uint32Array,\n ): void {\n countingSortByDepth(centers, count, dx, dy, dz, depthMin, depthMax, order, this._scratch);\n }\n}\n\nexport interface SortRequest {\n dx: number;\n dy: number;\n dz: number;\n depthMin: number;\n depthMax: number;\n}\n\n/**\n * Worker-backed sorter for static splats.\n *\n * At most one sort is in flight. A request made while the worker is busy\n * replaces any earlier pending one, so a fast-moving camera never queues work\n * it no longer wants. A single order buffer is transferred to the worker and\n * back, never copied.\n *\n * The worker is built from a Blob of this module's own sort routine, so there\n * is no second file for a bundler to lose.\n */\nexport class AsyncDepthSorter {\n private _worker: Worker | null;\n private _pending: SortRequest | null = null;\n /** The order buffer, when it is on this side of the worker boundary. */\n private _order: Uint32Array | null;\n\n /**\n * @param centers - Flat `[x,y,z] * count`. Copied into the worker once.\n * @param onSorted - Called with each finished order. The array is only valid\n * for the duration of the call - it goes back to the worker on the next\n * request - so copy out of it before returning.\n */\n constructor(centers: Float32Array, count: number, onSorted: (order: Uint32Array) => void) {\n this._order = new Uint32Array(count);\n\n // Wrapped as an expression so the text works whether a bundler leaves the\n // routine as a function declaration or rewrites it as an arrow.\n const source = `\n const sortByDepth = (${countingSortByDepth.toString()});\n let centers = null;\n const scratch = { keys: null, counts: null };\n self.onmessage = (e) => {\n const m = e.data;\n if (m.centers) { centers = m.centers; return; }\n const order = m.order;\n sortByDepth(centers, order.length, m.dx, m.dy, m.dz, m.depthMin, m.depthMax, order, scratch);\n self.postMessage({ order }, [order.buffer]);\n };\n `;\n const url = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));\n this._worker = new Worker(url, { name: 'splat-depth-sort' });\n URL.revokeObjectURL(url);\n\n this._worker.onmessage = (e: MessageEvent<{ order: Uint32Array }>) => {\n this._order = e.data.order;\n onSorted(this._order);\n if (this._pending) {\n const next = this._pending;\n this._pending = null;\n this.request(next);\n }\n };\n\n const copy = centers.slice(0, count * 3);\n this._worker.postMessage({ centers: copy }, [copy.buffer]);\n }\n\n /** True while a sort is running in the worker. */\n get busy(): boolean {\n return this._order === null;\n }\n\n request(req: SortRequest): void {\n if (!this._worker) return;\n const order = this._order;\n if (!order) {\n this._pending = req;\n return;\n }\n this._order = null;\n this._worker.postMessage({ ...req, order }, [order.buffer]);\n }\n\n dispose(): void {\n this._worker?.terminate();\n this._worker = null;\n this._pending = null;\n }\n}\n", "import { ClampToEdgeWrapping, DataTexture, FloatType, NearestFilter, RGBAFormat } from 'three';\n\nimport type { Mat4 } from '../math';\n\n// Column-major 4x4 -> three row-major texels (the bottom row is implicit 0,0,0,1).\nconst idx = [0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14];\n/** Transforms per texture row. The shader's palette lookup hard-codes this. */\nexport const PALETTE_ROW_SLOTS = 512;\nconst width = PALETTE_ROW_SLOTS * 3;\n\nfunction createPaletteTexture(data: Float32Array, w: number, h: number): DataTexture {\n const texture = new DataTexture(data, w, h, RGBAFormat, FloatType);\n texture.name = 'transformPalette';\n texture.minFilter = NearestFilter;\n texture.magFilter = NearestFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The per-splat table of skinning matrices, stored as a float texture: three\n * RGBA texels per transform, {@link PALETTE_ROW_SLOTS} transforms per row.\n *\n * Slot 0 is reserved for identity and is what unmapped influences point at.\n */\nclass TransformPalette {\n private _texture!: DataTexture;\n private _data!: Float32Array;\n private _dirty = false;\n private _nextIdx = 1;\n private readonly _identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0];\n\n constructor(initialSize = 4096) {\n this._realloc(Math.ceil(initialSize / PALETTE_ROW_SLOTS));\n this._data.set(this._identity, 0);\n this.upload();\n }\n\n /**\n * The backing texture. Replaced when the palette grows, so read it each\n * frame rather than holding on to it.\n */\n get texture(): DataTexture {\n return this._texture;\n }\n\n /**\n * The backing array: twelve floats per slot, three row-major vec4 rows.\n * Replaced when the palette grows, like {@link TransformPalette.texture}.\n */\n get data(): Float32Array {\n return this._data;\n }\n\n /** Incremented every time {@link TransformPalette.upload} reports a change. */\n version = 0;\n\n /** Slots the palette can hold before it has to grow. */\n get capacity(): number {\n return this._data.length / 12;\n }\n\n private _realloc(height: number): void {\n const data = new Float32Array(width * height * 4);\n if (this._texture) {\n data.set(this._data);\n this._texture.dispose();\n }\n this._data = data;\n this._texture = createPaletteTexture(data, width, height);\n this._dirty = true;\n }\n\n getTransform(index: number, transform: Mat4): void {\n const dst = transform.data;\n const data = this._data;\n for (let i = 0; i < 12; ++i) {\n dst[idx[i]] = data[index * 12 + i];\n }\n }\n\n setTransform(index: number, transform: Mat4): void {\n const src = transform.data;\n const data = this._data;\n const base = index * 12;\n let changed = false;\n for (let i = 0; i < 12; ++i) {\n const v = src[idx[i]];\n if (data[base + i] !== v) {\n data[base + i] = v;\n changed = true;\n }\n }\n if (changed) this._dirty = true;\n }\n\n /** Flag the texture for re-upload if anything changed. Returns whether it did. */\n upload(): boolean {\n if (!this._dirty) return false;\n this._dirty = false;\n this._texture.needsUpdate = true;\n this.version++;\n return true;\n }\n\n /** Reserve `num` consecutive slots and return the index of the first. */\n alloc(num = 1): number {\n const result = this._nextIdx;\n while (this._nextIdx + num > this._data.length / 12) {\n this._realloc(this._texture.image.height * 2);\n }\n this._nextIdx += num;\n return result;\n }\n\n free(num = 1): void {\n this._nextIdx -= num;\n }\n\n dispose(): void {\n this._texture.dispose();\n }\n}\n\nexport { TransformPalette };\n", "import { PALETTE_ROW_SLOTS } from '../transform-palette';\n\n// GLSL ES 3.00 sources for the WebGLRenderer splat material.\n//\n// One vertex stage does what the PlayCanvas build spreads over two passes\n// (skin into a work buffer, then project): fetch the splat, blend its bone\n// transforms, lift it to world space, project its covariance to a screen-space\n// quad. The maths is kept line-for-line comparable with that build so the two\n// can be diffed, and so the A/B suite has a reason to agree.\n//\n// Defines:\n// USE_BONE_BLENDING - splat carries skinning weights (characters).\n// USE_NONRIGID_COV - let the palette's per-axis scale stretch the gaussian\n// (bone-length scaling).\n// USE_VARIANT_MASK - per-splat group id + per-group visibility.\n// USE_ANTIALIAS - compensate opacity for the screen-space dilation.\n\nconst lightingChunk = /* glsl */ `\nuniform vec3 uSunColor;\nuniform float uSunIntensity;\nuniform vec3 uAmbientColor;\nuniform int uPointLightCount;\nuniform highp sampler2D uPointLightTex;\n\n// Baked splat colour is multiplied by this. With no lights it is exactly 1.\nvec3 computeLitFactor(vec3 worldCenter) {\n vec3 lit = uAmbientColor + uSunColor * uSunIntensity;\n for (int i = 0; i < uPointLightCount; i++) {\n vec4 posRange = texelFetch(uPointLightTex, ivec2(i, 0), 0);\n vec4 colorInt = texelFetch(uPointLightTex, ivec2(i, 1), 0);\n vec3 toLight = posRange.xyz - worldCenter;\n float dist = length(toLight);\n float range = posRange.w;\n if (dist >= range) continue;\n float t = dist / range;\n float atten = 1.0 - t * t;\n atten = atten * atten;\n lit += colorInt.rgb * colorInt.w * atten;\n }\n return lit;\n}\n`;\n\nconst skinningChunk = /* glsl */ `\nuniform highp sampler2D transformPalette;\n\n#ifdef USE_BONE_BLENDING\nuniform highp sampler2D boneIndices;\nuniform highp sampler2D boneWeights;\n#endif\n\n#ifdef USE_VARIANT_MASK\nuniform highp sampler2D splatGroupIds;\nuniform highp sampler2D splatVariantMask;\n\nbool isSplatHiddenByVariantMask(ivec2 splatUV) {\n float gidF = texelFetch(splatGroupIds, splatUV, 0).r;\n int gid = int(gidF + 0.5);\n float bit = texelFetch(splatVariantMask, ivec2(gid, 0), 0).r;\n return bit < 0.5;\n}\n#endif\n\nbool isReasonablePaletteTransform(mat4 t) {\n mat3 lin = mat3(t);\n vec3 s = vec3(length(lin[0]), length(lin[1]), length(lin[2]));\n // Reject only when EVERY column is near-zero (a truly empty palette slot).\n // Linear-blend skinning of two very different bone rotations produces a\n // candy-wrapper matrix with one short column; that is still a valid\n // mid-rotation transform. Requiring all columns to pass would collapse\n // joint-spanning splats (notably the neck) back to the bind pose.\n return any(greaterThan(s, vec3(1e-4)));\n}\n\nmat4 readTransformFromPalette(uint paletteIndex) {\n if (paletteIndex == 0u) {\n return mat4(1.0);\n }\n\n int u = int(paletteIndex % ${PALETTE_ROW_SLOTS}u) * 3;\n int v = int(paletteIndex / ${PALETTE_ROW_SLOTS}u);\n\n mat4 t;\n t[0] = texelFetch(transformPalette, ivec2(u, v), 0);\n t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);\n t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);\n t[3] = vec4(0.0, 0.0, 0.0, 1.0);\n\n mat4 result = transpose(t);\n if (!isReasonablePaletteTransform(result)) {\n return mat4(1.0);\n }\n return result;\n}\n\nmat4 getSplatPaletteTransform(ivec2 splatUV) {\n #ifdef USE_BONE_BLENDING\n vec4 boneIdxVec = texelFetch(boneIndices, splatUV, 0);\n vec4 boneWeightVec = texelFetch(boneWeights, splatUV, 0);\n float totalWeight = dot(boneWeightVec, vec4(1.0));\n if (totalWeight > 0.001) {\n mat4 blended = mat4(0.0);\n for (int i = 0; i < 4; i++) {\n float w = boneWeightVec[i];\n if (w > 0.001) {\n uint idx = uint(boneIdxVec[i] + 0.5);\n blended += readTransformFromPalette(idx) * w;\n }\n }\n mat4 result = blended / totalWeight;\n if (isReasonablePaletteTransform(result)) {\n return result;\n }\n }\n #endif\n\n return mat4(1.0);\n}\n\nvec4 mat3ToQuatXYZW(mat3 R) {\n vec4 q;\n float trace = R[0][0] + R[1][1] + R[2][2];\n if (trace > 0.0) {\n float s = sqrt(trace + 1.0) * 2.0;\n q.w = 0.25 * s;\n q.x = (R[1][2] - R[2][1]) / s;\n q.y = (R[2][0] - R[0][2]) / s;\n q.z = (R[0][1] - R[1][0]) / s;\n } else if (R[0][0] > R[1][1] && R[0][0] > R[2][2]) {\n float s = sqrt(1.0 + R[0][0] - R[1][1] - R[2][2]) * 2.0;\n q.w = (R[1][2] - R[2][1]) / s;\n q.x = 0.25 * s;\n q.y = (R[1][0] + R[0][1]) / s;\n q.z = (R[2][0] + R[0][2]) / s;\n } else if (R[1][1] > R[2][2]) {\n float s = sqrt(1.0 + R[1][1] - R[0][0] - R[2][2]) * 2.0;\n q.w = (R[2][0] - R[0][2]) / s;\n q.x = (R[1][0] + R[0][1]) / s;\n q.y = 0.25 * s;\n q.z = (R[2][1] + R[1][2]) / s;\n } else {\n float s = sqrt(1.0 + R[2][2] - R[0][0] - R[1][1]) * 2.0;\n q.w = (R[0][1] - R[1][0]) / s;\n q.x = (R[2][0] + R[0][2]) / s;\n q.y = (R[2][1] + R[1][2]) / s;\n q.z = 0.25 * s;\n }\n return q;\n}\n`;\n\nexport const SPLAT_VERTEX_GLSL = /* glsl */ `\nprecision highp float;\nprecision highp int;\nprecision highp usampler2D;\n\n// Quad corner in [-1, 1].\nin vec3 position;\n// Index of the splat this instance draws; instances arrive back-to-front.\nin uint splatOrder;\n\nuniform mat4 modelMatrix;\nuniform mat4 viewMatrix;\nuniform mat4 projectionMatrix;\n\nuniform highp usampler2D tTransformA;\nuniform highp sampler2D tTransformB;\nuniform highp sampler2D tColor;\nuniform int uTexWidth;\n\n// Drawing-buffer size in pixels.\nuniform vec2 uViewport;\nuniform float uMinPixelSize;\n// World rotation (xyzw) and scale of the splat object.\nuniform vec4 uModelRotation;\nuniform vec3 uModelScale;\n// rgb tint colour, a tint amount.\nuniform vec4 uTint;\n// x contrast, y saturation.\nuniform vec2 uGrade;\n// 1 when the render target expects linear colour, 0 when it is display-referred.\nuniform float uOutputLinear;\n\nout mediump vec2 gaussianUV;\nout mediump vec4 gaussianColor;\n\n${lightingChunk}\n${skinningChunk}\n\nconst vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);\n\nmat3 quatToMat3(vec4 R) {\n vec4 R2 = R + R;\n float X = R2.x * R.w;\n vec4 Y = R2.y * R;\n vec4 Z = R2.z * R;\n float W = R2.w * R.w;\n return mat3(\n 1.0 - Z.z - W, Y.z + X, Y.w - Z.x,\n Y.z - X, 1.0 - Y.y - W, Z.w + Y.x,\n Y.w + Z.x, Z.w - Y.x, 1.0 - Y.y - Z.z\n );\n}\n\nvec4 quatMul(vec4 a, vec4 b) {\n return vec4(\n a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,\n a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,\n a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,\n a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z\n );\n}\n\nvoid computeCovariance(vec4 rotation, vec3 scale, out vec3 covA, out vec3 covB) {\n mat3 rot = quatToMat3(rotation);\n mat3 M = transpose(mat3(\n scale.x * rot[0],\n scale.y * rot[1],\n scale.z * rot[2]\n ));\n covA = vec3(dot(M[0], M[0]), dot(M[0], M[1]), dot(M[0], M[2]));\n covB = vec3(dot(M[1], M[1]), dot(M[1], M[2]), dot(M[2], M[2]));\n}\n\nvec3 sRGBToLinear(vec3 c) {\n return mix(\n pow(c * 0.9478672986 + vec3(0.0521327014), vec3(2.4)),\n c * 0.0773993808,\n vec3(lessThanEqual(c, vec3(0.04045)))\n );\n}\n\nvoid main(void) {\n ivec2 splatUV = ivec2(int(splatOrder % uint(uTexWidth)), int(splatOrder / uint(uTexWidth)));\n uvec4 tA = texelFetch(tTransformA, splatUV, 0);\n vec4 tB = texelFetch(tTransformB, splatUV, 0);\n\n vec3 modelCenter = uintBitsToFloat(tA.xyz);\n vec3 packedRot = vec3(unpackHalf2x16(tA.w), tB.w);\n // xyzw, with w recovered: quaternions are stored on the w >= 0 hemisphere.\n vec4 srcRotation = vec4(packedRot, sqrt(max(0.0, 1.0 - dot(packedRot, packedRot))));\n vec3 srcScale = tB.xyz;\n\n // ---- Skin, then lift to world space --------------------------------\n mat4 palette = getSplatPaletteTransform(splatUV);\n vec3 modelDeformed = (palette * vec4(modelCenter, 1.0)).xyz;\n vec3 worldCenter = (modelMatrix * vec4(modelDeformed, 1.0)).xyz;\n\n vec4 worldRotation = quatMul(uModelRotation, srcRotation);\n if (worldRotation.w < 0.0) worldRotation = -worldRotation;\n vec3 worldScale = uModelScale * srcScale;\n\n #ifdef USE_BONE_BLENDING\n {\n // The full world-space skinning rotation comes from modelMatrix * palette;\n // the palette's own scale is deliberately dropped (rigid skinning).\n mat3 lin = mat3(modelMatrix * palette);\n vec3 s = vec3(length(lin[0]), length(lin[1]), length(lin[2]));\n if (s.x > 1e-5 && s.y > 1e-5 && s.z > 1e-5) {\n mat3 rot = mat3(lin[0] / s.x, lin[1] / s.y, lin[2] / s.z);\n vec4 composed = normalize(quatMul(mat3ToQuatXYZW(rot), srcRotation));\n if (composed.w < 0.0) composed = -composed;\n worldRotation = composed;\n }\n #ifdef USE_NONRIGID_COV\n // Bone-length scaling: the palette keeps its per-axis scale and the\n // gaussian stretches with the bone.\n worldScale *= s;\n #endif\n }\n #endif\n\n #ifdef USE_VARIANT_MASK\n if (isSplatHiddenByVariantMask(splatUV)) {\n gl_Position = discardVec;\n return;\n }\n #endif\n\n // ---- Project the centre --------------------------------------------\n bool ortho = projectionMatrix[3][3] == 1.0;\n vec4 centerView = viewMatrix * vec4(worldCenter, 1.0);\n if (!ortho && centerView.z > 0.0) {\n gl_Position = discardVec;\n return;\n }\n vec4 centerProj = projectionMatrix * centerView;\n centerProj.z = clamp(centerProj.z, -abs(centerProj.w), abs(centerProj.w));\n\n // ---- Project the covariance to a screen-space ellipse ----------------\n vec3 covA, covB;\n computeCovariance(worldRotation.wxyz, worldScale, covA, covB);\n mat3 Vrk = mat3(\n covA.x, covA.y, covA.z,\n covA.y, covB.x, covB.y,\n covA.z, covB.y, covB.z\n );\n\n float focal = uViewport.x * projectionMatrix[0][0];\n vec3 v = centerView.xyz;\n vec3 vp = ortho ? vec3(0.0, 0.0, 1.0) : v;\n float J1 = focal / vp.z;\n vec2 J2 = -J1 / vp.z * vp.xy;\n mat3 J = mat3(\n J1, 0.0, J2.x,\n 0.0, J1, J2.y,\n 0.0, 0.0, 0.0\n );\n mat3 W = transpose(mat3(viewMatrix));\n mat3 T = W * J;\n mat3 cov = transpose(T) * Vrk * T;\n\n #ifdef USE_ANTIALIAS\n float detOrig = cov[0][0] * cov[1][1] - cov[0][1] * cov[0][1];\n float detBlur = (cov[0][0] + 0.3) * (cov[1][1] + 0.3) - cov[0][1] * cov[0][1];\n float aaFactor = sqrt(max(detOrig / detBlur, 0.0));\n #endif\n\n float diagonal1 = cov[0][0] + 0.3;\n float offDiagonal = cov[0][1];\n float diagonal2 = cov[1][1] + 0.3;\n float mid = 0.5 * (diagonal1 + diagonal2);\n float radius = length(vec2((diagonal1 - diagonal2) / 2.0, offDiagonal));\n float lambda1 = mid + radius;\n float lambda2 = max(mid - radius, 0.1);\n\n float vmin = min(1024.0, min(uViewport.x, uViewport.y));\n float l1 = 2.0 * min(sqrt(2.0 * lambda1), vmin);\n float l2 = 2.0 * min(sqrt(2.0 * lambda2), vmin);\n if (max(l1, l2) < uMinPixelSize) {\n gl_Position = discardVec;\n return;\n }\n\n // Cull splats whose ellipse lies wholly off-screen.\n vec2 c = centerProj.ww / uViewport;\n if (any(greaterThan(abs(centerProj.xy) - vec2(max(l1, l2)) * c, centerProj.ww))) {\n gl_Position = discardVec;\n return;\n }\n\n vec2 diagonalVector = normalize(vec2(offDiagonal, lambda1 - diagonal1));\n vec2 v1 = l1 * diagonalVector;\n vec2 v2 = l2 * vec2(diagonalVector.y, -diagonalVector.x);\n vec2 cornerUV = position.xy;\n vec2 offset = (cornerUV.x * v1 + cornerUV.y * v2) * c;\n\n // ---- Colour -----------------------------------------------------------\n vec4 clr = texelFetch(tColor, splatUV, 0);\n #ifdef USE_ANTIALIAS\n clr.a *= aaFactor;\n #endif\n\n clr.rgb *= computeLitFactor(worldCenter);\n clr.rgb = mix(clr.rgb, uTint.rgb, clamp(uTint.a, 0.0, 1.0));\n // Identity grade is a true no-op: skipping it keeps HDR splat colours unclamped.\n if (uGrade.x != 1.0 || uGrade.y != 1.0) {\n clr.rgb = (clr.rgb - 0.5) * uGrade.x + 0.5;\n float luma = dot(clr.rgb, vec3(0.2126, 0.7152, 0.0722));\n clr.rgb = mix(vec3(luma), clr.rgb, uGrade.y);\n clr.rgb = clamp(clr.rgb, 0.0, 1.0);\n }\n\n if (255.0 * clr.a <= 1.0) {\n gl_Position = discardVec;\n return;\n }\n\n // Shrink the quad to where the gaussian is still above 1/255: fewer\n // fragments, identical pixels.\n float clip = min(1.0, sqrt(log(255.0 * clr.a)) * 0.5);\n offset *= clip;\n\n gl_Position = centerProj + vec4(offset, 0.0, 0.0);\n gaussianUV = cornerUV * clip;\n\n vec3 rgb = max(clr.rgb, 0.0);\n if (uOutputLinear > 0.5) rgb = sRGBToLinear(rgb);\n gaussianColor = vec4(rgb, clr.a);\n}\n`;\n\nexport const SPLAT_FRAGMENT_GLSL = /* glsl */ `\nprecision highp float;\n\nin mediump vec2 gaussianUV;\nin mediump vec4 gaussianColor;\n\nlayout(location = 0) out highp vec4 fragColor;\n\nconst float EXP4 = exp(-4.0);\nconst float INV_EXP4 = 1.0 / (1.0 - EXP4);\n\n// exp(-4x) rescaled to hit exactly 0 at the quad edge (x = 1).\nfloat normExp(float x) {\n return (exp(x * -4.0) - EXP4) * INV_EXP4;\n}\n\nvoid main(void) {\n mediump float A = dot(gaussianUV, gaussianUV);\n if (A > 1.0) {\n discard;\n }\n mediump float alpha = normExp(A) * gaussianColor.a;\n if (alpha < 1.0 / 255.0) {\n discard;\n }\n // Premultiplied.\n fragColor = vec4(gaussianColor.rgb * alpha, alpha);\n}\n`;\n", "import type { Mesh } from 'three';\n\nimport type { SplatEngine } from '../../engine';\nimport type { SplatBackend, SplatRenderImpl } from '../backend';\nimport type { Splat } from '../splat';\n\nimport { WebGLSplatImpl } from './splat-mesh';\n\n/**\n * Splat rendering for `THREE.WebGLRenderer`: GLSL ES 3.00, WebGL2.\n *\n * Splats are skinned and projected in the vertex stage. The depth sort runs on\n * the CPU - synchronously for skinned characters, in a worker for static\n * environments - which is what makes this backend's cost scale with the\n * number of animated characters.\n *\n * @group Engine\n */\nexport class WebGLSplatBackend implements SplatBackend {\n createImpl(host: Mesh, splat: Splat, engine: SplatEngine, asyncSort: boolean): SplatRenderImpl {\n return new WebGLSplatImpl(host, splat, engine, asyncSort);\n }\n}\n", "import { FileLoader, Loader } from 'three';\nimport type { LoadingManager } from 'three';\n\nimport { Animation } from '../animation';\nimport { SplatEngine } from '../engine';\nimport { decodeCharacterBundle } from '../loader/character/load';\nimport { parseGaussianPly } from '../loader/environment/ply';\nimport { packSplats } from '../splat/packed-splats';\nimport { Splat } from '../splat/splat';\nimport type { SplatMesh } from '../splat/splat-mesh';\n\nimport { SplatCharacter } from './splat-character';\n\nconst GLB_MAGIC = 0x46546c67; // 'glTF'\n\n/** File name without directory, query string or extension. */\nfunction baseName(url: string): string {\n const file = url.split(/[?#]/)[0].split('/').pop() ?? '';\n return file.replace(/\\.\\w+$/, '');\n}\n\n/**\n * Shared plumbing: fetch bytes the three.js way - through a `FileLoader`, so\n * the `LoadingManager`, base path, request headers and credentials mode all\n * apply - then hand them to an asynchronous `parseAsync`.\n */\nabstract class SplatLoaderBase<T> extends Loader<T> {\n /**\n * The engine loaded objects belong to: the skeleton library, clip registry\n * and lights they share. Leave unset to use {@link SplatEngine.shared}.\n */\n engine: SplatEngine | null = null;\n\n constructor(manager?: LoadingManager) {\n super(manager);\n }\n\n setEngine(engine: SplatEngine | null): this {\n this.engine = engine;\n return this;\n }\n\n /** Decode bytes already in memory. `name` labels the result; for a loaded file it is the file's base name. */\n abstract parseAsync(data: ArrayBuffer, name?: string): Promise<T>;\n\n override load(\n url: string,\n onLoad: (result: T) => void,\n onProgress?: (event: ProgressEvent) => void,\n onError?: (error: unknown) => void,\n ): void {\n const loader = new FileLoader(this.manager);\n loader.setPath(this.path);\n loader.setResponseType('arraybuffer');\n loader.setRequestHeader(this.requestHeader);\n loader.setWithCredentials(this.withCredentials);\n loader.load(\n url,\n (data) => {\n this.parseAsync(data as ArrayBuffer, baseName(url)).then(onLoad, (error) => {\n if (onError) onError(error);\n else console.error(error);\n this.manager.itemError(url);\n });\n },\n onProgress,\n onError,\n );\n }\n\n protected get resolvedEngine(): SplatEngine {\n return this.engine ?? SplatEngine.shared;\n }\n}\n\n/**\n * Loads a `.vsplat` character bundle (or a legacy `.bin` one - the container\n * is recognised from the file's own bytes) as a {@link SplatCharacter}.\n *\n * ```ts\n * const character = await new VSplatLoader().loadAsync('/assets/hero.vsplat');\n * scene.add(character);\n * ```\n *\n * @group Loaders\n */\nexport class VSplatLoader extends SplatLoaderBase<SplatCharacter> {\n override async parseAsync(data: ArrayBuffer, name = 'character'): Promise<SplatCharacter> {\n const bundle = await decodeCharacterBundle(data);\n return new SplatCharacter(this.resolvedEngine, [bundle], name);\n }\n}\n\n/**\n * Loads an animation clip for {@link SplatCharacter.play}: a MetaHuman-rig\n * `.glb`, or an `.anim` file.\n *\n * ```ts\n * const run = await new SplatClipLoader().loadAsync('/assets/run.glb');\n * character.play(run);\n * ```\n *\n * A clip is not tied to one character; play the same one on as many as you like.\n *\n * @group Loaders\n */\nexport class SplatClipLoader extends SplatLoaderBase<Animation> {\n /** For a `.glb` holding several animations, the one to take. Default: the first. */\n animationName: string | undefined;\n\n override async parseAsync(data: ArrayBuffer, name = ''): Promise<Animation> {\n const isGlb = data.byteLength >= 4 && new DataView(data).getUint32(0, true) === GLB_MAGIC;\n const clip = isGlb ? Animation.parseGlb(data, this.animationName) : Animation.parse(data);\n if (!clip.name) clip.name = name;\n return clip;\n }\n}\n\n/**\n * Loads an uncompressed 3D Gaussian Splatting `.ply` as a static\n * {@link SplatMesh} - an environment, a prop, a scanned object.\n *\n * ```ts\n * const room = await new SplatPLYLoader().loadAsync('/assets/room.ply');\n * room.rotation.x = Math.PI; // many captures are authored Y-down\n * scene.add(room);\n * ```\n *\n * The mesh is given `renderOrder = -1` so it draws before characters, which\n * then always composite on top of it. Splats do not write depth, so without\n * that a large environment whose origin happens to be nearer the camera would\n * be drawn over a character standing in it.\n *\n * @group Loaders\n */\nexport class SplatPLYLoader extends SplatLoaderBase<SplatMesh> {\n override async parseAsync(data: ArrayBuffer, name = 'splat'): Promise<SplatMesh> {\n const { numSplats, splats } = parseGaussianPly(data);\n const splat = new Splat(this.resolvedEngine, { packed: packSplats(numSplats, splats) });\n const mesh = splat.object3D;\n mesh.name = name;\n mesh.renderOrder = -1;\n return mesh;\n }\n}\n", "import type { SplatAttributes } from '../character/types';\n\nconst HEADER_END = 'end_header\\n';\n/** Headers are a few hundred bytes; anything past this is not a PLY we read. */\nconst MAX_HEADER_BYTES = 64 * 1024;\n\nconst PLY_TYPES: Record<string, { size: number; read: (v: DataView, o: number) => number }> = {\n char: { size: 1, read: (v, o) => v.getInt8(o) },\n int8: { size: 1, read: (v, o) => v.getInt8(o) },\n uchar: { size: 1, read: (v, o) => v.getUint8(o) },\n uint8: { size: 1, read: (v, o) => v.getUint8(o) },\n short: { size: 2, read: (v, o) => v.getInt16(o, true) },\n int16: { size: 2, read: (v, o) => v.getInt16(o, true) },\n ushort: { size: 2, read: (v, o) => v.getUint16(o, true) },\n uint16: { size: 2, read: (v, o) => v.getUint16(o, true) },\n int: { size: 4, read: (v, o) => v.getInt32(o, true) },\n int32: { size: 4, read: (v, o) => v.getInt32(o, true) },\n uint: { size: 4, read: (v, o) => v.getUint32(o, true) },\n uint32: { size: 4, read: (v, o) => v.getUint32(o, true) },\n float: { size: 4, read: (v, o) => v.getFloat32(o, true) },\n float32: { size: 4, read: (v, o) => v.getFloat32(o, true) },\n double: { size: 8, read: (v, o) => v.getFloat64(o, true) },\n float64: { size: 8, read: (v, o) => v.getFloat64(o, true) },\n};\n\n/** The fourteen properties a gaussian splat needs, in {@link SplatAttributes} order. */\nconst REQUIRED = [\n 'x', 'y', 'z',\n 'scale_0', 'scale_1', 'scale_2',\n 'rot_0', 'rot_1', 'rot_2', 'rot_3',\n 'f_dc_0', 'f_dc_1', 'f_dc_2',\n 'opacity',\n] as const;\n\ninterface PlyProperty {\n name: string;\n type: string;\n offset: number;\n}\n\n/**\n * Parse an uncompressed 3D Gaussian Splatting `.ply` (the layout written by\n * the reference trainer and most tools since): one binary little-endian\n * `vertex` element carrying position, log-scale, a `wxyz` rotation, the\n * spherical-harmonic DC colour and a logit opacity.\n *\n * Higher-order SH (`f_rest_*`) and normals are skipped: splats here are lit\n * flat, by their DC colour.\n *\n * @throws If the file is not a binary little-endian PLY, or lacks a required property.\n */\nexport function parseGaussianPly(file: ArrayBuffer): { numSplats: number; splats: SplatAttributes } {\n const headerBytes = new Uint8Array(file, 0, Math.min(file.byteLength, MAX_HEADER_BYTES));\n const headerText = new TextDecoder('ascii').decode(headerBytes);\n const end = headerText.indexOf(HEADER_END);\n if (!headerText.startsWith('ply') || end < 0) {\n throw new Error('[parseGaussianPly] not a PLY file: missing \"ply\" magic or \"end_header\"');\n }\n const dataStart = end + HEADER_END.length;\n\n let numSplats = 0;\n let stride = 0;\n let inVertex = false;\n let sawVertex = false;\n let skipBefore = 0;\n const props: PlyProperty[] = [];\n\n for (const raw of headerText.slice(0, end).split('\\n')) {\n const tokens = raw.trim().split(/\\s+/);\n switch (tokens[0]) {\n case 'format':\n if (tokens[1] !== 'binary_little_endian') {\n throw new Error(`[parseGaussianPly] unsupported PLY format '${tokens[1]}'; expected binary_little_endian`);\n }\n break;\n case 'element':\n inVertex = tokens[1] === 'vertex';\n if (inVertex) {\n sawVertex = true;\n numSplats = Number.parseInt(tokens[2], 10);\n } else if (!sawVertex) {\n // An element stored ahead of `vertex` would shift where vertex data\n // begins; nothing we read writes one, so reject rather than guess.\n skipBefore++;\n }\n break;\n case 'property': {\n if (!inVertex) break;\n if (tokens[1] === 'list') {\n throw new Error('[parseGaussianPly] list properties on the vertex element are not supported');\n }\n const type = PLY_TYPES[tokens[1]];\n if (!type) throw new Error(`[parseGaussianPly] unknown property type '${tokens[1]}'`);\n props.push({ name: tokens[2], type: tokens[1], offset: stride });\n stride += type.size;\n break;\n }\n default:\n break;\n }\n }\n\n if (!sawVertex) throw new Error('[parseGaussianPly] PLY has no vertex element');\n if (skipBefore > 0) throw new Error('[parseGaussianPly] PLY stores another element before vertex');\n if (!Number.isFinite(numSplats) || numSplats < 0) {\n throw new Error('[parseGaussianPly] PLY vertex count is not a non-negative integer');\n }\n if (dataStart + numSplats * stride > file.byteLength) {\n throw new Error(\n `[parseGaussianPly] truncated: header declares ${numSplats} vertices x ${stride} B, ` +\n `but only ${file.byteLength - dataStart} B follow it`,\n );\n }\n\n const byName = new Map(props.map((p) => [p.name, p]));\n const columns = REQUIRED.map((name) => {\n const p = byName.get(name);\n if (!p) throw new Error(`[parseGaussianPly] PLY is missing the required property '${name}'`);\n return p;\n });\n\n const out = REQUIRED.map(() => new Float32Array(numSplats));\n\n // The overwhelmingly common case is an all-float32 vertex whose stride is a\n // multiple of four: read whole columns through one aligned Float32Array view\n // instead of a DataView call per value.\n const allFloat = columns.every((p) => PLY_TYPES[p.type].size === 4 && p.type.startsWith('float'));\n if (allFloat && stride % 4 === 0 && columns.every((p) => p.offset % 4 === 0)) {\n const aligned =\n dataStart % 4 === 0\n ? new Float32Array(file, dataStart, (numSplats * stride) / 4)\n : new Float32Array(file.slice(dataStart, dataStart + numSplats * stride));\n const step = stride / 4;\n for (let c = 0; c < columns.length; c++) {\n const dst = out[c];\n for (let i = 0, o = columns[c].offset / 4; i < numSplats; i++, o += step) dst[i] = aligned[o];\n }\n } else {\n const view = new DataView(file, dataStart);\n for (let c = 0; c < columns.length; c++) {\n const dst = out[c];\n const { offset, type } = columns[c];\n const read = PLY_TYPES[type].read;\n for (let i = 0; i < numSplats; i++) dst[i] = read(view, i * stride + offset);\n }\n }\n\n const [x, y, z, scale_0, scale_1, scale_2, rot_0, rot_1, rot_2, rot_3, f_dc_0, f_dc_1, f_dc_2, opacity] = out;\n return {\n numSplats,\n splats: { x, y, z, scale_0, scale_1, scale_2, rot_0, rot_1, rot_2, rot_3, f_dc_0, f_dc_1, f_dc_2, opacity },\n };\n}\n", "import { Euler, MathUtils } from 'three';\nimport type { Object3D } from 'three';\n\nimport type { SplatEngine } from './engine';\nimport { EngineDisposedError } from './engine';\nimport { parseGaussianPly } from './loader/environment/ply';\nimport { cachedFetch } from './loader/shared/bin-cache';\nimport { packSplats } from './splat/packed-splats';\nimport { Splat } from './splat/splat';\n\n/** @group Environment */\nexport interface LoadEnvironmentOptions {\n /** Object name. Default: basename of the URL. */\n name?: string;\n /** World position. Default: origin. */\n position?: { x: number; y: number; z: number };\n /** Euler angles in degrees. Default: no rotation. */\n rotation?: { x: number; y: number; z: number };\n /** Uniform scale. Default: 1. */\n scale?: number;\n /** Explicit filename for extension detection on URLs without one. */\n filename?: string;\n}\n\n/**\n * Environments draw before characters so characters always composite on top,\n * matching the PlayCanvas build's dedicated environment layer.\n */\nconst ENVIRONMENT_RENDER_ORDER = -1;\n\nconst _euler = new Euler();\n\n/**\n * Gaussian-splat environment loaded into an engine.\n *\n * A static, unskinned splat that responds to the engine's lighting registry\n * (sun + sky + point lights). Its depth sort runs in a worker and only when\n * the view direction changes, so a large scene costs nothing while the camera\n * is still.\n *\n * Construct via {@link Environment.load} - the constructor is internal.\n *\n * @group Environment\n */\nexport class Environment {\n /** The splat that draws the environment. */\n readonly splat: Splat;\n\n private constructor(splat: Splat) {\n this.splat = splat;\n }\n\n /** The three.js object for the environment. Transform it like any other. */\n get object3D(): Object3D {\n return this.splat.object3D;\n }\n\n /**\n * Fetch, decode and add an environment splat.\n *\n * Reads uncompressed 3D Gaussian Splatting `.ply` files.\n *\n * @param url - Location of the splat file.\n */\n static async load(engine: SplatEngine, url: string, opts?: LoadEnvironmentOptions): Promise<Environment> {\n const fname = opts?.filename ?? url.split('?')[0].split('/').pop() ?? 'environment';\n const lower = fname.toLowerCase();\n if (!lower.endsWith('.ply') || lower.endsWith('.compressed.ply')) {\n throw new Error(`[Environment.load] unsupported environment format '${fname}'; expected an uncompressed .ply`);\n }\n\n const res = await cachedFetch(url);\n if (!res.ok) throw new Error(`[Environment.load] fetch failed (${res.status}): ${url}`);\n const { numSplats, splats } = parseGaussianPly(await res.arrayBuffer());\n if (engine.destroyed) throw new EngineDisposedError('Environment.load');\n\n const splat = new Splat(engine, { packed: packSplats(numSplats, splats) });\n const object = splat.object3D;\n object.name = opts?.name ?? fname.replace(/\\.\\w+$/, '');\n object.renderOrder = ENVIRONMENT_RENDER_ORDER;\n if (opts?.position) object.position.set(opts.position.x, opts.position.y, opts.position.z);\n if (opts?.rotation) {\n // 'ZYX' is the order that reproduces the PlayCanvas build's euler convention.\n const { x, y, z } = opts.rotation;\n object.quaternion.setFromEuler(\n _euler.set(x * MathUtils.DEG2RAD, y * MathUtils.DEG2RAD, z * MathUtils.DEG2RAD, 'ZYX'),\n );\n }\n if (opts?.scale !== undefined) object.scale.setScalar(opts.scale);\n\n engine.contentRoot.add(object);\n return new Environment(splat);\n }\n\n /** Remove the environment and release its GPU resources. */\n destroy(): void {\n this.splat.destroy();\n }\n}\n", "import { Color, Vector3 } from 'three';\n\nimport type { SplatEngine } from '../engine';\n\nimport { applyHexTo, rawColor } from './color';\n\n/** @group Lighting */\nexport interface CreateSunLightOptions {\n /** Azimuth in degrees. 0 = +Z, 90 = +X. */\n azimuth?: number;\n /** Elevation in degrees. 0 = horizon, 90 = directly overhead. */\n elevation?: number;\n /** Sun colour as CSS hex string, e.g. '#fff4e0'. */\n color?: string;\n /** Brightness multiplier applied to `color` in the shader. */\n intensity?: number;\n /** Start disabled. Lights default to enabled. */\n enabled?: boolean;\n}\n\n/**\n * Directional light for splats. Splats have no normals, so the sun is a flat\n * brightness term: every splat receives `color * intensity`, regardless of\n * which way it faces.\n *\n * @group Lighting\n */\nexport class SunLight {\n azimuth = 30;\n elevation = 60;\n /** Raw component values; not colour-managed. */\n color = rawColor(new Color(), 1, 0.95, 0.85);\n intensity = 1.0;\n enabled = true;\n\n /** Unit vector pointing from the scene toward the sun. */\n lightDir(out: Vector3 = new Vector3()): Vector3 {\n const azRad = (this.azimuth * Math.PI) / 180;\n const elRad = (this.elevation * Math.PI) / 180;\n const ce = Math.cos(elRad);\n return out.set(ce * Math.sin(azRad), Math.sin(elRad), ce * Math.cos(azRad));\n }\n\n /** Create a sun and make it the engine's sun. */\n static create(engine: SplatEngine, opts?: CreateSunLightOptions): SunLight {\n const sun = new SunLight();\n if (opts?.azimuth !== undefined) sun.azimuth = opts.azimuth;\n if (opts?.elevation !== undefined) sun.elevation = opts.elevation;\n if (opts?.color !== undefined) applyHexTo(sun.color, opts.color);\n if (opts?.intensity !== undefined) sun.intensity = opts.intensity;\n if (opts?.enabled !== undefined) sun.enabled = opts.enabled;\n engine.lighting.sun = sun;\n return sun;\n }\n}\n", "import type { Color } from 'three';\n\n/** Parse `#rrggbb` into raw 0..1 components. */\nexport function parseHex(css: string): [number, number, number] {\n const hex = css.replace('#', '');\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n return [r, g, b];\n}\n\n/**\n * Write a CSS hex colour into `color` as raw component values.\n *\n * Deliberately not `Color.set(hex)`: light colours here multiply baked,\n * display-referred splat colour, so they are used as written. three.js colour\n * management would convert the hex to linear and darken every light.\n */\nexport function applyHexTo(color: Color, css: string): void {\n const [r, g, b] = parseHex(css);\n color.r = r;\n color.g = g;\n color.b = b;\n}\n\n/** A `Color` holding exactly the given component values, with no colour-space conversion. */\nexport function rawColor(color: Color, r: number, g: number, b: number): Color {\n color.r = r;\n color.g = g;\n color.b = b;\n return color;\n}\n", "import { Color } from 'three';\n\nimport type { SplatEngine } from '../engine';\n\nimport { applyHexTo, rawColor } from './color';\n\n/** @group Lighting */\nexport interface CreateSkyLightOptions {\n /** Sky colour as CSS hex string. */\n color?: string;\n intensity?: number;\n enabled?: boolean;\n}\n\n/**\n * Ambient light for splats: a constant `color * intensity` added to every splat.\n *\n * @group Lighting\n */\nexport class SkyLight {\n /** Raw component values; not colour-managed. */\n color = rawColor(new Color(), 0.55, 0.62, 0.78);\n intensity = 0.35;\n enabled = true;\n\n /** Create a sky light and make it the engine's sky. */\n static create(engine: SplatEngine, opts?: CreateSkyLightOptions): SkyLight {\n const sky = new SkyLight();\n if (opts?.color !== undefined) applyHexTo(sky.color, opts.color);\n if (opts?.intensity !== undefined) sky.intensity = opts.intensity;\n if (opts?.enabled !== undefined) sky.enabled = opts.enabled;\n engine.lighting.sky = sky;\n return sky;\n }\n}\n", "import { Color, Vector3 } from 'three';\n\nimport type { SplatEngine } from '../engine';\n\nimport { applyHexTo, rawColor } from './color';\n\n/** @group Lighting */\nexport interface CreatePointLightOptions {\n position?: { x: number; y: number; z: number };\n /** Light colour as CSS hex string. */\n color?: string;\n intensity?: number;\n /** Hard cutoff distance in world units. Contribution is 0 at and beyond this. */\n range?: number;\n enabled?: boolean;\n}\n\n/** @group Lighting */\nexport class PointLight {\n /** World-space position. */\n position = new Vector3();\n /** Raw component values; not colour-managed. */\n color = rawColor(new Color(), 1, 1, 1);\n intensity = 1.0;\n range = 5.0;\n enabled = true;\n\n private _engine: SplatEngine | null = null;\n\n /** @internal */\n _attach(engine: SplatEngine): void {\n this._engine = engine;\n }\n\n /** Remove this light from its engine. After calling, the light stops contributing. */\n destroy(): void {\n const engine = this._engine;\n if (!engine) return;\n const i = engine.lighting.points.indexOf(this);\n if (i >= 0) engine.lighting.points.splice(i, 1);\n this._engine = null;\n }\n\n /** Create a point light and register it on the engine's lighting registry. */\n static create(engine: SplatEngine, opts?: CreatePointLightOptions): PointLight {\n const light = new PointLight();\n if (opts?.position) light.position.set(opts.position.x, opts.position.y, opts.position.z);\n if (opts?.color !== undefined) applyHexTo(light.color, opts.color);\n if (opts?.intensity !== undefined) light.intensity = opts.intensity;\n if (opts?.range !== undefined) light.range = opts.range;\n if (opts?.enabled !== undefined) light.enabled = opts.enabled;\n light._attach(engine);\n engine.lighting.points.push(light);\n return light;\n }\n}\n"],
5
+ "mappings": "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U,IAAG,WAAU,IAAG,WAAU,IAAG,WAAU,UAAS,WAAU,WAAU,WAAU,UAAS,SAAQ,WAAU,WAAU,IAAG,UAAS,GAAE,WAAU,IAAG,GAAE,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,GAAE,WAAU,GAAE,WAAU,IAAG,WAAU,GAAE,WAAU,GAAE,WAAU,GAAE,WAAU,WAAU,SAAS,WAAU,UAAS,GAAE,WAAU,IAAG,WAAU,IAAG,UAAS,IAAG,WAAU,GAAE,WAAU,IAAG,WAAU,UAAS,UAAS,UAAS,WAAU,IAAG,WAAU,GAAE,WAAU,GAAE,WAAU,IAAG,WAAU,UAAU,UAAS,SAAS,WAAU,GAAE,WAAU,IAAG,WAAU,GAAE,WAAU,IAAG,WAAU,GAAE,WAAU,GAAE,WAAU,UAAS,SAAS,UAAS,WAAU,GAAE,WAAU,GAAE,WAAU,IAAG,WAAU,GAAE,WAAU,GAAE,WAAU,IAAG,WAAU,WAAU,UAAS,WAAU,UAAU,GAAE,SAAS,GAAE,WAAU,UAAS,GAAE,GAAE,WAAU,GAAE,UAAS,IAAG,WAAU,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,UAAS,UAAS,UAAU,WAAU,GAAE,IAAG,IAAG,IAAG,UAAS,UAAS,UAAU,WAAU,IAAG,UAAS,IAAG,WAAU,GAAE,IAAG,IAAG,IAAG,WAAU,UAAU,UAAS,WAAU,GAAE,SAAS,GAAE,WAAU,UAAS,GAAE,GAAE,WAAU,GAAE,UAAS,IAAG,WAAU,UAAS,UAAS,UAAU,WAAU,IAAG,UAAS,IAAG,WAAU,UAAS,UAAS,UAAU,WAAU,IAAG,IAAG,GAAE,IAAG,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,SAAS,SAAQ,UAAS,WAAU,GAAE,UAAS,GAAE,WAAU,GAAE,IAAG,GAAE,IAAG,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,SAAQ,UAAS,WAAU,SAAQ,WAAU,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,GAAE,IAAG,UAAS,UAAS,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,IAAG,IAAG,WAAU,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,SAAS,UAAS,WAAU,UAAS,UAAU,UAAS,WAAU,WAAU,UAAU,UAAS,UAAS,UAAS,SAAS,UAAS,UAAS,WAAU,UAAU,UAAS,WAAU,UAAS,SAAS,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,IAAG,IAAG,WAAU,WAAU,IAAG,IAAG,UAAS,WAAU,IAAG,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,UAAS,UAAU,SAAQ,WAAU,IAAG,IAAG,UAAS,WAAU,WAAU,SAAQ,UAAS,WAAU,WAAU,SAAQ,UAAS,WAAU,IAAG,IAAG,UAAS,WAAU,WAAU,SAAQ,UAAS,WAAU,WAAU,SAAQ,UAAS,WAAU,UAAS,SAAS,UAAS,WAAU,GAAE,IAAG,UAAS,UAAS,GAAE,GAAE,UAAS,WAAU,WAAU,WAAU,UAAS,WAAU,WAAU,WAAU,UAAS,WAAU,WAAU,SAAS,SAAQ,WAAU,GAAE,GAAE,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,GAAE,GAAE,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,UAAU,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,IAAG,IAAG,UAAS,UAAS,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,WAAU,WAAU,UAAS,UAAS,UAAU,UAAS,UAAS,UAAS,UAAU,UAAS,UAAS,UAAS,SAAQ,WAAU,UAAS,UAAS,UAAU,UAAS,UAAS,UAAS,UAAU,UAAS,UAAS,UAAS,SAAQ,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,UAAU,UAAS,WAAU,WAAU,UAAU,UAAS,WAAU,WAAU,SAAQ,WAAU,WAAU,WAAU,UAAU,UAAS,WAAU,WAAU,UAAU,UAAS,WAAU,WAAU,SAAQ,WAAU,UAAS,UAAS,WAAU,WAAU,SAAQ,SAAQ,WAAU,UAAS,SAAQ,SAAQ,WAAU,UAAS,UAAS,QAAO,UAAS,WAAU,UAAS,UAAS,WAAU,WAAU,SAAQ,UAAS,UAAS,WAAU,SAAQ,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,WAAU,SAAQ,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,WAAU,UAAS,WAAU,UAAS,WAAU,UAAU,UAAS,UAAS,WAAU,SAAS,SAAQ,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,WAAU,WAAU,SAAU,UAAS,IAAG,IAAG,GAAE,IAAG,UAAS,UAAS,SAAS,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,SAAU,UAAS,IAAG,GAAE,IAAG,IAAG,WAAU,WAAU,SAAS,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,SAAS,WAAU,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,IAAG,IAAG,WAAU,UAAS,IAAG,IAAG,IAAG,IAAG,UAAS,UAAS,UAAU,WAAU,IAAG,IAAG,WAAU,UAAS,WAAU,WAAU,UAAU,WAAU,IAAG,IAAG,WAAU,WAAU,WAAU,WAAU,UAAS,WAAU,GAAE,IAAG,IAAG,IAAG,UAAS,UAAS,UAAU,WAAU,IAAG,IAAG,WAAU,WAAU,UAAS,UAAS,UAAS,WAAU,GAAE,IAAG,IAAG,IAAG,WAAU,WAAU,UAAU,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,GAAE,IAAG,UAAS,UAAS,WAAU,IAAG,GAAE,WAAU,GAAE,IAAG,GAAE,IAAG,UAAS,GAAE,GAAE,WAAU,GAAE,IAAG,UAAS,UAAS,UAAS,IAAG,IAAG,WAAU,GAAE,IAAG,GAAE,IAAG,WAAU,GAAE,IAAG,WAAU,GAAE,IAAG,UAAS,WAAU,UAAS,GAAE,GAAE,WAAU,GAAE,IAAG,UAAS,WAAU,UAAS,GAAE,GAAE,WAAU,IAAG,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,UAAS,IAAG,IAAG,UAAS,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,WAAU,IAAG,IAAG,UAAS,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,UAAS,UAAS,UAAS,UAAS,WAAU,WAAU,UAAS,UAAS,UAAS,UAAS,WAAU,WAAU,UAAS,WAAU,SAAS,WAAU,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,UAAS,UAAS,SAAS,WAAU,WAAU,WAAU,SAAS,WAAU,IAAG,IAAG,UAAS,WAAU,IAAG,IAAG,UAAS,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,UAAS,UAAS,WAAU,UAAS,WAAU,WAAU,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,WAAU,WAAU,WAAU,UAAS,UAAS,SAAQ,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,UAAS,UAAU,WAAU,WAAU,UAAS,UAAU,WAAU,WAAU,QAAO,UAAS,WAAU,UAAS,UAAS,WAAU,WAAU,UAAS,WAAU,UAAU,WAAU,UAAS,WAAU,UAAU,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,SAAQ,WAAU,SAAQ,WAAU,WAAU,IAAG,GAAE,WAAU,UAAS,IAAG,IAAG,WAAU,UAAS,UAAS,SAAQ,WAAU,UAAS,IAAG,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,QAAS,UAAS,WAAU,WAAU,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,SAAU,WAAU,WAAU,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,IAAG,IAAG,WAAU,WAAU,GAAE,IAAG,UAAS,WAAU,WAAU,UAAS,WAAU,UAAS,UAAS,WAAU,WAAU,UAAS,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,IAAG,IAAG,IAAG,GAAE,UAAS,WAAU,WAAU,WAAU,UAAS,UAAS,WAAU,WAAU,UAAS,UAAS,WAAU,WAAU,UAAS,WAAU,WAAU,UAAU,UAAS,WAAU,UAAS,SAAS,UAAS,UAAS,UAAS,WAAU,UAAS,WAAU,SAAQ,WAAU,UAAS,WAAU,SAAQ,WAAU,UAAS,WAAU,SAAQ,WAAU,UAAS,WAAU,UAAS,SAAS,UAAS,WAAU,UAAS,UAAU,WAAU,WAAU,UAAS,UAAU,WAAU,WAAU,WAAU,UAAU,UAAS,UAAS,WAAU,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,UAAS,UAAS,UAAS,WAAU,IAAG,IAAG,WAAU,WAAU,IAAG,IAAG,WAAU,WAAU,UAAS,UAAS,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,UAAS,UAAS,WAAU,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,WAAU,WAAU,WAAU,WAAU,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,IAAG,UAAS,UAAS,WAAU,UAAS,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,WAAU,WAAU,WAAU,UAAS,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,UAAS,IAAG,GAAE,WAAU,WAAU,IAAG,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,WAAU,GAAE,IAAG,WAAU,WAAU,IAAG,IAAG,WAAU,UAAS,GAAE,GAAE,WAAU,UAAS,IAAG,IAAG,WAAU,UAAS,IAAG,IAAG,WAAU,UAAS,IAAG,IAAG,WAAU,UAAS,IAAG,IAAG,WAAU,UAAS,IAAG,IAAG,WAAU,WAAU,UAAU,UAAS,WAAU,UAAS,SAAS,UAAS,WAAU,UAAS,UAAS,QAAS,WAAU,WAAU,WAAU,QAAS,WAAU,WAAU,UAAU,UAAS,WAAU,UAAS,SAAS,UAAS,WAAU,UAAS,WAAU,UAAS,WAAU,WAAU,UAAS,UAAS,WAAU,UAAS,WAAU,UAAS,WAAU,WAAU,UAAS,UAAS,WAAU,UAAS,WAAU,UAAS,WAAU,WAAU,UAAS,UAAS,WAAU,GAAE,IAAG,SAAQ,WAAU,GAAE,IAAG,UAAS,WAAU,UAAS,QAAS,WAAU,WAAU,WAAU,OAAQ,WAAU,WAAU,UAAS,UAAU,WAAU,WAAU,WAAU,SAAS,WAAU,WAAU,IAAG,IAAG,UAAS,WAAU,GAAE,IAAG,UAAS,WAAU,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,UAAS,WAAU,UAAS,WAAU,IAAG,IAAG,GAAE,IAAG,IAAG,IAAG,GAAE,IAAG,IAAG,IAA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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuE3C,IAAM;AAAA;AAAA,EAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmC1C,aAAa;AAAA,EACb,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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",
6
+ "names": ["Matrix4", "Vector3", "Vector3", "idx", "cache", "normalize", "idx", "idx", "Group", "Group", "width", "SH_C0", "SH_C0", "FIRST_PLANAR_VERSION", "_f16Buf", "_f16U32", "_f16F32", "f16ToF32", "SH_C0", "BYTES_PER_ELEMENT", "idx", "cacheKeyFor", "ClampToEdgeWrapping", "DataTexture", "FloatType", "NearestFilter", "RGBAFormat", "Sphere", "Vector2", "Vector3", "Vector4", "BufferAttribute", "Vector3", "ClampToEdgeWrapping", "DataTexture", "FloatType", "NearestFilter", "RGBAFormat", "Vector3", "BufferAttribute", "width", "DataTexture", "NearestFilter", "ClampToEdgeWrapping", "Vector4", "Vector2", "Sphere", "RGBAFormat", "FloatType", "Vector3", "idx", "Vector3", "Vector3", "Matrix4", "GLB_MAGIC", "Euler", "MathUtils", "_euler", "Euler", "MathUtils", "Color", "Vector3", "Color", "Vector3", "Color", "Color", "Color", "Vector3", "Vector3", "Color"]
7
+ }