@lovelace_lol/loom3 1.0.27 → 1.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/index.cjs +391 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +152 -224
- package/dist/index.d.ts +152 -224
- package/dist/index.js +384 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -349,6 +349,15 @@ const loom = new Loom3({
|
|
|
349
349
|
|
|
350
350
|
`annotationRegions` is the Loom3 field for camera/marker region defaults and profile overrides.
|
|
351
351
|
|
|
352
|
+
If your app fetches a full saved `CharacterConfig` from Firestore or another backend, use `extendCharacterConfigWithPreset(...)` to build the runtime shape before handing that config to camera/marker tooling:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import { extendCharacterConfigWithPreset } from '@lovelace_lol/loom3';
|
|
356
|
+
|
|
357
|
+
const savedConfig = await fetchCharacterConfig();
|
|
358
|
+
const runtimeConfig = extendCharacterConfigWithPreset(savedConfig);
|
|
359
|
+
```
|
|
360
|
+
|
|
352
361
|
For the current runtime-oriented documentation, including:
|
|
353
362
|
|
|
354
363
|
- `paddingFactor`
|
package/dist/index.cjs
CHANGED
|
@@ -1887,7 +1887,17 @@ var CC4_BONE_NODES = {
|
|
|
1887
1887
|
NECK: "NeckTwist01",
|
|
1888
1888
|
NECK_TWIST: "NeckTwist02",
|
|
1889
1889
|
JAW: "JawRoot",
|
|
1890
|
-
TONGUE: "Tongue01"
|
|
1890
|
+
TONGUE: "Tongue01",
|
|
1891
|
+
SPINE_01: "Spine01",
|
|
1892
|
+
SPINE_02: "Spine02",
|
|
1893
|
+
CLAVICLE_L: "L_Clavicle",
|
|
1894
|
+
CLAVICLE_R: "R_Clavicle",
|
|
1895
|
+
HAND_L: "L_Hand",
|
|
1896
|
+
HAND_R: "R_Hand",
|
|
1897
|
+
FOOT_L: "L_Foot",
|
|
1898
|
+
FOOT_R: "R_Foot",
|
|
1899
|
+
TOEBASE_L: "L_ToeBase",
|
|
1900
|
+
TOEBASE_R: "R_ToeBase"
|
|
1891
1901
|
};
|
|
1892
1902
|
var CC4_EYE_MESH_NODES = {
|
|
1893
1903
|
LEFT: "CC_Base_Eye",
|
|
@@ -2125,7 +2135,7 @@ var CC4_PRESET = {
|
|
|
2125
2135
|
},
|
|
2126
2136
|
{
|
|
2127
2137
|
name: "head",
|
|
2128
|
-
bones: ["
|
|
2138
|
+
bones: ["HEAD", "JAW"],
|
|
2129
2139
|
paddingFactor: 1.5,
|
|
2130
2140
|
children: ["face", "left_eye", "right_eye", "mouth"],
|
|
2131
2141
|
expandAnimation: "staggered",
|
|
@@ -2133,66 +2143,66 @@ var CC4_PRESET = {
|
|
|
2133
2143
|
},
|
|
2134
2144
|
{
|
|
2135
2145
|
name: "face",
|
|
2136
|
-
bones: ["
|
|
2146
|
+
bones: ["HEAD"],
|
|
2137
2147
|
// meshes: populated by user selection in wizard - varies per character
|
|
2138
2148
|
paddingFactor: 1.3,
|
|
2139
2149
|
parent: "head"
|
|
2140
2150
|
},
|
|
2141
2151
|
{
|
|
2142
2152
|
name: "left_eye",
|
|
2143
|
-
bones: ["
|
|
2153
|
+
bones: ["EYE_L"],
|
|
2144
2154
|
paddingFactor: 0.9,
|
|
2145
2155
|
parent: "head"
|
|
2146
2156
|
},
|
|
2147
2157
|
{
|
|
2148
2158
|
name: "right_eye",
|
|
2149
|
-
bones: ["
|
|
2159
|
+
bones: ["EYE_R"],
|
|
2150
2160
|
paddingFactor: 0.9,
|
|
2151
2161
|
parent: "head"
|
|
2152
2162
|
},
|
|
2153
2163
|
{
|
|
2154
2164
|
name: "mouth",
|
|
2155
|
-
bones: ["
|
|
2165
|
+
bones: ["JAW"],
|
|
2156
2166
|
paddingFactor: 1.5,
|
|
2157
2167
|
parent: "head"
|
|
2158
2168
|
},
|
|
2159
2169
|
{
|
|
2160
2170
|
name: "upper_body",
|
|
2161
2171
|
bones: [
|
|
2162
|
-
"
|
|
2163
|
-
"
|
|
2164
|
-
"
|
|
2165
|
-
"
|
|
2172
|
+
"SPINE_02",
|
|
2173
|
+
"HEAD",
|
|
2174
|
+
"CLAVICLE_L",
|
|
2175
|
+
"CLAVICLE_R"
|
|
2166
2176
|
],
|
|
2167
2177
|
paddingFactor: 1.6
|
|
2168
2178
|
},
|
|
2169
2179
|
{
|
|
2170
2180
|
name: "back",
|
|
2171
|
-
bones: ["
|
|
2181
|
+
bones: ["SPINE_01", "SPINE_02"],
|
|
2172
2182
|
paddingFactor: 1.8,
|
|
2173
2183
|
cameraAngle: 180
|
|
2174
2184
|
},
|
|
2175
2185
|
{
|
|
2176
2186
|
name: "left_hand",
|
|
2177
|
-
bones: ["
|
|
2187
|
+
bones: ["HAND_L"],
|
|
2178
2188
|
paddingFactor: 1.3,
|
|
2179
2189
|
cameraAngle: 270
|
|
2180
2190
|
},
|
|
2181
2191
|
{
|
|
2182
2192
|
name: "right_hand",
|
|
2183
|
-
bones: ["
|
|
2193
|
+
bones: ["HAND_R"],
|
|
2184
2194
|
paddingFactor: 1.3,
|
|
2185
2195
|
cameraAngle: 90
|
|
2186
2196
|
},
|
|
2187
2197
|
{
|
|
2188
2198
|
name: "left_foot",
|
|
2189
|
-
bones: ["
|
|
2199
|
+
bones: ["FOOT_L", "TOEBASE_L"],
|
|
2190
2200
|
paddingFactor: 2.5,
|
|
2191
2201
|
cameraAngle: 270
|
|
2192
2202
|
},
|
|
2193
2203
|
{
|
|
2194
2204
|
name: "right_foot",
|
|
2195
|
-
bones: ["
|
|
2205
|
+
bones: ["FOOT_R", "TOEBASE_R"],
|
|
2196
2206
|
paddingFactor: 2.5,
|
|
2197
2207
|
cameraAngle: 90
|
|
2198
2208
|
}
|
|
@@ -3005,6 +3015,9 @@ function resolveProfile(base, override) {
|
|
|
3005
3015
|
hairPhysics: mergeHairPhysicsConfig(base.hairPhysics, override.hairPhysics)
|
|
3006
3016
|
};
|
|
3007
3017
|
}
|
|
3018
|
+
function applyProfileToPreset(base, override) {
|
|
3019
|
+
return override ? resolveProfile(base, override) : base;
|
|
3020
|
+
}
|
|
3008
3021
|
|
|
3009
3022
|
// src/presets/bettaFish.ts
|
|
3010
3023
|
var BONES = [
|
|
@@ -3677,6 +3690,9 @@ var MESHES = {
|
|
|
3677
3690
|
morphCount: 0,
|
|
3678
3691
|
// Fish model has no morphs
|
|
3679
3692
|
material: {
|
|
3693
|
+
renderOrder: 20,
|
|
3694
|
+
transparent: true,
|
|
3695
|
+
opacity: 1,
|
|
3680
3696
|
depthWrite: true,
|
|
3681
3697
|
depthTest: true,
|
|
3682
3698
|
blending: "Normal"
|
|
@@ -3687,29 +3703,126 @@ var MESHES = {
|
|
|
3687
3703
|
category: "eye",
|
|
3688
3704
|
morphCount: 0,
|
|
3689
3705
|
material: {
|
|
3690
|
-
renderOrder:
|
|
3691
|
-
|
|
3706
|
+
renderOrder: 17,
|
|
3707
|
+
transparent: true,
|
|
3708
|
+
opacity: 1,
|
|
3709
|
+
depthWrite: true,
|
|
3710
|
+
depthTest: true,
|
|
3711
|
+
blending: "Normal"
|
|
3712
|
+
}
|
|
3713
|
+
},
|
|
3714
|
+
// Hidden helper shell from the source asset; keep it suppressed by default
|
|
3715
|
+
// so Betta does not rely on a Firestore-only mesh override.
|
|
3716
|
+
"Cube_0": {
|
|
3717
|
+
category: "body",
|
|
3718
|
+
morphCount: 0,
|
|
3719
|
+
material: {
|
|
3720
|
+
renderOrder: -20,
|
|
3721
|
+
transparent: true,
|
|
3722
|
+
opacity: 0,
|
|
3692
3723
|
depthWrite: true,
|
|
3693
3724
|
depthTest: true,
|
|
3694
3725
|
blending: "Normal"
|
|
3695
3726
|
}
|
|
3696
3727
|
}
|
|
3697
3728
|
};
|
|
3698
|
-
var
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3729
|
+
var ANNOTATION_REGIONS = [
|
|
3730
|
+
{
|
|
3731
|
+
name: "full_body",
|
|
3732
|
+
objects: ["*"],
|
|
3733
|
+
paddingFactor: 2.5
|
|
3734
|
+
},
|
|
3735
|
+
{
|
|
3736
|
+
name: "head",
|
|
3737
|
+
bones: ["HEAD"],
|
|
3738
|
+
paddingFactor: 1.8,
|
|
3739
|
+
children: ["left_eye", "right_eye", "mouth"],
|
|
3740
|
+
expandAnimation: "staggered"
|
|
3741
|
+
},
|
|
3742
|
+
{
|
|
3743
|
+
name: "left_eye",
|
|
3744
|
+
meshes: ["EYES_0"],
|
|
3745
|
+
parent: "head",
|
|
3746
|
+
paddingFactor: 1.4,
|
|
3747
|
+
cameraAngle: 270
|
|
3748
|
+
},
|
|
3749
|
+
{
|
|
3750
|
+
name: "right_eye",
|
|
3751
|
+
meshes: ["EYES_0"],
|
|
3752
|
+
parent: "head",
|
|
3753
|
+
paddingFactor: 1.4,
|
|
3754
|
+
cameraAngle: 90
|
|
3755
|
+
},
|
|
3756
|
+
{
|
|
3757
|
+
name: "mouth",
|
|
3758
|
+
bones: ["HEAD"],
|
|
3759
|
+
parent: "head",
|
|
3760
|
+
paddingFactor: 1.5
|
|
3761
|
+
},
|
|
3762
|
+
{
|
|
3763
|
+
name: "body",
|
|
3764
|
+
bones: ["BODY_FRONT", "BODY_MID", "BODY_BACK"],
|
|
3765
|
+
paddingFactor: 1.8
|
|
3766
|
+
},
|
|
3767
|
+
{
|
|
3768
|
+
name: "tail",
|
|
3769
|
+
bones: ["TAIL_BASE", "TAIL_TOP", "TAIL_MID"],
|
|
3770
|
+
paddingFactor: 1.6
|
|
3771
|
+
},
|
|
3772
|
+
{
|
|
3773
|
+
name: "dorsal_fin",
|
|
3774
|
+
bones: ["DORSAL_ROOT", "DORSAL_L", "DORSAL_R"],
|
|
3775
|
+
paddingFactor: 1.8
|
|
3776
|
+
},
|
|
3777
|
+
{
|
|
3778
|
+
name: "pectoral_fins",
|
|
3779
|
+
bones: ["PECTORAL_L_ROOT", "PECTORAL_R_ROOT"],
|
|
3780
|
+
paddingFactor: 1.8,
|
|
3781
|
+
children: ["pectoral_fin_left", "pectoral_fin_right"],
|
|
3782
|
+
expandAnimation: "outward"
|
|
3783
|
+
},
|
|
3784
|
+
{
|
|
3785
|
+
name: "pectoral_fin_left",
|
|
3786
|
+
bones: ["PECTORAL_L_ROOT", "PECTORAL_L_CHAIN1", "PECTORAL_L_CHAIN2"],
|
|
3787
|
+
parent: "pectoral_fins",
|
|
3788
|
+
paddingFactor: 1.6,
|
|
3789
|
+
cameraAngle: 270
|
|
3790
|
+
},
|
|
3791
|
+
{
|
|
3792
|
+
name: "pectoral_fin_right",
|
|
3793
|
+
bones: ["PECTORAL_R_ROOT", "PECTORAL_R_CHAIN1", "PECTORAL_R_ROOT2"],
|
|
3794
|
+
parent: "pectoral_fins",
|
|
3795
|
+
paddingFactor: 1.6,
|
|
3796
|
+
cameraAngle: 90
|
|
3797
|
+
},
|
|
3798
|
+
{
|
|
3799
|
+
name: "ventral_fins",
|
|
3800
|
+
bones: ["VENTRAL_L", "VENTRAL_R"],
|
|
3801
|
+
paddingFactor: 1.6
|
|
3802
|
+
},
|
|
3803
|
+
{
|
|
3804
|
+
name: "gills",
|
|
3805
|
+
bones: ["GILL_L", "GILL_R"],
|
|
3806
|
+
paddingFactor: 1.6,
|
|
3807
|
+
children: ["throat", "gill"],
|
|
3808
|
+
expandAnimation: "outward"
|
|
3809
|
+
},
|
|
3810
|
+
{
|
|
3811
|
+
name: "throat",
|
|
3812
|
+
bones: ["GILL_L", "GILL_L_MID", "GILL_L_TIP"],
|
|
3813
|
+
parent: "gills",
|
|
3814
|
+
paddingFactor: 1.4,
|
|
3815
|
+
cameraAngle: 270
|
|
3816
|
+
},
|
|
3817
|
+
{
|
|
3818
|
+
name: "gill",
|
|
3819
|
+
bones: ["GILL_R", "GILL_R_MID", "GILL_R_TIP"],
|
|
3820
|
+
parent: "gills",
|
|
3821
|
+
paddingFactor: 1.4,
|
|
3822
|
+
cameraAngle: 90
|
|
3823
|
+
}
|
|
3824
|
+
];
|
|
3825
|
+
var BETTA_FISH_PROFILE = {
|
|
3713
3826
|
name: "Betta Fish",
|
|
3714
3827
|
animalType: "fish",
|
|
3715
3828
|
emoji: "\u{1F41F}",
|
|
@@ -3727,18 +3840,27 @@ var AU_MAPPING_CONFIG = {
|
|
|
3727
3840
|
compositeRotations: COMPOSITE_ROTATIONS2,
|
|
3728
3841
|
eyeMeshNodes: EYE_MESH_NODES,
|
|
3729
3842
|
meshes: MESHES,
|
|
3843
|
+
annotationRegions: ANNOTATION_REGIONS,
|
|
3730
3844
|
auMixDefaults: {},
|
|
3731
3845
|
// No mixed AUs (morph+bone) in this model
|
|
3732
3846
|
continuumPairs: CONTINUUM_PAIRS_MAP2,
|
|
3733
3847
|
continuumLabels: CONTINUUM_LABELS2
|
|
3734
3848
|
};
|
|
3849
|
+
var BETTA_FISH_PRESET = {
|
|
3850
|
+
...BETTA_FISH_PROFILE,
|
|
3851
|
+
bones: BONES,
|
|
3852
|
+
boneBindings: BONE_BINDINGS,
|
|
3853
|
+
actionInfo: AU_INFO2
|
|
3854
|
+
};
|
|
3855
|
+
var AU_MAPPING_CONFIG = BETTA_FISH_PRESET;
|
|
3856
|
+
var FISH_AU_MAPPING_CONFIG = BETTA_FISH_PRESET;
|
|
3735
3857
|
|
|
3736
3858
|
// src/presets/index.ts
|
|
3737
3859
|
function resolvePreset(presetType) {
|
|
3738
3860
|
switch (presetType) {
|
|
3739
3861
|
case "fish":
|
|
3740
3862
|
case "skeletal":
|
|
3741
|
-
return
|
|
3863
|
+
return BETTA_FISH_PRESET;
|
|
3742
3864
|
case "cc4":
|
|
3743
3865
|
case "custom":
|
|
3744
3866
|
default:
|
|
@@ -3747,7 +3869,7 @@ function resolvePreset(presetType) {
|
|
|
3747
3869
|
}
|
|
3748
3870
|
function resolvePresetWithOverrides(presetType, overrides) {
|
|
3749
3871
|
const base = resolvePreset(presetType);
|
|
3750
|
-
return
|
|
3872
|
+
return applyProfileToPreset(base, overrides);
|
|
3751
3873
|
}
|
|
3752
3874
|
|
|
3753
3875
|
// src/engines/three/Loom3.ts
|
|
@@ -3824,7 +3946,7 @@ var _Loom3 = class _Loom3 {
|
|
|
3824
3946
|
/** Store original emissive colors for highlight reset */
|
|
3825
3947
|
__publicField(this, "originalEmissive", /* @__PURE__ */ new Map());
|
|
3826
3948
|
const basePreset = config.presetType ? resolvePreset(config.presetType) : CC4_PRESET;
|
|
3827
|
-
this.config =
|
|
3949
|
+
this.config = applyProfileToPreset(basePreset, config.profile);
|
|
3828
3950
|
this.mixWeights = { ...this.config.auMixDefaults };
|
|
3829
3951
|
this.animation = animation || new AnimationThree();
|
|
3830
3952
|
this.compositeRotations = this.config.compositeRotations || COMPOSITE_ROTATIONS;
|
|
@@ -5232,6 +5354,199 @@ var BLENDING_MODES = {
|
|
|
5232
5354
|
"None": 0
|
|
5233
5355
|
// THREE.NoBlending
|
|
5234
5356
|
};
|
|
5357
|
+
|
|
5358
|
+
// src/characters/resolveCharacterConfig.ts
|
|
5359
|
+
var PROFILE_OVERRIDE_KEYS = [
|
|
5360
|
+
"name",
|
|
5361
|
+
"animalType",
|
|
5362
|
+
"emoji",
|
|
5363
|
+
"auToMorphs",
|
|
5364
|
+
"auToBones",
|
|
5365
|
+
"boneNodes",
|
|
5366
|
+
"bonePrefix",
|
|
5367
|
+
"boneSuffix",
|
|
5368
|
+
"morphPrefix",
|
|
5369
|
+
"morphSuffix",
|
|
5370
|
+
"suffixPattern",
|
|
5371
|
+
"leftMorphSuffixes",
|
|
5372
|
+
"rightMorphSuffixes",
|
|
5373
|
+
"morphToMesh",
|
|
5374
|
+
"auFacePartToMeshCategory",
|
|
5375
|
+
"visemeKeys",
|
|
5376
|
+
"visemeMeshCategory",
|
|
5377
|
+
"visemeJawAmounts",
|
|
5378
|
+
"auMixDefaults",
|
|
5379
|
+
"auInfo",
|
|
5380
|
+
"eyeMeshNodes",
|
|
5381
|
+
"compositeRotations",
|
|
5382
|
+
"meshes",
|
|
5383
|
+
"continuumPairs",
|
|
5384
|
+
"continuumLabels",
|
|
5385
|
+
"annotationRegions",
|
|
5386
|
+
"hairPhysics"
|
|
5387
|
+
];
|
|
5388
|
+
function isPlainObject2(value) {
|
|
5389
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5390
|
+
}
|
|
5391
|
+
function cloneArray(value) {
|
|
5392
|
+
return value ? value.map((entry) => cloneValue2(entry)) : void 0;
|
|
5393
|
+
}
|
|
5394
|
+
function cloneValue2(value) {
|
|
5395
|
+
if (Array.isArray(value)) {
|
|
5396
|
+
return value.map((entry) => cloneValue2(entry));
|
|
5397
|
+
}
|
|
5398
|
+
if (isPlainObject2(value)) {
|
|
5399
|
+
const next = {};
|
|
5400
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
5401
|
+
next[key] = cloneValue2(entry);
|
|
5402
|
+
}
|
|
5403
|
+
return next;
|
|
5404
|
+
}
|
|
5405
|
+
return value;
|
|
5406
|
+
}
|
|
5407
|
+
function mergeProfileOverrideValue(base, override) {
|
|
5408
|
+
if (override === void 0) {
|
|
5409
|
+
return base === void 0 ? void 0 : cloneValue2(base);
|
|
5410
|
+
}
|
|
5411
|
+
if (Array.isArray(override)) {
|
|
5412
|
+
return cloneValue2(override);
|
|
5413
|
+
}
|
|
5414
|
+
if (isPlainObject2(base) && isPlainObject2(override)) {
|
|
5415
|
+
return {
|
|
5416
|
+
...cloneValue2(base),
|
|
5417
|
+
...cloneValue2(override)
|
|
5418
|
+
};
|
|
5419
|
+
}
|
|
5420
|
+
return cloneValue2(override);
|
|
5421
|
+
}
|
|
5422
|
+
function cloneVector3(value) {
|
|
5423
|
+
return value ? { ...value } : void 0;
|
|
5424
|
+
}
|
|
5425
|
+
function cloneRegion(region) {
|
|
5426
|
+
return {
|
|
5427
|
+
...region,
|
|
5428
|
+
bones: cloneArray(region.bones),
|
|
5429
|
+
meshes: cloneArray(region.meshes),
|
|
5430
|
+
objects: cloneArray(region.objects),
|
|
5431
|
+
children: cloneArray(region.children),
|
|
5432
|
+
cameraOffset: cloneVector3(region.cameraOffset),
|
|
5433
|
+
customPosition: region.customPosition ? { ...region.customPosition } : void 0,
|
|
5434
|
+
style: region.style ? {
|
|
5435
|
+
...region.style,
|
|
5436
|
+
line: region.style.line ? { ...region.style.line } : void 0
|
|
5437
|
+
} : void 0
|
|
5438
|
+
};
|
|
5439
|
+
}
|
|
5440
|
+
function mergeRegion(base, override) {
|
|
5441
|
+
return {
|
|
5442
|
+
...base,
|
|
5443
|
+
...override,
|
|
5444
|
+
bones: override.bones !== void 0 ? [...override.bones] : base.bones ? [...base.bones] : void 0,
|
|
5445
|
+
meshes: override.meshes !== void 0 ? [...override.meshes] : base.meshes ? [...base.meshes] : void 0,
|
|
5446
|
+
objects: override.objects !== void 0 ? [...override.objects] : base.objects ? [...base.objects] : void 0,
|
|
5447
|
+
children: override.children !== void 0 ? [...override.children] : base.children ? [...base.children] : void 0,
|
|
5448
|
+
cameraOffset: override.cameraOffset ? { ...base.cameraOffset, ...override.cameraOffset } : cloneVector3(base.cameraOffset),
|
|
5449
|
+
customPosition: override.customPosition ? { ...override.customPosition } : base.customPosition ? { ...base.customPosition } : void 0,
|
|
5450
|
+
style: override.style ? {
|
|
5451
|
+
...base.style,
|
|
5452
|
+
...override.style,
|
|
5453
|
+
line: override.style.line ? { ...base.style?.line, ...override.style.line } : base.style?.line ? { ...base.style.line } : void 0
|
|
5454
|
+
} : base.style ? {
|
|
5455
|
+
...base.style,
|
|
5456
|
+
line: base.style.line ? { ...base.style.line } : void 0
|
|
5457
|
+
} : void 0
|
|
5458
|
+
};
|
|
5459
|
+
}
|
|
5460
|
+
function mergeRegionsByName(base, override) {
|
|
5461
|
+
if (!base && !override) return void 0;
|
|
5462
|
+
const merged = /* @__PURE__ */ new Map();
|
|
5463
|
+
for (const region of base ?? []) {
|
|
5464
|
+
merged.set(region.name, cloneRegion(region));
|
|
5465
|
+
}
|
|
5466
|
+
for (const region of override ?? []) {
|
|
5467
|
+
const existing = merged.get(region.name);
|
|
5468
|
+
merged.set(region.name, existing ? mergeRegion(existing, region) : cloneRegion(region));
|
|
5469
|
+
}
|
|
5470
|
+
return Array.from(merged.values());
|
|
5471
|
+
}
|
|
5472
|
+
function extractProfileOverrides(config) {
|
|
5473
|
+
const topLevelConfig = config;
|
|
5474
|
+
const legacyNestedOverrides = isPlainObject2(config.profile) ? config.profile : {};
|
|
5475
|
+
const overrides = {};
|
|
5476
|
+
for (const key of PROFILE_OVERRIDE_KEYS) {
|
|
5477
|
+
if (key === "annotationRegions") {
|
|
5478
|
+
const topLevelAnnotationRegions = Array.isArray(topLevelConfig.annotationRegions) ? topLevelConfig.annotationRegions : void 0;
|
|
5479
|
+
const legacyAnnotationRegions = Array.isArray(legacyNestedOverrides.annotationRegions) ? legacyNestedOverrides.annotationRegions : void 0;
|
|
5480
|
+
const presetOverrideRegions = mergeRegionsByName(legacyAnnotationRegions, topLevelAnnotationRegions);
|
|
5481
|
+
const regions = mergeRegionsByName(
|
|
5482
|
+
presetOverrideRegions,
|
|
5483
|
+
Array.isArray(config.regions) && config.regions.length > 0 ? config.regions : void 0
|
|
5484
|
+
);
|
|
5485
|
+
if (regions) {
|
|
5486
|
+
overrides.annotationRegions = regions.map((region) => cloneRegion(region));
|
|
5487
|
+
}
|
|
5488
|
+
continue;
|
|
5489
|
+
}
|
|
5490
|
+
const topLevelValue = topLevelConfig[key];
|
|
5491
|
+
const legacyValue = legacyNestedOverrides[key];
|
|
5492
|
+
const mergedValue = mergeProfileOverrideValue(legacyValue, topLevelValue);
|
|
5493
|
+
if (mergedValue !== void 0) {
|
|
5494
|
+
overrides[key] = mergedValue;
|
|
5495
|
+
}
|
|
5496
|
+
}
|
|
5497
|
+
return overrides;
|
|
5498
|
+
}
|
|
5499
|
+
function applyCharacterProfileToPreset(config) {
|
|
5500
|
+
const presetType = config.auPresetType;
|
|
5501
|
+
if (!presetType) {
|
|
5502
|
+
return null;
|
|
5503
|
+
}
|
|
5504
|
+
return applyProfileToPreset(resolvePreset(presetType), extractProfileOverrides(config));
|
|
5505
|
+
}
|
|
5506
|
+
function orderResolvedRegions(resolvedRegions, prioritizedLists) {
|
|
5507
|
+
if (!resolvedRegions) return void 0;
|
|
5508
|
+
const resolvedByName = new Map(resolvedRegions.map((region) => [region.name, region]));
|
|
5509
|
+
const orderedNames = [];
|
|
5510
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5511
|
+
for (const regions of prioritizedLists) {
|
|
5512
|
+
for (const region of regions ?? []) {
|
|
5513
|
+
if (seen.has(region.name)) continue;
|
|
5514
|
+
seen.add(region.name);
|
|
5515
|
+
orderedNames.push(region.name);
|
|
5516
|
+
}
|
|
5517
|
+
}
|
|
5518
|
+
for (const region of resolvedRegions) {
|
|
5519
|
+
if (seen.has(region.name)) continue;
|
|
5520
|
+
seen.add(region.name);
|
|
5521
|
+
orderedNames.push(region.name);
|
|
5522
|
+
}
|
|
5523
|
+
return orderedNames.map((name) => resolvedByName.get(name)).filter((region) => Boolean(region));
|
|
5524
|
+
}
|
|
5525
|
+
function extendCharacterConfigWithPreset(config) {
|
|
5526
|
+
const presetType = config.auPresetType;
|
|
5527
|
+
if (!presetType || presetType === "custom") {
|
|
5528
|
+
return config;
|
|
5529
|
+
}
|
|
5530
|
+
const profileOverrides = extractProfileOverrides(config);
|
|
5531
|
+
const presetResolvedProfile = applyCharacterProfileToPreset(config);
|
|
5532
|
+
if (!presetResolvedProfile) {
|
|
5533
|
+
return config;
|
|
5534
|
+
}
|
|
5535
|
+
const presetRegions = presetResolvedProfile.annotationRegions;
|
|
5536
|
+
const mergedRegions = mergeRegionsByName(presetRegions, config.regions);
|
|
5537
|
+
const resolvedRegions = orderResolvedRegions(
|
|
5538
|
+
mergedRegions,
|
|
5539
|
+
[config.regions, profileOverrides.annotationRegions, presetRegions]
|
|
5540
|
+
);
|
|
5541
|
+
return {
|
|
5542
|
+
...config,
|
|
5543
|
+
...presetResolvedProfile,
|
|
5544
|
+
regions: resolvedRegions ?? config.regions
|
|
5545
|
+
};
|
|
5546
|
+
}
|
|
5547
|
+
function resolveCharacterConfig(config) {
|
|
5548
|
+
return extendCharacterConfigWithPreset(config);
|
|
5549
|
+
}
|
|
5235
5550
|
var DEFAULT_HEAD_BONE_NAMES = ["CC_Base_Head", "Head", "head", "Bip01_Head"];
|
|
5236
5551
|
var DEFAULT_REFERENCE_HEIGHT = 1.8;
|
|
5237
5552
|
var DEFAULT_FORWARD_OFFSET = 0.08;
|
|
@@ -5416,26 +5731,39 @@ function detectFacingDirection(model, eyeBoneNames = {
|
|
|
5416
5731
|
}
|
|
5417
5732
|
|
|
5418
5733
|
// src/regions/regionMapping.ts
|
|
5419
|
-
function
|
|
5420
|
-
|
|
5734
|
+
function normalizeLooseName(value) {
|
|
5735
|
+
return value.replace(/\./g, "");
|
|
5736
|
+
}
|
|
5737
|
+
function resolveBoneNameCandidates(semanticName, config) {
|
|
5738
|
+
if (!config) return [semanticName];
|
|
5421
5739
|
const { bonePrefix, boneSuffix, boneNodes } = config;
|
|
5422
5740
|
if (!boneNodes || !boneNodes[semanticName]) {
|
|
5423
|
-
return semanticName;
|
|
5741
|
+
return [semanticName];
|
|
5424
5742
|
}
|
|
5425
5743
|
const baseName = boneNodes[semanticName];
|
|
5426
|
-
if (baseName.includes("_") || baseName.includes(".")) {
|
|
5427
|
-
return baseName;
|
|
5428
|
-
}
|
|
5429
5744
|
const prefix = bonePrefix || "";
|
|
5430
5745
|
const suffix = boneSuffix || "";
|
|
5431
|
-
|
|
5746
|
+
if (!prefix && !suffix) {
|
|
5747
|
+
return [baseName];
|
|
5748
|
+
}
|
|
5749
|
+
const prefixedBase = prefix && baseName.startsWith(prefix) ? baseName : prefix + baseName;
|
|
5750
|
+
const fullyAffixed = suffix && !prefixedBase.endsWith(suffix) ? `${prefixedBase}${suffix}` : prefixedBase;
|
|
5751
|
+
return Array.from(/* @__PURE__ */ new Set([fullyAffixed, baseName]));
|
|
5752
|
+
}
|
|
5753
|
+
function resolveBoneName(semanticName, config) {
|
|
5754
|
+
return resolveBoneNameCandidates(semanticName, config)[0] ?? semanticName;
|
|
5432
5755
|
}
|
|
5433
5756
|
function resolveBoneNames(names, config) {
|
|
5434
5757
|
if (!names || names.length === 0) return [];
|
|
5435
|
-
return
|
|
5758
|
+
return Array.from(
|
|
5759
|
+
new Set(
|
|
5760
|
+
names.flatMap((name) => resolveBoneNameCandidates(name, config))
|
|
5761
|
+
)
|
|
5762
|
+
);
|
|
5436
5763
|
}
|
|
5437
5764
|
function fuzzyNameMatch(objectName, targetName, suffixPattern) {
|
|
5438
5765
|
if (objectName === targetName) return true;
|
|
5766
|
+
if (normalizeLooseName(objectName) === normalizeLooseName(targetName)) return true;
|
|
5439
5767
|
if (!objectName.startsWith(targetName)) return false;
|
|
5440
5768
|
const suffix = objectName.slice(targetName.length);
|
|
5441
5769
|
if (suffix === "") return true;
|
|
@@ -5582,6 +5910,9 @@ var HairPhysics = class {
|
|
|
5582
5910
|
|
|
5583
5911
|
// src/validation/generateMappingCorrections.ts
|
|
5584
5912
|
var DEFAULT_MIN_CONFIDENCE = 0.6;
|
|
5913
|
+
function normalizeLooseName2(value) {
|
|
5914
|
+
return value.replace(/\./g, "");
|
|
5915
|
+
}
|
|
5585
5916
|
function levenshteinDistance(a, b) {
|
|
5586
5917
|
const matrix = [];
|
|
5587
5918
|
const aLen = a.length;
|
|
@@ -5618,6 +5949,9 @@ function scoreCandidate(targetBase, candidate, fullTarget, suffixPattern) {
|
|
|
5618
5949
|
if (candidate === fullTarget) {
|
|
5619
5950
|
return { score: 1, reason: "exact match" };
|
|
5620
5951
|
}
|
|
5952
|
+
if (normalizeLooseName2(candidate) === normalizeLooseName2(fullTarget)) {
|
|
5953
|
+
return { score: 1, reason: "separator-normalized exact match" };
|
|
5954
|
+
}
|
|
5621
5955
|
if (suffixPattern && candidate.startsWith(fullTarget)) {
|
|
5622
5956
|
const suffix = candidate.slice(fullTarget.length);
|
|
5623
5957
|
if (suffix === "" || suffixPattern.test(suffix)) {
|
|
@@ -5806,11 +6140,17 @@ function generateMappingCorrections(meshes, skeleton, config, options = {}) {
|
|
|
5806
6140
|
}
|
|
5807
6141
|
|
|
5808
6142
|
// src/validation/validateMappings.ts
|
|
6143
|
+
function normalizeLooseName3(value) {
|
|
6144
|
+
return value.replace(/\./g, "");
|
|
6145
|
+
}
|
|
5809
6146
|
function fuzzyMatch(targetName, candidateName, prefix, suffix, suffixPattern) {
|
|
5810
6147
|
const fullTarget = prefix + targetName + suffix;
|
|
5811
6148
|
if (candidateName === fullTarget) {
|
|
5812
6149
|
return true;
|
|
5813
6150
|
}
|
|
6151
|
+
if (normalizeLooseName3(candidateName) === normalizeLooseName3(fullTarget)) {
|
|
6152
|
+
return true;
|
|
6153
|
+
}
|
|
5814
6154
|
if (suffixPattern && candidateName.startsWith(fullTarget)) {
|
|
5815
6155
|
const suffix2 = candidateName.slice(fullTarget.length);
|
|
5816
6156
|
return suffix2 === "" || suffixPattern.test(suffix2);
|
|
@@ -6526,6 +6866,7 @@ async function analyzeModel(options) {
|
|
|
6526
6866
|
}
|
|
6527
6867
|
|
|
6528
6868
|
exports.AU_INFO = AU_INFO;
|
|
6869
|
+
exports.AU_MAPPING_CONFIG = AU_MAPPING_CONFIG;
|
|
6529
6870
|
exports.AU_MIX_DEFAULTS = AU_MIX_DEFAULTS;
|
|
6530
6871
|
exports.AU_TO_MORPHS = AU_TO_MORPHS;
|
|
6531
6872
|
exports.AnimationThree = AnimationThree;
|
|
@@ -6542,7 +6883,7 @@ exports.COMPOSITE_ROTATIONS = COMPOSITE_ROTATIONS;
|
|
|
6542
6883
|
exports.CONTINUUM_LABELS = CONTINUUM_LABELS;
|
|
6543
6884
|
exports.CONTINUUM_PAIRS_MAP = CONTINUUM_PAIRS_MAP;
|
|
6544
6885
|
exports.DEFAULT_HAIR_PHYSICS_CONFIG = DEFAULT_HAIR_PHYSICS_CONFIG;
|
|
6545
|
-
exports.FISH_AU_MAPPING_CONFIG =
|
|
6886
|
+
exports.FISH_AU_MAPPING_CONFIG = FISH_AU_MAPPING_CONFIG;
|
|
6546
6887
|
exports.HairPhysics = HairPhysics;
|
|
6547
6888
|
exports.Loom3 = Loom3;
|
|
6548
6889
|
exports.Loom3Three = Loom3;
|
|
@@ -6551,10 +6892,14 @@ exports.MORPH_TO_MESH = MORPH_TO_MESH;
|
|
|
6551
6892
|
exports.VISEME_JAW_AMOUNTS = VISEME_JAW_AMOUNTS;
|
|
6552
6893
|
exports.VISEME_KEYS = VISEME_KEYS;
|
|
6553
6894
|
exports.analyzeModel = analyzeModel;
|
|
6895
|
+
exports.applyCharacterProfileToPreset = applyCharacterProfileToPreset;
|
|
6896
|
+
exports.applyProfileToPreset = applyProfileToPreset;
|
|
6554
6897
|
exports.collectMorphMeshes = collectMorphMeshes;
|
|
6555
6898
|
exports.detectFacingDirection = detectFacingDirection;
|
|
6899
|
+
exports.extendCharacterConfigWithPreset = extendCharacterConfigWithPreset;
|
|
6556
6900
|
exports.extractFromGLTF = extractFromGLTF;
|
|
6557
6901
|
exports.extractModelData = extractModelData;
|
|
6902
|
+
exports.extractProfileOverrides = extractProfileOverrides;
|
|
6558
6903
|
exports.findFaceCenter = findFaceCenter;
|
|
6559
6904
|
exports.fuzzyNameMatch = fuzzyNameMatch;
|
|
6560
6905
|
exports.generateMappingCorrections = generateMappingCorrections;
|
|
@@ -6562,8 +6907,10 @@ exports.getModelForwardDirection = getModelForwardDirection;
|
|
|
6562
6907
|
exports.hasLeftRightMorphs = hasLeftRightMorphs;
|
|
6563
6908
|
exports.isMixedAU = isMixedAU;
|
|
6564
6909
|
exports.isPresetCompatible = isPresetCompatible;
|
|
6910
|
+
exports.mergeCharacterRegionsByName = mergeRegionsByName;
|
|
6565
6911
|
exports.resolveBoneName = resolveBoneName;
|
|
6566
6912
|
exports.resolveBoneNames = resolveBoneNames;
|
|
6913
|
+
exports.resolveCharacterConfig = resolveCharacterConfig;
|
|
6567
6914
|
exports.resolveFaceCenter = resolveFaceCenter;
|
|
6568
6915
|
exports.resolvePreset = resolvePreset;
|
|
6569
6916
|
exports.resolvePresetWithOverrides = resolvePresetWithOverrides;
|