loomlarge 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -36,6 +36,38 @@ interface AUMappingConfig {
36
36
  * Helper type for mesh categories in morphToMesh
37
37
  */
38
38
  type MorphCategory = 'face' | 'viseme' | 'eye' | 'tearLine' | 'tongue' | 'hair';
39
+ /**
40
+ * Mesh category types for character mesh classification
41
+ */
42
+ type MeshCategory = 'body' | 'eye' | 'eyeOcclusion' | 'tearLine' | 'teeth' | 'tongue' | 'hair' | 'eyebrow' | 'cornea' | 'eyelash';
43
+ /**
44
+ * Blending mode names (matches Three.js constants)
45
+ */
46
+ type BlendingMode = 'Normal' | 'Additive' | 'Subtractive' | 'Multiply' | 'None';
47
+ /**
48
+ * Blending mode options for Three.js materials
49
+ * Maps mode name to Three.js blending constant value
50
+ */
51
+ declare const BLENDING_MODES: Record<BlendingMode, number>;
52
+ /**
53
+ * Material settings for mesh rendering
54
+ */
55
+ interface MeshMaterialSettings {
56
+ renderOrder?: number;
57
+ transparent?: boolean;
58
+ opacity?: number;
59
+ depthWrite?: boolean;
60
+ depthTest?: boolean;
61
+ blending?: BlendingMode;
62
+ }
63
+ /**
64
+ * Mesh info including category, morph count, and optional material settings
65
+ */
66
+ interface MeshInfo$1 {
67
+ category: MeshCategory;
68
+ morphCount: number;
69
+ material?: MeshMaterialSettings;
70
+ }
39
71
 
40
72
  /**
41
73
  * LoomLarge - Core Type Definitions
@@ -68,6 +100,8 @@ interface BoneBinding {
68
100
  scale: -1 | 1;
69
101
  maxDegrees?: number;
70
102
  maxUnits?: number;
103
+ /** Rotation axis this binding affects (pitch/yaw/roll). Required for rotation channels. */
104
+ axis?: 'pitch' | 'yaw' | 'roll';
71
105
  }
72
106
  /**
73
107
  * RotationAxis - Defines which AUs control a specific rotation axis
@@ -203,10 +237,21 @@ interface LoomLarge {
203
237
  onReady(payload: ReadyPayload): void;
204
238
  /**
205
239
  * Update animation state. Call each frame with delta time in seconds.
240
+ * If using start(), this is called automatically.
206
241
  */
207
242
  update(deltaSeconds: number): void;
243
+ /**
244
+ * Start the internal animation loop (RAF-based).
245
+ * Automatically calls update() each frame with delta time.
246
+ */
247
+ start(): void;
248
+ /**
249
+ * Stop the internal animation loop.
250
+ */
251
+ stop(): void;
208
252
  /**
209
253
  * Dispose engine resources and cleanup.
254
+ * Stops the animation loop and clears all transitions.
210
255
  */
211
256
  dispose(): void;
212
257
  /**
@@ -369,16 +414,43 @@ declare class LoomLargeThree implements LoomLarge {
369
414
  private bones;
370
415
  private mixWeights;
371
416
  private visemeValues;
417
+ private clock;
418
+ private rafId;
419
+ private running;
372
420
  private static readonly VISEME_JAW_AMOUNTS;
373
421
  private static readonly JAW_MAX_DEGREES;
374
422
  constructor(config?: LoomLargeConfig, animation?: Animation);
375
423
  onReady(payload: ReadyPayload): void;
376
424
  update(deltaSeconds: number): void;
425
+ /** Start the internal RAF loop */
426
+ start(): void;
427
+ /** Stop the internal RAF loop */
428
+ stop(): void;
377
429
  dispose(): void;
378
430
  setAU(id: number | string, v: number, balance?: number): void;
379
431
  transitionAU(id: number | string, to: number, durationMs?: number, balance?: number): TransitionHandle;
380
432
  getAU(id: number): number;
433
+ /**
434
+ * Set a morph target value.
435
+ *
436
+ * Fast paths (in order of speed):
437
+ * 1. Pass pre-resolved { infl, idx } array directly - zero lookups
438
+ * 2. String key with cache hit - one Map lookup
439
+ * 3. String key cache miss - dictionary lookup, then cached for next time
440
+ */
381
441
  setMorph(key: string, v: number, meshNames?: string[]): void;
