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 +160 -34
- package/dist/index.cjs +436 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +150 -1
- package/dist/index.d.ts +150 -1
- package/dist/index.js +422 -50
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
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. [
|
|
14
|
-
4. [
|
|
15
|
-
5. [
|
|
16
|
-
6. [
|
|
17
|
-
7. [
|
|
18
|
-
8. [
|
|
19
|
-
9. [
|
|
20
|
-
10. [
|
|
21
|
-
11. [
|
|
22
|
-
12. [
|
|
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.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
requestAnimationFrame(animate);
|
|
72
|
+
// 6. In your animation loop, call loom.update(deltaSeconds)
|
|
73
|
+
// This drives all transitions and animations
|
|
74
|
+
```
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
const deltaSeconds = (now - lastTime) / 1000;
|
|
80
|
-
lastTime = now;
|
|
76
|
+
### Quick start examples
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
loom.update(deltaSeconds);
|
|
78
|
+
Once your character is loaded, you can control facial expressions immediately:
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
|