@lovelace_lol/embody 0.0.6 → 0.0.8

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 (127) hide show
  1. package/README.md +541 -2394
  2. package/dist/index.d.ts +2 -100
  3. package/dist/index.js +7714 -12951
  4. package/dist/index.js.map +1 -1
  5. package/dist/three/annotations/DOMControls.d.ts +73 -0
  6. package/dist/three/annotations/DPthree.d.ts +113 -0
  7. package/dist/three/annotations/DPthree3DMarkers.d.ts +319 -0
  8. package/dist/three/annotations/DPthreeCameraController.d.ts +414 -0
  9. package/dist/three/annotations/DPthreeHTMLMarkers.d.ts +131 -0
  10. package/dist/three/annotations/DPthreeMarkers.d.ts +52 -0
  11. package/dist/three/annotations/adapter.d.ts +157 -0
  12. package/dist/three/annotations/animationFrameTaskScheduler.d.ts +18 -0
  13. package/dist/three/annotations/annotationAnchorModel.d.ts +16 -0
  14. package/dist/three/annotations/annotationCameraCore.d.ts +5 -0
  15. package/dist/three/annotations/boneResolutionProfile.d.ts +7 -0
  16. package/dist/three/annotations/index.d.ts +20 -0
  17. package/dist/three/annotations/loadFrame.d.ts +2 -0
  18. package/dist/three/annotations/markerSurfaceRaycast.d.ts +11 -0
  19. package/dist/three/annotations/markerVisibilityLifecycle.d.ts +21 -0
  20. package/dist/three/annotations/modelRenderPreparation.d.ts +6 -0
  21. package/dist/three/annotations/runtimeAnnotationPreview.d.ts +15 -0
  22. package/dist/three/annotations/runtimeAnnotationPreviewSide.d.ts +10 -0
  23. package/dist/three/annotations/runtimeAnnotationSidePreview.d.ts +5 -0
  24. package/dist/three/annotations/types.d.ts +262 -0
  25. package/dist/three/gaze.d.ts +122 -0
  26. package/dist/three/index.d.ts +147 -0
  27. package/dist/three/model.d.ts +31 -0
  28. package/dist/three/modelSkinning.d.ts +3 -0
  29. package/dist/three/reference-pose.d.ts +73 -0
  30. package/dist/three/scene.d.ts +253 -0
  31. package/dist/three/sceneRenderingBinding.d.ts +22 -0
  32. package/dist/three.js +7696 -8936
  33. package/dist/three.js.map +1 -1
  34. package/dist/wasm/README.md +551 -62
  35. package/dist/wasm/auto.d.ts +1 -0
  36. package/dist/wasm/embody_wasm.d.ts +388 -52
  37. package/dist/wasm/embody_wasm.js +1514 -119
  38. package/dist/wasm/embody_wasm_bg.wasm +0 -0
  39. package/dist/wasm/embody_wasm_bg.wasm.d.ts +115 -40
  40. package/dist/wasm/index.d.ts +126 -0
  41. package/dist/wasm.d.ts +1 -43
  42. package/dist/wasm.js +1043 -239
  43. package/dist/wasm.js.map +1 -1
  44. package/package.json +34 -39
  45. package/service-worker/character-asset-service-worker.js +295 -0
  46. package/dist/authoring/boneAuthoring.d.ts +0 -132
  47. package/dist/camera/annotationCameraAngles.d.ts +0 -28
  48. package/dist/camera/cameraRelativeGaze.d.ts +0 -15
  49. package/dist/camera/rustAnnotationCameraCore.d.ts +0 -136
  50. package/dist/cljs.cjs +0 -362
  51. package/dist/cljs.cjs.map +0 -1
  52. package/dist/cljs.d.ts +0 -5
  53. package/dist/cljs.js +0 -359
  54. package/dist/cljs.js.map +0 -1
  55. package/dist/core/TsClipCompiler.d.ts +0 -51
  56. package/dist/core/WasmRuntimeCore.d.ts +0 -41
  57. package/dist/core/compositeAxis.d.ts +0 -4
  58. package/dist/core/contracts/abi.d.ts +0 -70
  59. package/dist/core/contracts/clip.d.ts +0 -44
  60. package/dist/core/contracts/frame.d.ts +0 -27
  61. package/dist/core/contracts/host.d.ts +0 -28
  62. package/dist/core/contracts/ids.d.ts +0 -15
  63. package/dist/core/contracts/index.d.ts +0 -10
  64. package/dist/core/contracts/model.d.ts +0 -31
  65. package/dist/core/contracts/primitives.d.ts +0 -17
  66. package/dist/core/contracts/skeletonFit.d.ts +0 -41
  67. package/dist/core/index.d.ts +0 -6
  68. package/dist/core/types.d.ts +0 -472
  69. package/dist/core.cjs +0 -343
  70. package/dist/core.cjs.map +0 -1
  71. package/dist/core.js +0 -323
  72. package/dist/core.js.map +0 -1
  73. package/dist/engines/three/Embody.d.ts +0 -372
  74. package/dist/engines/three/ThreeAnimationRuntime.d.ts +0 -203
  75. package/dist/engines/three/ThreeClipAdapter.d.ts +0 -24
  76. package/dist/engines/three/ThreeFrameApplier.d.ts +0 -68
  77. package/dist/engines/three/ThreeModelInspector.d.ts +0 -54
  78. package/dist/engines/three/bakedClipPartitioning.d.ts +0 -16
  79. package/dist/engines/three/balanceUtils.d.ts +0 -3
  80. package/dist/engines/three/characterHost.d.ts +0 -80
  81. package/dist/engines/three/characterScene.d.ts +0 -98
  82. package/dist/engines/three/hair/HairPhysicsController.d.ts +0 -124
  83. package/dist/engines/three/index.d.ts +0 -20
  84. package/dist/engines/three/modelLoader.d.ts +0 -61
  85. package/dist/engines/three/profileTestScene.d.ts +0 -52
  86. package/dist/engines/three/types.d.ts +0 -20
  87. package/dist/hair/appearance.d.ts +0 -29
  88. package/dist/index.cjs +0 -14871
  89. package/dist/index.cjs.map +0 -1
  90. package/dist/interfaces/Animation.d.ts +0 -315
  91. package/dist/interfaces/EmbodyRuntime.d.ts +0 -90
  92. package/dist/interfaces/Hair.d.ts +0 -181
  93. package/dist/interfaces/HairPhysics.d.ts +0 -90
  94. package/dist/interfaces/index.d.ts +0 -11
  95. package/dist/mappings/extendPresetWithProfile.d.ts +0 -17
  96. package/dist/mappings/types.d.ts +0 -309
  97. package/dist/mappings/visemeSystem.d.ts +0 -26
  98. package/dist/physics/HairPhysics.d.ts +0 -86
  99. package/dist/physics/RustHairPhysics.d.ts +0 -18
  100. package/dist/physics/index.d.ts +0 -6
  101. package/dist/preset.cjs +0 -2005
  102. package/dist/preset.cjs.map +0 -1
  103. package/dist/preset.js +0 -2003
  104. package/dist/preset.js.map +0 -1
  105. package/dist/presets/bettaFish.d.ts +0 -328
  106. package/dist/presets/cc4.d.ts +0 -145
  107. package/dist/presets/index.d.ts +0 -30
  108. package/dist/presets/registry.d.ts +0 -57
  109. package/dist/profiles/resolveProfileConfig.d.ts +0 -36
  110. package/dist/profiles/rustResolvedProfile.d.ts +0 -31
  111. package/dist/profiles/types.d.ts +0 -118
  112. package/dist/regions/normalizeRegionTree.d.ts +0 -6
  113. package/dist/regions/regionMapping.d.ts +0 -17
  114. package/dist/regions/types.d.ts +0 -122
  115. package/dist/skeletonTemplates/humanoidSkeletonTemplates.d.ts +0 -32
  116. package/dist/test/setupWasm.d.ts +0 -1
  117. package/dist/three.cjs +0 -9550
  118. package/dist/three.cjs.map +0 -1
  119. package/dist/validation/analyzeModel.d.ts +0 -68
  120. package/dist/validation/extractModelData.d.ts +0 -90
  121. package/dist/validation/generateMappingCorrections.d.ts +0 -32
  122. package/dist/validation/geometryHelpers.d.ts +0 -66
  123. package/dist/validation/types.d.ts +0 -10
  124. package/dist/validation/validateMappings.d.ts +0 -77
  125. package/dist/wasm.cjs +0 -302
  126. package/dist/wasm.cjs.map +0 -1
  127. package/dist/wasmTypes.d.ts +0 -123