442
+ setMorph(key: string, v: number, targets: {
443
+ infl: number[];
444
+ idx: number;
445
+ }[]): void;
446
+ /**
447
+ * Resolve morph key to direct targets for ultra-fast repeated access.
448
+ * Use this when you need to set the same morph many times (e.g., in animation loops).
449
+ */
450
+ resolveMorphTargets(key: string, meshNames?: string[]): {
451
+ infl: number[];
452
+ idx: number;
453
+ }[];
382
454
  transitionMorph(key: string, to: number, durationMs?: number, meshNames?: string[]): TransitionHandle;
383
455
  setViseme(visemeIndex: number, value: number, jawScale?: number): void;
384
456
  transitionViseme(visemeIndex: number, to: number, durationMs?: number, jawScale?: number): TransitionHandle;
@@ -391,7 +463,34 @@ declare class LoomLargeThree implements LoomLarge {
391
463
  getActiveTransitionCount(): number;
392
464
  resetToNeutral(): void;
393
465
  getMeshList(): MeshInfo[];
466
+ /** Get all morph targets grouped by mesh name */
467
+ getMorphTargets(): Record<string, string[]>;
468
+ /** Get all resolved bone names and their current transforms */
469
+ getBones(): Record<string, {
470
+ position: [number, number, number];
471
+ rotation: [number, number, number];
472
+ }>;
394
473
  setMeshVisible(meshName: string, visible: boolean): void;
474
+ /** Blending mode options for Three.js materials */
475
+ private static readonly BLENDING_MODES;
476
+ /** Get material config for a mesh */
477
+ getMeshMaterialConfig(meshName: string): {
478
+ renderOrder: number;
479
+ transparent: boolean;
480
+ opacity: number;
481
+ depthWrite: boolean;
482
+ depthTest: boolean;
483
+ blending: string;
484
+ } | null;
485
+ /** Set material config for a mesh */
486
+ setMeshMaterialConfig(meshName: string, config: {
487
+ renderOrder?: number;
488
+ transparent?: boolean;
489
+ opacity?: number;
490
+ depthWrite?: boolean;
491
+ depthTest?: boolean;
492
+ blending?: string;
493
+ }): void;
395
494
  setAUMappings(mappings: AUMappingConfig): void;
396
495
  getAUMappings(): AUMappingConfig;
397
496
  private computeSideValues;
@@ -407,6 +506,11 @@ declare class LoomLargeThree implements LoomLarge {
407
506
  private applyCompositeRotation;
408
507
  private resolveBones;
409
508
  private combineHandles;
509
+ /**
510
+ * Apply render order and material settings from CC4_MESHES to all meshes.
511
+ * This ensures proper layering (e.g., hair renders on top of eyebrows).
512
+ */
513
+ private applyMeshMaterialSettings;
410
514
  }
411
515
  /**
412
516
  * Helper function to collect meshes with morph targets from a scene.
@@ -539,6 +643,51 @@ interface HairPhysics$1 {
539
643
  * and AU metadata that we painstakingly worked through.
540
644
  */
541
645
 
646
+ declare const AU_TO_MORPHS: Record<number, string[]>;
647
+ declare const VISEME_KEYS: string[];
648
+ declare const BONE_AU_TO_BINDINGS: Record<number, BoneBinding[]>;
649
+ /** Check if an AU has both morphs and bones (can blend between them) */
650
+ declare const isMixedAU: (id: number) => boolean;
651
+ /** Check if an AU has separate left/right morphs */
652
+ declare const hasLeftRightMorphs: (auId: number) => boolean;
653
+ declare const COMPOSITE_ROTATIONS: CompositeRotation[];
654
+ /**
655
+ * Continuum pair mappings - precomputed from COMPOSITE_ROTATIONS
656
+ * Maps AU ID to its continuum partner info for bidirectional axes
657
+ * (e.g., AU 51 "Head Left" is paired with AU 52 "Head Right")
658
+ */
659
+ declare const CONTINUUM_PAIRS_MAP: Record<number, {
660
+ pairId: number;
661
+ isNegative: boolean;
662
+ axis: 'pitch' | 'yaw' | 'roll';
663
+ node: 'JAW' | 'HEAD' | 'EYE_L' | 'EYE_R' | 'TONGUE';
664
+ }>;
665
+ /**
666
+ * Human-readable labels for continuum pairs
667
+ * Key format: "negativeAU-positiveAU"
668
+ * Used by UI components (ContinuumSlider, AUSection) to display friendly axis names
669
+ */
670
+ declare const CONTINUUM_LABELS: Record<string, string>;
671
+ declare const CC4_BONE_NODES: {
672
+ readonly EYE_L: "CC_Base_L_Eye";
673
+ readonly EYE_R: "CC_Base_R_Eye";
674
+ readonly HEAD: "CC_Base_Head";
675
+ readonly NECK: "CC_Base_NeckTwist01";
676
+ readonly NECK_TWIST: "CC_Base_NeckTwist02";
677
+ readonly JAW: "CC_Base_JawRoot";
678
+ readonly TONGUE: "CC_Base_Tongue01";
679
+ };
680
+ declare const CC4_EYE_MESH_NODES: {
681
+ readonly LEFT: "CC_Base_Eye";
682
+ readonly RIGHT: "CC_Base_Eye_1";
683
+ };
684
+ declare const AU_INFO: Record<string, AUInfo>;
685
+ /** Default mix weights (0 = morph only, 1 = bone only) */
686
+ declare const AU_MIX_DEFAULTS: Record<number, number>;
687
+ /** Exact mesh name -> category mapping from the character GLB */
688
+ declare const CC4_MESHES: Record<string, MeshInfo$1>;
689
+ /** Which mesh each morph category applies to */
690
+ declare const MORPH_TO_MESH: Record<MorphCategory, string[]>;
542
691
  declare const CC4_PRESET: AUMappingConfig;
543
692
 
544
693
  /**
@@ -628,4 +777,4 @@ declare class HairPhysics {
628
777
  reset(): void;
629
778
  }
630
779
 
631
- export { type AUInfo, type AUMappingConfig, type Animation, AnimationThree, type BoneBinding, type BoneKey, CC4_PRESET, type CompositeRotation, type CompositeRotationState, DEFAULT_HAIR_PHYSICS_CONFIG, type HairMorphOutput$1 as HairMorphOutput, HairPhysics, type HairPhysicsConfig$1 as HairPhysicsConfig, type HairPhysics$1 as HairPhysicsInterface, type HairMorphOutput as HairPhysicsMorphOutput, type HairPhysicsState, type HairState, type HairStrand, type HeadState$1 as HeadState, type LoomEuler, type LoomLarge, type LoomLargeConfig, LoomLargeThree, type LoomMesh, type LoomObject3D, type LoomQuaternion, type LoomVector3, type MeshInfo, type MorphCategory, type ReadyPayload, type RotationAxis, type RotationAxisState, type RotationsState, type TransitionHandle, collectMorphMeshes, LoomLargeThree as default };
780
+ export { type AUInfo, type AUMappingConfig, AU_INFO, AU_MIX_DEFAULTS, AU_TO_MORPHS, type Animation, AnimationThree, BLENDING_MODES, BONE_AU_TO_BINDINGS, type BlendingMode, type BoneBinding, type BoneKey, CC4_BONE_NODES, CC4_EYE_MESH_NODES, CC4_MESHES, CC4_PRESET, COMPOSITE_ROTATIONS, CONTINUUM_LABELS, CONTINUUM_PAIRS_MAP, type CompositeRotation, type CompositeRotationState, DEFAULT_HAIR_PHYSICS_CONFIG, type HairMorphOutput$1 as HairMorphOutput, HairPhysics, type HairPhysicsConfig$1 as HairPhysicsConfig, type HairPhysics$1 as HairPhysicsInterface, type HairMorphOutput as HairPhysicsMorphOutput, type HairPhysicsState, type HairState, type HairStrand, type HeadState$1 as HeadState, type LoomEuler, type LoomLarge, type LoomLargeConfig, LoomLargeThree, type LoomMesh, type LoomObject3D, type LoomQuaternion, type LoomVector3, MORPH_TO_MESH, type MeshCategory, type MeshInfo, type MeshInfo$1 as MeshMaterialInfo, type MeshMaterialSettings, type MorphCategory, type ReadyPayload, type RotationAxis, type RotationAxisState, type RotationsState, type TransitionHandle, VISEME_KEYS, collectMorphMeshes, LoomLargeThree as default, hasLeftRightMorphs, isMixedAU };
package/dist/index.d.ts CHANGED
@@ -36,6 +36,38 @@ interface AUMappingConfig {
36
36
  * Helper type for mesh categories in morphToMesh
37
37
  */
38
38
  type MorphCategory = 'face' | 'viseme' | 'eye' | 'tearLine' | 'tongue' | 'hair';
39
+ /**
40
+ * Mesh category types for character mesh classification
41
+ */
42
+ type MeshCategory = 'body' | 'eye' | 'eyeOcclusion' | 'tearLine' | 'teeth' | 'tongue' | 'hair' | 'eyebrow' | 'cornea' | 'eyelash';
43
+ /**
44
+ * Blending mode names (matches Three.js constants)
45
+ */
46
+ type BlendingMode = 'Normal' | 'Additive' | 'Subtractive' | 'Multiply' | 'None';
47
+ /**
48
+ * Blending mode options for Three.js materials
49
+ * Maps mode name to Three.js blending constant value
50
+ */
51
+ declare const BLENDING_MODES: Record<BlendingMode, number>;
52
+ /**
53
+ * Material settings for mesh rendering
54
+ */
55
+ interface MeshMaterialSettings {
56
+ renderOrder?: number;
57
+ transparent?: boolean;
58
+ opacity?: number;
59
+ depthWrite?: boolean;
60
+ depthTest?: boolean;
61
+ blending?: BlendingMode;
62
+ }
63
+ /**
64
+ * Mesh info including category, morph count, and optional material settings
65
+ */
66
+ interface MeshInfo$1 {
67
+ category: MeshCategory;
68
+ morphCount: number;
69
+ material?: MeshMaterialSettings;
70
+ }
39
71
 
40
72
  /**
41
73
  * LoomLarge - Core Type Definitions
@@ -68,6 +100,8 @@ interface BoneBinding {
68
100
  scale: -1 | 1;
69
101
  maxDegrees?: number;
70
102
  maxUnits?: number;
103
+ /** Rotation axis this binding affects (pitch/yaw/roll). Required for rotation channels. */
104
+ axis?: 'pitch' | 'yaw' | 'roll';
71
105
  }
