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/README.md CHANGED
@@ -10,16 +10,17 @@ LoomLarge provides pre-built mappings that connect [Facial Action Coding System
10
10
 
11
11
  1. [Installation & Setup](#1-installation--setup)
12
12
  2. [Using Presets](#2-using-presets)
13
- 3. [Extending & Custom Presets](#3-extending--custom-presets)
14
- 4. [Action Unit Control](#4-action-unit-control)
15
- 5. [Mix Weight System](#5-mix-weight-system)
16
- 6. [Composite Rotation System](#6-composite-rotation-system)
17
- 7. [Continuum Pairs](#7-continuum-pairs)
18
- 8. [Direct Morph Control](#8-direct-morph-control)
19
- 9. [Viseme System](#9-viseme-system)
20
- 10. [Transition System](#10-transition-system)
21
- 11. [Playback & State Control](#11-playback--state-control)
22
- 12. [Hair Physics](#12-hair-physics)
13
+ 3. [Getting to Know Your Character](#3-getting-to-know-your-character)
14
+ 4. [Extending & Custom Presets](#4-extending--custom-presets)
15
+ 5. [Action Unit Control](#5-action-unit-control)
16
+ 6. [Mix Weight System](#6-mix-weight-system)
17
+ 7. [Composite Rotation System](#7-composite-rotation-system)
18
+ 8. [Continuum Pairs](#8-continuum-pairs)
19
+ 9. [Direct Morph Control](#9-direct-morph-control)
20
+ 10. [Viseme System](#10-viseme-system)
21
+ 11. [Transition System](#11-transition-system)
22
+ 12. [Playback & State Control](#12-playback--state-control)
23
+ 13. [Hair Physics](#13-hair-physics)
23
24
 
24
25
  ---
25
26
 
@@ -66,25 +67,45 @@ loader.load('/character.glb', (gltf) => {
66
67
 
67
68
  // 5. Initialize LoomLarge with the meshes and model
68
69
  loom.onReady({ meshes, model: gltf.scene });
69
-
70
- console.log(`Loaded ${meshes.length} meshes with morph targets`);
71
70
  });
72
71
 
73
- // 6. Animation loop - call loom.update() every frame
74
- let lastTime = performance.now();
75
- function animate() {
76
- requestAnimationFrame(animate);
72
+ // 6. In your animation loop, call loom.update(deltaSeconds)
73
+ // This drives all transitions and animations
74
+ ```
77
75
 
78
- const now = performance.now();
79
- const deltaSeconds = (now - lastTime) / 1000;
80
- lastTime = now;
76
+ ### Quick start examples
81
77
 
82
- // Update LoomLarge transitions
83
- loom.update(deltaSeconds);
78
+ Once your character is loaded, you can control facial expressions immediately:
84
79
 
85
- renderer.render(scene, camera);
86
- }
87
- animate();
80
+ ```typescript
81
+ // Make the character smile
82
+ loom.setAU(12, 0.8);
83
+
84
+ // Raise eyebrows
85
+ loom.setAU(1, 0.6);
86
+ loom.setAU(2, 0.6);
87
+
88
+ // Blink
89
+ loom.setAU(45, 1.0);
90
+
91
+ // Open jaw
92
+ loom.setAU(26, 0.5);
93
+
94
+ // Turn head left
95
+ loom.setAU(51, 0.4);
96
+
97
+ // Look up
98
+ loom.setAU(63, 0.6);
99
+ ```
100
+
101
+ Animate smoothly with transitions:
102
+
103
+ ```typescript
104
+ // Smile over 200ms
105
+ await loom.transitionAU(12, 0.8, 200).promise;
106
+
107
+ // Then fade back to neutral
108
+ await loom.transitionAU(12, 0, 300).promise;
88
109
  ```
89
110
 
90
111
  ### The `collectMorphMeshes` helper
@@ -178,7 +199,112 @@ const loom = new LoomLargeThree({ auMappings: CC4_PRESET });
178
199
 
179
200
  ---
180
201
 
181
- ## 3. Extending & Custom Presets
202
+ ## 3. Getting to Know Your Character
203
+
204
+ Before customizing presets or extending mappings, it's helpful to understand what's actually in your character model. LoomLarge provides several methods to inspect meshes, morph targets, and bones.
205
+
206
+ ### Listing meshes
207
+
208
+ Get all meshes in your character with their visibility and morph target counts:
209
+
210
+ ```typescript
211
+ const meshes = loom.getMeshList();
212
+ console.log(meshes);
213
+ // [
214
+ // { name: 'CC_Base_Body', visible: true, morphCount: 142 },
215
+ // { name: 'CC_Base_Tongue', visible: true, morphCount: 12 },
216
+ // { name: 'CC_Base_EyeOcclusion_L', visible: true, morphCount: 8 },
217
+ // { name: 'CC_Base_EyeOcclusion_R', visible: true, morphCount: 8 },
218
+ // { name: 'Male_Bushy_1', visible: true, morphCount: 142 },
219
+ // ...
220
+ // ]
221
+ ```
222
+
223
+ ### Listing morph targets
224
+
225
+ Get all morph target names grouped by mesh:
226
+
227
+ ```typescript
228
+ const morphs = loom.getMorphTargets();
229
+ console.log(morphs);
230
+ // {
231
+ // 'CC_Base_Body': [
232
+ // 'A01_Brow_Inner_Up', 'A02_Brow_Down_Left', 'A02_Brow_Down_Right',
233
+ // 'A04_Brow_Outer_Up_Left', 'A04_Brow_Outer_Up_Right',
234
+ // 'Mouth_Smile_L', 'Mouth_Smile_R', 'Eye_Blink_L', 'Eye_Blink_R',
235
+ // ...
236
+ // ],
237
+ // 'CC_Base_Tongue': [
238
+ // 'V_Tongue_Out', 'V_Tongue_Up', 'V_Tongue_Down', ...
239
+ // ],
240
+ // ...
241
+ // }
242
+ ```
243
+
244
+ This is invaluable when creating custom presets—you need to know the exact morph target names your character uses.
245
+
246
+ ### Listing bones
247
+
248
+ Get all resolved bones with their current positions and rotations (in degrees):
249
+
250
+ ```typescript
251
+ const bones = loom.getBones();
252
+ console.log(bones);
253
+ // {
254
+ // 'HEAD': { position: [0, 156.2, 0], rotation: [0, 0, 0] },
255
+ // 'JAW': { position: [0, 154.1, 2.3], rotation: [0, 0, 0] },
256
+ // 'EYE_L': { position: [-3.2, 160.5, 8.1], rotation: [0, 0, 0] },
257
+ // 'EYE_R': { position: [3.2, 160.5, 8.1], rotation: [0, 0, 0] },
258
+ // 'TONGUE': { position: [0, 152.3, 1.8], rotation: [0, 0, 0] },
259
+ // }
260
+ ```
261
+
262
+ ### Controlling mesh visibility
263
+
264
+ Hide or show individual meshes:
265
+
266
+ ```typescript
267
+ // Hide hair mesh
268
+ loom.setMeshVisible('Side_part_wavy_1', false);
269
+
270
+ // Show it again
271
+ loom.setMeshVisible('Side_part_wavy_1', true);
272
+ ```
273
+
274
+ ### Adjusting material properties
275
+
276
+ Fine-tune render order, transparency, and blending for each mesh:
277
+
278
+ ```typescript
279
+ // Get current material config
280
+ const config = loom.getMeshMaterialConfig('CC_Base_Body');
281
+ console.log(config);
282
+ // {
283
+ // renderOrder: 0,
284
+ // transparent: false,
285
+ // opacity: 1,
286
+ // depthWrite: true,
287
+ // depthTest: true,
288
+ // blending: 'Normal'
289
+ // }
290
+
291
+ // Set custom material config
292
+ loom.setMeshMaterialConfig('CC_Base_EyeOcclusion_L', {
293
+ renderOrder: 10,
294
+ transparent: true,
295
+ opacity: 0.8,
296
+ blending: 'Normal' // 'Normal', 'Additive', 'Subtractive', 'Multiply', 'None'
297
+ });
298
+ ```
299
+
300
+ This is especially useful for:
301
+ - Fixing render order issues (eyebrows behind hair, etc.)
302
+ - Making meshes semi-transparent for debugging
303
+ - Adjusting blending modes for special effects
304
+
305
+ ---
306
+
307
+ ## 4. Extending & Custom Presets
182
308
 
183
309
  ### Extending an existing preset
184
310
 
@@ -255,7 +381,7 @@ const current = loom.getAUMappings();
255
381
 
256
382
  ---
257
383
 
258
- ## 4. Action Unit Control
384
+ ## 5. Action Unit Control
259
385
 
260
386
  Action Units are the core of FACS. Each AU represents a specific muscular movement of the face.
261
387
 
@@ -329,7 +455,7 @@ loom.setAU(12, 0.8, 1); // Right side only
329
455
 
330
456
  ---
331
457
 
332
- ## 5. Mix Weight System
458
+ ## 6. Mix Weight System
333
459
 
334
460
  Some AUs can be driven by both morph targets (blend shapes) AND bone rotations. The mix weight controls the blend between them.
335
461
 
@@ -374,7 +500,7 @@ if (isMixedAU(26)) {
374
500
 
375
501
  ---
376
502
 
377
- ## 6. Composite Rotation System
503
+ ## 7. Composite Rotation System
378
504
 
379
505
  Bones like the head and eyes need multi-axis rotation (pitch, yaw, roll). The composite rotation system handles this automatically.
380
506
 
@@ -432,7 +558,7 @@ loom.setAU(64, 0.4);
432
558
 
433
559
  ---
434
560
 
435
- ## 7. Continuum Pairs
561
+ ## 8. Continuum Pairs
436
562
 
437
563
  Continuum pairs are bidirectional AU pairs that represent opposite directions on the same axis. They're linked so that activating one should deactivate the other.
438
564
 
@@ -478,7 +604,7 @@ const pair = CONTINUUM_PAIRS_MAP[51];
478
604
 
479
605
  ---
480
606
 
481
- ## 8. Direct Morph Control
607
+ ## 9. Direct Morph Control
482
608
 
483
609
  Sometimes you need to control morph targets directly by name, bypassing the AU system.
484
610
 
@@ -517,7 +643,7 @@ LoomLarge caches morph target lookups for performance. The first time you access
517
643
 
518
644
  ---
519
645
 
520
- ## 9. Viseme System
646
+ ## 10. Viseme System
521
647
 
522
648
  Visemes are mouth shapes used for lip-sync. LoomLarge includes 15 visemes with automatic jaw coupling.
523
649
 
@@ -602,7 +728,7 @@ speak([5, 0, 10, 4]);
602
728
 
603
729
  ---
604
730
 
605
- ## 10. Transition System
731
+ ## 11. Transition System
606
732
 
607
733
  All animated changes in LoomLarge go through the transition system, which provides smooth interpolation with easing.
608
734
 
@@ -682,7 +808,7 @@ loom.clearTransitions();
682
808
 
683
809
  ---
684
810
 
685
- ## 11. Playback & State Control
811
+ ## 12. Playback & State Control
686
812
 
687
813
  ### Pausing and resuming
688
814
 
@@ -737,7 +863,7 @@ loom.dispose();
737
863
 
738
864
  ---
739
865
 
740
- ## 12. Hair Physics
866
+ ## 13. Hair Physics
741
867
 
742
868
  LoomLarge includes an experimental hair physics system that simulates hair movement based on head motion.
743
869