package/dist/preset.js DELETED
@@ -1,2003 +0,0 @@
1
- // src/presets/cc4.ts
2
- var AU_TO_MORPHS = {
3
- 1: {
4
- left: ["Brow_Raise_Inner_L"],
5
- right: ["Brow_Raise_Inner_R"],
6
- center: []
7
- },
8
- 2: {
9
- left: ["Brow_Raise_Outer_L"],
10
- right: ["Brow_Raise_Outer_R"],
11
- center: []
12
- },
13
- 4: {
14
- left: ["Brow_Drop_L"],
15
- right: ["Brow_Drop_R"],
16
- center: []
17
- },
18
- 5: {
19
- left: ["Eye_Wide_L"],
20
- right: ["Eye_Wide_R"],
21
- center: []
22
- },
23
- 6: {
24
- left: ["Cheek_Raise_L"],
25
- right: ["Cheek_Raise_R"],
26
- center: []
27
- },
28
- 7: {
29
- left: ["Eye_Squint_L"],
30
- right: ["Eye_Squint_R"],
31
- center: []
32
- },
33
- 8: {
34
- left: ["Mouth_Press_L"],
35
- right: ["Mouth_Press_R"],
36
- center: ["Mouth_Close"]
37
- },
38
- 9: {
39
- left: ["Nose_Sneer_L"],
40
- right: ["Nose_Sneer_R"],
41
- center: []
42
- },
43
- 10: {
44
- left: ["Mouth_Up_Upper_L"],
45
- right: ["Mouth_Up_Upper_R"],
46
- center: []
47
- },
48
- 11: {
49
- left: ["Mouth_Up_Upper_L"],
50
- right: ["Mouth_Up_Upper_R"],
51
- center: []
52
- },
53
- 12: {
54
- left: ["Mouth_Smile_L"],
55
- right: ["Mouth_Smile_R"],
56
- center: []
57
- },
58
- 13: {
59
- left: ["Mouth_Smile_L", "Mouth_Up_Upper_L"],
60
- right: ["Mouth_Smile_R", "Mouth_Up_Upper_R"],
61
- center: []
62
- },
63
- 14: {
64
- left: ["Mouth_Dimple_L"],
65
- right: ["Mouth_Dimple_R"],
66
- center: []
67
- },
68
- 15: {
69
- left: ["Mouth_Frown_L"],
70
- right: ["Mouth_Frown_R"],
71
- center: []
72
- },
73
- 16: {
74
- left: ["Mouth_Down_Lower_L"],
75
- right: ["Mouth_Down_Lower_R"],
76
- center: []
77
- },
78
- 17: {
79
- left: [],
80
- right: [],
81
- center: ["Mouth_Shrug_Lower"]
82
- },
83
- 18: {
84
- left: [],
85
- right: [],
86
- center: ["Mouth_Pucker"]
87
- },
88
- 19: {
89
- left: [],
90
- right: [],
91
- center: ["Tongue_Out"]
92
- },
93
- 20: {
94
- left: ["Mouth_Stretch_L"],
95
- right: ["Mouth_Stretch_R"],
96
- center: []
97
- },
98
- 22: {
99
- left: [],
100
- right: [],
101
- center: ["Mouth_Funnel"]
102
- },
103
- 23: {
104
- left: ["Mouth_Press_L"],
105
- right: ["Mouth_Press_R"],
106
- center: []
107
- },
108
- 24: {
109
- left: ["Mouth_Press_L"],
110
- right: ["Mouth_Press_R"],
111
- center: []
112
- },
113
- 25: {
114
- left: [],
115
- right: [],
116
- center: ["Jaw_Open"]
117
- },
118
- 26: {
119
- left: [],
120
- right: [],
121
- center: ["Jaw_Open"]
122
- },
123
- 27: {
124
- left: [],
125
- right: [],
126
- center: ["Jaw_Open"]
127
- },
128
- 28: {
129
- left: [],
130
- right: [],
131
- center: ["Mouth_Roll_In_Upper", "Mouth_Roll_In_Lower"]
132
- },
133
- 29: {
134
- left: [],
135
- right: [],
136
- center: ["Jaw_Forward"]
137
- },
138
- 30: {
139
- left: ["Jaw_L"],
140
- right: [],
141
- center: []
142
- },
143
- 31: {
144
- left: [],
145
- right: [],
146
- center: []
147
- },
148
- 32: {
149
- left: [],
150
- right: [],
151
- center: ["Mouth_Roll_In_Lower"]
152
- },
153
- 34: {
154
- left: ["Cheek_Puff_L"],
155
- right: ["Cheek_Puff_R"],
156
- center: []
157
- },
158
- 35: {
159
- left: [],
160
- right: ["Jaw_R"],
161
- center: []
162
- },
163
- 36: {
164
- left: ["Tongue_Bulge_L"],
165
- right: ["Tongue_Bulge_R"],
166
- center: []
167
- },
168
- 37: {
169
- left: [],
170
- right: [],
171
- center: ["Tongue_Up"]
172
- },
173
- 38: {
174
- left: [],
175
- right: [],
176
- center: ["Tongue_Down"]
177
- },
178
- 39: {
179
- left: ["Tongue_L"],
180
- right: [],
181
- center: []
182
- },
183
- 40: {
184
- left: [],
185
- right: ["Tongue_R"],
186
- center: []
187
- },
188
- 41: {
189
- left: [],
190
- right: [],
191
- center: []
192
- },
193
- 42: {
194
- left: [],
195
- right: [],
196
- center: []
197
- },
198
- 43: {
199
- left: ["Eye_Blink_L"],
200
- right: ["Eye_Blink_R"],
201
- center: []
202
- },
203
- 45: {
204
- left: ["Eye_Blink_L"],
205
- right: ["Eye_Blink_R"],
206
- center: []
207
- },
208
- 51: {
209
- left: ["Head_Turn_L"],
210
- right: [],
211
- center: []
212
- },
213
- 52: {
214
- left: [],
215
- right: ["Head_Turn_R"],
216
- center: []
217
- },
218
- 53: {
219
- left: [],
220
- right: [],
221
- center: ["Head_Turn_Up"]
222
- },
223
- 54: {
224
- left: [],
225
- right: [],
226
- center: ["Head_Turn_Down"]
227
- },
228
- 55: {
229
- left: ["Head_Tilt_L"],
230
- right: [],
231
- center: []
232
- },
233
- 56: {
234
- left: [],
235
- right: ["Head_Tilt_R"],
236
- center: []
237
- },
238
- 61: {
239
- left: ["Eye_L_Look_L"],
240
- right: ["Eye_R_Look_L"],
241
- center: []
242
- },
243
- 62: {
244
- left: ["Eye_L_Look_R"],
245
- right: ["Eye_R_Look_R"],
246
- center: []
247
- },
248
- 63: {
249
- left: ["Eye_L_Look_Up"],
250
- right: ["Eye_R_Look_Up"],
251
- center: []
252
- },
253
- 64: {
254
- left: ["Eye_L_Look_Down"],
255
- right: ["Eye_R_Look_Down"],
256
- center: []
257
- },
258
- 65: {
259
- left: ["Eye_L_Look_L"],
260
- right: [],
261
- center: []
262
- },
263
- 66: {
264
- left: [],
265
- right: ["Eye_L_Look_R"],
266
- center: []
267
- },
268
- 67: {
269
- left: [],
270
- right: [],
271
- center: ["Eye_L_Look_Up"]
272
- },
273
- 68: {
274
- left: [],
275
- right: [],
276
- center: ["Eye_L_Look_Down"]
277
- },
278
- 69: {
279
- left: ["Eye_R_Look_L"],
280
- right: [],
281
- center: []
282
- },
283
- 70: {
284
- left: [],
285
- right: ["Eye_R_Look_R"],
286
- center: []
287
- },
288
- 71: {
289
- left: [],
290
- right: [],
291
- center: ["Eye_R_Look_Up"]
292
- },
293
- 72: {
294
- left: [],
295
- right: [],
296
- center: ["Eye_R_Look_Down"]
297
- },
298
- 73: {
299
- left: [],
300
- right: [],
301
- center: ["Tongue_Narrow"]
302
- },
303
- 74: {
304
- left: [],
305
- right: [],
306
- center: ["Tongue_Wide"]
307
- },
308
- 75: {
309
- left: [],
310
- right: [],
311
- center: ["Tongue_Roll"]
312
- },
313
- 76: {
314
- left: [],
315
- right: [],
316
- center: ["Tongue_Tip_Up"]
317
- },
318
- 77: {
319
- left: [],
320
- right: [],
321
- center: ["Tongue_Tip_Down"]
322
- },
323
- 80: {
324
- left: ["EO Bulge L"],
325
- right: ["EO Bulge R"],
326
- center: []
327
- },
328
- 81: {
329
- left: ["EO Depth L"],
330
- right: ["EO Depth R"],
331
- center: []
332
- },
333
- 82: {
334
- left: ["EO Inner Depth L"],
335
- right: ["EO Inner Depth R"],
336
- center: []
337
- },
338
- 83: {
339
- left: ["EO Inner Height L"],
340
- right: ["EO Inner Height R"],
341
- center: []
342
- },
343
- 84: {
344
- left: ["EO Inner Width L"],
345
- right: ["EO Inner Width R"],
346
- center: []
347
- },
348
- 85: {
349
- left: ["EO Outer Depth L"],
350
- right: ["EO Outer Depth R"],
351
- center: []
352
- },
353
- 86: {
354
- left: ["EO Outer Height L"],
355
- right: ["EO Outer Height R"],
356
- center: []
357
- },
358
- 87: {
359
- left: ["EO Outer Width L"],
360
- right: ["EO Outer Width R"],
361
- center: []
362
- },
363
- 88: {
364
- left: ["EO Upper Depth L"],
365
- right: ["EO Upper Depth R"],
366
- center: []
367
- },
368
- 89: {
369
- left: ["EO Lower Depth L"],
370
- right: ["EO Lower Depth R"],
371
- center: []
372
- },
373
- 90: {
374
- left: ["EO Center Upper Depth L"],
375
- right: ["EO Center Upper Depth R"],
376
- center: []
377
- },
378
- 91: {
379
- left: ["EO Center Upper Height L"],
380
- right: ["EO Center Upper Height R"],
381
- center: []
382
- },
383
- 92: {
384
- left: ["EO Center Lower Depth L"],
385
- right: ["EO Center Lower Depth R"],
386
- center: []
387
- },
388
- 93: {
389
- left: ["EO Center Lower Height L"],
390
- right: ["EO Center Lower Height R"],
391
- center: []
392
- },
393
- 94: {
394
- left: ["EO Inner Upper Depth L"],
395
- right: ["EO Inner Upper Depth R"],
396
- center: []
397
- },
398
- 95: {
399
- left: ["EO Inner Upper Height L"],
400
- right: ["EO Inner Upper Height R"],
401
- center: []
402
- },
403
- 96: {
404
- left: ["EO Inner Lower Depth L"],
405
- right: ["EO Inner Lower Depth R"],
406
- center: []
407
- },
408
- 97: {
409
- left: ["EO Inner Lower Height L"],
410
- right: ["EO Inner Lower Height R"],
411
- center: []
412
- },
413
- 98: {
414
- left: ["EO Outer Upper Depth L"],
415
- right: ["EO Outer Upper Depth R"],
416
- center: []
417
- },
418
- 99: {
419
- left: ["EO Outer Upper Height L"],
420
- right: ["EO Outer Upper Height R"],
421
- center: []
422
- },
423
- 100: {
424
- left: ["EO Outer Lower Depth L"],
425
- right: ["EO Outer Lower Depth R"],
426
- center: []
427
- },
428
- 101: {
429
- left: ["EO Outer Lower Height L"],
430
- right: ["EO Outer Lower Height R"],
431
- center: []
432
- },
433
- 102: {
434
- left: ["EO Duct Depth L"],
435
- right: ["EO Duct Depth R"],
436
- center: []
437
- }
438
- };
439
- var CC4_BONE_PREFIX = "CC_Base_";
440
- var CC4_SUFFIX_PATTERN = "_\\d+$|\\.\\d+$";
441
- var CC4_BONES = {
442
- EYE_L: "CC_Base_L_Eye",
443
- EYE_R: "CC_Base_R_Eye",
444
- HEAD: "CC_Base_Head",
445
- NECK: "CC_Base_NeckTwist01",
446
- NECK_TWIST: "CC_Base_NeckTwist02",
447
- JAW: "CC_Base_JawRoot",
448
- TONGUE: "CC_Base_Tongue01",
449
- SPINE_01: "CC_Base_Spine01",
450
- SPINE_02: "CC_Base_Spine02",
451
- CLAVICLE_L: "CC_Base_L_Clavicle",
452
- CLAVICLE_R: "CC_Base_R_Clavicle",
453
- HAND_L: "CC_Base_L_Hand",
454
- HAND_R: "CC_Base_R_Hand",
455
- FOOT_L: "CC_Base_L_Foot",
456
- FOOT_R: "CC_Base_R_Foot",
457
- TOEBASE_L: "CC_Base_L_ToeBase",
458
- TOEBASE_R: "CC_Base_R_ToeBase"
459
- };
460
- var CC4_BONE_NODES = {
461
- EYE_L: "L_Eye",
462
- EYE_R: "R_Eye",
463
- HEAD: "Head",
464
- NECK: "NeckTwist01",
465
- NECK_TWIST: "NeckTwist02",
466
- JAW: "JawRoot",
467
- TONGUE: "Tongue01",
468
- SPINE_01: "Spine01",
469
- SPINE_02: "Spine02",
470
- CLAVICLE_L: "L_Clavicle",
471
- CLAVICLE_R: "R_Clavicle",
472
- HAND_L: "L_Hand",
473
- HAND_R: "R_Hand",
474
- FOOT_L: "L_Foot",
475
- FOOT_R: "R_Foot",
476
- TOEBASE_L: "L_ToeBase",
477
- TOEBASE_R: "R_ToeBase",
478
- // Concrete-name aliases keep existing runtime callers compatible.
479
- [CC4_BONES.EYE_L]: CC4_BONES.EYE_L,
480
- [CC4_BONES.EYE_R]: CC4_BONES.EYE_R,
481
- [CC4_BONES.HEAD]: CC4_BONES.HEAD,
482
- [CC4_BONES.NECK]: CC4_BONES.NECK,
483
- [CC4_BONES.NECK_TWIST]: CC4_BONES.NECK_TWIST,
484
- [CC4_BONES.JAW]: CC4_BONES.JAW,
485
- [CC4_BONES.TONGUE]: CC4_BONES.TONGUE,
486
- [CC4_BONES.SPINE_01]: CC4_BONES.SPINE_01,
487
- [CC4_BONES.SPINE_02]: CC4_BONES.SPINE_02,
488
- [CC4_BONES.CLAVICLE_L]: CC4_BONES.CLAVICLE_L,
489
- [CC4_BONES.CLAVICLE_R]: CC4_BONES.CLAVICLE_R,
490
- [CC4_BONES.HAND_L]: CC4_BONES.HAND_L,
491
- [CC4_BONES.HAND_R]: CC4_BONES.HAND_R,
492
- [CC4_BONES.FOOT_L]: CC4_BONES.FOOT_L,
493
- [CC4_BONES.FOOT_R]: CC4_BONES.FOOT_R,
494
- [CC4_BONES.TOEBASE_L]: CC4_BONES.TOEBASE_L,
495
- [CC4_BONES.TOEBASE_R]: CC4_BONES.TOEBASE_R
496
- };
497
- var BONE_AU_TO_BINDINGS = {
498
- // Jaw open/close (jaw drop)
499
- 25: [{ node: CC4_BONES.JAW, channel: "rz", scale: 1, maxDegrees: 20 }],
500
- 26: [{ node: CC4_BONES.JAW, channel: "rz", scale: 1, maxDegrees: 30 }],
501
- 27: [{ node: CC4_BONES.JAW, channel: "rz", scale: 1, maxDegrees: 35 }],
502
- // Jaw lateral (left/right)
503
- 30: [{ node: CC4_BONES.JAW, channel: "ry", scale: -1, maxDegrees: 15 }],
504
- 35: [{ node: CC4_BONES.JAW, channel: "ry", scale: 1, maxDegrees: 15 }],
505
- // Head yaw (turn left/right)
506
- // AU 51 = Turn Left: positive ry rotation (scale: 1)
507
- // AU 52 = Turn Right: negative ry rotation (scale: -1)
508
- 51: [{ node: CC4_BONES.HEAD, channel: "ry", scale: 1, maxDegrees: 60 }],
509
- 52: [{ node: CC4_BONES.HEAD, channel: "ry", scale: -1, maxDegrees: 60 }],
510
- // Head pitch (up/down)
511
- // AU 53 = Head Up: negative rx rotation (scale: -1)
512
- // AU 54 = Head Down: positive rx rotation (scale: 1)
513
- 53: [{ node: CC4_BONES.HEAD, channel: "rx", scale: -1, maxDegrees: 30 }],
514
- 54: [{ node: CC4_BONES.HEAD, channel: "rx", scale: 1, maxDegrees: 30 }],
515
- // Head roll (tilt)
516
- 55: [{ node: CC4_BONES.HEAD, channel: "rz", scale: -1, maxDegrees: 25 }],
517
- 56: [{ node: CC4_BONES.HEAD, channel: "rz", scale: 1, maxDegrees: 25 }],
518
- // Eyes horizontal (left/right) - CC4 uses rz for yaw
519
- // AU 61 = Eyes Turn Left = character looks toward THEIR left = viewer's RIGHT
520
- // AU 62 = Eyes Turn Right = character looks toward THEIR right = viewer's LEFT
521
- // For CC4 rigs: positive rz = eyes rotate left (look right), negative rz = eyes rotate right (look left)
522
- 61: [
523
- { node: CC4_BONES.EYE_L, channel: "rz", scale: 1, maxDegrees: 25, side: "left" },
524
- { node: CC4_BONES.EYE_R, channel: "rz", scale: 1, maxDegrees: 25, side: "right" }
525
- ],
526
- 62: [
527
- { node: CC4_BONES.EYE_L, channel: "rz", scale: -1, maxDegrees: 25, side: "left" },
528
- { node: CC4_BONES.EYE_R, channel: "rz", scale: -1, maxDegrees: 25, side: "right" }
529
- ],
530
- // Eyes vertical (up/down) - rx
531
- // AU 63 = Eyes Up = character looks up
532
- // AU 64 = Eyes Down = character looks down
533
- // For CC4 rigs: negative rx = eyes rotate up, positive rx = eyes rotate down
534
- 63: [
535
- { node: CC4_BONES.EYE_L, channel: "rx", scale: -1, maxDegrees: 20, side: "left" },
536
- { node: CC4_BONES.EYE_R, channel: "rx", scale: -1, maxDegrees: 20, side: "right" }
537
- ],
538
- 64: [
539
- { node: CC4_BONES.EYE_L, channel: "rx", scale: 1, maxDegrees: 20, side: "left" },
540
- { node: CC4_BONES.EYE_R, channel: "rx", scale: 1, maxDegrees: 20, side: "right" }
541
- ],
542
- 65: [{ node: CC4_BONES.EYE_L, channel: "rz", scale: 1, maxDegrees: 25, side: "left" }],
543
- 66: [{ node: CC4_BONES.EYE_L, channel: "rz", scale: -1, maxDegrees: 25, side: "left" }],
544
- 67: [{ node: CC4_BONES.EYE_L, channel: "rx", scale: -1, maxDegrees: 20, side: "left" }],
545
- 68: [{ node: CC4_BONES.EYE_L, channel: "rx", scale: 1, maxDegrees: 20, side: "left" }],
546
- 69: [{ node: CC4_BONES.EYE_R, channel: "rz", scale: 1, maxDegrees: 25, side: "right" }],
547
- 70: [{ node: CC4_BONES.EYE_R, channel: "rz", scale: -1, maxDegrees: 25, side: "right" }],
548
- 71: [{ node: CC4_BONES.EYE_R, channel: "rx", scale: -1, maxDegrees: 20, side: "right" }],
549
- 72: [{ node: CC4_BONES.EYE_R, channel: "rx", scale: 1, maxDegrees: 20, side: "right" }],
550
- // Tongue controls (optional, for rigs that expose them)
551
- 37: [{ node: CC4_BONES.TONGUE, channel: "rz", scale: 1, maxDegrees: 20 }],
552
- 38: [{ node: CC4_BONES.TONGUE, channel: "rz", scale: -1, maxDegrees: 20 }],
553
- 39: [{ node: CC4_BONES.TONGUE, channel: "ry", scale: -1, maxDegrees: 20 }],
554
- 40: [{ node: CC4_BONES.TONGUE, channel: "ry", scale: 1, maxDegrees: 20 }],
555
- 41: [{ node: CC4_BONES.TONGUE, channel: "rx", scale: -1, maxDegrees: 20 }],
556
- 42: [{ node: CC4_BONES.TONGUE, channel: "rx", scale: 1, maxDegrees: 20 }]
557
- };
558
- var LIP_SYNC_CONTROL_TO_BINDINGS = {
559
- 103: [{ node: CC4_BONES.JAW, channel: "rz", scale: 1, maxDegrees: 30 }]
560
- };
561
- var CC4_PROFILE_BONE_BINDINGS = {
562
- ...BONE_AU_TO_BINDINGS,
563
- ...LIP_SYNC_CONTROL_TO_BINDINGS
564
- };
565
- var VISEME_KEYS = [
566
- "AE",
567
- "Ah",
568
- "B_M_P",
569
- "Ch_J",
570
- "EE",
571
- "Er",
572
- "F_V",
573
- "Ih",
574
- "K_G_H_NG",
575
- "Oh",
576
- "R",
577
- "S_Z",
578
- "T_L_D_N",
579
- "Th",
580
- "W_OO"
581
- ];
582
- var VISEME_JAW_AMOUNTS = [
583
- 0.75,
584
- // 0: AE
585
- 0.8,
586
- // 1: Ah
587
- 0,
588
- // 2: B_M_P
589
- 0.3,
590
- // 3: Ch_J
591
- 0.2,
592
- // 4: EE
593
- 0.35,
594
- // 5: Er
595
- 0.1,
596
- // 6: F_V
597
- 0.2,
598
- // 7: Ih
599
- 0.35,
600
- // 8: K_G_H_NG
601
- 0.6,
602
- // 9: Oh
603
- 0.35,
604
- // 10: R
605
- 0.1,
606
- // 11: S_Z
607
- 0.3,
608
- // 12: T_L_D_N
609
- 0.15,
610
- // 13: Th
611
- 0.5
612
- // 14: W_OO
613
- ];
614
- var CC4_VISEME_SYSTEM_ID = "cc4-arkit-15";
615
- var CC4_VISEME_SLOTS = [
616
- {
617
- id: "ae",
618
- label: "AE",
619
- order: 0,
620
- providerIds: { azure: [4], sapi: [4] },
621
- phonemes: ["AE", "EH", "EY", "UH"],
622
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(ae|eh|ey)([_ .-]|$)"],
623
- features: { jawOpen: 0.75, lipSpread: 0.35 },
624
- defaultJawAmount: VISEME_JAW_AMOUNTS[0]
625
- },
626
- {
627
- id: "ah",
628
- label: "Ah",
629
- order: 1,
630
- providerIds: { azure: [1, 2, 9, 11, 12], sapi: [1, 2, 9, 11, 12] },
631
- phonemes: ["AA", "AE", "AH", "AX", "AW", "AY", "HH"],
632
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(ah|aa|aah|open)([_ .-]|$)"],
633
- features: { jawOpen: 0.8 },
634
- defaultJawAmount: VISEME_JAW_AMOUNTS[1]
635
- },
636
- {
637
- id: "b-m-p",
638
- label: "B_M_P",
639
- order: 2,
640
- providerIds: { azure: [0, 21], sapi: [0, 21] },
641
- phonemes: ["B", "M", "P"],
642
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(b[_ .-]?m[_ .-]?p|bmp|closed|sil|rest)([_ .-]|$)"],
643
- features: { jawOpen: 0, lipClosed: 1 },
644
- defaultJawAmount: VISEME_JAW_AMOUNTS[2]
645
- },
646
- {
647
- id: "ch-j",
648
- label: "Ch_J",
649
- order: 3,
650
- providerIds: { azure: [16], sapi: [16] },
651
- phonemes: ["CH", "JH", "SH", "ZH"],
652
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(ch|j|sh|zh)([_ .-]|$)"],
653
- features: { jawOpen: 0.3, fricative: 0.6 },
654
- defaultJawAmount: VISEME_JAW_AMOUNTS[3]
655
- },
656
- {
657
- id: "ee",
658
- label: "EE",
659
- order: 4,
660
- providerIds: { azure: [6], sapi: [6] },
661
- phonemes: ["IY", "IH", "IX", "Y"],
662
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(ee|iy|y)([_ .-]|$)"],
663
- features: { jawOpen: 0.2, lipSpread: 0.8 },
664
- defaultJawAmount: VISEME_JAW_AMOUNTS[4]
665
- },
666
- {
667
- id: "er",
668
- label: "Er",
669
- order: 5,
670
- providerIds: { azure: [5], sapi: [5] },
671
- phonemes: ["ER"],
672
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(er)([_ .-]|$)"],
673
- features: { jawOpen: 0.35, lipRound: 0.35 },
674
- defaultJawAmount: VISEME_JAW_AMOUNTS[5]
675
- },
676
- {
677
- id: "f-v",
678
- label: "F_V",
679
- order: 6,
680
- providerIds: { azure: [18], sapi: [18] },
681
- phonemes: ["F", "V"],
682
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(f[_ .-]?v|fv)([_ .-]|$)"],
683
- features: { jawOpen: 0.1, fricative: 1 },
684
- defaultJawAmount: VISEME_JAW_AMOUNTS[6]
685
- },
686
- {
687
- id: "ih",
688
- label: "Ih",
689
- order: 7,
690
- providerIds: { azure: [6], sapi: [6] },
691
- phonemes: ["IH", "IX"],
692
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(ih|ix)([_ .-]|$)"],
693
- features: { jawOpen: 0.2, lipSpread: 0.55 },
694
- defaultJawAmount: VISEME_JAW_AMOUNTS[7]
695
- },
696
- {
697
- id: "k-g-h-ng",
698
- label: "K_G_H_NG",
699
- order: 8,
700
- providerIds: { azure: [20], sapi: [20] },
701
- phonemes: ["K", "G", "NG"],
702
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(k[_ .-]?g[_ .-]?h?[_ .-]?ng|kg|ng)([_ .-]|$)"],
703
- features: { jawOpen: 0.35 },
704
- defaultJawAmount: VISEME_JAW_AMOUNTS[8]
705
- },
706
- {
707
- id: "oh",
708
- label: "Oh",
709
- order: 9,
710
- providerIds: { azure: [3, 8, 10], sapi: [3, 8, 10] },
711
- phonemes: ["AO", "OW", "OY"],
712
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(oh|ao|ow|oy)([_ .-]|$)"],
713
- features: { jawOpen: 0.6, lipRound: 0.8 },
714
- defaultJawAmount: VISEME_JAW_AMOUNTS[9]
715
- },
716
- {
717
- id: "r",
718
- label: "R",
719
- order: 10,
720
- providerIds: { azure: [13], sapi: [13] },
721
- phonemes: ["R"],
722
- matchers: ["(^|[_ .-])(v|viseme)[_ .-]?r([_ .-]|$)", "(^|[_ .-])r[_ .-]?(sound|viseme)([_ .-]|$)"],
723
- features: { jawOpen: 0.35, lipRound: 0.5 },
724
- defaultJawAmount: VISEME_JAW_AMOUNTS[10]
725
- },
726
- {
727
- id: "s-z",
728
- label: "S_Z",
729
- order: 11,
730
- providerIds: { azure: [15], sapi: [15] },
731
- phonemes: ["S", "Z"],
732
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(s[_ .-]?z|sz)([_ .-]|$)"],
733
- features: { jawOpen: 0.1, fricative: 1 },
734
- defaultJawAmount: VISEME_JAW_AMOUNTS[11]
735
- },
736
- {
737
- id: "t-l-d-n",
738
- label: "T_L_D_N",
739
- order: 12,
740
- providerIds: { azure: [14, 19], sapi: [14, 19] },
741
- phonemes: ["T", "L", "D", "N"],
742
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(t[_ .-]?l[_ .-]?d[_ .-]?n|tldn)([_ .-]|$)", "(^|[_ .-])(v|viseme)[_ .-]?l([_ .-]|$)"],
743
- features: { jawOpen: 0.3, tongueTip: 1 },
744
- defaultJawAmount: VISEME_JAW_AMOUNTS[12]
745
- },
746
- {
747
- id: "th",
748
- label: "Th",
749
- order: 13,
750
- providerIds: { azure: [17], sapi: [17] },
751
- phonemes: ["TH", "DH"],
752
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(th|dh)([_ .-]|$)"],
753
- features: { jawOpen: 0.15, tongueTip: 0.8, fricative: 0.8 },
754
- defaultJawAmount: VISEME_JAW_AMOUNTS[13]
755
- },
756
- {
757
- id: "w-oo",
758
- label: "W_OO",
759
- order: 14,
760
- providerIds: { azure: [7], sapi: [7] },
761
- phonemes: ["W", "UW"],
762
- matchers: ["(^|[_ .-])(v|viseme)?[_ .-]?(w[_ .-]?oo|woo|uw|oo)([_ .-]|$)"],
763
- features: { jawOpen: 0.5, lipRound: 1 },
764
- defaultJawAmount: VISEME_JAW_AMOUNTS[14]
765
- }
766
- ];
767
- var CONTINUUM_PAIRS_MAP = {
768
- // Eyes horizontal - both eyes share same AUs (yaw maps to rz via COMPOSITE_ROTATIONS)
769
- 61: { pairId: 62, isNegative: true, axis: "yaw", node: CC4_BONES.EYE_L },
770
- 62: { pairId: 61, isNegative: false, axis: "yaw", node: CC4_BONES.EYE_L },
771
- 65: { pairId: 66, isNegative: true, axis: "yaw", node: CC4_BONES.EYE_L },
772
- 66: { pairId: 65, isNegative: false, axis: "yaw", node: CC4_BONES.EYE_L },
773
- 69: { pairId: 70, isNegative: true, axis: "yaw", node: CC4_BONES.EYE_R },
774
- 70: { pairId: 69, isNegative: false, axis: "yaw", node: CC4_BONES.EYE_R },
775
- // Eyes vertical (pitch)
776
- 64: { pairId: 63, isNegative: true, axis: "pitch", node: CC4_BONES.EYE_L },
777
- 63: { pairId: 64, isNegative: false, axis: "pitch", node: CC4_BONES.EYE_L },
778
- 68: { pairId: 67, isNegative: true, axis: "pitch", node: CC4_BONES.EYE_L },
779
- 67: { pairId: 68, isNegative: false, axis: "pitch", node: CC4_BONES.EYE_L },
780
- 72: { pairId: 71, isNegative: true, axis: "pitch", node: CC4_BONES.EYE_R },
781
- 71: { pairId: 72, isNegative: false, axis: "pitch", node: CC4_BONES.EYE_R },
782
- // Head yaw (turn left/right)
783
- 51: { pairId: 52, isNegative: true, axis: "yaw", node: CC4_BONES.HEAD },
784
- 52: { pairId: 51, isNegative: false, axis: "yaw", node: CC4_BONES.HEAD },
785
- // Head pitch (up/down)
786
- 54: { pairId: 53, isNegative: true, axis: "pitch", node: CC4_BONES.HEAD },
787
- 53: { pairId: 54, isNegative: false, axis: "pitch", node: CC4_BONES.HEAD },
788
- // Head roll (tilt left/right)
789
- 55: { pairId: 56, isNegative: true, axis: "roll", node: CC4_BONES.HEAD },
790
- 56: { pairId: 55, isNegative: false, axis: "roll", node: CC4_BONES.HEAD },
791
- // Jaw yaw (left/right)
792
- 30: { pairId: 35, isNegative: true, axis: "yaw", node: CC4_BONES.JAW },
793
- 35: { pairId: 30, isNegative: false, axis: "yaw", node: CC4_BONES.JAW },
794
- // Tongue yaw (left/right)
795
- 39: { pairId: 40, isNegative: true, axis: "yaw", node: CC4_BONES.TONGUE },
796
- 40: { pairId: 39, isNegative: false, axis: "yaw", node: CC4_BONES.TONGUE },
797
- // Tongue pitch (up/down)
798
- 38: { pairId: 37, isNegative: true, axis: "pitch", node: CC4_BONES.TONGUE },
799
- 37: { pairId: 38, isNegative: false, axis: "pitch", node: CC4_BONES.TONGUE },
800
- // Tongue roll (tilt left/right)
801
- 41: { pairId: 42, isNegative: true, axis: "roll", node: CC4_BONES.TONGUE },
802
- 42: { pairId: 41, isNegative: false, axis: "roll", node: CC4_BONES.TONGUE },
803
- // Extended tongue morphs (continuum pairs)
804
- 73: { pairId: 74, isNegative: true, axis: "yaw", node: CC4_BONES.TONGUE },
805
- // Tongue Narrow/Wide
806
- 74: { pairId: 73, isNegative: false, axis: "yaw", node: CC4_BONES.TONGUE },
807
- 76: { pairId: 77, isNegative: false, axis: "pitch", node: CC4_BONES.TONGUE },
808
- // Tongue Tip Up/Down
809
- 77: { pairId: 76, isNegative: true, axis: "pitch", node: CC4_BONES.TONGUE }
810
- };
811
- var CONTINUUM_LABELS = {
812
- "61-62": "Eyes \u2014 Horizontal",
813
- "64-63": "Eyes \u2014 Vertical",
814
- "65-66": "Left Eye \u2014 Horizontal",
815
- "68-67": "Left Eye \u2014 Vertical",
816
- "69-70": "Right Eye \u2014 Horizontal",
817
- "72-71": "Right Eye \u2014 Vertical",
818
- "51-52": "Head \u2014 Horizontal",
819
- "54-53": "Head \u2014 Vertical",
820
- "55-56": "Head \u2014 Tilt",
821
- "30-35": "Jaw \u2014 Horizontal",
822
- "38-37": "Tongue \u2014 Vertical",
823
- "39-40": "Tongue \u2014 Horizontal",
824
- "41-42": "Tongue \u2014 Tilt",
825
- "73-74": "Tongue \u2014 Width",
826
- "76-77": "Tongue Tip \u2014 Vertical"
827
- };
828
- var CC4_EYE_MESH_NODES = {
829
- LEFT: "CC_Base_Eye",
830
- RIGHT: "CC_Base_Eye_1"
831
- };
832
- var AU_INFO = {
833
- // Forehead / Brow (Upper)
834
- "1": { id: "1", name: "Inner Brow Raiser", muscularBasis: "frontalis (pars medialis)", links: ["https://en.wikipedia.org/wiki/Frontalis_muscle"], faceArea: "Upper", facePart: "Forehead" },
835
- "2": { id: "2", name: "Outer Brow Raiser", muscularBasis: "frontalis (pars lateralis)", links: ["https://en.wikipedia.org/wiki/Frontalis_muscle"], faceArea: "Upper", facePart: "Forehead" },
836
- "4": { id: "4", name: "Brow Lowerer", muscularBasis: "corrugator/depressor supercilii", links: ["https://en.wikipedia.org/wiki/Corrugator_supercilii"], faceArea: "Upper", facePart: "Forehead" },
837
- // Eyelids / Eyes (Upper)
838
- "5": { id: "5", name: "Upper Lid Raiser", muscularBasis: "levator palpebrae superioris", links: ["https://en.wikipedia.org/wiki/Levator_palpebrae_superioris"], faceArea: "Upper", facePart: "Eyelids" },
839
- "6": { id: "6", name: "Cheek Raiser", muscularBasis: "orbicularis oculi (pars orbitalis)", links: ["https://en.wikipedia.org/wiki/Orbicularis_oculi"], faceArea: "Upper", facePart: "Cheeks" },
840
- "7": { id: "7", name: "Lid Tightener", muscularBasis: "orbicularis oculi (pars palpebralis)", links: ["https://en.wikipedia.org/wiki/Orbicularis_oculi"], faceArea: "Upper", facePart: "Eyelids" },
841
- "43": { id: "43", name: "Eyes Closed", muscularBasis: "orbicularis oculi", links: ["https://en.wikipedia.org/wiki/Orbicularis_oculi_muscle"], faceArea: "Upper", facePart: "Eyelids" },
842
- "45": { id: "45", name: "Blink", muscularBasis: "orbicularis oculi", links: ["https://en.wikipedia.org/wiki/Orbicularis_oculi_muscle"], faceArea: "Upper", facePart: "Eyelids" },
843
- "61": { id: "61", name: "Eyes Turn Left", faceArea: "Upper", facePart: "Eyes" },
844
- "62": { id: "62", name: "Eyes Turn Right", faceArea: "Upper", facePart: "Eyes" },
845
- "63": { id: "63", name: "Eyes Up", faceArea: "Upper", facePart: "Eyes" },
846
- "64": { id: "64", name: "Eyes Down", faceArea: "Upper", facePart: "Eyes" },
847
- "65": { id: "65", name: "Left Eye Look Left", faceArea: "Upper", facePart: "Eyes" },
848
- "66": { id: "66", name: "Left Eye Look Right", faceArea: "Upper", facePart: "Eyes" },
849
- "67": { id: "67", name: "Left Eye Look Up", faceArea: "Upper", facePart: "Eyes" },
850
- "68": { id: "68", name: "Left Eye Look Down", faceArea: "Upper", facePart: "Eyes" },
851
- "69": { id: "69", name: "Right Eye Look Left", faceArea: "Upper", facePart: "Eyes" },
852
- "70": { id: "70", name: "Right Eye Look Right", faceArea: "Upper", facePart: "Eyes" },
853
- "71": { id: "71", name: "Right Eye Look Up", faceArea: "Upper", facePart: "Eyes" },
854
- "72": { id: "72", name: "Right Eye Look Down", faceArea: "Upper", facePart: "Eyes" },
855
- // Nose / Cheeks
856
- "9": { id: "9", name: "Nose Wrinkler", muscularBasis: "levator labii superioris alaeque nasi", links: ["https://en.wikipedia.org/wiki/Levator_labii_superioris_alaeque_nasi"], faceArea: "Upper", facePart: "Nose" },
857
- "34": { id: "34", name: "Cheek Puff", faceArea: "Lower", facePart: "Cheeks" },
858
- // Mouth (Lower)
859
- "8": { id: "8", name: "Lips Toward Each Other", muscularBasis: "orbicularis oris", links: ["https://en.wikipedia.org/wiki/Orbicularis_oris"], faceArea: "Lower", facePart: "Mouth" },
860
- "10": { id: "10", name: "Upper Lip Raiser", muscularBasis: "levator labii superioris", links: ["https://en.wikipedia.org/wiki/Levator_labii_superioris"], faceArea: "Lower", facePart: "Mouth" },
861
- "11": { id: "11", name: "Nasolabial Deepener", muscularBasis: "zygomaticus minor", links: ["https://en.wikipedia.org/wiki/Zygomaticus_minor"], faceArea: "Lower", facePart: "Cheeks" },
862
- "12": { id: "12", name: "Lip Corner Puller", muscularBasis: "zygomaticus major", links: ["https://en.wikipedia.org/wiki/Zygomaticus_major"], faceArea: "Lower", facePart: "Mouth" },
863
- "13": { id: "13", name: "Sharp Lip Puller", muscularBasis: "levator anguli oris", links: ["https://en.wikipedia.org/wiki/Levator_anguli_oris"], faceArea: "Lower", facePart: "Mouth" },
864
- "14": { id: "14", name: "Dimpler", muscularBasis: "buccinator", links: ["https://en.wikipedia.org/wiki/Buccinator"], faceArea: "Lower", facePart: "Cheeks" },
865
- "15": { id: "15", name: "Lip Corner Depressor", muscularBasis: "depressor anguli oris", links: ["https://en.wikipedia.org/wiki/Depressor_anguli_oris"], faceArea: "Lower", facePart: "Mouth" },
866
- "16": { id: "16", name: "Lower Lip Depressor", muscularBasis: "depressor labii inferioris", links: ["https://en.wikipedia.org/wiki/Depressor_labii_inferioris"], faceArea: "Lower", facePart: "Mouth" },
867
- "17": { id: "17", name: "Chin Raiser", muscularBasis: "mentalis", links: ["https://en.wikipedia.org/wiki/Mentalis"], faceArea: "Lower", facePart: "Chin" },
868
- "18": { id: "18", name: "Lip Pucker", faceArea: "Lower", facePart: "Mouth" },
869
- "20": { id: "20", name: "Lip Stretcher", muscularBasis: "risorius + platysma", links: ["https://en.wikipedia.org/wiki/Risorius", "https://en.wikipedia.org/wiki/Platysma"], faceArea: "Lower", facePart: "Mouth" },
870
- "22": { id: "22", name: "Lip Funneler", muscularBasis: "orbicularis oris", links: ["https://en.wikipedia.org/wiki/Orbicularis_oris"], faceArea: "Lower", facePart: "Mouth" },
871
- "23": { id: "23", name: "Lip Tightener", muscularBasis: "orbicularis oris", faceArea: "Lower", facePart: "Mouth" },
872
- "24": { id: "24", name: "Lip Presser", muscularBasis: "orbicularis oris", faceArea: "Lower", facePart: "Mouth" },
873
- "25": { id: "25", name: "Lips Part", faceArea: "Lower", facePart: "Mouth" },
874
- "27": { id: "27", name: "Mouth Stretch", muscularBasis: "pterygoids + digastric", links: ["https://en.wikipedia.org/wiki/Pterygoid_bone", "https://en.wikipedia.org/wiki/Digastric_muscle"], faceArea: "Lower", facePart: "Mouth" },
875
- "28": { id: "28", name: "Lip Suck", muscularBasis: "orbicularis oris", faceArea: "Lower", facePart: "Mouth" },
876
- // Tongue (Lower)
877
- "19": { id: "19", name: "Tongue Show", faceArea: "Lower", facePart: "Tongue" },
878
- "36": { id: "36", name: "Tongue Bulge", faceArea: "Lower", facePart: "Tongue" },
879
- "37": { id: "37", name: "Tongue Up", faceArea: "Lower", facePart: "Tongue" },
880
- "38": { id: "38", name: "Tongue Down", faceArea: "Lower", facePart: "Tongue" },
881
- "39": { id: "39", name: "Tongue Left", faceArea: "Lower", facePart: "Tongue" },
882
- "40": { id: "40", name: "Tongue Right", faceArea: "Lower", facePart: "Tongue" },
883
- "41": { id: "41", name: "Tongue Tilt Left", faceArea: "Lower", facePart: "Tongue" },
884
- "42": { id: "42", name: "Tongue Tilt Right", faceArea: "Lower", facePart: "Tongue" },
885
- // Extended tongue controls (CC4-specific morphs)
886
- "73": { id: "73", name: "Tongue Narrow", faceArea: "Lower", facePart: "Tongue" },
887
- "74": { id: "74", name: "Tongue Wide", faceArea: "Lower", facePart: "Tongue" },
888
- "75": { id: "75", name: "Tongue Roll", faceArea: "Lower", facePart: "Tongue" },
889
- "76": { id: "76", name: "Tongue Tip Up", faceArea: "Lower", facePart: "Tongue" },
890
- "77": { id: "77", name: "Tongue Tip Down", faceArea: "Lower", facePart: "Tongue" },
891
- // Jaw (Lower)
892
- "26": { id: "26", name: "Jaw Drop", muscularBasis: "masseter (relax temporalis)", links: ["https://en.wikipedia.org/wiki/Masseter_muscle"], faceArea: "Lower", facePart: "Jaw" },
893
- "29": { id: "29", name: "Jaw Thrust", faceArea: "Lower", facePart: "Jaw" },
894
- "30": { id: "30", name: "Jaw Left", faceArea: "Lower", facePart: "Jaw" },
895
- "31": { id: "31", name: "Jaw Clencher", muscularBasis: "masseter + temporalis", faceArea: "Lower", facePart: "Jaw" },
896
- "32": { id: "32", name: "Lip Bite", muscularBasis: "orbicularis oris", faceArea: "Lower", facePart: "Mouth" },
897
- "35": { id: "35", name: "Jaw Right", faceArea: "Lower", facePart: "Jaw" },
898
- // Head position (M51-M56 in FACS notation)
899
- "51": { id: "51", name: "Head Turn Left", faceArea: "Upper", facePart: "Head" },
900
- "52": { id: "52", name: "Head Turn Right", faceArea: "Upper", facePart: "Head" },
901
- "53": { id: "53", name: "Head Up", faceArea: "Upper", facePart: "Head" },
902
- "54": { id: "54", name: "Head Down", faceArea: "Upper", facePart: "Head" },
903
- "55": { id: "55", name: "Head Tilt Left", faceArea: "Upper", facePart: "Head" },
904
- "56": { id: "56", name: "Head Tilt Right", faceArea: "Upper", facePart: "Head" },
905
- // Eye (Upper) - EO morphs applied to CC_Base_Eye meshes
906
- "80": { id: "80", name: "Eye Bulge", faceArea: "Upper", facePart: "Eye" },
907
- "81": { id: "81", name: "Eye Depth", faceArea: "Upper", facePart: "Eye" },
908
- "82": { id: "82", name: "Eye Inner Depth", faceArea: "Upper", facePart: "Eye" },
909
- "83": { id: "83", name: "Eye Inner Height", faceArea: "Upper", facePart: "Eye" },
910
- "84": { id: "84", name: "Eye Inner Width", faceArea: "Upper", facePart: "Eye" },
911
- "85": { id: "85", name: "Eye Outer Depth", faceArea: "Upper", facePart: "Eye" },
912
- "86": { id: "86", name: "Eye Outer Height", faceArea: "Upper", facePart: "Eye" },
913
- "87": { id: "87", name: "Eye Outer Width", faceArea: "Upper", facePart: "Eye" },
914
- "88": { id: "88", name: "Eye Upper Depth", faceArea: "Upper", facePart: "Eye" },
915
- "89": { id: "89", name: "Eye Lower Depth", faceArea: "Upper", facePart: "Eye" },
916
- "90": { id: "90", name: "Eye Center Upper Depth", faceArea: "Upper", facePart: "Eye" },
917
- "91": { id: "91", name: "Eye Center Upper Height", faceArea: "Upper", facePart: "Eye" },
918
- "92": { id: "92", name: "Eye Center Lower Depth", faceArea: "Upper", facePart: "Eye" },
919
- "93": { id: "93", name: "Eye Center Lower Height", faceArea: "Upper", facePart: "Eye" },
920
- "94": { id: "94", name: "Eye Inner Upper Depth", faceArea: "Upper", facePart: "Eye" },
921
- "95": { id: "95", name: "Eye Inner Upper Height", faceArea: "Upper", facePart: "Eye" },
922
- "96": { id: "96", name: "Eye Inner Lower Depth", faceArea: "Upper", facePart: "Eye" },
923
- "97": { id: "97", name: "Eye Inner Lower Height", faceArea: "Upper", facePart: "Eye" },
924
- "98": { id: "98", name: "Eye Outer Upper Depth", faceArea: "Upper", facePart: "Eye" },
925
- "99": { id: "99", name: "Eye Outer Upper Height", faceArea: "Upper", facePart: "Eye" },
926
- "100": { id: "100", name: "Eye Outer Lower Depth", faceArea: "Upper", facePart: "Eye" },
927
- "101": { id: "101", name: "Eye Outer Lower Height", faceArea: "Upper", facePart: "Eye" },
928
- "102": { id: "102", name: "Eye Duct Depth", faceArea: "Upper", facePart: "Eye" }
929
- };
930
- var AU_MIX_DEFAULTS = {
931
- 31: 0.7,
932
- 32: 0.7,
933
- 33: 0.7,
934
- 54: 0.7,
935
- 55: 0.7,
936
- 56: 0.7,
937
- // head
938
- 61: 0.5,
939
- 62: 0.5,
940
- 63: 0.5,
941
- 64: 0.5,
942
- // eyes
943
- 25: 0.5,
944
- 26: 0.5,
945
- 27: 0.5,
946
- // jaw open (lips part, jaw drop, mouth stretch)
947
- 30: 0.5,
948
- 35: 0.5
949
- // jaw left/right
950
- };
951
- var CC4_MESHES = {
952
- // Body (6 meshes, 80 morphs each) - default render order 0
953
- "CC_Base_Body_1": { category: "body", morphCount: 80 },
954
- "CC_Base_Body_2": { category: "body", morphCount: 80 },
955
- "CC_Base_Body_3": { category: "body", morphCount: 80 },
956
- "CC_Base_Body_4": { category: "body", morphCount: 80 },
957
- "CC_Base_Body_5": { category: "body", morphCount: 80 },
958
- "CC_Base_Body_6": { category: "body", morphCount: 80 },
959
- // Eyes (bone-driven, no morphs) - render first (behind everything)
960
- "CC_Base_Eye": { category: "eye", morphCount: 0, material: { renderOrder: -10 } },
961
- "CC_Base_Eye_1": { category: "eye", morphCount: 0, material: { renderOrder: -10 } },
962
- "CC_Base_Eye_2": { category: "eye", morphCount: 0, material: { renderOrder: -10 } },
963
- "CC_Base_Eye_3": { category: "eye", morphCount: 0, material: { renderOrder: -10 } },
964
- "CC_Base_Eye_4": { category: "eye", morphCount: 0, material: { renderOrder: -10 } },
965
- // Eye occlusion (94 morphs each) - render on top of eyes with transparency support
966
- "CC_Base_EyeOcclusion_1": { category: "eyeOcclusion", morphCount: 94, material: { renderOrder: 2, transparent: true, opacity: 1, depthWrite: true, depthTest: true, blending: "Normal" } },
967
- "CC_Base_EyeOcclusion_2": { category: "eyeOcclusion", morphCount: 94, material: { renderOrder: 2, transparent: true, opacity: 1, depthWrite: true, depthTest: true, blending: "Normal" } },
968
- // Tear lines (90 morphs each) - on top of eyes/face
969
- "CC_Base_TearLine_1": { category: "tearLine", morphCount: 90, material: { renderOrder: 2 } },
970
- "CC_Base_TearLine_2": { category: "tearLine", morphCount: 90, material: { renderOrder: 2 } },
971
- // Cornea (no morphs) - render first with eyes
972
- "CC_Base_Cornea": { category: "cornea", morphCount: 0, material: { renderOrder: -10 } },
973
- "CC_Base_Cornea_1": { category: "cornea", morphCount: 0, material: { renderOrder: -10 } },
974
- // Teeth (no morphs, follow jaw bone) - default render order
975
- "CC_Base_Teeth_1": { category: "teeth", morphCount: 0 },
976
- "CC_Base_Teeth_2": { category: "teeth", morphCount: 0 },
977
- // Tongue (23 morphs) - default render order
978
- "CC_Base_Tongue": { category: "tongue", morphCount: 23 },
979
- // Eyebrows (91 morphs each) - above face
980
- "Male_Bushy_1": { category: "eyebrow", morphCount: 91, material: { renderOrder: 5 } },
981
- "Male_Bushy_2": { category: "eyebrow", morphCount: 91, material: { renderOrder: 5 } },
982
- // Hair (14 styling morphs each) - render last (on top of everything)
983
- "Side_part_wavy_1": { category: "hair", morphCount: 14, material: { renderOrder: 10 } },
984
- "Side_part_wavy_2": { category: "hair", morphCount: 14, material: { renderOrder: 10 } }
985
- };
986
- var MORPH_TO_MESH = {
987
- // Face/AU morphs target the main body mesh only.
988
- // Include both CC4 naming variants (with and without _1/_2 suffixes).
989
- face: ["CC_Base_Body"],
990
- viseme: ["CC_Base_Body", "CC_Base_Body_1"],
991
- eye: ["CC_Base_EyeOcclusion", "CC_Base_EyeOcclusion_1", "CC_Base_EyeOcclusion_2"],
992
- tongue: ["CC_Base_Tongue", "CC_Base_Tongue_1"],
993
- hair: ["Side_part_wavy", "Side_part_wavy_1", "Side_part_wavy_2"]
994
- };
995
- var AU_FACEPART_TO_MESH_CATEGORY = {
996
- Eye: "eye",
997
- Eyes: "eye",
998
- Eyelids: "eye",
999
- Tongue: "tongue"
1000
- };
1001
- var CC4_MAPPING_SECTIONS = [
1002
- { id: "Forehead", label: "Forehead", kind: "au", order: 0, meshCategory: "face", facePart: "Forehead" },
1003
- { id: "Eyelids", label: "Eyelids", kind: "au", order: 1, meshCategory: "eye", facePart: "Eyelids" },
1004
- { id: "Eyes", label: "Eyes", kind: "au", order: 2, meshCategory: "eye", facePart: "Eyes" },
1005
- { id: "Cheeks", label: "Cheeks", kind: "au", order: 3, meshCategory: "face", facePart: "Cheeks" },
1006
- { id: "Nose", label: "Nose", kind: "au", order: 4, meshCategory: "face", facePart: "Nose" },
1007
- { id: "Mouth", label: "Mouth", kind: "au", order: 5, meshCategory: "face", facePart: "Mouth" },
1008
- { id: "Chin", label: "Chin", kind: "au", order: 6, meshCategory: "face", facePart: "Chin" },
1009
- { id: "Jaw", label: "Jaw", kind: "au", order: 7, meshCategory: "face", facePart: "Jaw" },
1010
- { id: "Tongue", label: "Tongue", kind: "au", order: 8, meshCategory: "tongue", facePart: "Tongue" },
1011
- { id: "Head", label: "Head", kind: "au", order: 9, meshCategory: "face", facePart: "Head" },
1012
- { id: "Joint Controls", label: "Joint Controls", kind: "au", order: 10, meshCategory: "face", facePart: "Joint Controls" },
1013
- { id: "Eye", label: "Eye", kind: "au", order: 11, meshCategory: "eye", facePart: "Eye" },
1014
- { id: "Hair", label: "Hair", kind: "hair", order: 12, meshCategory: "hair" },
1015
- { id: "Visemes", label: "Visemes", kind: "viseme", order: 13, meshCategory: "viseme" },
1016
- { id: "LipSync", label: "Lip Sync", kind: "lipSync", order: 14, meshCategory: "face" },
1017
- { id: "Unmapped", label: "Unmapped", kind: "unmapped", order: 15, meshCategory: "face" }
1018
- ];
1019
- var CC4_HAIR_PHYSICS = {
1020
- stiffness: 7.5,
1021
- damping: 0.18,
1022
- inertia: 3.5,
1023
- gravity: 12,
1024
- responseScale: 2.5,
1025
- idleSwayAmount: 0.12,
1026
- idleSwaySpeed: 1,
1027
- windStrength: 0,
1028
- windDirectionX: 1,
1029
- windDirectionZ: 0,
1030
- windTurbulence: 0.3,
1031
- windFrequency: 1.4,
1032
- idleClipDuration: 10,
1033
- impulseClipDuration: 1.4,
1034
- direction: {
1035
- yawSign: -1,
1036
- pitchSign: -1
1037
- },
1038
- morphTargets: {
1039
- swayLeft: { key: "L_Hair_Left", axis: "yaw" },
1040
- swayRight: { key: "L_Hair_Right", axis: "yaw" },
1041
- swayFront: { key: "L_Hair_Front", axis: "pitch" },
1042
- fluffRight: { key: "Fluffy_Right", axis: "yaw" },
1043
- fluffBottom: { key: "Fluffy_Bottom_ALL", axis: "pitch" },
1044
- headUp: {
1045
- Hairline_High_ALL: { value: 0.45, axis: "pitch" },
1046
- Length_Short: { value: 0.65, axis: "pitch" }
1047
- },
1048
- headDown: {
1049
- L_Hair_Front: { value: 2, axis: "pitch" },
1050
- Fluffy_Bottom_ALL: { value: 1, axis: "pitch" }
1051
- }
1052
- }
1053
- };
1054
- var CC4_PRESET = {
1055
- name: "Character Creator 4",
1056
- animalType: "human",
1057
- // No emoji for humans - uses FaTheaterMasks icon instead
1058
- auToMorphs: AU_TO_MORPHS,
1059
- auToBones: CC4_PROFILE_BONE_BINDINGS,
1060
- boneNodes: CC4_BONE_NODES,
1061
- bonePrefix: CC4_BONE_PREFIX,
1062
- suffixPattern: CC4_SUFFIX_PATTERN,
1063
- morphToMesh: MORPH_TO_MESH,
1064
- auFacePartToMeshCategory: AU_FACEPART_TO_MESH_CATEGORY,
1065
- mappingSections: CC4_MAPPING_SECTIONS,
1066
- visemeKeys: VISEME_KEYS,
1067
- visemeSystemId: CC4_VISEME_SYSTEM_ID,
1068
- visemeSlots: CC4_VISEME_SLOTS,
1069
- visemeMeshCategory: "viseme",
1070
- visemeJawAmounts: VISEME_JAW_AMOUNTS,
1071
- auMixDefaults: AU_MIX_DEFAULTS,
1072
- auInfo: AU_INFO,
1073
- eyeMeshNodes: CC4_EYE_MESH_NODES,
1074
- meshes: CC4_MESHES,
1075
- continuumPairs: CONTINUUM_PAIRS_MAP,
1076
- continuumLabels: CONTINUUM_LABELS,
1077
- hairPhysics: CC4_HAIR_PHYSICS,
1078
- annotationRegions: [
1079
- {
1080
- name: "full_body",
1081
- objects: ["*"],
1082
- paddingFactor: 2
1083
- },
1084
- {
1085
- name: "head",
1086
- bones: ["HEAD", "JAW"],
1087
- paddingFactor: 1.5,
1088
- children: ["face", "left_eye", "right_eye", "mouth"],
1089
- expandAnimation: "staggered"
1090
- },
1091
- {
1092
- name: "face",
1093
- bones: ["HEAD"],
1094
- // meshes: populated by user selection in wizard - varies per character
1095
- paddingFactor: 1.3,
1096
- parent: "head"
1097
- },
1098
- {
1099
- name: "left_eye",
1100
- bones: ["EYE_L"],
1101
- paddingFactor: 0.9,
1102
- parent: "head"
1103
- },
1104
- {
1105
- name: "right_eye",
1106
- bones: ["EYE_R"],
1107
- paddingFactor: 0.9,
1108
- parent: "head"
1109
- },
1110
- {
1111
- name: "mouth",
1112
- bones: ["JAW"],
1113
- paddingFactor: 1.5,
1114
- parent: "head"
1115
- },
1116
- {
1117
- name: "upper_body",
1118
- bones: [
1119
- "SPINE_02",
1120
- "HEAD",
1121
- "CLAVICLE_L",
1122
- "CLAVICLE_R"
1123
- ],
1124
- paddingFactor: 1.6
1125
- },
1126
- {
1127
- name: "back",
1128
- bones: ["SPINE_01", "SPINE_02"],
1129
- paddingFactor: 1.8,
1130
- cameraAngle: 180
1131
- },
1132
- {
1133
- name: "left_hand",
1134
- bones: ["HAND_L"],
1135
- paddingFactor: 1.3,
1136
- cameraAngle: 270
1137
- },
1138
- {
1139
- name: "right_hand",
1140
- bones: ["HAND_R"],
1141
- paddingFactor: 1.3,
1142
- cameraAngle: 90
1143
- },
1144
- {
1145
- name: "left_foot",
1146
- bones: ["FOOT_L", "TOEBASE_L"],
1147
- paddingFactor: 2.5,
1148
- cameraAngle: 270
1149
- },
1150
- {
1151
- name: "right_foot",
1152
- bones: ["FOOT_R", "TOEBASE_R"],
1153
- paddingFactor: 2.5,
1154
- cameraAngle: 90
1155
- }
1156
- ]
1157
- };
1158
-
1159
- // src/presets/bettaFish.ts
1160
- var BONES = [
1161
- "Armature_rootJoint",
1162
- "Bone_Armature",
1163
- "Bone.001_Armature",
1164
- "Bone.009_Armature",
1165
- "Bone.027_Armature",
1166
- "Bone.029_Armature",
1167
- "Bone.031_Armature",
1168
- "Bone.028_Armature",
1169
- "Bone.030_Armature",
1170
- "Bone.032_Armature",
1171
- "Bone.010_Armature",
1172
- "Bone.012_Armature",
1173
- "Bone.014_Armature",
1174
- "Bone.016_Armature",
1175
- "Bone.011_Armature",
1176
- "Bone.013_Armature",
1177
- "Bone.015_Armature",
1178
- "Bone.017_Armature",
1179
- "Bone.002_Armature",
1180
- "Bone.003_Armature",
1181
- "Bone.004_Armature",
1182
- "Bone.005_Armature",
1183
- "Bone.020_Armature",
1184
- "Bone.025_Armature",
1185
- "Bone.026_Armature",
1186
- "Bone.039_Armature",
1187
- "Bone.040_Armature",
1188
- "Bone.041_Armature",
1189
- "Bone.042_Armature",
1190
- "Bone.043_Armature",
1191
- "Bone.044_Armature",
1192
- "Bone.045_Armature",
1193
- "Bone.019_Armature",
1194
- "Bone.023_Armature",
1195
- "Bone.024_Armature",
1196
- "Bone.034_Armature",
1197
- "Bone.036_Armature",
1198
- "Bone.038_Armature",
1199
- "Bone.018_Armature",
1200
- "Bone.021_Armature",
1201
- "Bone.022_Armature",
1202
- "Bone.033_Armature",
1203
- "Bone.035_Armature",
1204
- "Bone.037_Armature",
1205
- "Bone.046_Armature",
1206
- "Bone.048_Armature",
1207
- "Bone.050_Armature",
1208
- "Bone.047_Armature",
1209
- "Bone.049_Armature",
1210
- "Bone.051_Armature",
1211
- "Bone.006_Armature",
1212
- "Bone.007_Armature",
1213
- "Bone.008_Armature"
1214
- ];
1215
- var BONE_PREFIX = "Bone.";
1216
- var BONE_SUFFIX = "_Armature";
1217
- var BONE_NODES = {
1218
- // Root bones (special - don't use prefix/suffix)
1219
- ROOT: "Armature_rootJoint",
1220
- BODY_ROOT: "Bone_Armature",
1221
- // Head and body (use base names)
1222
- HEAD: "001",
1223
- BODY_FRONT: "002",
1224
- BODY_MID: "003",
1225
- BODY_BACK: "004",
1226
- TAIL_BASE: "005",
1227
- // Gills - bilateral (even = left, odd = right)
1228
- GILL_L: "046",
1229
- GILL_L_MID: "048",
1230
- GILL_L_TIP: "050",
1231
- GILL_R: "047",
1232
- GILL_R_MID: "049",
1233
- GILL_R_TIP: "051",
1234
- // Dorsal fin (top fin)
1235
- DORSAL_ROOT: "006",
1236
- DORSAL_L: "007",
1237
- DORSAL_R: "008",
1238
- // Ventral fins (belly fins)
1239
- VENTRAL_L: "018",
1240
- VENTRAL_L_MID: "021",
1241
- VENTRAL_L_TIP: "022",
1242
- VENTRAL_R: "033",
1243
- VENTRAL_R_MID: "035",
1244
- VENTRAL_R_TIP: "037",
1245
- // Pectoral fins - left side chain
1246
- PECTORAL_L_ROOT: "009",
1247
- PECTORAL_L_CHAIN1: "027",
1248
- PECTORAL_L_CHAIN1_MID: "029",
1249
- PECTORAL_L_CHAIN1_TIP: "031",
1250
- PECTORAL_L_CHAIN2: "028",
1251
- PECTORAL_L_CHAIN2_MID: "030",
1252
- PECTORAL_L_CHAIN2_TIP: "032",
1253
- // Pectoral fins - right side chain
1254
- PECTORAL_R_ROOT: "010",
1255
- PECTORAL_R_CHAIN1: "012",
1256
- PECTORAL_R_CHAIN1_A: "014",
1257
- PECTORAL_R_CHAIN1_B: "016",
1258
- PECTORAL_R_ROOT2: "011",
1259
- PECTORAL_R_CHAIN2: "013",
1260
- PECTORAL_R_CHAIN2_A: "015",
1261
- PECTORAL_R_CHAIN2_B: "017",
1262
- // Eyes (special - mesh name, not bone)
1263
- EYE_L: "EYES_0",
1264
- EYE_R: "EYES_0",
1265
- // Main tail fins
1266
- TAIL_TOP: "020",
1267
- TAIL_TOP_MID: "025",
1268
- TAIL_TOP_TIP: "026",
1269
- TAIL_MID: "039",
1270
- TAIL_MID_A: "040",
1271
- TAIL_MID_A_TIP: "041",
1272
- TAIL_MID_B: "042",
1273
- TAIL_MID_B_TIP: "043",
1274
- TAIL_MID_C: "044",
1275
- TAIL_MID_C_TIP: "045",
1276
- // Side tail chains
1277
- TAIL_SIDE_L: "019",
1278
- TAIL_SIDE_L_MID: "023",
1279
- TAIL_SIDE_L_TIP: "024",
1280
- TAIL_SIDE_R: "034",
1281
- TAIL_SIDE_R_MID: "036",
1282
- TAIL_SIDE_R_TIP: "038"
1283
- };
1284
- var BONE_BINDINGS = {
1285
- // ========== BODY ORIENTATION (AU 2-7) ==========
1286
- // AU 2: Turn Left
1287
- 2: [
1288
- { node: "HEAD", channel: "ry", scale: 1, maxDegrees: 30 },
1289
- { node: "BODY_FRONT", channel: "ry", scale: 1, maxDegrees: 14 },
1290
- { node: "BODY_MID", channel: "ry", scale: 1, maxDegrees: 5 }
1291
- ],
1292
- // AU 3: Turn Right
1293
- 3: [
1294
- { node: "HEAD", channel: "ry", scale: -1, maxDegrees: 30 },
1295
- { node: "BODY_FRONT", channel: "ry", scale: -1, maxDegrees: 14 },
1296
- { node: "BODY_MID", channel: "ry", scale: -1, maxDegrees: 5 }
1297
- ],
1298
- // AU 4: Pitch Up
1299
- 4: [
1300
- { node: "HEAD", channel: "rx", scale: -1, maxDegrees: 20 },
1301
- { node: "BODY_FRONT", channel: "rx", scale: -1, maxDegrees: 5 }
1302
- ],
1303
- // AU 5: Pitch Down
1304
- 5: [
1305
- { node: "HEAD", channel: "rx", scale: 1, maxDegrees: 20 },
1306
- { node: "BODY_FRONT", channel: "rx", scale: 1, maxDegrees: 5 }
1307
- ],
1308
- // AU 6: Roll Left
1309
- 6: [
1310
- { node: "BODY_ROOT", channel: "rz", scale: -1, maxDegrees: 25 }
1311
- ],
1312
- // AU 7: Roll Right
1313
- 7: [
1314
- { node: "BODY_ROOT", channel: "rz", scale: 1, maxDegrees: 25 }
1315
- ],
1316
- // ========== TAIL (AU 12-15) ==========
1317
- // Tail sweep uses rz (roll axis) to sweep left/right in fish's local space
1318
- // AU 12: Tail Sweep Left
1319
- 12: [
1320
- { node: "BODY_BACK", channel: "rz", scale: 1, maxDegrees: 15 },
1321
- { node: "TAIL_BASE", channel: "rz", scale: 1, maxDegrees: 30 },
1322
- { node: "TAIL_TOP", channel: "rz", scale: 1, maxDegrees: 20 },
1323
- { node: "TAIL_MID", channel: "rz", scale: 1, maxDegrees: 20 }
1324
- ],
1325
- // AU 13: Tail Sweep Right
1326
- 13: [
1327
- { node: "BODY_BACK", channel: "rz", scale: -1, maxDegrees: 15 },
1328
- { node: "TAIL_BASE", channel: "rz", scale: -1, maxDegrees: 30 },
1329
- { node: "TAIL_TOP", channel: "rz", scale: -1, maxDegrees: 20 },
1330
- { node: "TAIL_MID", channel: "rz", scale: -1, maxDegrees: 20 }
1331
- ],
1332
- // Tail fin spread/close (fan motion)
1333
- // AU 14: Tail Fin Spread
1334
- 14: [
1335
- { node: "TAIL_TOP", channel: "rx", scale: -1, maxDegrees: 20 },
1336
- { node: "TAIL_SIDE_L", channel: "rx", scale: 1, maxDegrees: 15 },
1337
- { node: "TAIL_SIDE_R", channel: "rx", scale: -1, maxDegrees: 15 }
1338
- ],
1339
- // AU 15: Tail Fin Close
1340
- 15: [
1341
- { node: "TAIL_TOP", channel: "rx", scale: 1, maxDegrees: 15 },
1342
- { node: "TAIL_SIDE_L", channel: "rx", scale: -1, maxDegrees: 12 },
1343
- { node: "TAIL_SIDE_R", channel: "rx", scale: 1, maxDegrees: 12 }
1344
- ],
1345
- // ========== PECTORAL FINS (AU 20-27, front/head fins) ==========
1346
- // These are the decorative fins attached to the head (bones 009-017)
1347
- // AU 20: Pectoral L Up
1348
- 20: [
1349
- { node: "PECTORAL_L_ROOT", channel: "rz", scale: 1, maxDegrees: 40 },
1350
- { node: "PECTORAL_L_CHAIN1", channel: "rz", scale: 1, maxDegrees: 20 },
1351
- { node: "PECTORAL_L_CHAIN2", channel: "rz", scale: 1, maxDegrees: 20 }
1352
- ],
1353
- // AU 21: Pectoral L Down
1354
- 21: [
1355
- { node: "PECTORAL_L_ROOT", channel: "rz", scale: -1, maxDegrees: 40 },
1356
- { node: "PECTORAL_L_CHAIN1", channel: "rz", scale: -1, maxDegrees: 20 },
1357
- { node: "PECTORAL_L_CHAIN2", channel: "rz", scale: -1, maxDegrees: 20 }
1358
- ],
1359
- // AU 22: Pectoral R Up
1360
- 22: [
1361
- { node: "PECTORAL_R_ROOT", channel: "rz", scale: -1, maxDegrees: 40 },
1362
- { node: "PECTORAL_R_CHAIN1", channel: "rz", scale: -1, maxDegrees: 20 },
1363
- { node: "PECTORAL_R_ROOT2", channel: "rz", scale: -1, maxDegrees: 40 }
1364
- ],
1365
- // AU 23: Pectoral R Down
1366
- 23: [
1367
- { node: "PECTORAL_R_ROOT", channel: "rz", scale: 1, maxDegrees: 40 },
1368
- { node: "PECTORAL_R_CHAIN1", channel: "rz", scale: 1, maxDegrees: 20 },
1369
- { node: "PECTORAL_R_ROOT2", channel: "rz", scale: 1, maxDegrees: 40 }
1370
- ],
1371
- // AU 24: Pectoral L Forward
1372
- 24: [
1373
- { node: "PECTORAL_L_ROOT", channel: "ry", scale: 1, maxDegrees: 30 }
1374
- ],
1375
- // AU 25: Pectoral L Back
1376
- 25: [
1377
- { node: "PECTORAL_L_ROOT", channel: "ry", scale: -1, maxDegrees: 30 }
1378
- ],
1379
- // AU 26: Pectoral R Forward
1380
- 26: [
1381
- { node: "PECTORAL_R_ROOT", channel: "ry", scale: -1, maxDegrees: 30 }
1382
- ],
1383
- // AU 27: Pectoral R Back
1384
- 27: [
1385
- { node: "PECTORAL_R_ROOT", channel: "ry", scale: 1, maxDegrees: 30 }
1386
- ],
1387
- // ========== VENTRAL FINS (AU 30-33, belly fins) ==========
1388
- // AU 30: Ventral L Up
1389
- 30: [
1390
- { node: "VENTRAL_L", channel: "rz", scale: 1, maxDegrees: 30 },
1391
- { node: "VENTRAL_L_MID", channel: "rz", scale: 1, maxDegrees: 15 }
1392
- ],
1393
- // AU 31: Ventral L Down
1394
- 31: [
1395
- { node: "VENTRAL_L", channel: "rz", scale: -1, maxDegrees: 30 },
1396
- { node: "VENTRAL_L_MID", channel: "rz", scale: -1, maxDegrees: 15 }
1397
- ],
1398
- // AU 32: Ventral R Up
1399
- 32: [
1400
- { node: "VENTRAL_R", channel: "rz", scale: -1, maxDegrees: 30 },
1401
- { node: "VENTRAL_R_MID", channel: "rz", scale: -1, maxDegrees: 15 }
1402
- ],
1403
- // AU 33: Ventral R Down
1404
- 33: [
1405
- { node: "VENTRAL_R", channel: "rz", scale: 1, maxDegrees: 30 },
1406
- { node: "VENTRAL_R_MID", channel: "rz", scale: 1, maxDegrees: 15 }
1407
- ],
1408
- // ========== GILLS (AU 45-46, separate L/R - 0=closed, 1=flared) ==========
1409
- // AU 45: Gill L
1410
- 45: [
1411
- { node: "GILL_L", channel: "rz", scale: 1, maxDegrees: 40 },
1412
- { node: "GILL_L_MID", channel: "rz", scale: 1, maxDegrees: 20 }
1413
- ],
1414
- // AU 46: Gill R
1415
- 46: [
1416
- { node: "GILL_R", channel: "rz", scale: -1, maxDegrees: 40 },
1417
- { node: "GILL_R_MID", channel: "rz", scale: -1, maxDegrees: 20 }
1418
- ],
1419
- // ========== HEAD (AU 51-56, matching FACS standard) ==========
1420
- // AU 51: Head Turn Left
1421
- 51: [
1422
- { node: "HEAD", channel: "ry", scale: 1, maxDegrees: 30 },
1423
- { node: "BODY_FRONT", channel: "ry", scale: 1, maxDegrees: 14 },
1424
- { node: "BODY_MID", channel: "ry", scale: 1, maxDegrees: 5 }
1425
- ],
1426
- // AU 52: Head Turn Right
1427
- 52: [
1428
- { node: "HEAD", channel: "ry", scale: -1, maxDegrees: 30 },
1429
- { node: "BODY_FRONT", channel: "ry", scale: -1, maxDegrees: 14 },
1430
- { node: "BODY_MID", channel: "ry", scale: -1, maxDegrees: 5 }
1431
- ],
1432
- // AU 53: Head Up
1433
- 53: [
1434
- { node: "DORSAL_ROOT", channel: "rx", scale: -1, maxDegrees: 25 },
1435
- { node: "DORSAL_L", channel: "rx", scale: -1, maxDegrees: 15 },
1436
- { node: "DORSAL_R", channel: "rx", scale: -1, maxDegrees: 15 }
1437
- ],
1438
- // AU 54: Head Down
1439
- 54: [
1440
- { node: "DORSAL_ROOT", channel: "rx", scale: 1, maxDegrees: 25 },
1441
- { node: "DORSAL_L", channel: "rx", scale: 1, maxDegrees: 15 },
1442
- { node: "DORSAL_R", channel: "rx", scale: 1, maxDegrees: 15 }
1443
- ],
1444
- // Note: AU 55/56 (Head Tilt) removed - fish don't have this motion
1445
- // ========== EYES (AU 61-64, rotate the EYES_0 mesh) ==========
1446
- // Fish has a single combined eyes mesh - both eyes rotate together
1447
- // AU 61: Eyes Left
1448
- 61: [
1449
- { node: "EYE_L", channel: "ry", scale: 1, maxDegrees: 25 }
1450
- // Look left (yaw)
1451
- ],
1452
- // AU 62: Eyes Right
1453
- 62: [
1454
- { node: "EYE_L", channel: "ry", scale: -1, maxDegrees: 25 }
1455
- // Look right (yaw)
1456
- ],
1457
- // AU 63: Eyes Up
1458
- 63: [
1459
- { node: "EYE_L", channel: "rx", scale: -1, maxDegrees: 20 }
1460
- // Look up (pitch)
1461
- ],
1462
- // AU 64: Eyes Down
1463
- 64: [
1464
- { node: "EYE_L", channel: "rx", scale: 1, maxDegrees: 20 }
1465
- // Look down (pitch)
1466
- ]
1467
- };
1468
- var AU_INFO2 = {
1469
- // Body Orientation
1470
- "2": { id: "2", name: "Turn Left", facePart: "Body Orientation", muscularBasis: "Myomere muscles", links: ["https://en.wikipedia.org/wiki/Myomere"] },
1471
- "3": { id: "3", name: "Turn Right", facePart: "Body Orientation", muscularBasis: "Myomere muscles", links: ["https://en.wikipedia.org/wiki/Myomere"] },
1472
- "4": { id: "4", name: "Pitch Up", facePart: "Body Orientation", muscularBasis: "Epaxial muscles", links: ["https://en.wikipedia.org/wiki/Epaxial_muscles"] },
1473
- "5": { id: "5", name: "Pitch Down", facePart: "Body Orientation", muscularBasis: "Hypaxial muscles", links: ["https://en.wikipedia.org/wiki/Hypaxial_muscles"] },
1474
- "6": { id: "6", name: "Roll Left", facePart: "Body Orientation", muscularBasis: "Lateral body muscles", links: ["https://en.wikipedia.org/wiki/Fish_locomotion"] },
1475
- "7": { id: "7", name: "Roll Right", facePart: "Body Orientation", muscularBasis: "Lateral body muscles", links: ["https://en.wikipedia.org/wiki/Fish_locomotion"] },
1476
- // Tail (Caudal fin)
1477
- "12": { id: "12", name: "Tail Sweep Left", facePart: "Caudal Fin", muscularBasis: "Caudal fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Caudal_fin"] },
1478
- "13": { id: "13", name: "Tail Sweep Right", facePart: "Caudal Fin", muscularBasis: "Caudal fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Caudal_fin"] },
1479
- "14": { id: "14", name: "Tail Fin Spread", facePart: "Caudal Fin", muscularBasis: "Fin ray muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Caudal_fin"] },
1480
- "15": { id: "15", name: "Tail Fin Close", facePart: "Caudal Fin", muscularBasis: "Fin ray muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Caudal_fin"] },
1481
- // Pectoral Fins (side fins for steering and braking)
1482
- "20": { id: "20", name: "Pectoral L Up", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1483
- "21": { id: "21", name: "Pectoral L Down", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1484
- "22": { id: "22", name: "Pectoral R Up", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1485
- "23": { id: "23", name: "Pectoral R Down", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1486
- "24": { id: "24", name: "Pectoral L Forward", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1487
- "25": { id: "25", name: "Pectoral L Back", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1488
- "26": { id: "26", name: "Pectoral R Forward", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1489
- "27": { id: "27", name: "Pectoral R Back", facePart: "Pectoral Fins", muscularBasis: "Pectoral fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pectoral_fins"] },
1490
- // Ventral/Pelvic Fins (belly fins for stability)
1491
- "30": { id: "30", name: "Ventral L Up", facePart: "Pelvic Fins", muscularBasis: "Pelvic fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pelvic_fins"] },
1492
- "31": { id: "31", name: "Ventral L Down", facePart: "Pelvic Fins", muscularBasis: "Pelvic fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pelvic_fins"] },
1493
- "32": { id: "32", name: "Ventral R Up", facePart: "Pelvic Fins", muscularBasis: "Pelvic fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pelvic_fins"] },
1494
- "33": { id: "33", name: "Ventral R Down", facePart: "Pelvic Fins", muscularBasis: "Pelvic fin muscles", links: ["https://en.wikipedia.org/wiki/Fish_fin#Pelvic_fins"] },
1495
- // Gills (separate L/R - single AU per side, 0=closed, 1=flared)
1496
- "45": { id: "45", name: "Gill L", facePart: "Gills", muscularBasis: "Opercular muscles", links: ["https://en.wikipedia.org/wiki/Operculum_(fish)"] },
1497
- "46": { id: "46", name: "Gill R", facePart: "Gills", muscularBasis: "Opercular muscles", links: ["https://en.wikipedia.org/wiki/Operculum_(fish)"] },
1498
- // Head (AU 51-56, matching FACS standard)
1499
- "51": { id: "51", name: "Head Turn Left", facePart: "Head", muscularBasis: "Cranial muscles", links: ["https://en.wikipedia.org/wiki/Fish_anatomy#Head"] },
1500
- "52": { id: "52", name: "Head Turn Right", facePart: "Head", muscularBasis: "Cranial muscles", links: ["https://en.wikipedia.org/wiki/Fish_anatomy#Head"] },
1501
- "53": { id: "53", name: "Head Up", facePart: "Head", muscularBasis: "Cranial muscles", links: ["https://en.wikipedia.org/wiki/Fish_anatomy#Head"] },
1502
- "54": { id: "54", name: "Head Down", facePart: "Head", muscularBasis: "Cranial muscles", links: ["https://en.wikipedia.org/wiki/Fish_anatomy#Head"] },
1503
- // Note: AU 55/56 (Head Tilt) removed - fish don't have this motion
1504
- // Eye movement (similar to human AU 61-64)
1505
- "61": { id: "61", name: "Eyes Left", facePart: "Eyes", muscularBasis: "Extraocular muscles", links: ["https://en.wikipedia.org/wiki/Extraocular_muscles"] },
1506
- "62": { id: "62", name: "Eyes Right", facePart: "Eyes", muscularBasis: "Extraocular muscles", links: ["https://en.wikipedia.org/wiki/Extraocular_muscles"] },
1507
- "63": { id: "63", name: "Eyes Up", facePart: "Eyes", muscularBasis: "Superior rectus", links: ["https://en.wikipedia.org/wiki/Superior_rectus_muscle"] },
1508
- "64": { id: "64", name: "Eyes Down", facePart: "Eyes", muscularBasis: "Inferior rectus", links: ["https://en.wikipedia.org/wiki/Inferior_rectus_muscle"] }
1509
- };
1510
- var CONTINUUM_PAIRS_MAP2 = {
1511
- // Body Orientation (AU 2-7)
1512
- 2: { pairId: 3, isNegative: true, axis: "yaw", node: "HEAD" },
1513
- // Turn Left ↔ Turn Right
1514
- 3: { pairId: 2, isNegative: false, axis: "yaw", node: "HEAD" },
1515
- 5: { pairId: 4, isNegative: true, axis: "pitch", node: "HEAD" },
1516
- // Pitch Down ↔ Pitch Up
1517
- 4: { pairId: 5, isNegative: false, axis: "pitch", node: "HEAD" },
1518
- 6: { pairId: 7, isNegative: true, axis: "roll", node: "BODY_ROOT" },
1519
- // Roll Left ↔ Roll Right
1520
- 7: { pairId: 6, isNegative: false, axis: "roll", node: "BODY_ROOT" },
1521
- // Tail (AU 12-15)
1522
- 12: { pairId: 13, isNegative: true, axis: "roll", node: "TAIL_BASE" },
1523
- // Tail Sweep Left ↔ Right
1524
- 13: { pairId: 12, isNegative: false, axis: "roll", node: "TAIL_BASE" },
1525
- 15: { pairId: 14, isNegative: true, axis: "pitch", node: "TAIL_TOP" },
1526
- // Tail Fin Close ↔ Spread
1527
- 14: { pairId: 15, isNegative: false, axis: "pitch", node: "TAIL_TOP" },
1528
- // Pectoral Fins (AU 20-27)
1529
- 21: { pairId: 20, isNegative: true, axis: "roll", node: "PECTORAL_L_ROOT" },
1530
- // Pectoral L Down ↔ Up
1531
- 20: { pairId: 21, isNegative: false, axis: "roll", node: "PECTORAL_L_ROOT" },
1532
- 25: { pairId: 24, isNegative: true, axis: "yaw", node: "PECTORAL_L_ROOT" },
1533
- // Pectoral L Back ↔ Forward
1534
- 24: { pairId: 25, isNegative: false, axis: "yaw", node: "PECTORAL_L_ROOT" },
1535
- 23: { pairId: 22, isNegative: true, axis: "roll", node: "PECTORAL_R_ROOT" },
1536
- // Pectoral R Down ↔ Up
1537
- 22: { pairId: 23, isNegative: false, axis: "roll", node: "PECTORAL_R_ROOT" },
1538
- 27: { pairId: 26, isNegative: true, axis: "yaw", node: "PECTORAL_R_ROOT" },
1539
- // Pectoral R Back ↔ Forward
1540
- 26: { pairId: 27, isNegative: false, axis: "yaw", node: "PECTORAL_R_ROOT" },
1541
- // Ventral Fins (AU 30-33)
1542
- 31: { pairId: 30, isNegative: true, axis: "roll", node: "VENTRAL_L" },
1543
- // Ventral L Down ↔ Up
1544
- 30: { pairId: 31, isNegative: false, axis: "roll", node: "VENTRAL_L" },
1545
- 33: { pairId: 32, isNegative: true, axis: "roll", node: "VENTRAL_R" },
1546
- // Ventral R Down ↔ Up
1547
- 32: { pairId: 33, isNegative: false, axis: "roll", node: "VENTRAL_R" },
1548
- // Head (AU 51-56, matching FACS standard)
1549
- 51: { pairId: 52, isNegative: true, axis: "yaw", node: "HEAD" },
1550
- // Head Turn Left ↔ Right
1551
- 52: { pairId: 51, isNegative: false, axis: "yaw", node: "HEAD" },
1552
- 54: { pairId: 53, isNegative: true, axis: "pitch", node: "DORSAL_ROOT" },
1553
- // Head Down ↔ Up
1554
- 53: { pairId: 54, isNegative: false, axis: "pitch", node: "DORSAL_ROOT" },
1555
- // Note: AU 55/56 (Head Tilt) removed - fish don't have this motion
1556
- // Gills (AU 45-46) are NOT in continuum - they're single AUs (0=closed, 1=flared)
1557
- // Each side is independent, not paired opposites
1558
- // Eye movement (AU 61-64)
1559
- 61: { pairId: 62, isNegative: true, axis: "yaw", node: "HEAD" },
1560
- // Eyes Left ↔ Right
1561
- 62: { pairId: 61, isNegative: false, axis: "yaw", node: "HEAD" },
1562
- 64: { pairId: 63, isNegative: true, axis: "pitch", node: "HEAD" },
1563
- // Eyes Down ↔ Up
1564
- 63: { pairId: 64, isNegative: false, axis: "pitch", node: "HEAD" }
1565
- };
1566
- function buildContinuumLabel(negativeAU, positiveAU) {
1567
- const negName = negativeAU.name;
1568
- const posName = positiveAU.name;
1569
- const negWords = negName.split(" ");
1570
- const posWords = posName.split(" ");
1571
- let commonPrefixWords = [];
1572
- for (let i = 0; i < Math.min(negWords.length, posWords.length); i++) {
1573
- if (negWords[i] === posWords[i]) {
1574
- commonPrefixWords.push(negWords[i]);
1575
- } else {
1576
- break;
1577
- }
1578
- }
1579
- const prefix = commonPrefixWords.join(" ");
1580
- const negSuffix = negWords.slice(commonPrefixWords.length).join(" ");
1581
- const posSuffix = posWords.slice(commonPrefixWords.length).join(" ");
1582
- if (prefix && negSuffix && posSuffix) {
1583
- return `${prefix} \u2014 ${negSuffix} \u2194 ${posSuffix}`;
1584
- }
1585
- return `${negName} \u2194 ${posName}`;
1586
- }
1587
- function getContinuumLabelForPair(negativeId, positiveId) {
1588
- const negAU = AU_INFO2[String(negativeId)];
1589
- const posAU = AU_INFO2[String(positiveId)];
1590
- if (!negAU || !posAU) {
1591
- return `AU ${negativeId} \u2194 AU ${positiveId}`;
1592
- }
1593
- return buildContinuumLabel(negAU, posAU);
1594
- }
1595
- function buildContinuumLabels() {
1596
- const labels = {};
1597
- const seen = /* @__PURE__ */ new Set();
1598
- for (const [auIdStr, info] of Object.entries(CONTINUUM_PAIRS_MAP2)) {
1599
- if (info.isNegative) {
1600
- const negId = Number(auIdStr);
1601
- const posId = info.pairId;
1602
- const key = `${negId}-${posId}`;
1603
- if (!seen.has(key)) {
1604
- seen.add(key);
1605
- labels[key] = getContinuumLabelForPair(negId, posId);
1606
- }
1607
- }
1608
- }
1609
- return labels;
1610
- }
1611
- var CONTINUUM_LABELS2 = buildContinuumLabels();
1612
- var COMPOSITE_ROTATIONS2 = [
1613
- // ========== HEAD & BODY - Combined entry per node (like CC4) ==========
1614
- // AU 51/52 = Head Turn Left/Right (yaw)
1615
- // AU 53/54 = Head Up/Down (pitch) - note: pitch on HEAD is from body AUs 4/5
1616
- // No head tilt for fish - removed AU 55/56
1617
- {
1618
- node: "HEAD",
1619
- pitch: { aus: [4, 5], axis: "rx", negative: 5, positive: 4 },
1620
- // Body Pitch Up/Down
1621
- yaw: { aus: [51, 52], axis: "ry", negative: 51, positive: 52 },
1622
- // Head Turn Left/Right
1623
- roll: null
1624
- },
1625
- {
1626
- node: "BODY_FRONT",
1627
- pitch: { aus: [4, 5], axis: "rx", negative: 5, positive: 4 },
1628
- // Body Pitch Up/Down
1629
- yaw: { aus: [51, 52], axis: "ry", negative: 51, positive: 52 },
1630
- // Head Turn Left/Right
1631
- roll: null
1632
- },
1633
- {
1634
- node: "BODY_MID",
1635
- pitch: null,
1636
- yaw: { aus: [51, 52], axis: "ry", negative: 51, positive: 52 },
1637
- // Head Turn Left/Right
1638
- roll: null
1639
- },
1640
- {
1641
- node: "BODY_ROOT",
1642
- pitch: null,
1643
- yaw: null,
1644
- roll: { aus: [6, 7], axis: "rz", negative: 6, positive: 7 }
1645
- // Body Roll Left/Right
1646
- },
1647
- // ========== TAIL (AU 12-15) ==========
1648
- // Tail sweep uses rz (roll axis) to sweep left/right in fish's local space
1649
- {
1650
- node: "TAIL_BASE",
1651
- pitch: null,
1652
- yaw: null,
1653
- roll: { aus: [12, 13], axis: "rz", negative: 13, positive: 12 }
1654
- // Tail Sweep Left/Right
1655
- },
1656
- {
1657
- node: "BODY_BACK",
1658
- pitch: null,
1659
- yaw: null,
1660
- roll: { aus: [12, 13], axis: "rz", negative: 13, positive: 12 }
1661
- },
1662
- {
1663
- node: "TAIL_TOP",
1664
- pitch: { aus: [14, 15], axis: "rx", negative: 15, positive: 14 },
1665
- // Tail Fin Spread/Close
1666
- yaw: null,
1667
- roll: { aus: [12, 13], axis: "rz", negative: 13, positive: 12 }
1668
- },
1669
- {
1670
- node: "TAIL_MID",
1671
- pitch: null,
1672
- yaw: null,
1673
- roll: { aus: [12, 13], axis: "rz", negative: 13, positive: 12 }
1674
- },
1675
- // Side tail fins for spread/close
1676
- {
1677
- node: "TAIL_SIDE_L",
1678
- pitch: { aus: [14, 15], axis: "rx", negative: 15, positive: 14 },
1679
- yaw: null,
1680
- roll: null
1681
- },
1682
- {
1683
- node: "TAIL_SIDE_R",
1684
- pitch: { aus: [14, 15], axis: "rx", negative: 15, positive: 14 },
1685
- yaw: null,
1686
- roll: null
1687
- },
1688
- // ========== PECTORAL FINS (AU 20-27, head-attached decorative fins) ==========
1689
- {
1690
- node: "PECTORAL_L_ROOT",
1691
- pitch: null,
1692
- yaw: { aus: [24, 25], axis: "ry", negative: 25, positive: 24 },
1693
- // Pectoral L Forward/Back
1694
- roll: { aus: [20, 21], axis: "rz", negative: 21, positive: 20 }
1695
- // Pectoral L Up/Down
1696
- },
1697
- {
1698
- node: "PECTORAL_L_CHAIN1",
1699
- pitch: null,
1700
- yaw: null,
1701
- roll: { aus: [20, 21], axis: "rz", negative: 21, positive: 20 }
1702
- },
1703
- {
1704
- node: "PECTORAL_L_CHAIN2",
1705
- pitch: null,
1706
- yaw: null,
1707
- roll: { aus: [20, 21], axis: "rz", negative: 21, positive: 20 }
1708
- },
1709
- {
1710
- node: "PECTORAL_R_ROOT",
1711
- pitch: null,
1712
- yaw: { aus: [26, 27], axis: "ry", negative: 27, positive: 26 },
1713
- // Pectoral R Forward/Back
1714
- roll: { aus: [22, 23], axis: "rz", negative: 23, positive: 22 }
1715
- // Pectoral R Up/Down
1716
- },
1717
- {
1718
- node: "PECTORAL_R_ROOT2",
1719
- pitch: null,
1720
- yaw: null,
1721
- roll: { aus: [22, 23], axis: "rz", negative: 23, positive: 22 }
1722
- },
1723
- {
1724
- node: "PECTORAL_R_CHAIN1",
1725
- pitch: null,
1726
- yaw: null,
1727
- roll: { aus: [22, 23], axis: "rz", negative: 23, positive: 22 }
1728
- },
1729
- // ========== VENTRAL FINS (AU 30-33, belly fins) ==========
1730
- {
1731
- node: "VENTRAL_L",
1732
- pitch: null,
1733
- yaw: null,
1734
- roll: { aus: [30, 31], axis: "rz", negative: 31, positive: 30 }
1735
- // Ventral L Up/Down
1736
- },
1737
- {
1738
- node: "VENTRAL_L_MID",
1739
- pitch: null,
1740
- yaw: null,
1741
- roll: { aus: [30, 31], axis: "rz", negative: 31, positive: 30 }
1742
- },
1743
- {
1744
- node: "VENTRAL_R",
1745
- pitch: null,
1746
- yaw: null,
1747
- roll: { aus: [32, 33], axis: "rz", negative: 33, positive: 32 }
1748
- // Ventral R Up/Down
1749
- },
1750
- {
1751
- node: "VENTRAL_R_MID",
1752
- pitch: null,
1753
- yaw: null,
1754
- roll: { aus: [32, 33], axis: "rz", negative: 33, positive: 32 }
1755
- },
1756
- // ========== DORSAL FIN (AU 53/54 - Head Up/Down via dorsal bones) ==========
1757
- // In this fish model, the dorsal bones control the head's vertical movement
1758
- // No head tilt for fish - AU 55/56 removed
1759
- {
1760
- node: "DORSAL_ROOT",
1761
- pitch: { aus: [53, 54], axis: "rx", negative: 54, positive: 53 },
1762
- // Head Up/Down
1763
- yaw: null,
1764
- roll: null
1765
- },
1766
- {
1767
- node: "DORSAL_L",
1768
- pitch: { aus: [53, 54], axis: "rx", negative: 54, positive: 53 },
1769
- yaw: null,
1770
- roll: null
1771
- },
1772
- {
1773
- node: "DORSAL_R",
1774
- pitch: { aus: [53, 54], axis: "rx", negative: 54, positive: 53 },
1775
- yaw: null,
1776
- roll: null
1777
- },
1778
- // ========== GILLS (AU 45-46, separate L/R - single AU per side, not continuum) ==========
1779
- // AU 45 controls left side only, AU 46 controls right side only
1780
- // These are intensity-only AUs (0=closed, 1=flared) - no negative partner
1781
- {
1782
- node: "GILL_L",
1783
- pitch: null,
1784
- yaw: null,
1785
- roll: { aus: [45], axis: "rz", negative: void 0, positive: 45 }
1786
- // Gill L
1787
- },
1788
- {
1789
- node: "GILL_L_MID",
1790
- pitch: null,
1791
- yaw: null,
1792
- roll: { aus: [45], axis: "rz", negative: void 0, positive: 45 }
1793
- },
1794
- {
1795
- node: "GILL_R",
1796
- pitch: null,
1797
- yaw: null,
1798
- roll: { aus: [46], axis: "rz", negative: void 0, positive: 46 }
1799
- // Gill R
1800
- },
1801
- {
1802
- node: "GILL_R_MID",
1803
- pitch: null,
1804
- yaw: null,
1805
- roll: { aus: [46], axis: "rz", negative: void 0, positive: 46 }
1806
- },
1807
- // ========== EYES (AU 61-64) ==========
1808
- // Single EYES_0 mesh rotates both fish eyes together
1809
- {
1810
- node: "EYE_L",
1811
- pitch: { aus: [63, 64], axis: "rx", negative: 64, positive: 63 },
1812
- // Eyes Up/Down
1813
- yaw: { aus: [61, 62], axis: "ry", negative: 62, positive: 61 },
1814
- // Eyes Left/Right
1815
- roll: null
1816
- }
1817
- ];
1818
- var EYE_MESH_NODES = {
1819
- LEFT: "EYES_0",
1820
- RIGHT: "EYES_0"
1821
- // Same mesh, both eyes rotate together
1822
- };
1823
- var MESHES = {
1824
- // Body mesh - main fish body with proper depth and blending
1825
- "BODY_0": {
1826
- category: "body",
1827
- morphCount: 0,
1828
- // Fish model has no morphs
1829
- material: {
1830
- renderOrder: 20,
1831
- transparent: true,
1832
- opacity: 1,
1833
- depthWrite: true,
1834
- depthTest: true,
1835
- blending: "Normal"
1836
- }
1837
- },
1838
- // Eyes mesh - render behind body with proper transparency support
1839
- "EYES_0": {
1840
- category: "eye",
1841
- morphCount: 0,
1842
- material: {
1843
- renderOrder: 17,
1844
- transparent: true,
1845
- opacity: 1,
1846
- depthWrite: true,
1847
- depthTest: true,
1848
- blending: "Normal"
1849
- }
1850
- },
1851
- // Hidden helper shell from the source asset; keep it suppressed by default
1852
- // so Betta does not rely on a Firestore-only mesh override.
1853
- "Cube_0": {
1854
- category: "body",
1855
- morphCount: 0,
1856
- material: {
1857
- renderOrder: -20,
1858
- transparent: true,
1859
- opacity: 0,
1860
- depthWrite: true,
1861
- depthTest: true,
1862
- blending: "Normal"
1863
- }
1864
- }
1865
- };
1866
- var ANNOTATION_REGIONS = [
1867
- {
1868
- name: "full_body",
1869
- objects: ["*"],
1870
- paddingFactor: 2.5
1871
- },
1872
- {
1873
- name: "head",
1874
- bones: ["HEAD"],
1875
- paddingFactor: 1.8,
1876
- children: ["left_eye", "right_eye", "mouth"],
1877
- expandAnimation: "staggered"
1878
- },
1879
- {
1880
- name: "left_eye",
1881
- meshes: ["EYES_0"],
1882
- parent: "head",
1883
- paddingFactor: 1.4,
1884
- cameraAngle: 270
1885
- },
1886
- {
1887
- name: "right_eye",
1888
- meshes: ["EYES_0"],
1889
- parent: "head",
1890
- paddingFactor: 1.4,
1891
- cameraAngle: 90
1892
- },
1893
- {
1894
- name: "mouth",
1895
- bones: ["HEAD"],
1896
- parent: "head",
1897
- paddingFactor: 1.5
1898
- },
1899
- {
1900
- name: "body",
1901
- bones: ["BODY_FRONT", "BODY_MID", "BODY_BACK"],
1902
- paddingFactor: 1.8
1903
- },
1904
- {
1905
- name: "tail",
1906
- bones: ["TAIL_BASE", "TAIL_TOP", "TAIL_MID"],
1907
- paddingFactor: 1.6
1908
- },
1909
- {
1910
- name: "dorsal_fin",
1911
- bones: ["DORSAL_ROOT", "DORSAL_L", "DORSAL_R"],
1912
- paddingFactor: 1.8
1913
- },
1914
- {
1915
- name: "pectoral_fins",
1916
- bones: ["PECTORAL_L_ROOT", "PECTORAL_R_ROOT"],
1917
- paddingFactor: 1.8,
1918
- children: ["pectoral_fin_left", "pectoral_fin_right"],
1919
- expandAnimation: "outward"
1920
- },
1921
- {
1922
- name: "pectoral_fin_left",
1923
- bones: ["PECTORAL_L_ROOT", "PECTORAL_L_CHAIN1", "PECTORAL_L_CHAIN2"],
1924
- parent: "pectoral_fins",
1925
- paddingFactor: 1.6,
1926
- cameraAngle: 270
1927
- },
1928
- {
1929
- name: "pectoral_fin_right",
1930
- bones: ["PECTORAL_R_ROOT", "PECTORAL_R_CHAIN1", "PECTORAL_R_ROOT2"],
1931
- parent: "pectoral_fins",
1932
- paddingFactor: 1.6,
1933
- cameraAngle: 90
1934
- },
1935
- {
1936
- name: "ventral_fins",
1937
- bones: ["VENTRAL_L", "VENTRAL_R"],
1938
- paddingFactor: 1.6
1939
- },
1940
- {
1941
- name: "gills",
1942
- bones: ["GILL_L", "GILL_R"],
1943
- paddingFactor: 1.6,
1944
- children: ["gill_left", "gill_right"],
1945
- expandAnimation: "outward"
1946
- },
1947
- {
1948
- name: "gill_left",
1949
- bones: ["GILL_L", "GILL_L_MID", "GILL_L_TIP"],
1950
- parent: "gills",
1951
- paddingFactor: 1.4,
1952
- cameraAngle: 270,
1953
- style: { lineDirection: "left" }
1954
- },
1955
- {
1956
- name: "gill_right",
1957
- bones: ["GILL_R", "GILL_R_MID", "GILL_R_TIP"],
1958
- parent: "gills",
1959
- paddingFactor: 1.4,
1960
- cameraAngle: 90,
1961
- style: { lineDirection: "right" }
1962
- }
1963
- ];
1964
- var BETTA_FISH_PROFILE = {
1965
- name: "Betta Fish",
1966
- animalType: "fish",
1967
- emoji: "\u{1F41F}",
1968
- auToBones: BONE_BINDINGS,
1969
- boneNodes: BONE_NODES,
1970
- // Prefix/suffix for bone resolution: 'Bone.' + '001' + '_Armature' = 'Bone.001_Armature'
1971
- bonePrefix: BONE_PREFIX,
1972
- boneSuffix: BONE_SUFFIX,
1973
- // Suffix pattern for fuzzy matching (Sketchfab/Blender exports)
1974
- suffixPattern: "_\\d+$|\\.\\d+$",
1975
- auToMorphs: {},
1976
- morphToMesh: {},
1977
- visemeKeys: [],
1978
- auInfo: AU_INFO2,
1979
- compositeRotations: COMPOSITE_ROTATIONS2,
1980
- eyeMeshNodes: EYE_MESH_NODES,
1981
- meshes: MESHES,
1982
- annotationRegions: ANNOTATION_REGIONS,
1983
- auMixDefaults: {},
1984
- // No mixed AUs (morph+bone) in this model
1985
- continuumPairs: CONTINUUM_PAIRS_MAP2,
1986
- continuumLabels: CONTINUUM_LABELS2
1987
- };
1988
- var BETTA_FISH_PRESET = {
1989
- ...BETTA_FISH_PROFILE,
1990
- bones: BONES,
1991
- boneBindings: BONE_BINDINGS,
1992
- actionInfo: AU_INFO2
1993
- };
1994
-
1995
- // src/presets/registry.ts
1996
- var EMBEDDED_PRESETS = {
1997
- cc4: CC4_PRESET,
1998
- fish: BETTA_FISH_PRESET
1999
- };
2000
-
2001
- export { EMBEDDED_PRESETS };
2002
- //# sourceMappingURL=preset.js.map
2003
- //# sourceMappingURL=preset.js.map