@lovelace_lol/embody 0.0.5 → 0.0.7

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/dist/index.cjs CHANGED
@@ -3696,410 +3696,6 @@ function getBlendingName(value) {
3696
3696
  return "Normal";
3697
3697
  }
3698
3698
 
3699
- // src/core/TsRuntimeCore.ts
3700
- var identityQuat = { x: 0, y: 0, z: 0, w: 1 };
3701
- function isRotationBoneBinding2(binding) {
3702
- return binding?.channel === "rx" || binding?.channel === "ry" || binding?.channel === "rz";
3703
- }
3704
- var TsRuntimeCore = class {
3705
- constructor(options) {
3706
- __publicField(this, "profile");
3707
- __publicField(this, "model");
3708
- __publicField(this, "auValues", {});
3709
- __publicField(this, "auBalances", {});
3710
- __publicField(this, "visemeValues");
3711
- __publicField(this, "visemeJawScales");
3712
- __publicField(this, "mixWeights");
3713
- this.profile = options.profile;
3714
- this.model = options.model;
3715
- this.visemeValues = new Array(getProfileVisemeSlots(this.profile).length).fill(0);
3716
- this.visemeJawScales = new Array(this.visemeValues.length).fill(1);
3717
- this.mixWeights = { ...this.profile.auMixDefaults };
3718
- }
3719
- setProfile(profile) {
3720
- this.profile = profile;
3721
- this.visemeValues = new Array(getProfileVisemeSlots(this.profile).length).fill(0);
3722
- this.visemeJawScales = new Array(this.visemeValues.length).fill(1);
3723
- this.mixWeights = { ...this.profile.auMixDefaults };
3724
- }
3725
- setModelDescriptor(model) {
3726
- this.model = model;
3727
- }
3728
- setAU(id, value, balance) {
3729
- if (value < 0 && this.profile.continuumPairs) {
3730
- const pairInfo = this.profile.continuumPairs[id];
3731
- if (pairInfo) {
3732
- const negAU = pairInfo.isNegative ? id : pairInfo.pairId;
3733
- const posAU = pairInfo.isNegative ? pairInfo.pairId : id;
3734
- this.setContinuum(negAU, posAU, pairInfo.isNegative ? -value : value, balance);
3735
- return;
3736
- }
3737
- }
3738
- this.auValues[id] = clamp01(value);
3739
- if (balance !== void 0) {
3740
- this.auBalances[id] = clampBalance2(balance);
3741
- }
3742
- }
3743
- getAU(id) {
3744
- return this.auValues[id] ?? 0;
3745
- }
3746
- setContinuum(negAU, posAU, continuumValue, balance) {
3747
- const value = Math.max(-1, Math.min(1, continuumValue));
3748
- if (value < 0) {
3749
- this.setAU(posAU, 0, balance);
3750
- this.setAU(negAU, Math.abs(value), balance);
3751
- return;
3752
- }
3753
- if (value > 0) {
3754
- this.setAU(negAU, 0, balance);
3755
- this.setAU(posAU, value, balance);
3756
- return;
3757
- }
3758
- this.setAU(negAU, 0, balance);
3759
- this.setAU(posAU, 0, balance);
3760
- }
3761
- setViseme(visemeIndex, value, jawScale = 1) {
3762
- if (visemeIndex < 0 || visemeIndex >= this.visemeValues.length) return;
3763
- this.visemeValues[visemeIndex] = clamp01(value);
3764
- this.visemeJawScales[visemeIndex] = jawScale;
3765
- }
3766
- setVisemeById(slotId, value, jawScale = 1) {
3767
- const index = getVisemeSlotIndex(this.profile, slotId);
3768
- if (index < 0) return;
3769
- this.setViseme(index, value, jawScale);
3770
- }
3771
- setAUMixWeight(id, weight) {
3772
- this.mixWeights[id] = clamp01(weight);
3773
- }
3774
- evaluateFrameDelta(deltaSeconds) {
3775
- const morphWrites = /* @__PURE__ */ new Map();
3776
- this.collectAUWrites(morphWrites);
3777
- this.collectVisemeWrites(morphWrites);
3778
- return {
3779
- deltaSeconds,
3780
- morphTargets: Array.from(morphWrites.values()),
3781
- bones: this.collectBoneWrites()
3782
- };
3783
- }
3784
- collectAUWrites(morphWrites) {
3785
- for (const [auIdText, entry] of Object.entries(this.profile.auToMorphs || {})) {
3786
- const auId = Number(auIdText);
3787
- if (Number.isNaN(auId) || !entry) continue;
3788
- const mixWeight = this.isMixedAU(auId) ? this.getAUMixWeight(auId) : 1;
3789
- const base = clamp01(this.auValues[auId] ?? 0) * mixWeight;
3790
- const { left, right } = computeSideValues(base, this.auBalances[auId]);
3791
- const meshNames = getMeshNamesForAUProfile(this.profile, auId);
3792
- for (const morph of entry.left || []) {
3793
- this.addMorphWrites(morphWrites, morph, meshNames, left);
3794
- }
3795
- for (const morph of entry.right || []) {
3796
- this.addMorphWrites(morphWrites, morph, meshNames, right);
3797
- }
3798
- for (const morph of entry.center || []) {
3799
- this.addMorphWrites(morphWrites, morph, meshNames, base);
3800
- }
3801
- }
3802
- }
3803
- collectVisemeWrites(morphWrites) {
3804
- const meshNames = getMeshNamesForVisemeProfile(this.profile);
3805
- const localMax = /* @__PURE__ */ new Map();
3806
- for (let index = 0; index < this.visemeValues.length; index += 1) {
3807
- const value = clamp01(this.visemeValues[index] ?? 0);
3808
- for (const bindingTarget of getVisemeBindingTargets(this.profile, index)) {
3809
- const weighted = clamp01(value * bindingTarget.weight);
3810
- for (const resolved of this.resolveMorphTargets(bindingTarget.morph, meshNames)) {
3811
- const key = morphWriteKey(resolved.mesh.id, resolved.morphTarget.id);
3812
- const existing = localMax.get(key);
3813
- if (!existing || weighted > existing.value) {
3814
- localMax.set(key, {
3815
- meshId: resolved.mesh.id,
3816
- morphTargetId: resolved.morphTarget.id,
3817
- value: weighted,
3818
- mode: "absolute"
3819
- });
3820
- }
3821
- }
3822
- }
3823
- }
3824
- for (const [key, write] of localMax) {
3825
- const existing = morphWrites.get(key);
3826
- if (!existing || write.value > existing.value) {
3827
- morphWrites.set(key, write);
3828
- }
3829
- }
3830
- }
3831
- collectBoneWrites() {
3832
- const writes = [];
3833
- const rotations = this.computeRotationState();
3834
- for (const composite of this.profile.compositeRotations || []) {
3835
- const bone = this.findBoneDescriptor(composite.node);
3836
- if (!bone) continue;
3837
- const transform = this.evaluateCompositeTransform(bone, composite, rotations[composite.node]);
3838
- if (transform) {
3839
- writes.push({
3840
- boneId: bone.id,
3841
- transform,
3842
- mode: "absolute",
3843
- space: "local"
3844
- });
3845
- }
3846
- }
3847
- for (const [nodeKey, translation] of Object.entries(this.computeTranslations())) {
3848
- const bone = this.findBoneDescriptor(nodeKey);
3849
- if (!bone) continue;
3850
- const position = addVec3(bone.restTransform?.position, translation);
3851
- upsertBoneWrite(writes, bone.id, { position });
3852
- }
3853
- const jawAmount = this.getActiveVisemeJawAmount();
3854
- const jawBinding = this.findAutoVisemeJawBinding();
3855
- const jawBone = jawBinding ? this.findBoneDescriptor(jawBinding.node) : void 0;
3856
- if (jawBone && jawBinding?.maxDegrees && jawBinding.channel) {
3857
- const current = writes.find((write) => write.boneId === jawBone.id);
3858
- if (jawAmount > 1e-6 || !current?.transform.rotation) {
3859
- const rest = jawBone.restTransform?.rotation ?? identityQuat;
3860
- const rotation = jawAmount > 1e-6 ? multiplyQuat(
3861
- rest,
3862
- quatFromChannel(jawBinding.channel, deg2rad(jawBinding.maxDegrees) * jawAmount * jawBinding.scale)
3863
- ) : rest;
3864
- upsertBoneWrite(writes, jawBone.id, { rotation });
3865
- }
3866
- }
3867
- return writes;
3868
- }
3869
- computeRotationState() {
3870
- const rotations = {};
3871
- for (const composite of this.profile.compositeRotations || []) {
3872
- rotations[composite.node] = {
3873
- pitch: this.getCompositeAxisValueForNode(composite.node, composite.pitch),
3874
- yaw: this.getCompositeAxisValueForNode(composite.node, composite.yaw),
3875
- roll: this.getCompositeAxisValueForNode(composite.node, composite.roll)
3876
- };
3877
- }
3878
- return rotations;
3879
- }
3880
- evaluateCompositeTransform(bone, composite, state) {
3881
- if (!state) return null;
3882
- let rotation = bone.restTransform?.rotation ?? identityQuat;
3883
- const applyAxis = (axisConfig, direction) => {
3884
- if (!axisConfig || Math.abs(direction) <= 1e-6) return;
3885
- const binding = getCompositeAxisBinding(
3886
- composite.node,
3887
- axisConfig,
3888
- direction,
3889
- (auId) => this.getEffectiveBoneAUValue(auId, composite.node),
3890
- this.profile.auToBones
3891
- );
3892
- if (!binding?.maxDegrees || !binding.channel) return;
3893
- rotation = multiplyQuat(
3894
- rotation,
3895
- quatFromChannel(binding.channel, deg2rad(binding.maxDegrees) * Math.abs(direction) * binding.scale)
3896
- );
3897
- };
3898
- applyAxis(composite.yaw, state.yaw);
3899
- applyAxis(composite.pitch, state.pitch);
3900
- applyAxis(composite.roll, state.roll);
3901
- return { rotation };
3902
- }
3903
- computeTranslations() {
3904
- const translations = {};
3905
- for (const [auIdText, bindings] of Object.entries(this.profile.auToBones || {})) {
3906
- const auId = Number(auIdText);
3907
- if (Number.isNaN(auId)) continue;
3908
- const value = clamp01(this.auValues[auId] ?? 0);
3909
- for (const binding of bindings || []) {
3910
- if (binding.channel !== "tx" && binding.channel !== "ty" && binding.channel !== "tz") continue;
3911
- if (binding.maxUnits === void 0) continue;
3912
- const current = translations[binding.node] ?? { x: 0, y: 0, z: 0 };
3913
- translations[binding.node] = current;
3914
- if (value <= 1e-6) continue;
3915
- const offset = clampSigned(value * binding.scale) * binding.maxUnits;
3916
- translations[binding.node] = {
3917
- x: binding.channel === "tx" ? offset : current.x,
3918
- y: binding.channel === "ty" ? offset : current.y,
3919
- z: binding.channel === "tz" ? offset : current.z
3920
- };
3921
- }
3922
- }
3923
- return translations;
3924
- }
3925
- addMorphWrites(morphWrites, morph, meshNames, value) {
3926
- for (const resolved of this.resolveMorphTargets(morph, meshNames)) {
3927
- const key = morphWriteKey(resolved.mesh.id, resolved.morphTarget.id);
3928
- const existing = morphWrites.get(key);
3929
- if (existing && existing.value >= value) continue;
3930
- morphWrites.set(key, {
3931
- meshId: resolved.mesh.id,
3932
- morphTargetId: resolved.morphTarget.id,
3933
- value,
3934
- mode: "absolute"
3935
- });
3936
- }
3937
- }
3938
- resolveMorphTargets(morph, meshNames) {
3939
- const result = [];
3940
- for (const meshName of meshNames) {
3941
- const mesh = this.model.meshes.find((candidate) => candidate.name === meshName);
3942
- if (!mesh) continue;
3943
- const morphTargets = mesh.morphTargetIds.map((id) => this.model.morphTargets.find((candidate) => candidate.id === id)).filter((target2) => !!target2);
3944
- const target = typeof morph === "number" ? morphTargets.find((candidate) => candidate.hostIndex === morph) : resolveMorphTargetByName(morphTargets, morph, this.profile);
3945
- if (target) {
3946
- result.push({ mesh, morphTarget: target });
3947
- }
3948
- }
3949
- return result;
3950
- }
3951
- findBoneDescriptor(nodeKey) {
3952
- const configuredName = this.profile.boneNodes[nodeKey] || nodeKey;
3953
- const prefix = this.profile.bonePrefix ?? "";
3954
- const suffix = this.profile.boneSuffix ?? "";
3955
- const prefixedName = prefix && !configuredName.startsWith(prefix) ? `${prefix}${configuredName}` : configuredName;
3956
- const fullName = suffix && !prefixedName.endsWith(suffix) ? `${prefixedName}${suffix}` : prefixedName;
3957
- const candidates = /* @__PURE__ */ new Set([nodeKey, configuredName, fullName]);
3958
- return this.model.bones.find((bone) => candidates.has(bone.name));
3959
- }
3960
- findAutoVisemeJawBinding() {
3961
- const candidates = [
3962
- this.profile.auToBones[103]?.find(isRotationBoneBinding2),
3963
- this.profile.auToBones[26]?.find(isRotationBoneBinding2)
3964
- ].filter((binding) => !!binding);
3965
- return candidates.find((binding) => !!this.findBoneDescriptor(binding.node)) ?? candidates[0] ?? null;
3966
- }
3967
- getActiveVisemeJawAmount() {
3968
- const jawAmounts = getVisemeJawAmounts(this.profile) ?? [];
3969
- let jawAmount = 0;
3970
- for (let index = 0; index < this.visemeValues.length; index += 1) {
3971
- const value = clamp01(this.visemeValues[index] ?? 0);
3972
- if (value <= 1e-6) continue;
3973
- const jawScale = this.visemeJawScales[index] ?? 1;
3974
- if (Math.abs(jawScale) <= 1e-6) continue;
3975
- jawAmount = Math.max(jawAmount, (jawAmounts[index] ?? 0) * value * jawScale);
3976
- }
3977
- return jawAmount;
3978
- }
3979
- getCompositeAxisValueForNode(nodeKey, axisConfig) {
3980
- return getCompositeAxisValue(axisConfig, (auId) => this.getEffectiveBoneAUValue(auId, nodeKey));
3981
- }
3982
- getEffectiveBoneAUValue(auId, nodeKey) {
3983
- const rawValue = clamp01(this.auValues[auId] ?? 0);
3984
- if (rawValue <= 1e-6) return 0;
3985
- const binding = this.profile.auToBones[auId]?.find((candidate) => candidate.node === nodeKey) ?? null;
3986
- if (!binding?.side) return rawValue;
3987
- return rawValue * getSideScale2(this.auBalances[auId] ?? 0, binding.side);
3988
- }
3989
- getAUMixWeight(auId) {
3990
- return this.mixWeights[auId] ?? this.profile.auMixDefaults?.[auId] ?? 1;
3991
- }
3992
- isMixedAU(auId) {
3993
- const morphs = this.profile.auToMorphs[auId];
3994
- const hasMorphs = !!(morphs?.left?.length || morphs?.right?.length || morphs?.center?.length);
3995
- return !!(hasMorphs && this.profile.auToBones[auId]?.length);
3996
- }
3997
- };
3998
- function resolveMorphTargetByName(targets, key, profile) {
3999
- const prefix = profile.morphPrefix || "";
4000
- const suffix = profile.morphSuffix || "";
4001
- const fullName = prefix + key + suffix;
4002
- const exact = targets.find((target) => target.name === fullName);
4003
- if (exact) return exact;
4004
- const suffixRegex = profile.suffixPattern ? new RegExp(profile.suffixPattern) : null;
4005
- if (!suffixRegex) return void 0;
4006
- return targets.find((target) => {
4007
- if (!target.name.startsWith(fullName)) return false;
4008
- const candidateSuffix = target.name.slice(fullName.length);
4009
- return candidateSuffix === "" || suffixRegex.test(candidateSuffix);
4010
- });
4011
- }
4012
- function computeSideValues(base, balance) {
4013
- const b = clampBalance2(balance ?? 0);
4014
- if (b === 0) return { left: base, right: base };
4015
- if (b < 0) return { left: base, right: base * (1 + b) };
4016
- return { left: base * (1 - b), right: base };
4017
- }
4018
- function getSideScale2(balance, side) {
4019
- if (side !== "left" && side !== "right") return 1;
4020
- const b = clampBalance2(balance);
4021
- if (side === "left") return b > 0 ? 1 - b : 1;
4022
- return b < 0 ? 1 + b : 1;
4023
- }
4024
- function addVec3(base, offset) {
4025
- return {
4026
- x: (base?.x ?? 0) + offset.x,
4027
- y: (base?.y ?? 0) + offset.y,
4028
- z: (base?.z ?? 0) + offset.z
4029
- };
4030
- }
4031
- function upsertBoneWrite(writes, boneId2, transform) {
4032
- const existingIndex = writes.findIndex((write) => write.boneId === boneId2);
4033
- if (existingIndex >= 0) {
4034
- const existing = writes[existingIndex];
4035
- writes[existingIndex] = {
4036
- ...existing,
4037
- transform: {
4038
- ...existing.transform,
4039
- ...transform
4040
- }
4041
- };
4042
- return;
4043
- }
4044
- writes.push({
4045
- boneId: boneId2,
4046
- transform,
4047
- mode: "absolute",
4048
- space: "local"
4049
- });
4050
- }
4051
- function quatFromChannel(channel, radians) {
4052
- if (channel === "rx") return quatFromAxis({ x: 1, y: 0, z: 0 }, radians);
4053
- if (channel === "ry") return quatFromAxis({ x: 0, y: 1, z: 0 }, radians);
4054
- return quatFromAxis({ x: 0, y: 0, z: 1 }, radians);
4055
- }
4056
- function quatFromAxis(axis, radians) {
4057
- const half = radians / 2;
4058
- const s = Math.sin(half);
4059
- return normalizeQuat({
4060
- x: axis.x * s,
4061
- y: axis.y * s,
4062
- z: axis.z * s,
4063
- w: Math.cos(half)
4064
- });
4065
- }
4066
- function multiplyQuat(a, b) {
4067
- return normalizeQuat({
4068
- x: a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
4069
- y: a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
4070
- z: a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
4071
- w: a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z
4072
- });
4073
- }
4074
- function normalizeQuat(q) {
4075
- const len = Math.hypot(q.x, q.y, q.z, q.w);
4076
- if (len <= 1e-12) return identityQuat;
4077
- return {
4078
- x: q.x / len,
4079
- y: q.y / len,
4080
- z: q.z / len,
4081
- w: q.w / len
4082
- };
4083
- }
4084
- function deg2rad(degrees) {
4085
- return degrees * Math.PI / 180;
4086
- }
4087
- function clamp01(value) {
4088
- if (!Number.isFinite(value)) return 0;
4089
- return value < 0 ? 0 : value > 1 ? 1 : value;
4090
- }
4091
- function clampSigned(value) {
4092
- if (!Number.isFinite(value)) return 0;
4093
- return value < -1 ? -1 : value > 1 ? 1 : value;
4094
- }
4095
- function clampBalance2(value) {
4096
- if (!Number.isFinite(value)) return 0;
4097
- return Math.max(-1, Math.min(1, value));
4098
- }
4099
- function morphWriteKey(meshId2, morphTargetId2) {
4100
- return `${meshId2}:${morphTargetId2}`;
4101
- }
4102
-
4103
3699
  // src/core/contracts/abi.ts
