@lovelace_lol/loom3 1.0.44 → 1.0.46
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 +16 -15
- package/dist/index.cjs +320 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +264 -212
- package/dist/index.d.ts +264 -212
- package/dist/index.js +303 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7011,7 +7011,7 @@ function normalizeRegionTree(regions, disabledNames) {
|
|
|
7011
7011
|
});
|
|
7012
7012
|
}
|
|
7013
7013
|
|
|
7014
|
-
// src/
|
|
7014
|
+
// src/profiles/resolveProfileConfig.ts
|
|
7015
7015
|
var PROFILE_OVERRIDE_KEYS = [
|
|
7016
7016
|
"name",
|
|
7017
7017
|
"animalType",
|
|
@@ -7118,7 +7118,7 @@ function mergeRegion(base, override) {
|
|
|
7118
7118
|
} : void 0
|
|
7119
7119
|
};
|
|
7120
7120
|
}
|
|
7121
|
-
function
|
|
7121
|
+
function mergeProfileRegionsByName(base, override) {
|
|
7122
7122
|
if (!base && !override) return void 0;
|
|
7123
7123
|
const merged = /* @__PURE__ */ new Map();
|
|
7124
7124
|
for (const region of base ?? []) {
|
|
@@ -7133,6 +7133,10 @@ function mergeRegionsByName(base, override) {
|
|
|
7133
7133
|
function getAnnotationRegions(value) {
|
|
7134
7134
|
return Array.isArray(value) ? value : void 0;
|
|
7135
7135
|
}
|
|
7136
|
+
var mergeRegionsByName = mergeProfileRegionsByName;
|
|
7137
|
+
function getProfilePresetId(config) {
|
|
7138
|
+
return config.profilePresetId ?? config.presetId ?? config.baseProfileId ?? config.auPresetType;
|
|
7139
|
+
}
|
|
7136
7140
|
function getLegacyNestedOverrides(config) {
|
|
7137
7141
|
return isPlainObject2(config.profile) ? config.profile : {};
|
|
7138
7142
|
}
|
|
@@ -7140,12 +7144,12 @@ function getLegacyRuntimeRegions(config) {
|
|
|
7140
7144
|
return Array.isArray(config.regions) && config.regions.length > 0 ? config.regions : void 0;
|
|
7141
7145
|
}
|
|
7142
7146
|
function getCanonicalAnnotationOverrides(config) {
|
|
7143
|
-
return
|
|
7147
|
+
return mergeProfileRegionsByName(
|
|
7144
7148
|
getAnnotationRegions(getLegacyNestedOverrides(config).annotationRegions),
|
|
7145
7149
|
getAnnotationRegions(config.annotationRegions)
|
|
7146
7150
|
);
|
|
7147
7151
|
}
|
|
7148
|
-
function
|
|
7152
|
+
function extractLegacyCharacterProfileOverrides(config) {
|
|
7149
7153
|
const topLevelConfig = config;
|
|
7150
7154
|
const legacyNestedOverrides = getLegacyNestedOverrides(config);
|
|
7151
7155
|
const canonicalAnnotationOverrides = getCanonicalAnnotationOverrides(config);
|
|
@@ -7168,12 +7172,18 @@ function extractProfileOverrides(config) {
|
|
|
7168
7172
|
}
|
|
7169
7173
|
return overrides;
|
|
7170
7174
|
}
|
|
7171
|
-
function
|
|
7172
|
-
|
|
7175
|
+
function extractProfileOverrides(config) {
|
|
7176
|
+
return extractLegacyCharacterProfileOverrides(config);
|
|
7177
|
+
}
|
|
7178
|
+
function resolveProfileFromPreset(config) {
|
|
7179
|
+
const presetType = getProfilePresetId(config);
|
|
7173
7180
|
if (!presetType) {
|
|
7174
7181
|
return null;
|
|
7175
7182
|
}
|
|
7176
|
-
return extendPresetWithProfile(getPreset(presetType),
|
|
7183
|
+
return extendPresetWithProfile(getPreset(presetType), extractLegacyCharacterProfileOverrides(config));
|
|
7184
|
+
}
|
|
7185
|
+
function applyCharacterProfileToPreset(config) {
|
|
7186
|
+
return resolveProfileFromPreset(config);
|
|
7177
7187
|
}
|
|
7178
7188
|
function orderExtendedRegions(extendedRegions, prioritizedLists) {
|
|
7179
7189
|
if (!extendedRegions) return void 0;
|
|
@@ -7194,15 +7204,15 @@ function orderExtendedRegions(extendedRegions, prioritizedLists) {
|
|
|
7194
7204
|
}
|
|
7195
7205
|
return orderedNames.map((name) => extendedByName.get(name)).filter((region) => Boolean(region));
|
|
7196
7206
|
}
|
|
7197
|
-
function
|
|
7198
|
-
const presetType = config
|
|
7207
|
+
function extendProfileConfigWithPreset(config) {
|
|
7208
|
+
const presetType = getProfilePresetId(config);
|
|
7199
7209
|
if (!presetType || presetType === "custom") {
|
|
7200
7210
|
return config;
|
|
7201
7211
|
}
|
|
7202
7212
|
const canonicalAnnotationOverrides = getCanonicalAnnotationOverrides(config);
|
|
7203
7213
|
const legacyRuntimeRegions = getLegacyRuntimeRegions(config);
|
|
7204
|
-
const profileOverrides =
|
|
7205
|
-
const extendedPresetProfile =
|
|
7214
|
+
const profileOverrides = extractLegacyCharacterProfileOverrides(config);
|
|
7215
|
+
const extendedPresetProfile = resolveProfileFromPreset(config);
|
|
7206
7216
|
if (!extendedPresetProfile) {
|
|
7207
7217
|
return config;
|
|
7208
7218
|
}
|
|
@@ -7216,7 +7226,7 @@ function extendCharacterConfigWithPreset(config) {
|
|
|
7216
7226
|
const extendedRegionNames = new Set((extendedAnnotationRegions ?? []).map((region) => region.name));
|
|
7217
7227
|
const legacyExtraRegions = canonicalAnnotationOverrides && legacyRuntimeRegions ? legacyRuntimeRegions.filter((region) => !presetRegionNames.has(region.name) && !extendedRegionNames.has(region.name)).map((region) => cloneRegion(region)) : void 0;
|
|
7218
7228
|
const mergedRegions = normalizeRegionTree(
|
|
7219
|
-
|
|
7229
|
+
mergeProfileRegionsByName(extendedAnnotationRegions, legacyExtraRegions),
|
|
7220
7230
|
profileOverrides.disabledRegions
|
|
7221
7231
|
);
|
|
7222
7232
|
const extendedRegions = orderExtendedRegions(
|
|
@@ -7230,6 +7240,9 @@ function extendCharacterConfigWithPreset(config) {
|
|
|
7230
7240
|
regions: extendedRegions ?? config.regions
|
|
7231
7241
|
};
|
|
7232
7242
|
}
|
|
7243
|
+
function extendCharacterConfigWithPreset(config) {
|
|
7244
|
+
return extendProfileConfigWithPreset(config);
|
|
7245
|
+
}
|
|
7233
7246
|
var DEFAULT_EPSILON = 1e-4;
|
|
7234
7247
|
var DEFAULT_YAW_WEIGHT = 0.35;
|
|
7235
7248
|
var DEFAULT_PITCH_WEIGHT = 0.2;
|
|
@@ -7454,9 +7467,9 @@ function detectFacingDirection(model, eyeBoneNames = {
|
|
|
7454
7467
|
function normalizeLooseName(value) {
|
|
7455
7468
|
return value.replace(/\./g, "");
|
|
7456
7469
|
}
|
|
7457
|
-
function resolveBoneNameCandidates(semanticName,
|
|
7458
|
-
if (!
|
|
7459
|
-
const { bonePrefix, boneSuffix, boneNodes } =
|
|
7470
|
+
function resolveBoneNameCandidates(semanticName, profile) {
|
|
7471
|
+
if (!profile) return [semanticName];
|
|
7472
|
+
const { bonePrefix, boneSuffix, boneNodes } = profile;
|
|
7460
7473
|
if (!boneNodes || !boneNodes[semanticName]) {
|
|
7461
7474
|
return [semanticName];
|
|
7462
7475
|
}
|
|
@@ -7470,14 +7483,14 @@ function resolveBoneNameCandidates(semanticName, config) {
|
|
|
7470
7483
|
const fullyAffixed = suffix && !prefixedBase.endsWith(suffix) ? `${prefixedBase}${suffix}` : prefixedBase;
|
|
7471
7484
|
return Array.from(/* @__PURE__ */ new Set([fullyAffixed, baseName]));
|
|
7472
7485
|
}
|
|
7473
|
-
function resolveBoneName(semanticName,
|
|
7474
|
-
return resolveBoneNameCandidates(semanticName,
|
|
7486
|
+
function resolveBoneName(semanticName, profile) {
|
|
7487
|
+
return resolveBoneNameCandidates(semanticName, profile)[0] ?? semanticName;
|
|
7475
7488
|
}
|
|
7476
|
-
function resolveBoneNames(names,
|
|
7489
|
+
function resolveBoneNames(names, profile) {
|
|
7477
7490
|
if (!names || names.length === 0) return [];
|
|
7478
7491
|
return Array.from(
|
|
7479
7492
|
new Set(
|
|
7480
|
-
names.flatMap((name) => resolveBoneNameCandidates(name,
|
|
7493
|
+
names.flatMap((name) => resolveBoneNameCandidates(name, profile))
|
|
7481
7494
|
)
|
|
7482
7495
|
);
|
|
7483
7496
|
}
|
|
@@ -7490,8 +7503,8 @@ function fuzzyNameMatch(objectName, targetName, suffixPattern) {
|
|
|
7490
7503
|
const regex = suffixPattern ? new RegExp(suffixPattern) : /^[_\.]\d+$/;
|
|
7491
7504
|
return regex.test(suffix);
|
|
7492
7505
|
}
|
|
7493
|
-
function resolveFaceCenter(model, region,
|
|
7494
|
-
const resolvedBones = resolveBoneNames(region.bones,
|
|
7506
|
+
function resolveFaceCenter(model, region, profile) {
|
|
7507
|
+
const resolvedBones = resolveBoneNames(region.bones, profile);
|
|
7495
7508
|
const headBoneNames = resolvedBones.filter((name) => name.toLowerCase().includes("head"));
|
|
7496
7509
|
const result = findFaceCenter(model, {
|
|
7497
7510
|
headBoneNames: headBoneNames.length > 0 ? headBoneNames : void 0,
|
|
@@ -7504,6 +7517,274 @@ function resolveFaceCenter(model, region, config) {
|
|
|
7504
7517
|
};
|
|
7505
7518
|
}
|
|
7506
7519
|
|
|
7520
|
+
// src/camera/annotationCameraAngles.ts
|
|
7521
|
+
var DEFAULT_LATERALITY = {
|
|
7522
|
+
leftSideX: -1,
|
|
7523
|
+
confidence: 0,
|
|
7524
|
+
evidence: ["default:left=-X"]
|
|
7525
|
+
};
|
|
7526
|
+
var SIDE_TOKEN_PATTERN = /(^|[_\s-])(left|right)(?=$|[_\s-])/i;
|
|
7527
|
+
var MIN_LATERAL_SEPARATION = 1e-3;
|
|
7528
|
+
function invertHorizontalSign(sign) {
|
|
7529
|
+
return sign === 1 ? -1 : 1;
|
|
7530
|
+
}
|
|
7531
|
+
function averagePoints(points) {
|
|
7532
|
+
if (points.length === 0) return null;
|
|
7533
|
+
const center = new THREE2.Vector3();
|
|
7534
|
+
for (const point of points) {
|
|
7535
|
+
center.add(point);
|
|
7536
|
+
}
|
|
7537
|
+
return center.divideScalar(points.length);
|
|
7538
|
+
}
|
|
7539
|
+
function replaceSemanticSideToken(name, replacement) {
|
|
7540
|
+
const match = SIDE_TOKEN_PATTERN.exec(name);
|
|
7541
|
+
if (!match) return null;
|
|
7542
|
+
const [fullMatch, prefix] = match;
|
|
7543
|
+
const start = match.index;
|
|
7544
|
+
const end = start + fullMatch.length;
|
|
7545
|
+
return `${name.slice(0, start)}${prefix}${replacement}${name.slice(end)}`;
|
|
7546
|
+
}
|
|
7547
|
+
function collectMatchedPoints(model, targetNames, matcher, extractor) {
|
|
7548
|
+
const points = [];
|
|
7549
|
+
for (const targetName of targetNames) {
|
|
7550
|
+
model.traverse((obj) => {
|
|
7551
|
+
if (!matcher(obj, targetName)) return;
|
|
7552
|
+
const point = extractor(obj);
|
|
7553
|
+
if (point) {
|
|
7554
|
+
points.push(point);
|
|
7555
|
+
}
|
|
7556
|
+
});
|
|
7557
|
+
}
|
|
7558
|
+
return points;
|
|
7559
|
+
}
|
|
7560
|
+
function getRegionWorldCenter(model, region, characterConfig) {
|
|
7561
|
+
if (region.customPosition) {
|
|
7562
|
+
return new THREE2.Vector3(
|
|
7563
|
+
region.customPosition.x,
|
|
7564
|
+
region.customPosition.y,
|
|
7565
|
+
region.customPosition.z
|
|
7566
|
+
);
|
|
7567
|
+
}
|
|
7568
|
+
if (region.objects?.includes("*")) {
|
|
7569
|
+
return null;
|
|
7570
|
+
}
|
|
7571
|
+
const suffixPattern = characterConfig?.suffixPattern;
|
|
7572
|
+
const points = [];
|
|
7573
|
+
if (region.bones?.length) {
|
|
7574
|
+
const boneNames = resolveBoneNames(region.bones, characterConfig ?? void 0);
|
|
7575
|
+
points.push(
|
|
7576
|
+
...collectMatchedPoints(
|
|
7577
|
+
model,
|
|
7578
|
+
boneNames,
|
|
7579
|
+
(obj, targetName) => fuzzyNameMatch(obj.name, targetName, suffixPattern),
|
|
7580
|
+
(obj) => {
|
|
7581
|
+
const worldPos = new THREE2.Vector3();
|
|
7582
|
+
obj.getWorldPosition(worldPos);
|
|
7583
|
+
return worldPos;
|
|
7584
|
+
}
|
|
7585
|
+
)
|
|
7586
|
+
);
|
|
7587
|
+
}
|
|
7588
|
+
if (region.meshes?.length) {
|
|
7589
|
+
points.push(
|
|
7590
|
+
...collectMatchedPoints(
|
|
7591
|
+
model,
|
|
7592
|
+
region.meshes,
|
|
7593
|
+
(obj, targetName) => obj.isMesh && fuzzyNameMatch(obj.name, targetName, suffixPattern),
|
|
7594
|
+
(obj) => {
|
|
7595
|
+
const box = new THREE2.Box3().setFromObject(obj);
|
|
7596
|
+
if (box.isEmpty()) {
|
|
7597
|
+
return null;
|
|
7598
|
+
}
|
|
7599
|
+
return box.getCenter(new THREE2.Vector3());
|
|
7600
|
+
}
|
|
7601
|
+
)
|
|
7602
|
+
);
|
|
7603
|
+
}
|
|
7604
|
+
if (region.objects?.length) {
|
|
7605
|
+
const objectTargets = region.objects.filter((target) => target !== "*");
|
|
7606
|
+
points.push(
|
|
7607
|
+
...collectMatchedPoints(
|
|
7608
|
+
model,
|
|
7609
|
+
objectTargets,
|
|
7610
|
+
(obj, targetName) => fuzzyNameMatch(obj.name, targetName, suffixPattern),
|
|
7611
|
+
(obj) => {
|
|
7612
|
+
if (obj.isMesh) {
|
|
7613
|
+
const box = new THREE2.Box3().setFromObject(obj);
|
|
7614
|
+
if (!box.isEmpty()) {
|
|
7615
|
+
return box.getCenter(new THREE2.Vector3());
|
|
7616
|
+
}
|
|
7617
|
+
}
|
|
7618
|
+
const worldPos = new THREE2.Vector3();
|
|
7619
|
+
obj.getWorldPosition(worldPos);
|
|
7620
|
+
return worldPos;
|
|
7621
|
+
}
|
|
7622
|
+
)
|
|
7623
|
+
);
|
|
7624
|
+
}
|
|
7625
|
+
return averagePoints(points);
|
|
7626
|
+
}
|
|
7627
|
+
function getRegionLocalCenter(model, region, characterConfig) {
|
|
7628
|
+
const worldCenter = getRegionWorldCenter(model, region, characterConfig);
|
|
7629
|
+
return worldCenter ? model.worldToLocal(worldCenter.clone()) : null;
|
|
7630
|
+
}
|
|
7631
|
+
function cloneLaterality(value) {
|
|
7632
|
+
return {
|
|
7633
|
+
leftSideX: value.leftSideX,
|
|
7634
|
+
confidence: value.confidence,
|
|
7635
|
+
evidence: [...value.evidence]
|
|
7636
|
+
};
|
|
7637
|
+
}
|
|
7638
|
+
function getDefaultAnnotationLaterality() {
|
|
7639
|
+
return cloneLaterality(DEFAULT_LATERALITY);
|
|
7640
|
+
}
|
|
7641
|
+
function normalizeCameraAngle(angle) {
|
|
7642
|
+
return (angle % 360 + 360) % 360;
|
|
7643
|
+
}
|
|
7644
|
+
function getRegionSemanticSide(regionName) {
|
|
7645
|
+
if (!regionName) return null;
|
|
7646
|
+
const match = SIDE_TOKEN_PATTERN.exec(regionName);
|
|
7647
|
+
if (!match) return null;
|
|
7648
|
+
return match[2].toLowerCase() === "left" ? "left" : "right";
|
|
7649
|
+
}
|
|
7650
|
+
function getSemanticHorizontalSign(regionName, laterality) {
|
|
7651
|
+
const side = getRegionSemanticSide(regionName);
|
|
7652
|
+
if (side === "left") return laterality.leftSideX;
|
|
7653
|
+
if (side === "right") return invertHorizontalSign(laterality.leftSideX);
|
|
7654
|
+
return null;
|
|
7655
|
+
}
|
|
7656
|
+
function getSemanticHorizontalSignForSide(side, laterality) {
|
|
7657
|
+
return side === "left" ? laterality.leftSideX : invertHorizontalSign(laterality.leftSideX);
|
|
7658
|
+
}
|
|
7659
|
+
function detectAnnotationLaterality(model, regions, characterConfig) {
|
|
7660
|
+
if (!model || regions.length === 0) {
|
|
7661
|
+
return getDefaultAnnotationLaterality();
|
|
7662
|
+
}
|
|
7663
|
+
model.updateMatrixWorld(true);
|
|
7664
|
+
const regionsByName = new Map(
|
|
7665
|
+
regions.map((region) => [region.name.toLowerCase(), region])
|
|
7666
|
+
);
|
|
7667
|
+
const votes = [];
|
|
7668
|
+
const pairedKeys = /* @__PURE__ */ new Set();
|
|
7669
|
+
for (const region of regions) {
|
|
7670
|
+
if (getRegionSemanticSide(region.name) !== "left") continue;
|
|
7671
|
+
const mirroredName = replaceSemanticSideToken(region.name, "right");
|
|
7672
|
+
if (!mirroredName) continue;
|
|
7673
|
+
const other = regionsByName.get(mirroredName.toLowerCase());
|
|
7674
|
+
if (!other) continue;
|
|
7675
|
+
const pairKey = [region.name.toLowerCase(), other.name.toLowerCase()].sort().join("|");
|
|
7676
|
+
if (pairedKeys.has(pairKey)) continue;
|
|
7677
|
+
pairedKeys.add(pairKey);
|
|
7678
|
+
const leftCenter = getRegionLocalCenter(model, region, characterConfig);
|
|
7679
|
+
const rightCenter = getRegionLocalCenter(model, other, characterConfig);
|
|
7680
|
+
if (!leftCenter || !rightCenter) continue;
|
|
7681
|
+
const separation = Math.abs(leftCenter.x - rightCenter.x);
|
|
7682
|
+
if (separation < MIN_LATERAL_SEPARATION) continue;
|
|
7683
|
+
votes.push({
|
|
7684
|
+
sign: leftCenter.x > rightCenter.x ? 1 : -1,
|
|
7685
|
+
weight: separation,
|
|
7686
|
+
evidence: `pair:${region.name}/${other.name}:${leftCenter.x.toFixed(3)}/${rightCenter.x.toFixed(3)}`
|
|
7687
|
+
});
|
|
7688
|
+
}
|
|
7689
|
+
if (votes.length === 0) {
|
|
7690
|
+
for (const region of regions) {
|
|
7691
|
+
const side = getRegionSemanticSide(region.name);
|
|
7692
|
+
if (!side) continue;
|
|
7693
|
+
const center = getRegionLocalCenter(model, region, characterConfig);
|
|
7694
|
+
if (!center || Math.abs(center.x) < MIN_LATERAL_SEPARATION) continue;
|
|
7695
|
+
const sign = side === "left" ? center.x > 0 ? 1 : -1 : center.x > 0 ? -1 : 1;
|
|
7696
|
+
votes.push({
|
|
7697
|
+
sign,
|
|
7698
|
+
weight: Math.abs(center.x),
|
|
7699
|
+
evidence: `single:${region.name}:${center.x.toFixed(3)}`
|
|
7700
|
+
});
|
|
7701
|
+
}
|
|
7702
|
+
}
|
|
7703
|
+
if (votes.length === 0) {
|
|
7704
|
+
return getDefaultAnnotationLaterality();
|
|
7705
|
+
}
|
|
7706
|
+
let signedWeight = 0;
|
|
7707
|
+
let totalWeight = 0;
|
|
7708
|
+
for (const vote of votes) {
|
|
7709
|
+
signedWeight += vote.sign * vote.weight;
|
|
7710
|
+
totalWeight += vote.weight;
|
|
7711
|
+
}
|
|
7712
|
+
if (Math.abs(signedWeight) < MIN_LATERAL_SEPARATION) {
|
|
7713
|
+
return getDefaultAnnotationLaterality();
|
|
7714
|
+
}
|
|
7715
|
+
return {
|
|
7716
|
+
leftSideX: signedWeight > 0 ? 1 : -1,
|
|
7717
|
+
confidence: totalWeight > 0 ? Math.abs(signedWeight) / totalWeight : 0,
|
|
7718
|
+
evidence: votes.map((vote) => vote.evidence)
|
|
7719
|
+
};
|
|
7720
|
+
}
|
|
7721
|
+
function resolveRegionCameraAngle(region, laterality) {
|
|
7722
|
+
if (region.cameraAngle === void 0) {
|
|
7723
|
+
return void 0;
|
|
7724
|
+
}
|
|
7725
|
+
const normalizedAngle = normalizeCameraAngle(region.cameraAngle);
|
|
7726
|
+
const side = getRegionSemanticSide(region.name);
|
|
7727
|
+
if (side && (normalizedAngle === 90 || normalizedAngle === 270)) {
|
|
7728
|
+
return side === "left" ? laterality.leftSideX > 0 ? 90 : 270 : laterality.leftSideX > 0 ? 270 : 90;
|
|
7729
|
+
}
|
|
7730
|
+
return normalizedAngle;
|
|
7731
|
+
}
|
|
7732
|
+
function resolveRegionVisibilityCameraAngle(region, laterality) {
|
|
7733
|
+
const explicitAngle = resolveRegionCameraAngle(region, laterality);
|
|
7734
|
+
if (explicitAngle !== void 0) {
|
|
7735
|
+
return explicitAngle;
|
|
7736
|
+
}
|
|
7737
|
+
if (!region.parent) {
|
|
7738
|
+
return void 0;
|
|
7739
|
+
}
|
|
7740
|
+
const side = getRegionSemanticSide(region.name);
|
|
7741
|
+
if (!side) {
|
|
7742
|
+
return void 0;
|
|
7743
|
+
}
|
|
7744
|
+
return side === "left" ? laterality.leftSideX > 0 ? 90 : 270 : laterality.leftSideX > 0 ? 270 : 90;
|
|
7745
|
+
}
|
|
7746
|
+
function toWorldDirection(model, localDirection) {
|
|
7747
|
+
const worldDirection = localDirection.clone();
|
|
7748
|
+
if (model) {
|
|
7749
|
+
model.updateMatrixWorld(true);
|
|
7750
|
+
const worldQuaternion = new THREE2.Quaternion();
|
|
7751
|
+
model.getWorldQuaternion(worldQuaternion);
|
|
7752
|
+
worldDirection.applyQuaternion(worldQuaternion);
|
|
7753
|
+
}
|
|
7754
|
+
return worldDirection.normalize();
|
|
7755
|
+
}
|
|
7756
|
+
function toModelLocalDirection2(model, worldDirection) {
|
|
7757
|
+
const localDirection = worldDirection.clone();
|
|
7758
|
+
if (model) {
|
|
7759
|
+
model.updateMatrixWorld(true);
|
|
7760
|
+
const worldQuaternion = new THREE2.Quaternion();
|
|
7761
|
+
model.getWorldQuaternion(worldQuaternion);
|
|
7762
|
+
localDirection.applyQuaternion(worldQuaternion.invert());
|
|
7763
|
+
}
|
|
7764
|
+
return localDirection.normalize();
|
|
7765
|
+
}
|
|
7766
|
+
function getWorldDirectionForCameraAngle(model, cameraAngle) {
|
|
7767
|
+
const angleRad = normalizeCameraAngle(cameraAngle) * Math.PI / 180;
|
|
7768
|
+
return toWorldDirection(
|
|
7769
|
+
model,
|
|
7770
|
+
new THREE2.Vector3(Math.sin(angleRad), 0, Math.cos(angleRad))
|
|
7771
|
+
);
|
|
7772
|
+
}
|
|
7773
|
+
function getModelLocalOrbitAngle(model, modelCenter, worldPosition) {
|
|
7774
|
+
const worldOffset = new THREE2.Vector3().subVectors(worldPosition, modelCenter);
|
|
7775
|
+
const localOffset = toModelLocalDirection2(model, worldOffset);
|
|
7776
|
+
return normalizeCameraAngle(Math.atan2(localOffset.x, localOffset.z) * (180 / Math.PI));
|
|
7777
|
+
}
|
|
7778
|
+
function passesMarkerCameraAngleGate(params) {
|
|
7779
|
+
const { markerAngle, currentCameraAngle, rangeDegrees = 90 } = params;
|
|
7780
|
+
if (markerAngle === void 0 || markerAngle === 0 || currentCameraAngle === void 0) {
|
|
7781
|
+
return true;
|
|
7782
|
+
}
|
|
7783
|
+
let diff = Math.abs(currentCameraAngle - markerAngle);
|
|
7784
|
+
if (diff > 180) diff = 360 - diff;
|
|
7785
|
+
return diff <= rangeDegrees;
|
|
7786
|
+
}
|
|
7787
|
+
|
|
7507
7788
|
// src/physics/HairPhysics.ts
|
|
7508
7789
|
var DEFAULT_HAIR_PHYSICS_CONFIG = {
|
|
7509
7790
|
mass: 1,
|
|
@@ -8612,6 +8893,6 @@ async function analyzeModel(options) {
|
|
|
8612
8893
|
};
|
|
8613
8894
|
}
|
|
8614
8895
|
|
|
8615
|
-
export { AU_INFO, AU_MAPPING_CONFIG, AU_MIX_DEFAULTS, AU_TO_MORPHS, AnimationThree, BETTA_FISH_PRESET, BLENDING_MODES, BONE_AU_TO_BINDINGS, CC4_BONE_NODES, CC4_BONE_PREFIX, CC4_EYE_MESH_NODES, CC4_MAPPING_SECTIONS, CC4_MESHES, CC4_PRESET, CC4_SUFFIX_PATTERN, CC4_VISEME_SLOTS, CC4_VISEME_SYSTEM_ID, COMPOSITE_ROTATIONS, CONTINUUM_LABELS, CONTINUUM_PAIRS_MAP, DEFAULT_HAIR_PHYSICS_CONFIG, FISH_AU_MAPPING_CONFIG, HairPhysics, Loom3, Loom3 as Loom3Three, Loom3 as LoomLargeThree, MORPH_TO_MESH, VISEME_JAW_AMOUNTS, VISEME_KEYS, analyzeModel, applyCharacterProfileToPreset, buildMappingEditorModel, collectMorphMeshes, compileVisemeKeys, computeCameraRelativeGazeOffset, detectFacingDirection, extendCharacterConfigWithPreset, extendPresetWithProfile, extractFromGLTF, extractModelData, extractProfileOverrides, findFaceCenter, fuzzyNameMatch, generateMappingCorrections, getMeshNamesForAUProfile, getMeshNamesForVisemeProfile, getModelForwardDirection, getPreset, getPresetWithProfile, getProfileVisemeSlots, getVisemeBindingTargets, getVisemeJawAmounts, getVisemeSlotIndex, hasLeftRightMorphs, isMixedAU, isPresetCompatible, mapProviderVisemeToSlot, mergeRegionsByName as mergeCharacterRegionsByName, resolveBoneName, resolveBoneNames, resolveFaceCenter, resolvePreset, resolvePresetWithOverrides, resolveVisemeMeshCategory, suggestBestPreset, validateMappingConfig, validateMappings };
|
|
8896
|
+
export { AU_INFO, AU_MAPPING_CONFIG, AU_MIX_DEFAULTS, AU_TO_MORPHS, AnimationThree, BETTA_FISH_PRESET, BLENDING_MODES, BONE_AU_TO_BINDINGS, CC4_BONE_NODES, CC4_BONE_PREFIX, CC4_EYE_MESH_NODES, CC4_MAPPING_SECTIONS, CC4_MESHES, CC4_PRESET, CC4_SUFFIX_PATTERN, CC4_VISEME_SLOTS, CC4_VISEME_SYSTEM_ID, COMPOSITE_ROTATIONS, CONTINUUM_LABELS, CONTINUUM_PAIRS_MAP, DEFAULT_HAIR_PHYSICS_CONFIG, FISH_AU_MAPPING_CONFIG, HairPhysics, Loom3, Loom3 as Loom3Three, Loom3 as LoomLargeThree, MORPH_TO_MESH, VISEME_JAW_AMOUNTS, VISEME_KEYS, analyzeModel, applyCharacterProfileToPreset, buildMappingEditorModel, collectMorphMeshes, compileVisemeKeys, computeCameraRelativeGazeOffset, detectAnnotationLaterality, detectFacingDirection, extendCharacterConfigWithPreset, extendPresetWithProfile, extendProfileConfigWithPreset, extractFromGLTF, extractLegacyCharacterProfileOverrides, extractModelData, extractProfileOverrides, findFaceCenter, fuzzyNameMatch, generateMappingCorrections, getDefaultAnnotationLaterality, getMeshNamesForAUProfile, getMeshNamesForVisemeProfile, getModelForwardDirection, getModelLocalOrbitAngle, getPreset, getPresetWithProfile, getProfilePresetId, getProfileVisemeSlots, getRegionSemanticSide, getSemanticHorizontalSign, getSemanticHorizontalSignForSide, getVisemeBindingTargets, getVisemeJawAmounts, getVisemeSlotIndex, getWorldDirectionForCameraAngle, hasLeftRightMorphs, isMixedAU, isPresetCompatible, mapProviderVisemeToSlot, mergeRegionsByName as mergeCharacterRegionsByName, mergeProfileRegionsByName, normalizeCameraAngle, passesMarkerCameraAngleGate, resolveBoneName, resolveBoneNames, resolveFaceCenter, resolvePreset, resolvePresetWithOverrides, resolveProfileFromPreset, resolveRegionCameraAngle, resolveRegionVisibilityCameraAngle, resolveVisemeMeshCategory, suggestBestPreset, toModelLocalDirection2 as toModelLocalDirection, toWorldDirection, validateMappingConfig, validateMappings };
|
|
8616
8897
|
//# sourceMappingURL=index.js.map
|
|
8617
8898
|
//# sourceMappingURL=index.js.map
|