72
106
  /**
73
107
  * RotationAxis - Defines which AUs control a specific rotation axis
@@ -203,10 +237,21 @@ interface LoomLarge {
203
237
  onReady(payload: ReadyPayload): void;
204
238
  /**
205
239
  * Update animation state. Call each frame with delta time in seconds.
240
+ * If using start(), this is called automatically.
206
241
  */
207
242
  update(deltaSeconds: number): void;
243
+ /**
244
+ * Start the internal animation loop (RAF-based).
245
+ * Automatically calls update() each frame with delta time.
246
+ */
247
+ start(): void;
248
+ /**
249
+ * Stop the internal animation loop.
250
+ */
251
+ stop(): void;
208
252
  /**
209
253
  * Dispose engine resources and cleanup.
254
+ * Stops the animation loop and clears all transitions.
210
255
  */
211
256
  dispose(): void;
212
257
  /**
@@ -369,16 +414,43 @@ declare class LoomLargeThree implements LoomLarge {
369
414
  private bones;
370
415
  private mixWeights;
371
416
  private visemeValues;
417
+ private clock;
418
+ private rafId;
419
+ private running;
372
420
  private static readonly VISEME_JAW_AMOUNTS;
373
421
  private static readonly JAW_MAX_DEGREES;
374
422
  constructor(config?: LoomLargeConfig, animation?: Animation);
375
423
  onReady(payload: ReadyPayload): void;
376
424
  update(deltaSeconds: number): void;
425
+ /** Start the internal RAF loop */
426
+ start(): void;
427
+ /** Stop the internal RAF loop */
428
+ stop(): void;
377
429
  dispose(): void;
