@lovelace_lol/embody 0.0.3 → 0.0.4
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/core.cjs +2 -12
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +2 -12
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +14 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/profiles/rustResolvedProfile.d.ts +31 -0
- package/dist/three.cjs +2 -233
- package/dist/three.cjs.map +1 -1
- package/dist/three.js +2 -233
- package/dist/three.js.map +1 -1
- package/dist/wasm/embody_wasm.d.ts +24 -10
- package/dist/wasm/embody_wasm.js +57 -0
- package/dist/wasm/embody_wasm_bg.wasm +0 -0
- package/dist/wasm/embody_wasm_bg.wasm.d.ts +12 -10
- package/dist/wasmTypes.d.ts +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BoneBinding, CompositeRotation } from '../core/types';
|
|
2
|
+
import type { HairPhysicsProfileConfig, MappingEditorSection, MeshInfo, MorphTargetRef, Profile, VisemeSlot } from '../mappings/types';
|
|
3
|
+
import type { EmbodyCoreWasmModule } from '../wasmTypes';
|
|
4
|
+
export interface RustResolvedVisemeBindingTarget {
|
|
5
|
+
morph: MorphTargetRef;
|
|
6
|
+
weight: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RustResolvedProfileView {
|
|
9
|
+
visemeSlots: VisemeSlot[];
|
|
10
|
+
visemeJawAmounts: number[];
|
|
11
|
+
visemeBindingTargets: RustResolvedVisemeBindingTarget[][];
|
|
12
|
+
visemeMeshCategory: string;
|
|
13
|
+
visemeMeshNames: string[];
|
|
14
|
+
auMeshNames: Record<string, string[]>;
|
|
15
|
+
meshes: Record<string, MeshInfo>;
|
|
16
|
+
mappingSections: MappingEditorSection[];
|
|
17
|
+
auFacePartToMeshCategory: Record<string, string>;
|
|
18
|
+
auMixDefaults: Record<string, number>;
|
|
19
|
+
boneNodes: Record<string, string>;
|
|
20
|
+
auToBones: Record<string, BoneBinding[]>;
|
|
21
|
+
compositeRotations: CompositeRotation[];
|
|
22
|
+
continuumPairs: Record<string, {
|
|
23
|
+
pairId: number;
|
|
24
|
+
isNegative: boolean;
|
|
25
|
+
axis?: 'pitch' | 'yaw' | 'roll';
|
|
26
|
+
node?: string;
|
|
27
|
+
} | null>;
|
|
28
|
+
hairPhysics?: HairPhysicsProfileConfig;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveRustProfileView(wasm: EmbodyCoreWasmModule, profile: Profile | Record<string, unknown>): RustResolvedProfileView;
|
|
31
|
+
export declare function resolveRustEmbeddedProfileView(wasm: EmbodyCoreWasmModule, presetId: string, profileOverride?: Partial<Profile> | Record<string, unknown> | null): RustResolvedProfileView;
|
package/dist/three.cjs
CHANGED
|
@@ -3922,14 +3922,6 @@ var PACKED_BONE_FLAG_HAS_POSITION = 1;
|
|
|
3922
3922
|
var PACKED_BONE_FLAG_HAS_ROTATION = 2;
|
|
3923
3923
|
|
|
3924
3924
|
// src/core/WasmRuntimeCore.ts
|
|
3925
|
-
var AXIS_GROUP_NEGATIVE = 0;
|
|
3926
|
-
var AXIS_GROUP_POSITIVE = 1;
|
|
3927
|
-
var AXIS_GROUP_PLAIN = 2;
|
|
3928
|
-
var BONE_SIDE_NONE = 0;
|
|
3929
|
-
var BONE_SIDE_LEFT = 1;
|
|
3930
|
-
var BONE_SIDE_RIGHT = 2;
|
|
3931
|
-
var ROTATION_CHANNELS = { rx: 0, ry: 1, rz: 2 };
|
|
3932
|
-
var TRANSLATION_CHANNELS = { tx: 0, ty: 1, tz: 2 };
|
|
3933
3925
|
var WasmRuntimeCore = class {
|
|
3934
3926
|
constructor(options) {
|
|
3935
3927
|
__publicField(this, "wasm");
|
|
@@ -3943,12 +3935,11 @@ var WasmRuntimeCore = class {
|
|
|
3943
3935
|
if (!RuntimeCtor) {
|
|
3944
3936
|
throw new Error("Embody Wasm module does not export RuntimeCore");
|
|
3945
3937
|
}
|
|
3946
|
-
this.core = new RuntimeCtor(
|
|
3938
|
+
this.core = new RuntimeCtor(0);
|
|
3947
3939
|
this.reloadBindings();
|
|
3948
3940
|
}
|
|
3949
3941
|
setProfile(profile) {
|
|
3950
3942
|
this.profile = profile;
|
|
3951
|
-
this.core.set_viseme_slot_count(getProfileVisemeSlots(profile).length);
|
|
3952
3943
|
this.reloadBindings();
|
|
3953
3944
|
}
|
|
3954
3945
|
setModelDescriptor(model) {
|
|
@@ -3993,191 +3984,9 @@ var WasmRuntimeCore = class {
|
|
|
3993
3984
|
};
|
|
3994
3985
|
}
|
|
3995
3986
|
reloadBindings() {
|
|
3996
|
-
|
|
3997
|
-
this.core.load_au_morph_bindings(auBindings);
|
|
3998
|
-
this.core.load_viseme_morph_bindings(visemeBindings);
|
|
3999
|
-
this.core.set_mixed_aus(mixedAus);
|
|
4000
|
-
const boneBindings = compileBoneBindings(this.profile, this.model);
|
|
4001
|
-
this.core.load_bone_rest_transforms(boneBindings.restTransforms);
|
|
4002
|
-
this.core.load_composite_axes(boneBindings.compositeAxes);
|
|
4003
|
-
this.core.load_bone_translations(boneBindings.translations);
|
|
4004
|
-
this.core.load_jaw_binding(boneBindings.jawBinding);
|
|
4005
|
-
this.core.load_viseme_jaw_amounts(boneBindings.visemeJawAmounts);
|
|
3987
|
+
this.core.configure_with_profile(JSON.stringify(this.profile), JSON.stringify(this.model));
|
|
4006
3988
|
}
|
|
4007
3989
|
};
|
|
4008
|
-
function compileMorphBindings(profile, model) {
|
|
4009
|
-
const auRows = [];
|
|
4010
|
-
const mixed = [];
|
|
4011
|
-
for (const [auIdText, entry] of Object.entries(profile.auToMorphs || {})) {
|
|
4012
|
-
const auId = Number(auIdText);
|
|
4013
|
-
if (Number.isNaN(auId) || !entry) continue;
|
|
4014
|
-
const meshNames = getMeshNamesForAUProfile(profile, auId);
|
|
4015
|
-
const hasMorphs = !!(entry.left?.length || entry.right?.length || entry.center?.length);
|
|
4016
|
-
if (hasMorphs && profile.auToBones?.[auId]?.length) {
|
|
4017
|
-
mixed.push(auId);
|
|
4018
|
-
}
|
|
4019
|
-
pushAuSide(auRows, auId, 0, entry.left || [], meshNames, model, profile);
|
|
4020
|
-
pushAuSide(auRows, auId, 1, entry.right || [], meshNames, model, profile);
|
|
4021
|
-
pushAuSide(auRows, auId, 2, entry.center || [], meshNames, model, profile);
|
|
4022
|
-
}
|
|
4023
|
-
const visemeRows = [];
|
|
4024
|
-
const visemeMeshNames = getMeshNamesForVisemeProfile(profile);
|
|
4025
|
-
const slotCount = getProfileVisemeSlots(profile).length;
|
|
4026
|
-
for (let index = 0; index < slotCount; index += 1) {
|
|
4027
|
-
for (const bindingTarget of getVisemeBindingTargets(profile, index)) {
|
|
4028
|
-
for (const resolved of resolveMorphTargets(model, profile, bindingTarget.morph, visemeMeshNames)) {
|
|
4029
|
-
visemeRows.push(
|
|
4030
|
-
index,
|
|
4031
|
-
Number(resolved.mesh.id),
|
|
4032
|
-
Number(resolved.morphTarget.id),
|
|
4033
|
-
bindingTarget.weight
|
|
4034
|
-
);
|
|
4035
|
-
}
|
|
4036
|
-
}
|
|
4037
|
-
}
|
|
4038
|
-
return {
|
|
4039
|
-
auBindings: Float32Array.from(auRows),
|
|
4040
|
-
visemeBindings: Float32Array.from(visemeRows),
|
|
4041
|
-
mixedAus: Uint32Array.from(mixed)
|
|
4042
|
-
};
|
|
4043
|
-
}
|
|
4044
|
-
function compileBoneBindings(profile, model) {
|
|
4045
|
-
const referencedBones = /* @__PURE__ */ new Map();
|
|
4046
|
-
const findBone = (nodeKey) => {
|
|
4047
|
-
const bone = findBoneDescriptor(profile, model, nodeKey);
|
|
4048
|
-
if (bone) referencedBones.set(bone.id, bone);
|
|
4049
|
-
return bone;
|
|
4050
|
-
};
|
|
4051
|
-
const boneSideForAU = (auId, nodeKey) => {
|
|
4052
|
-
const side = profile.auToBones?.[auId]?.find((candidate) => candidate.node === nodeKey)?.side;
|
|
4053
|
-
if (side === "left") return BONE_SIDE_LEFT;
|
|
4054
|
-
if (side === "right") return BONE_SIDE_RIGHT;
|
|
4055
|
-
return BONE_SIDE_NONE;
|
|
4056
|
-
};
|
|
4057
|
-
const compositeRows = [];
|
|
4058
|
-
for (const composite of profile.compositeRotations || []) {
|
|
4059
|
-
const bone = findBone(composite.node);
|
|
4060
|
-
if (!bone) continue;
|
|
4061
|
-
const axes = [
|
|
4062
|
-
{ axis: 1, config: composite.yaw },
|
|
4063
|
-
{ axis: 0, config: composite.pitch },
|
|
4064
|
-
{ axis: 2, config: composite.roll }
|
|
4065
|
-
];
|
|
4066
|
-
for (const { axis, config } of axes) {
|
|
4067
|
-
if (!config) continue;
|
|
4068
|
-
const negativeAUs = toAUList(config.negative);
|
|
4069
|
-
const positiveAUs = toAUList(config.positive);
|
|
4070
|
-
const hasDirectional = negativeAUs.length > 0 && positiveAUs.length > 0;
|
|
4071
|
-
const valueRows = [];
|
|
4072
|
-
if (hasDirectional) {
|
|
4073
|
-
for (const auId of negativeAUs) {
|
|
4074
|
-
valueRows.push([auId, AXIS_GROUP_NEGATIVE, boneSideForAU(auId, composite.node)]);
|
|
4075
|
-
}
|
|
4076
|
-
for (const auId of positiveAUs) {
|
|
4077
|
-
valueRows.push([auId, AXIS_GROUP_POSITIVE, boneSideForAU(auId, composite.node)]);
|
|
4078
|
-
}
|
|
4079
|
-
} else {
|
|
4080
|
-
for (const auId of config.aus) {
|
|
4081
|
-
valueRows.push([auId, AXIS_GROUP_PLAIN, boneSideForAU(auId, composite.node)]);
|
|
4082
|
-
}
|
|
4083
|
-
}
|
|
4084
|
-
const bindingRows = [];
|
|
4085
|
-
const pushBindingRows = (auIds, group) => {
|
|
4086
|
-
for (const auId of auIds) {
|
|
4087
|
-
const binding = profile.auToBones?.[auId]?.find(
|
|
4088
|
-
(candidate) => candidate.node === composite.node
|
|
4089
|
-
);
|
|
4090
|
-
if (!binding?.maxDegrees) continue;
|
|
4091
|
-
const channel = ROTATION_CHANNELS[binding.channel];
|
|
4092
|
-
if (channel === void 0) continue;
|
|
4093
|
-
bindingRows.push([
|
|
4094
|
-
auId,
|
|
4095
|
-
group,
|
|
4096
|
-
boneSideForAU(auId, composite.node),
|
|
4097
|
-
channel,
|
|
4098
|
-
binding.scale,
|
|
4099
|
-
binding.maxDegrees
|
|
4100
|
-
]);
|
|
4101
|
-
}
|
|
4102
|
-
};
|
|
4103
|
-
pushBindingRows(negativeAUs, AXIS_GROUP_NEGATIVE);
|
|
4104
|
-
pushBindingRows(positiveAUs, AXIS_GROUP_POSITIVE);
|
|
4105
|
-
pushBindingRows(config.aus, AXIS_GROUP_PLAIN);
|
|
4106
|
-
compositeRows.push(
|
|
4107
|
-
Number(bone.id),
|
|
4108
|
-
axis,
|
|
4109
|
-
hasDirectional ? 1 : 0,
|
|
4110
|
-
valueRows.length,
|
|
4111
|
-
bindingRows.length,
|
|
4112
|
-
0,
|
|
4113
|
-
0,
|
|
4114
|
-
0
|
|
4115
|
-
);
|
|
4116
|
-
for (const row of valueRows) compositeRows.push(...row);
|
|
4117
|
-
for (const row of bindingRows) compositeRows.push(...row);
|
|
4118
|
-
}
|
|
4119
|
-
}
|
|
4120
|
-
const translationRows = [];
|
|
4121
|
-
for (const [auIdText, bindings] of Object.entries(profile.auToBones || {})) {
|
|
4122
|
-
const auId = Number(auIdText);
|
|
4123
|
-
if (Number.isNaN(auId)) continue;
|
|
4124
|
-
for (const binding of bindings || []) {
|
|
4125
|
-
const channel = TRANSLATION_CHANNELS[binding.channel];
|
|
4126
|
-
if (channel === void 0 || binding.maxUnits === void 0) continue;
|
|
4127
|
-
const bone = findBone(binding.node);
|
|
4128
|
-
if (!bone) continue;
|
|
4129
|
-
translationRows.push(auId, Number(bone.id), channel, binding.scale, binding.maxUnits);
|
|
4130
|
-
}
|
|
4131
|
-
}
|
|
4132
|
-
const jawRow = [];
|
|
4133
|
-
const jawBinding = findAutoVisemeJawBinding(profile, model);
|
|
4134
|
-
if (jawBinding?.maxDegrees) {
|
|
4135
|
-
const bone = findBone(jawBinding.node);
|
|
4136
|
-
const channel = ROTATION_CHANNELS[jawBinding.channel];
|
|
4137
|
-
if (bone && channel !== void 0) {
|
|
4138
|
-
jawRow.push(Number(bone.id), channel, jawBinding.scale, jawBinding.maxDegrees);
|
|
4139
|
-
}
|
|
4140
|
-
}
|
|
4141
|
-
const restRows = [];
|
|
4142
|
-
for (const bone of referencedBones.values()) {
|
|
4143
|
-
const position = bone.restTransform?.position;
|
|
4144
|
-
const rotation = bone.restTransform?.rotation;
|
|
4145
|
-
restRows.push(
|
|
4146
|
-
Number(bone.id),
|
|
4147
|
-
position?.x ?? 0,
|
|
4148
|
-
position?.y ?? 0,
|
|
4149
|
-
position?.z ?? 0,
|
|
4150
|
-
rotation?.x ?? 0,
|
|
4151
|
-
rotation?.y ?? 0,
|
|
4152
|
-
rotation?.z ?? 0,
|
|
4153
|
-
rotation?.w ?? 1
|
|
4154
|
-
);
|
|
4155
|
-
}
|
|
4156
|
-
return {
|
|
4157
|
-
restTransforms: Float32Array.from(restRows),
|
|
4158
|
-
compositeAxes: Float32Array.from(compositeRows),
|
|
4159
|
-
translations: Float32Array.from(translationRows),
|
|
4160
|
-
jawBinding: Float32Array.from(jawRow),
|
|
4161
|
-
visemeJawAmounts: Float32Array.from(getVisemeJawAmounts(profile) ?? [])
|
|
4162
|
-
};
|
|
4163
|
-
}
|
|
4164
|
-
function findBoneDescriptor(profile, model, nodeKey) {
|
|
4165
|
-
const configuredName = profile.boneNodes?.[nodeKey] || nodeKey;
|
|
4166
|
-
const prefix = profile.bonePrefix ?? "";
|
|
4167
|
-
const suffix = profile.boneSuffix ?? "";
|
|
4168
|
-
const prefixedName = prefix && !configuredName.startsWith(prefix) ? `${prefix}${configuredName}` : configuredName;
|
|
4169
|
-
const fullName = suffix && !prefixedName.endsWith(suffix) ? `${prefixedName}${suffix}` : prefixedName;
|
|
4170
|
-
const candidates = /* @__PURE__ */ new Set([nodeKey, configuredName, fullName]);
|
|
4171
|
-
return model.bones.find((bone) => candidates.has(bone.name));
|
|
4172
|
-
}
|
|
4173
|
-
function findAutoVisemeJawBinding(profile, model) {
|
|
4174
|
-
const isRotation = (binding) => binding?.channel === "rx" || binding?.channel === "ry" || binding?.channel === "rz";
|
|
4175
|
-
const candidates = [
|
|
4176
|
-
profile.auToBones?.[103]?.find(isRotation),
|
|
4177
|
-
profile.auToBones?.[26]?.find(isRotation)
|
|
4178
|
-
].filter((binding) => !!binding);
|
|
4179
|
-
return candidates.find((binding) => !!findBoneDescriptor(profile, model, binding.node)) ?? candidates[0] ?? null;
|
|
4180
|
-
}
|
|
4181
3990
|
function unpackBoneFrameDelta(values) {
|
|
4182
3991
|
const stride = PACKED_BONE_FRAME_DELTA_STRIDE;
|
|
4183
3992
|
const writes = [];
|
|
@@ -4218,46 +4027,6 @@ function unpackMorphFrameDelta(values) {
|
|
|
4218
4027
|
}
|
|
4219
4028
|
return writes;
|
|
4220
4029
|
}
|
|
4221
|
-
function pushAuSide(rows, auId, side, morphs, meshNames, model, profile) {
|
|
4222
|
-
for (const morph of morphs) {
|
|
4223
|
-
for (const resolved of resolveMorphTargets(model, profile, morph, meshNames)) {
|
|
4224
|
-
rows.push(
|
|
4225
|
-
auId,
|
|
4226
|
-
side,
|
|
4227
|
-
Number(resolved.mesh.id),
|
|
4228
|
-
Number(resolved.morphTarget.id),
|
|
4229
|
-
1
|
|
4230
|
-
);
|
|
4231
|
-
}
|
|
4232
|
-
}
|
|
4233
|
-
}
|
|
4234
|
-
function resolveMorphTargets(model, profile, morph, meshNames) {
|
|
4235
|
-
const result = [];
|
|
4236
|
-
for (const meshName of meshNames) {
|
|
4237
|
-
const mesh = model.meshes.find((candidate) => candidate.name === meshName);
|
|
4238
|
-
if (!mesh) continue;
|
|
4239
|
-
const morphTargets = mesh.morphTargetIds.map((id) => model.morphTargets.find((candidate) => candidate.id === id)).filter((target2) => !!target2);
|
|
4240
|
-
const target = typeof morph === "number" ? morphTargets.find((candidate) => candidate.hostIndex === morph) : resolveMorphTargetByName2(morphTargets, morph, profile);
|
|
4241
|
-
if (target) {
|
|
4242
|
-
result.push({ mesh, morphTarget: target });
|
|
4243
|
-
}
|
|
4244
|
-
}
|
|
4245
|
-
return result;
|
|
4246
|
-
}
|
|
4247
|
-
function resolveMorphTargetByName2(targets, key, profile) {
|
|
4248
|
-
const prefix = profile.morphPrefix || "";
|
|
4249
|
-
const suffix = profile.morphSuffix || "";
|
|
4250
|
-
const fullName = prefix + key + suffix;
|
|
4251
|
-
const exact = targets.find((target) => target.name === fullName);
|
|
4252
|
-
if (exact) return exact;
|
|
4253
|
-
const suffixRegex = profile.suffixPattern ? new RegExp(profile.suffixPattern) : null;
|
|
4254
|
-
if (!suffixRegex) return void 0;
|
|
4255
|
-
return targets.find((target) => {
|
|
4256
|
-
if (!target.name.startsWith(fullName)) return false;
|
|
4257
|
-
const candidateSuffix = target.name.slice(fullName.length);
|
|
4258
|
-
return candidateSuffix === "" || suffixRegex.test(candidateSuffix);
|
|
4259
|
-
});
|
|
4260
|
-
}
|
|
4261
4030
|
|
|
4262
4031
|
// src/hair/appearance.ts
|
|
4263
4032
|
var HAIR_COLOR_PRESETS = {
|