4104
3700
  var PACKED_MORPH_FRAME_DELTA_STRIDE = 4;
4105
3701
  var PACKED_BONE_FRAME_DELTA_STRIDE = 9;
@@ -4233,11 +3829,13 @@ var WasmRuntimeCore = class {
4233
3829
  constructor(options) {
4234
3830
  __publicField(this, "wasm");
4235
3831
  __publicField(this, "core");
3832
+ __publicField(this, "allowEmptyBindings");
4236
3833
  __publicField(this, "profile");
4237
3834
  __publicField(this, "model");
4238
3835
  this.wasm = options.wasm;
4239
3836
  this.profile = options.profile;
4240
3837
  this.model = options.model;
3838
+ this.allowEmptyBindings = options.allowEmptyBindings ?? false;
4241
3839
  const RuntimeCtor = options.wasm.RuntimeCore;
4242
3840
  if (!RuntimeCtor) {
4243
3841
  throw new Error("Embody Wasm module does not export RuntimeCore");
@@ -4256,6 +3854,24 @@ var WasmRuntimeCore = class {
4256
3854
  setAU(id, value, balance = 0) {
4257
3855
  this.core.set_au(id >>> 0, value, balance);
4258
3856
  }
3857
+ setContinuum(negativeAU, positiveAU, value, balance = 0) {
3858
+ this.core.set_continuum(negativeAU >>> 0, positiveAU >>> 0, value, balance);
3859
+ }
3860
+ transitionAU(id, to, durationMs, balance = Number.NaN) {
3861
+ this.core.transition_au(id >>> 0, to, durationMs, balance);
3862
+ }
3863
+ transitionViseme(visemeIndex, to, durationMs, jawScale = 1) {
3864
+ this.core.transition_viseme(visemeIndex >>> 0, to, durationMs, jawScale);
3865
+ }
3866
+ update(deltaSeconds) {
3867
+ return this.core.update(deltaSeconds);
3868
+ }
3869
+ activeTransitionCount() {
3870
+ return this.core.active_transition_count();
3871
+ }
3872
+ clearTransitions() {
3873
+ this.core.clear_transitions();
3874
+ }
4259
3875
  getAU(id) {
4260
3876
  return this.core.get_au(id >>> 0);
4261
3877
  }
@@ -4291,7 +3907,13 @@ var WasmRuntimeCore = class {
4291
3907
  };
4292
3908
  }
4293
3909
  reloadBindings() {
4294
- this.core.configure_with_profile(JSON.stringify(this.profile), JSON.stringify(this.model));
3910
+ const profileJson = JSON.stringify(this.profile);
3911
+ const modelJson = JSON.stringify(this.model);
3912
+ if (this.allowEmptyBindings) {
3913
+ this.core.configure(profileJson, modelJson);
3914
+ } else {
3915
+ this.core.configure_with_profile(profileJson, modelJson);
3916
+ }
4295
3917
  }
4296
3918
  };
4297
3919
  function unpackBoneFrameDelta(values) {
@@ -5649,7 +5271,7 @@ var CC4_PRESET = {
5649
5271
  };
5650
5272
 
5651
5273
  // src/engines/three/hair/HairPhysicsController.ts
5652
- var clamp012 = (value) => value < 0 ? 0 : value > 1 ? 1 : value;
5274
+ var clamp01 = (value) => value < 0 ? 0 : value > 1 ? 1 : value;
5653
5275
  var HairPhysicsController = class {
5654
5276
  constructor(host) {
5655
5277
  __publicField(this, "host");
@@ -6147,7 +5769,7 @@ var HairPhysicsController = class {
6147
5769
  }
6148
5770
  }
6149
5771
  setMorphOnMeshes(meshNames, morphKey, value) {
6150
- const val = clamp012(value);
5772
+ const val = clamp01(value);
6151
5773
  for (const name of meshNames) {
6152
5774
  const mesh = this.registeredHairObjects.get(name) || this.host.getMeshByName(name);
6153
5775
  if (!mesh) continue;
@@ -6391,9 +6013,9 @@ var HairPhysicsController = class {
6391
6013
  const deltaVertical = vertical - this.lastHeadVertical;
6392
6014
  this.lastHeadHorizontal = horizontal;
6393
6015
  this.lastHeadVertical = vertical;
6394
- const leftWeight = clamp012(deltaHorizontal > 0 ? deltaHorizontal : 0);
6395
- const rightWeight = clamp012(deltaHorizontal < 0 ? -deltaHorizontal : 0);
6396
- const frontWeight = clamp012(deltaVertical > 0 ? deltaVertical : 0);
6016
+ const leftWeight = clamp01(deltaHorizontal > 0 ? deltaHorizontal : 0);
6017
+ const rightWeight = clamp01(deltaHorizontal < 0 ? -deltaHorizontal : 0);
6018
+ const frontWeight = clamp01(deltaVertical > 0 ? deltaVertical : 0);
6397
6019
  const minTrigger = 0.01;
6398
6020
  if (leftWeight <= minTrigger && rightWeight <= minTrigger && frontWeight <= minTrigger) return;
6399
6021
  if (this.impulseClipDirty) {
@@ -7363,7 +6985,7 @@ async function getPresetWithProfile(presetType, profile) {
7363
6985
  var resolvePresetWithOverrides = getPresetWithProfile;
7364
6986
 
7365
6987
  // src/engines/three/Embody.ts
7366
- var deg2rad2 = (d) => d * Math.PI / 180;
6988
+ var deg2rad = (d) => d * Math.PI / 180;
7367
6989
  var X_AXIS2 = new THREE.Vector3(1, 0, 0);
7368
6990
  var Y_AXIS2 = new THREE.Vector3(0, 1, 0);
7369
6991
  var Z_AXIS2 = new THREE.Vector3(0, 0, 1);
@@ -7386,9 +7008,18 @@ function buildAUToCompositeMap(composites) {
7386
7008
  });
7387
7009
  return map;
7388
7010
  }
7389
- function clamp013(x) {
7011
+ function clamp012(x) {
7390
7012
  return x < 0 ? 0 : x > 1 ? 1 : x;
7391
7013
  }
7014
+ var RESOLVED_TRANSITION_HANDLE = {
7015
+ promise: Promise.resolve(),
7016
+ pause: () => {
7017
+ },
7018
+ resume: () => {
7019
+ },
7020
+ cancel: () => {
7021
+ }
7022
+ };
7392
7023
  var _Embody = class _Embody {
7393
7024
  constructor(config = {}, animation) {
7394
7025
  // Optional hook for animation schedulers.
@@ -7432,7 +7063,6 @@ var _Embody = class _Embody {
7432
7063
  __publicField(this, "modelInspector", new ThreeModelInspector());
7433
7064
  __publicField(this, "frameApplier", new ThreeFrameApplier());
7434
7065
  __publicField(this, "modelDescriptor", null);
7435
- __publicField(this, "tsRuntimeCore", null);
7436
7066
  __publicField(this, "wasmRuntimeCore", null);
7437
7067
  __publicField(this, "framePathReady", false);
7438
7068
  // Internal animation loop
@@ -7545,48 +7175,21 @@ var _Embody = class _Embody {
7545
7175
  bindHostNeutralRuntime(inspection) {
7546
7176
  this.modelDescriptor = inspection.descriptor;
7547
7177
  this.frameApplier.setBindings(buildFrameApplierBindings(inspection));
7548
- this.tsRuntimeCore = new TsRuntimeCore({
7178
+ const wasm$1 = wasm.requireInitializedEmbodyCore();
7179
+ this.attachWasmCore(wasm$1);
7180
+ this.wasmRuntimeCore = new WasmRuntimeCore({
7549
7181
  profile: this.config,
7550
- model: inspection.descriptor
7182
+ model: inspection.descriptor,
7183
+ wasm: wasm$1,
7184
+ allowEmptyBindings: true
7551
7185
  });
7552
7186
  this.syncRuntimeCoreState();
7553
7187
  this.framePathReady = true;
7554
- void wasm.initEmbodyCore().then((wasm) => {
7555
- if (!this.modelDescriptor) return;
7556
- this.attachWasmCore(wasm);
7557
- this.wasmRuntimeCore = new WasmRuntimeCore({
7558
- profile: this.config,
7559
- model: this.modelDescriptor,
7560
- wasm
7561
- });
7562
- this.syncRuntimeCoreState();
7563
- }).catch(() => {
7564
- this.wasmRuntimeCore = null;
7565
- });
7566
7188
  }
7567
7189
  attachWasmCore(core) {
7568
7190
  this.hairPhysics.setCore(core);
7569
7191
  }
7570
7192
  syncRuntimeCoreState() {
7571
- if (this.tsRuntimeCore) {
7572
- this.tsRuntimeCore.setProfile(this.config);
7573
- if (this.modelDescriptor) {
7574
- this.tsRuntimeCore.setModelDescriptor(this.modelDescriptor);
7575
- }
7576
- for (const [auIdText, value] of Object.entries(this.auValues)) {
7577
- const auId = Number(auIdText);
7578
- if (Number.isNaN(auId)) continue;
7579
- this.tsRuntimeCore.setAU(auId, value, this.auBalances[auId]);
7580
- }
7581
- for (const [auIdText, weight] of Object.entries(this.mixWeights)) {
7582
- const auId = Number(auIdText);
7583
- if (Number.isNaN(auId)) continue;
7584
- this.tsRuntimeCore.setAUMixWeight(auId, weight);
7585
- }
7586
- for (let index = 0; index < this.visemeValues.length; index += 1) {
7587
- this.tsRuntimeCore.setViseme(index, this.visemeValues[index] ?? 0, this.visemeJawScales[index] ?? 1);
7588
- }
7589
- }
7590
7193
  if (this.wasmRuntimeCore) {
7591
7194
  this.wasmRuntimeCore.setProfile(this.config);
7592
7195
  if (this.modelDescriptor) {
@@ -7604,7 +7207,7 @@ var _Embody = class _Embody {
7604
7207
  this.wasmRuntimeCore.setAUMixWeight(auId, weight);
7605
7208
  }
7606
7209
  for (let index = 0; index < this.visemeValues.length; index += 1) {
7607
- this.wasmRuntimeCore.setViseme(index, this.visemeValues[index] ?? 0);
7210
+ this.wasmRuntimeCore.setViseme(index, this.visemeValues[index] ?? 0, this.visemeJawScales[index] ?? 1);
7608
7211
  }
7609
7212
  }
7610
7213
  }
@@ -7622,25 +7225,13 @@ var _Embody = class _Embody {
7622
7225
  });
7623
7226
  this.modelDescriptor = inspection.descriptor;
7624
7227
  this.frameApplier.setBindings(buildFrameApplierBindings(inspection));
7625
- this.tsRuntimeCore?.setModelDescriptor(inspection.descriptor);
7626
7228
  this.wasmRuntimeCore?.setModelDescriptor(inspection.descriptor);
7627
7229
  }
7628
- applyLiveMorphFrameDelta() {
7629
- if (!this.framePathReady || !this.model) return false;
7630
- if (this.wasmRuntimeCore) {
7631
- this.frameApplier.applyPackedMorphFrameDelta(
7632
- this.wasmRuntimeCore.evaluatePackedMorphFrameDelta()
7633
- );
7634
- return true;
7635
- }
7636
- if (this.tsRuntimeCore) {
7637
- const frame = this.tsRuntimeCore.evaluateFrameDelta();
7638
- this.frameApplier.applyFrameDelta(this.model, {
7639
- morphTargets: frame.morphTargets
7640
- });
7641
- return true;
7642
- }
7643
- return false;
7230
+ applyLiveFrameDelta() {
7231
+ if (!this.framePathReady || !this.model || !this.wasmRuntimeCore) return false;
7232
+ this.frameApplier.applyFrameDelta(this.model, this.wasmRuntimeCore.evaluateFrameDelta());
7233
+ this.pendingCompositeNodes.clear();
7234
+ return true;
7644
7235
  }
7645
7236
  rebuildMorphTargetsCache() {
7646
7237
  this.morphKeyCache.clear();
@@ -7742,6 +7333,11 @@ var _Embody = class _Embody {
7742
7333
  const dtSeconds = Math.max(0, deltaSeconds || 0);
7743
7334
  if (dtSeconds <= 0 || this.isPaused) return;
7744
7335
  this.animation.tick(dtSeconds);
7336
+ const wasmTransitionCount = this.wasmRuntimeCore?.activeTransitionCount() ?? 0;
7337
+ const remainingWasmTransitions = this.wasmRuntimeCore?.update(dtSeconds) ?? 0;
7338
+ if (wasmTransitionCount > 0 || remainingWasmTransitions > 0) {
7339
+ this.applyLiveFrameDelta();
7340
+ }
7745
7341
  this.flushPendingComposites();
7746
7342
  this.animationController.update(dtSeconds);
7747
7343
  this.hairPhysics.update(dtSeconds);
@@ -7776,7 +7372,6 @@ var _Embody = class _Embody {
7776
7372
  this.model = null;
7777
7373
  this.bones = {};
7778
7374
  this.modelDescriptor = null;
7779
- this.tsRuntimeCore = null;
7780
7375
  this.wasmRuntimeCore = null;
7781
7376
  this.framePathReady = false;
7782
7377
  }
@@ -7813,15 +7408,14 @@ var _Embody = class _Embody {
7813
7408
  if (balance !== void 0) {
7814
7409
  this.auBalances[id] = balance;
7815
7410
  }
7816
- this.tsRuntimeCore?.setAU(id, v, balance);
7817
7411
  this.wasmRuntimeCore?.setAU(id, v, balance ?? this.auBalances[id] ?? 0);
7818
- const appliedViaFrame = this.applyLiveMorphFrameDelta();
7412
+ const appliedViaFrame = this.applyLiveFrameDelta();
7819
7413
  if (!appliedViaFrame) {
7820
7414
  const resolvedMorphTargets = this.resolvedAUMorphTargets.get(id);
7821
7415
  const { left: leftKeys, right: rightKeys, center: centerKeys } = this.getAUMorphsBySide(id);
7822
7416
  if (resolvedMorphTargets) {
7823
7417
  const mixWeight = this.isMixedAU(id) ? this.getAUMixWeight(id) : 1;
7824
- const base = clamp013(v) * mixWeight;
7418
+ const base = clamp012(v) * mixWeight;
7825
7419
  const { left: leftVal, right: rightVal } = this.computeSideValues(base, balance);
7826
7420
  if (resolvedMorphTargets.left.length || resolvedMorphTargets.right.length) {
7827
7421
  this.applyMorphTargets(resolvedMorphTargets.left, leftVal);
@@ -7830,7 +7424,7 @@ var _Embody = class _Embody {
7830
7424
  this.applyMorphTargets(resolvedMorphTargets.center, base);
7831
7425
  } else if (leftKeys.length || rightKeys.length || centerKeys.length) {
7832
7426
  const mixWeight = this.isMixedAU(id) ? this.getAUMixWeight(id) : 1;
7833
- const base = clamp013(v) * mixWeight;
7427
+ const base = clamp012(v) * mixWeight;
7834
7428
  const meshNames = this.getMeshNamesForAU(id);
7835
7429
  const { left: leftVal, right: rightVal } = this.computeSideValues(base, balance);
7836
7430
  if (leftKeys.length || rightKeys.length) {
@@ -7849,6 +7443,7 @@ var _Embody = class _Embody {
7849
7443
  }
7850
7444
  }
7851
7445
  }
7446
+ if (appliedViaFrame) return;
7852
7447
  const compositeInfo = this.auToCompositeMap.get(id);
7853
7448
  if (compositeInfo) {
7854
7449
  for (const nodeKey of compositeInfo.nodes) {
@@ -7883,7 +7478,7 @@ var _Embody = class _Embody {
7883
7478
  return this.transitionContinuum(negAU, posAU, continuumValue, durationMs, balance);
7884
7479
  }
7885
7480
  }
7886
- const target = clamp013(to);
7481
+ const target = clamp012(to);
7887
7482
  if (balance !== void 0) {
7888
7483
  this.auBalances[numId] = balance;
7889
7484
  }
@@ -7894,6 +7489,19 @@ var _Embody = class _Embody {
7894
7489
  const base = target * mixWeight;
7895
7490
  const { left: leftVal, right: rightVal } = this.computeSideValues(base, storedBalance);
7896
7491
  this.auValues[numId] = target;
7492
+ if (this.wasmRuntimeCore) {
7493
+ this.wasmRuntimeCore.transitionAU(
7494
+ numId,
7495
+ target,
7496
+ durationMs,
7497
+ balance ?? this.auBalances[numId] ?? Number.NaN
7498
+ );
7499
+ this.update(0);
7500
+ if (durationMs <= 0) {
7501
+ this.applyLiveFrameDelta();
7502
+ }
7503
+ return RESOLVED_TRANSITION_HANDLE;
7504
+ }
7897
7505
  const handles = [];
7898
7506
  const meshNames = this.getMeshNamesForAU(numId);
7899
7507
  if (leftKeys.length || rightKeys.length) {
@@ -7956,6 +7564,17 @@ var _Embody = class _Embody {
7956
7564
  */
7957
7565
  setContinuum(negAU, posAU, continuumValue, balance) {
7958
7566
  const value = Math.max(-1, Math.min(1, continuumValue));
7567
+ this.auValues[negAU] = value < 0 ? Math.abs(value) : 0;
7568
+ this.auValues[posAU] = value > 0 ? value : 0;
7569
+ if (balance !== void 0) {
7570
+ this.auBalances[negAU] = balance;
7571
+ this.auBalances[posAU] = balance;
7572
+ }
7573
+ if (this.wasmRuntimeCore) {
7574
+ this.wasmRuntimeCore.setContinuum(negAU, posAU, value, balance ?? 0);
7575
+ this.applyLiveFrameDelta();
7576
+ return;
7577
+ }
7959
7578
  if (value < 0) {
7960
7579
  this.setAU(posAU, 0, balance);
7961
7580
  this.setAU(negAU, Math.abs(value), balance);
@@ -7981,10 +7600,32 @@ var _Embody = class _Embody {
7981
7600
  */
7982
7601
  transitionContinuum(negAU, posAU, continuumValue, durationMs = 200, balance) {
7983
7602
  const target = Math.max(-1, Math.min(1, continuumValue));
7984
- const driverKey = `continuum_${negAU}_${posAU}`;
7985
7603
  const currentNeg = this.auValues[negAU] ?? 0;
7986
7604
  const currentPos = this.auValues[posAU] ?? 0;
7987
7605
  const currentContinuum = currentPos - currentNeg;
7606
+ this.auValues[negAU] = target < 0 ? Math.abs(target) : 0;
7607
+ this.auValues[posAU] = target > 0 ? target : 0;
7608
+ if (balance !== void 0) {
7609
+ this.auBalances[negAU] = balance;
7610
+ this.auBalances[posAU] = balance;
7611
+ }
7612
+ if (this.wasmRuntimeCore) {
7613
+ if (target < 0) {
7614
+ this.wasmRuntimeCore.transitionAU(posAU, 0, durationMs, balance ?? this.auBalances[posAU] ?? Number.NaN);
7615
+ this.wasmRuntimeCore.transitionAU(negAU, Math.abs(target), durationMs, balance ?? this.auBalances[negAU] ?? Number.NaN);
7616
+ } else if (target > 0) {
7617
+ this.wasmRuntimeCore.transitionAU(negAU, 0, durationMs, balance ?? this.auBalances[negAU] ?? Number.NaN);
7618
+ this.wasmRuntimeCore.transitionAU(posAU, target, durationMs, balance ?? this.auBalances[posAU] ?? Number.NaN);
7619
+ } else {
7620
+ this.wasmRuntimeCore.transitionAU(negAU, 0, durationMs, balance ?? this.auBalances[negAU] ?? Number.NaN);
7621
+ this.wasmRuntimeCore.transitionAU(posAU, 0, durationMs, balance ?? this.auBalances[posAU] ?? Number.NaN);
7622
+ }
7623
+ if (durationMs <= 0) {
7624
+ this.applyLiveFrameDelta();
7625
+ }
7626
+ return RESOLVED_TRANSITION_HANDLE;
7627
+ }
7628
+ const driverKey = `continuum_${negAU}_${posAU}`;
7988
7629
  return this.animation.addTransition(driverKey, currentContinuum, target, durationMs, (value) => this.setContinuum(negAU, posAU, value, balance));
7989
7630
  }
7990
7631
  // ============================================================================
@@ -8066,7 +7707,7 @@ var _Embody = class _Embody {
8066
7707
  this.hairPhysics.refreshMeshSelection();
8067
7708
  }
8068
7709
  setMorph(key, v, meshNamesOrTargets) {
8069
- const val = clamp013(v);
7710
+ const val = clamp012(v);
8070
7711
  if (Array.isArray(meshNamesOrTargets) && meshNamesOrTargets.length > 0 && typeof meshNamesOrTargets[0] === "object" && "infl" in meshNamesOrTargets[0]) {
8071
7712
  const targets2 = meshNamesOrTargets;
8072
7713
  this.applyMorphTargets(targets2, val);
@@ -8078,7 +7719,7 @@ var _Embody = class _Embody {
8078
7719
  this.applyMorphTargets(targets, val);
8079
7720
  }
8080
7721
  setMorphInfluence(index, v, meshNames) {
8081
- const val = clamp013(v);
7722
+ const val = clamp012(v);
8082
7723
  const targets = this.resolveMorphTargetsByIndex(index, meshNames);
8083
7724
  if (targets.length === 0) return;
8084
7725
  this.applyMorphTargets(targets, val);
@@ -8153,21 +7794,21 @@ var _Embody = class _Embody {
8153
7794
  }
8154
7795
  transitionMorph(key, to, durationMs = 120, meshNames) {
8155
7796
  const transitionKey = meshNames?.length ? `morph_${this.getMorphKeyCacheKey(key, meshNames)}` : `morph_${this.getMorphKeyCacheKey(key)}`;
8156
- const target = clamp013(to);
7797
+ const target = clamp012(to);
8157
7798
  const targets = this.resolveMorphTargets(key, meshNames);
8158
7799
  const from = targets.length > 0 ? targets[0].infl[targets[0].idx] ?? 0 : this.getMorphValue(key);
8159
7800
  return this.animation.addTransition(transitionKey, from, target, durationMs, (value) => {
8160
- const val = clamp013(value);
7801
+ const val = clamp012(value);
8161
7802
  this.applyMorphTargets(targets, val);
8162
7803
  });
8163
7804
  }
8164
7805
  transitionMorphInfluence(index, to, durationMs = 120, meshNames) {
8165
7806
  const transitionKey = meshNames?.length ? `morph_${this.getMorphIndexCacheKey(index, meshNames)}` : `morph_${this.getMorphIndexCacheKey(index)}`;
8166
- const target = clamp013(to);
7807
+ const target = clamp012(to);
8167
7808
  const targets = this.resolveMorphTargetsByIndex(index, meshNames);
8168
7809
  const from = targets.length > 0 ? targets[0].infl[targets[0].idx] ?? 0 : this.getMorphValueByIndex(index);
8169
7810
  return this.animation.addTransition(transitionKey, from, target, durationMs, (value) => {
8170
- const val = clamp013(value);
7811
+ const val = clamp012(value);
8171
7812
  this.applyMorphTargets(targets, val);
8172
7813
  });
8173
7814
  }
@@ -8176,7 +7817,7 @@ var _Embody = class _Embody {
8176
7817
  // ============================================================================
8177
7818
  setViseme(visemeIndex, value, jawScale = 1) {
8178
7819
  if (visemeIndex < 0 || visemeIndex >= this.visemeValues.length) return;
8179
- const val = clamp013(value);
7820
+ const val = clamp012(value);
8180
7821
  this.visemeValues[visemeIndex] = val;
8181
7822
  this.visemeJawScales[visemeIndex] = jawScale;
8182
7823
  this.applyVisemeRuntimeState();
@@ -8188,16 +7829,24 @@ var _Embody = class _Embody {
8188
7829
  }, cancel: () => {
8189
7830
  } };
8190
7831
  }
8191
- const target = clamp013(to);
7832
+ const target = clamp012(to);
8192
7833
  const from = this.visemeValues[visemeIndex] ?? 0;
8193
7834
  this.visemeJawScales[visemeIndex] = jawScale;
7835
+ if (this.wasmRuntimeCore) {
7836
+ this.visemeValues[visemeIndex] = target;
7837
+ this.wasmRuntimeCore.transitionViseme(visemeIndex, target, durationMs, jawScale);
7838
+ if (durationMs <= 0) {
7839
+ this.applyLiveFrameDelta();
7840
+ }
7841
+ return RESOLVED_TRANSITION_HANDLE;
7842
+ }
8194
7843
  return this.animation.addTransition(
8195
7844
  `viseme_value_${visemeIndex}`,
8196
7845
  from,
8197
7846
  target,
8198
7847
  durationMs,
8199
7848
  (value) => {
8200
- this.visemeValues[visemeIndex] = clamp013(value);
7849
+ this.visemeValues[visemeIndex] = clamp012(value);
8201
7850
  this.visemeJawScales[visemeIndex] = jawScale;
8202
7851
  this.applyVisemeRuntimeState();
8203
7852
  }
@@ -8222,8 +7871,7 @@ var _Embody = class _Embody {
8222
7871
  // MIX WEIGHT CONTROL
8223
7872
  // ============================================================================
8224
7873
  setAUMixWeight(id, weight) {
8225
- this.mixWeights[id] = clamp013(weight);
8226
- this.tsRuntimeCore?.setAUMixWeight(id, weight);
7874
+ this.mixWeights[id] = clamp012(weight);
8227
7875
  this.wasmRuntimeCore?.setAUMixWeight(id, weight);
8228
7876
  const v = this.auValues[id] ?? 0;
8229
7877
  if (v > 0) this.setAU(id, v);
@@ -8261,9 +7909,10 @@ var _Embody = class _Embody {
8261
7909
  }
8262
7910
  clearTransitions() {
8263
7911
  this.animation.clearTransitions();
7912
+ this.wasmRuntimeCore?.clearTransitions();
8264
7913
  }
8265
7914
  getActiveTransitionCount() {
8266
- return this.animation.getActiveTransitionCount();
7915
+ return this.animation.getActiveTransitionCount() + (this.wasmRuntimeCore?.activeTransitionCount() ?? 0);
8267
7916
  }
8268
7917
  resetToNeutral() {
8269
7918
  this.auValues = {};
@@ -8273,6 +7922,7 @@ var _Embody = class _Embody {
8273
7922
  this.translations = {};
8274
7923
  this.initBoneRotations();
8275
7924
  this.clearTransitions();
7925
+ this.wasmRuntimeCore?.clear();
8276
7926
  const morphTargetsToReset = [];
8277
7927
  for (const m of this.meshes) {
8278
7928
  const infl = m.morphTargetInfluences;
@@ -8451,7 +8101,18 @@ var _Embody = class _Embody {
8451
8101
  this.bones = this.resolveBones(this.model);
8452
8102
  this.missingBoneWarnings.clear();
8453
8103
  this.rebuildMorphTargetsCache();
8454
- this.tsRuntimeCore?.setProfile(this.config);
8104
+ Object.values(this.bones).forEach((entry) => {
8105
+ if (!entry) return;
8106
+ this.frameApplier.applyObjectTransform(entry.obj, {
8107
+ position: { x: entry.basePos.x, y: entry.basePos.y, z: entry.basePos.z },
8108
+ rotation: {
8109
+ x: entry.baseQuat.x,
8110
+ y: entry.baseQuat.y,
8111
+ z: entry.baseQuat.z,
8112
+ w: entry.baseQuat.w
8113
+ }
8114
+ });
8115
+ });
8455
8116
  this.wasmRuntimeCore?.setProfile(this.config);
8456
8117
  this.refreshHostNeutralModelDescriptor();
8457
8118
  }
@@ -8568,20 +8229,20 @@ var _Embody = class _Embody {
8568
8229
  }
8569
8230
  applyVisemeRuntimeState() {
8570
8231
  for (let index = 0; index < this.visemeValues.length; index += 1) {
8571
- this.tsRuntimeCore?.setViseme(index, this.visemeValues[index] ?? 0, this.visemeJawScales[index] ?? 1);
8572
- this.wasmRuntimeCore?.setViseme(index, this.visemeValues[index] ?? 0);
8232
+ this.wasmRuntimeCore?.setViseme(index, this.visemeValues[index] ?? 0, this.visemeJawScales[index] ?? 1);
8573
8233
  }
8574
- if (!this.applyLiveMorphFrameDelta()) {
8234
+ const appliedViaFrame = this.applyLiveFrameDelta();
8235
+ if (!appliedViaFrame) {
8575
8236
  for (const targets of this.resolvedVisemeTargets) {
8576
8237
  this.frameApplier.resetMorphTargets(targets || []);
8577
8238
  }
8578
8239
  for (let index = 0; index < this.visemeValues.length; index += 1) {
8579
- const value = clamp013(this.visemeValues[index] ?? 0);
8240
+ const value = clamp012(this.visemeValues[index] ?? 0);
8580
8241
  if (value <= 1e-6) continue;
8581
8242
  const targets = this.resolvedVisemeTargets[index] || [];
8582
8243
  for (const target of targets) {
8583
8244
  if (target.idx >= target.infl.length) continue;
8584
- const weighted = clamp013(value * target.weight);
8245
+ const weighted = clamp012(value * target.weight);
8585
8246
  this.frameApplier.applyMorphTargets(
8586
8247
  [target],
8587
8248
  Math.max(target.infl[target.idx] ?? 0, weighted)
@@ -8589,7 +8250,9 @@ var _Embody = class _Embody {
8589
8250
  }
8590
8251
  }
8591
8252
  }
8592
- this.updateBoneRotation(this.getJawBoneNodeKey(), "pitch", this.getActiveVisemeJawAmount());
8253
+ if (!appliedViaFrame) {
8254
+ this.updateBoneRotation(this.getJawBoneNodeKey(), "pitch", this.getActiveVisemeJawAmount());
8255
+ }
8593
8256
  }
8594
8257
  getJawBoneNodeKey() {
8595
8258
  const candidates = [
@@ -8611,7 +8274,7 @@ var _Embody = class _Embody {
8611
8274
  getActiveVisemeJawAmount() {
8612
8275
  let jawAmount = 0;
8613
8276
  for (let index = 0; index < this.visemeValues.length; index += 1) {
8614
- const value = clamp013(this.visemeValues[index] ?? 0);
8277
+ const value = clamp012(this.visemeValues[index] ?? 0);
8615
8278
  if (value <= 1e-6) continue;
8616
8279
  const jawScale = this.visemeJawScales[index] ?? 1;
8617
8280
  if (Math.abs(jawScale) <= 1e-6) continue;
@@ -8894,7 +8557,7 @@ var _Embody = class _Embody {
8894
8557
  return !!(hasMorphs && this.config.auToBones[id]?.length);
8895
8558
  }
8896
8559
  getEffectiveBoneAUValue(auId, nodeKey) {
8897
- const rawValue = clamp013(this.auValues[auId] ?? 0);
8560
+ const rawValue = clamp012(this.auValues[auId] ?? 0);
8898
8561
  if (rawValue <= 1e-6) return 0;
8899
8562
  const binding = this.config.auToBones[auId]?.find((candidate) => candidate.node === nodeKey) ?? null;
8900
8563
  if (!binding?.side) return rawValue;
@@ -8994,7 +8657,7 @@ var _Embody = class _Embody {
8994
8657
  if (config.yaw && rotState.yaw !== 0) {
8995
8658
  const binding = this.getCompositeAxisBindingForNode(nodeKey, config.yaw, rotState.yaw);
8996
8659
  if (binding?.maxDegrees && binding.channel) {
8997
- const radians = deg2rad2(binding.maxDegrees) * Math.abs(rotState.yaw) * binding.scale;
8660
+ const radians = deg2rad(binding.maxDegrees) * Math.abs(rotState.yaw) * binding.scale;
8998
8661
  const axis = getAxis(binding.channel);
8999
8662
  const deltaQ = new THREE.Quaternion().setFromAxisAngle(axis, radians);
9000
8663
  compositeQ.multiply(deltaQ);
@@ -9003,7 +8666,7 @@ var _Embody = class _Embody {
9003
8666
  if (config.pitch && rotState.pitch !== 0) {
9004
8667
  const binding = this.getCompositeAxisBindingForNode(nodeKey, config.pitch, rotState.pitch);
9005
8668
  if (binding?.maxDegrees && binding.channel) {
9006
- const radians = deg2rad2(binding.maxDegrees) * Math.abs(rotState.pitch) * binding.scale;
8669
+ const radians = deg2rad(binding.maxDegrees) * Math.abs(rotState.pitch) * binding.scale;
9007
8670
  const axis = getAxis(binding.channel);
9008
8671
  const deltaQ = new THREE.Quaternion().setFromAxisAngle(axis, radians);
9009
8672
  compositeQ.multiply(deltaQ);
@@ -9012,7 +8675,7 @@ var _Embody = class _Embody {
9012
8675
  if (config.roll && rotState.roll !== 0) {
9013
8676
  const binding = this.getCompositeAxisBindingForNode(nodeKey, config.roll, rotState.roll);
9014
8677
  if (binding?.maxDegrees && binding.channel) {
9015
- const radians = deg2rad2(binding.maxDegrees) * Math.abs(rotState.roll) * binding.scale;
8678
+ const radians = deg2rad(binding.maxDegrees) * Math.abs(rotState.roll) * binding.scale;
9016
8679
  const axis = getAxis(binding.channel);
9017
8680
  const deltaQ = new THREE.Quaternion().setFromAxisAngle(axis, radians);
9018
8681
  compositeQ.multiply(deltaQ);
@@ -9851,11 +9514,11 @@ function applyCharacterModelTransform(model, transform = {}) {
9851
9514
  model.position.set(modelOffset.x ?? 0, modelOffset.y ?? 0, modelOffset.z ?? 0);
9852
9515
  }
9853
9516
  if (modelRotation) {
9854
- const deg2rad3 = Math.PI / 180;
9517
+ const deg2rad2 = Math.PI / 180;
9855
9518
  model.rotation.set(
9856
- (modelRotation.x ?? 0) * deg2rad3,
9857
- (modelRotation.y ?? 0) * deg2rad3,
9858
- (modelRotation.z ?? 0) * deg2rad3
9519
+ (modelRotation.x ?? 0) * deg2rad2,
9520
+ (modelRotation.y ?? 0) * deg2rad2,
9521
+ (modelRotation.z ?? 0) * deg2rad2
9859
9522
  );
9860
9523
  }
9861
9524
  if (modelScale !== void 0 && Number.isFinite(modelScale) && modelScale > 0) {
@@ -14871,7 +14534,7 @@ function computeHumanoidSkeletonTemplateRestBounds(template) {
14871
14534
  }
14872
14535
  const parentPosition = worldPositions.get(bone.parent);
14873
14536
  if (!parentPosition) continue;
14874
- worldPositions.set(bone.name, addVec32(parentPosition, bone.translation));
14537
+ worldPositions.set(bone.name, addVec3(parentPosition, bone.translation));
14875
14538
  unresolved.delete(bone.name);
14876
14539
  resolvedThisPass += 1;
14877
14540
  }
@@ -14932,7 +14595,7 @@ function assertNonEmptyString(value, fieldName) {
14932
14595
  throw new Error(`${fieldName} must be a non-empty string`);
14933
14596
  }
14934
14597
  }
14935
- function addVec32(a, b) {
14598
+ function addVec3(a, b) {
14936
14599
  return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
14937
14600
  }
14938
14601
 
@@ -15088,7 +14751,6 @@ exports.ThreeClipAdapter = ThreeClipAdapter;
15088
14751
  exports.ThreeFrameApplier = ThreeFrameApplier;
15089
14752
  exports.ThreeModelInspector = ThreeModelInspector;
15090
14753
  exports.TsClipCompiler = TsClipCompiler;
15091
- exports.TsRuntimeCore = TsRuntimeCore;
15092
14754
  exports.VISEME_JAW_AMOUNTS = VISEME_JAW_AMOUNTS;
15093
14755
  exports.VISEME_KEYS = VISEME_KEYS;
15094
14756
  exports.WasmRuntimeCore = WasmRuntimeCore;