378
430
  setAU(id: number | string, v: number, balance?: number): void;
379
431
  transitionAU(id: number | string, to: number, durationMs?: number, balance?: number): TransitionHandle;
380
432
  getAU(id: number): number;
433
+ /**
434
+ * Set a morph target value.
435
+ *
436
+ * Fast paths (in order of speed):
437
+ * 1. Pass pre-resolved { infl, idx } array directly - zero lookups
438
+ * 2. String key with cache hit - one Map lookup
439
+ * 3. String key cache miss - dictionary lookup, then cached for next time
440
+ */
381
441
  setMorph(key: string, v: number, meshNames?: string[]): void;
442
+ setMorph(key: string, v: number, targets: {
443
+ infl: number[];
444
+ idx: number;
445
+ }[]): void;
446
+ /**
447
+ * Resolve morph key to direct targets for ultra-fast repeated access.
448
+ * Use this when you need to set the same morph many times (e.g., in animation loops).
449
+ */
450
+ resolveMorphTargets(key: string, meshNames?: string[]): {
451
+ infl: number[];
452
+ idx: number;
453
+ }[];
382
454
  transitionMorph(key: string, to: number, durationMs?: number, meshNames?: string[]): TransitionHandle;
383
455
  setViseme(visemeIndex: number, value: number, jawScale?: number): void;
