@lovelace_lol/embody 0.0.7 → 0.0.9

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