384
456
  transitionViseme(visemeIndex: number, to: number, durationMs?: number, jawScale?: number): TransitionHandle;
@@ -391,7 +463,34 @@ declare class LoomLargeThree implements LoomLarge {
391
463
  getActiveTransitionCount(): number;
392
464
  resetToNeutral(): void;
393
465
  getMeshList(): MeshInfo[];
466
+ /** Get all morph targets grouped by mesh name */
467
+ getMorphTargets(): Record<string, string[]>;
468
+ /** Get all resolved bone names and their current transforms */
469
+ getBones(): Record<string, {
470
+ position: [number, number, number];
471
+ rotation: [number, number, number];
472
+ }>;
394
473
  setMeshVisible(meshName: string, visible: boolean): void;
474
+ /** Blending mode options for Three.js materials */
475
+ private static readonly BLENDING_MODES;
476
+ /** Get material config for a mesh */
477
+ getMeshMaterialConfig(meshName: string): {
478
+ renderOrder: number;
479
+ transparent: boolean;
480
+ opacity: number;
481
+ depthWrite: boolean;
482
+ depthTest: boolean;
483
+ blending: string;
484
+ } | null;
485
+ /** Set material config for a mesh */
486
+ setMeshMaterialConfig(meshName: string, config: {
487
+ renderOrder?: number;
488
+ transparent?: boolean;
489
+ opacity?: number;
490
+ depthWrite?: boolean;
491
+ depthTest?: boolean;
492
+ blending?: string;
493
+ }): void;
395
494
  setAUMappings(mappings: AUMappingConfig): void;
396
495
  getAUMappings(): AUMappingConfig;
397
496
  private computeSideValues;
@@ -407,6 +506,11 @@ declare class LoomLargeThree implements LoomLarge {
407
506
  private applyCompositeRotation;
408
507
  private resolveBones;
409
508
  private combineHandles;
509
+ /**
510
+ * Apply render order and material settings from CC4_MESHES to all meshes.
511
+ * This ensures proper layering (e.g., hair renders on top of eyebrows).
512
+ */
513
+ private applyMeshMaterialSettings;
410
514
  }
411
515
  /**
412
516
  * Helper function to collect meshes with morph targets from a scene.
@@ -539,6 +643,51 @@ interface HairPhysics$1 {
539
643
  * and AU metadata that we painstakingly worked through.
540
644
  */
541
645
 
646
+ declare const AU_TO_MORPHS: Record<number, string[]>;
647
+ declare const VISEME_KEYS: string[];
648
+ declare const BONE_AU_TO_BINDINGS: Record<number, BoneBinding[]>;
649
+ /** Check if an AU has both morphs and bones (can blend between them) */
650
+ declare const isMixedAU: (id: number) => boolean;
651
+ /** Check if an AU has separate left/right morphs */
652
+ declare const hasLeftRightMorphs: (auId: number) => boolean;
653
+ declare const COMPOSITE_ROTATIONS: CompositeRotation[];
654
+ /**
655
+ * Continuum pair mappings - precomputed from COMPOSITE_ROTATIONS
656
+ * Maps AU ID to its continuum partner info for bidirectional axes
657
+ * (e.g., AU 51 "Head Left" is paired with AU 52 "Head Right")
658
+ */
659
+ declare const CONTINUUM_PAIRS_MAP: Record<number, {
660
+ pairId: number;
661
+ isNegative: boolean;
662
+ axis: 'pitch' | 'yaw' | 'roll';
663
+ node: 'JAW' | 'HEAD' | 'EYE_L' | 'EYE_R' | 'TONGUE';
664
+ }>;
665
+ /**
666
+ * Human-readable labels for continuum pairs
667
+ * Key format: "negativeAU-positiveAU"
668
+ * Used by UI components (ContinuumSlider, AUSection) to display friendly axis names
669
+ */
670
+ declare const CONTINUUM_LABELS: Record<string, string>;
671
+ declare const CC4_BONE_NODES: {
672
+ readonly EYE_L: "CC_Base_L_Eye";
673
+ readonly EYE_R: "CC_Base_R_Eye";
674
+ readonly HEAD: "CC_Base_Head";
675
+ readonly NECK: "CC_Base_NeckTwist01";
676
+ readonly NECK_TWIST: "CC_Base_NeckTwist02";
677
+ readonly JAW: "CC_Base_JawRoot";
678
+ readonly TONGUE: "CC_Base_Tongue01";
679
+ };
680
+ declare const CC4_EYE_MESH_NODES: {
681
+ readonly LEFT: "CC_Base_Eye";
682
+ readonly RIGHT: "CC_Base_Eye_1";
683
+ };
684
+ declare const AU_INFO: Record<string, AUInfo>;
685
+ /** Default mix weights (0 = morph only, 1 = bone only) */
686
+ declare const AU_MIX_DEFAULTS: Record<number, number>;
687
+ /** Exact mesh name -> category mapping from the character GLB */
688
+ declare const CC4_MESHES: Record<string, MeshInfo$1>;
689
+ /** Which mesh each morph category applies to */
690
+ declare const MORPH_TO_MESH: Record<MorphCategory, string[]>;
542
691
  declare const CC4_PRESET: AUMappingConfig;
543
692
 
544
693
  /**
@@ -628,4 +777,4 @@ declare class HairPhysics {
628
777
  reset(): void;
629
778
  }
630
779
 
631
- export { type AUInfo, type AUMappingConfig, type Animation, AnimationThree, type BoneBinding, type BoneKey, CC4_PRESET, type CompositeRotation, type CompositeRotationState, DEFAULT_HAIR_PHYSICS_CONFIG, type HairMorphOutput$1 as HairMorphOutput, HairPhysics, type HairPhysicsConfig$1 as HairPhysicsConfig, type HairPhysics$1 as HairPhysicsInterface, type HairMorphOutput as HairPhysicsMorphOutput, type HairPhysicsState, type HairState, type HairStrand, type HeadState$1 as HeadState, type LoomEuler, type LoomLarge, type LoomLargeConfig, LoomLargeThree, type LoomMesh, type LoomObject3D, type LoomQuaternion, type LoomVector3, type MeshInfo, type MorphCategory, type ReadyPayload, type RotationAxis, type RotationAxisState, type RotationsState, type TransitionHandle, collectMorphMeshes, LoomLargeThree as default };
780
+ export { type AUInfo, type AUMappingConfig, AU_INFO, AU_MIX_DEFAULTS, AU_TO_MORPHS, type Animation, AnimationThree, BLENDING_MODES, BONE_AU_TO_BINDINGS, type BlendingMode, type BoneBinding, type BoneKey, CC4_BONE_NODES, CC4_EYE_MESH_NODES, CC4_MESHES, CC4_PRESET, COMPOSITE_ROTATIONS, CONTINUUM_LABELS, CONTINUUM_PAIRS_MAP, type CompositeRotation, type CompositeRotationState, DEFAULT_HAIR_PHYSICS_CONFIG, type HairMorphOutput$1 as HairMorphOutput, HairPhysics, type HairPhysicsConfig$1 as HairPhysicsConfig, type HairPhysics$1 as HairPhysicsInterface, type HairMorphOutput as HairPhysicsMorphOutput, type HairPhysicsState, type HairState, type HairStrand, type HeadState$1 as HeadState, type LoomEuler, type LoomLarge, type LoomLargeConfig, LoomLargeThree, type LoomMesh, type LoomObject3D, type LoomQuaternion, type LoomVector3, MORPH_TO_MESH, type MeshCategory, type MeshInfo, type MeshInfo$1 as MeshMaterialInfo, type MeshMaterialSettings, type MorphCategory, type ReadyPayload, type RotationAxis, type RotationAxisState, type RotationsState, type TransitionHandle, VISEME_KEYS, collectMorphMeshes, LoomLargeThree as default, hasLeftRightMorphs, isMixedAU };