@vizij/node-graph-authoring 0.1.0 → 0.1.1
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/{chunk-6WQOBROM.js → chunk-7UGGWHD3.js} +842 -22
- package/dist/cli/reportIr.cjs +832 -21
- package/dist/cli/reportIr.js +1 -1
- package/dist/index.cjs +832 -21
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -1942,7 +1942,16 @@ function inlineSingleUseConstants(spec) {
|
|
|
1942
1942
|
}
|
|
1943
1943
|
|
|
1944
1944
|
// src/graphBuilder.ts
|
|
1945
|
-
import {
|
|
1945
|
+
import {
|
|
1946
|
+
RIG_PIPELINE_V1_VERSION,
|
|
1947
|
+
buildAnimatableValue,
|
|
1948
|
+
cloneDeepSafe as cloneDeepSafe4,
|
|
1949
|
+
hasRigPipelineV1InputConfig,
|
|
1950
|
+
isRigElementStandardInputPath,
|
|
1951
|
+
normalizeStandardRigInputPath,
|
|
1952
|
+
resolveRigPipelineV1InputConfig,
|
|
1953
|
+
resolveStandardRigInputId
|
|
1954
|
+
} from "@vizij/utils";
|
|
1946
1955
|
import { SELF_BINDING_ID as SELF_BINDING_ID2 } from "@vizij/utils";
|
|
1947
1956
|
import { nodeRegistryVersion } from "@vizij/node-graph-wasm/metadata";
|
|
1948
1957
|
|
|
@@ -2068,6 +2077,61 @@ function buildBindingMetadataFromExpression(node, variables) {
|
|
|
2068
2077
|
}
|
|
2069
2078
|
|
|
2070
2079
|
// src/graphBuilder.ts
|
|
2080
|
+
function resolveBindingSlotInputId(bindingInputId, inputsById) {
|
|
2081
|
+
if (!bindingInputId || bindingInputId === SELF_BINDING_ID2) {
|
|
2082
|
+
return bindingInputId;
|
|
2083
|
+
}
|
|
2084
|
+
const resolvedInputId = resolveStandardRigInputId(bindingInputId, inputsById);
|
|
2085
|
+
if (inputsById.has(resolvedInputId)) {
|
|
2086
|
+
return resolvedInputId;
|
|
2087
|
+
}
|
|
2088
|
+
return bindingInputId;
|
|
2089
|
+
}
|
|
2090
|
+
function isRigElementAliasInput(inputId, inputsById) {
|
|
2091
|
+
const input = inputsById.get(inputId);
|
|
2092
|
+
if (!input?.path) {
|
|
2093
|
+
return false;
|
|
2094
|
+
}
|
|
2095
|
+
return isRigElementStandardInputPath(input.path);
|
|
2096
|
+
}
|
|
2097
|
+
function isHigherOrderRigBindingInput(inputId, inputsById) {
|
|
2098
|
+
const input = inputsById.get(inputId);
|
|
2099
|
+
if (!input?.path) {
|
|
2100
|
+
return false;
|
|
2101
|
+
}
|
|
2102
|
+
if (isRigElementAliasInput(inputId, inputsById)) {
|
|
2103
|
+
return false;
|
|
2104
|
+
}
|
|
2105
|
+
return true;
|
|
2106
|
+
}
|
|
2107
|
+
function bindingReferencesRigElementInput(binding, inputsById) {
|
|
2108
|
+
const candidateInputIds = /* @__PURE__ */ new Set();
|
|
2109
|
+
if (binding.inputId && binding.inputId !== SELF_BINDING_ID2) {
|
|
2110
|
+
candidateInputIds.add(binding.inputId);
|
|
2111
|
+
}
|
|
2112
|
+
binding.slots.forEach((slot) => {
|
|
2113
|
+
if (slot.inputId && slot.inputId !== SELF_BINDING_ID2) {
|
|
2114
|
+
candidateInputIds.add(slot.inputId);
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
for (const candidateInputId of candidateInputIds) {
|
|
2118
|
+
if (isRigElementStandardInputPath(candidateInputId)) {
|
|
2119
|
+
return true;
|
|
2120
|
+
}
|
|
2121
|
+
const resolvedCandidateId = resolveBindingSlotInputId(
|
|
2122
|
+
candidateInputId,
|
|
2123
|
+
inputsById
|
|
2124
|
+
);
|
|
2125
|
+
if (!resolvedCandidateId || resolvedCandidateId === SELF_BINDING_ID2) {
|
|
2126
|
+
continue;
|
|
2127
|
+
}
|
|
2128
|
+
const resolvedInput = inputsById.get(resolvedCandidateId);
|
|
2129
|
+
if (resolvedInput && isRigElementStandardInputPath(resolvedInput.path)) {
|
|
2130
|
+
return true;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
return false;
|
|
2134
|
+
}
|
|
2071
2135
|
function evaluateBinding({
|
|
2072
2136
|
binding,
|
|
2073
2137
|
target,
|
|
@@ -2076,9 +2140,18 @@ function evaluateBinding({
|
|
|
2076
2140
|
component,
|
|
2077
2141
|
safeId,
|
|
2078
2142
|
context,
|
|
2079
|
-
selfNodeId
|
|
2143
|
+
selfNodeId,
|
|
2144
|
+
enforceRigBoundaryRules = false
|
|
2080
2145
|
}) {
|
|
2081
|
-
const {
|
|
2146
|
+
const {
|
|
2147
|
+
nodes,
|
|
2148
|
+
edges,
|
|
2149
|
+
ensureInputNode,
|
|
2150
|
+
bindingIssues,
|
|
2151
|
+
summaryBindings,
|
|
2152
|
+
inputsById,
|
|
2153
|
+
inputBindings
|
|
2154
|
+
} = context;
|
|
2082
2155
|
const exprContext = {
|
|
2083
2156
|
componentSafeId: safeId,
|
|
2084
2157
|
nodes,
|
|
@@ -2102,6 +2175,10 @@ function evaluateBinding({
|
|
|
2102
2175
|
const fallbackAlias = `s${index + 1}`;
|
|
2103
2176
|
const alias = aliasBase.length > 0 ? aliasBase : fallbackAlias;
|
|
2104
2177
|
const slotId = slot.id && slot.id.length > 0 ? slot.id : alias;
|
|
2178
|
+
const resolvedSlotInputId = resolveBindingSlotInputId(
|
|
2179
|
+
slot.inputId,
|
|
2180
|
+
inputsById
|
|
2181
|
+
);
|
|
2105
2182
|
const slotValueType = slot.valueType === "vector" ? "vector" : "scalar";
|
|
2106
2183
|
let slotOutputId;
|
|
2107
2184
|
if (slot.inputId === SELF_BINDING_ID2) {
|
|
@@ -2117,19 +2194,30 @@ function evaluateBinding({
|
|
|
2117
2194
|
expressionIssues.push("Self reference unavailable for this input.");
|
|
2118
2195
|
slotOutputId = getConstantNodeId(exprContext, target.defaultValue);
|
|
2119
2196
|
}
|
|
2120
|
-
} else if (
|
|
2121
|
-
const
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
slotOutputId,
|
|
2128
|
-
slotValueType === "vector" ? "vector" : "scalar"
|
|
2197
|
+
} else if (resolvedSlotInputId) {
|
|
2198
|
+
const inputId = resolvedSlotInputId;
|
|
2199
|
+
const sourceBinding = inputBindings[inputId];
|
|
2200
|
+
const allowedHigherOrderViaRigElementSource = sourceBinding !== void 0 && bindingReferencesRigElementInput(sourceBinding, inputsById);
|
|
2201
|
+
if (enforceRigBoundaryRules && isHigherOrderRigBindingInput(inputId, inputsById) && !allowedHigherOrderViaRigElementSource && inputId !== SELF_BINDING_ID2) {
|
|
2202
|
+
expressionIssues.push(
|
|
2203
|
+
`Input "${inputId}" is a higher-order rig input and cannot directly drive animatable "${target.id}".`
|
|
2129
2204
|
);
|
|
2130
|
-
} else {
|
|
2131
|
-
expressionIssues.push(`Missing standard input "${slot.inputId}".`);
|
|
2132
2205
|
slotOutputId = getConstantNodeId(exprContext, 0);
|
|
2206
|
+
hasActiveSlot = true;
|
|
2207
|
+
} else {
|
|
2208
|
+
const inputNode = ensureInputNode(inputId);
|
|
2209
|
+
if (inputNode) {
|
|
2210
|
+
slotOutputId = inputNode.nodeId;
|
|
2211
|
+
hasActiveSlot = true;
|
|
2212
|
+
setNodeValueType(
|
|
2213
|
+
exprContext,
|
|
2214
|
+
slotOutputId,
|
|
2215
|
+
slotValueType === "vector" ? "vector" : "scalar"
|
|
2216
|
+
);
|
|
2217
|
+
} else {
|
|
2218
|
+
expressionIssues.push(`Missing standard input "${inputId}".`);
|
|
2219
|
+
slotOutputId = getConstantNodeId(exprContext, 0);
|
|
2220
|
+
}
|
|
2133
2221
|
}
|
|
2134
2222
|
} else {
|
|
2135
2223
|
slotOutputId = getConstantNodeId(exprContext, 0);
|
|
@@ -2139,7 +2227,7 @@ function evaluateBinding({
|
|
|
2139
2227
|
nodeId: slotOutputId,
|
|
2140
2228
|
slotId,
|
|
2141
2229
|
slotAlias: alias,
|
|
2142
|
-
inputId:
|
|
2230
|
+
inputId: resolvedSlotInputId ?? null,
|
|
2143
2231
|
targetId,
|
|
2144
2232
|
animatableId,
|
|
2145
2233
|
component,
|
|
@@ -2156,7 +2244,7 @@ function evaluateBinding({
|
|
|
2156
2244
|
component,
|
|
2157
2245
|
slotId,
|
|
2158
2246
|
slotAlias: alias,
|
|
2159
|
-
inputId:
|
|
2247
|
+
inputId: resolvedSlotInputId ?? null,
|
|
2160
2248
|
expression: trimmedExpression,
|
|
2161
2249
|
valueType: slotValueType,
|
|
2162
2250
|
nodeId: slotOutputId,
|
|
@@ -2303,6 +2391,20 @@ function buildRigInputPath(faceId, inputPath) {
|
|
|
2303
2391
|
const suffix = trimmed ? `/${trimmed}` : "";
|
|
2304
2392
|
return `rig/${faceId}${suffix}`;
|
|
2305
2393
|
}
|
|
2394
|
+
function buildPoseControlInputPath(faceId, inputId) {
|
|
2395
|
+
return `rig/${faceId}/pose/control/${inputId}`;
|
|
2396
|
+
}
|
|
2397
|
+
function isPoseWeightInputPath(path) {
|
|
2398
|
+
const normalized = normalizeStandardRigInputPath(path);
|
|
2399
|
+
return normalized.startsWith("/poses/") && normalized.endsWith(".weight");
|
|
2400
|
+
}
|
|
2401
|
+
function isPoseControlPath(path) {
|
|
2402
|
+
const normalized = normalizeStandardRigInputPath(path);
|
|
2403
|
+
return normalized.startsWith("/pose/control/");
|
|
2404
|
+
}
|
|
2405
|
+
function resolveInputComposeMode(mode) {
|
|
2406
|
+
return mode === "average" ? "average" : "add";
|
|
2407
|
+
}
|
|
2306
2408
|
function getComponentOrder(animatable) {
|
|
2307
2409
|
switch (animatable.type) {
|
|
2308
2410
|
case "vector2":
|
|
@@ -3025,7 +3127,9 @@ function buildRigGraphSpec({
|
|
|
3025
3127
|
bindings,
|
|
3026
3128
|
inputsById,
|
|
3027
3129
|
inputBindings,
|
|
3028
|
-
inputMetadata
|
|
3130
|
+
inputMetadata,
|
|
3131
|
+
inputComposeModesById,
|
|
3132
|
+
pipelineV1
|
|
3029
3133
|
}) {
|
|
3030
3134
|
const metadataByInputId = inputMetadata ?? /* @__PURE__ */ new Map();
|
|
3031
3135
|
const irBuilder = createIrGraphBuilder({
|
|
@@ -3048,8 +3152,634 @@ function buildRigGraphSpec({
|
|
|
3048
3152
|
const computedInputs = /* @__PURE__ */ new Set();
|
|
3049
3153
|
const summaryBindings = [];
|
|
3050
3154
|
const bindingIssues = /* @__PURE__ */ new Map();
|
|
3155
|
+
const stagedPipelineByInputId = /* @__PURE__ */ new Map();
|
|
3051
3156
|
const animatableEntries = /* @__PURE__ */ new Map();
|
|
3052
3157
|
const outputs = /* @__PURE__ */ new Set();
|
|
3158
|
+
const composeModeByInputId = /* @__PURE__ */ new Map();
|
|
3159
|
+
Object.entries(inputComposeModesById ?? {}).forEach(([inputId, mode]) => {
|
|
3160
|
+
if (!inputsById.has(inputId)) {
|
|
3161
|
+
return;
|
|
3162
|
+
}
|
|
3163
|
+
composeModeByInputId.set(inputId, resolveInputComposeMode(mode));
|
|
3164
|
+
});
|
|
3165
|
+
const shouldComposeInputWithPoseControl = (input) => {
|
|
3166
|
+
if (!composeModeByInputId.has(input.id)) {
|
|
3167
|
+
return false;
|
|
3168
|
+
}
|
|
3169
|
+
if (isPoseWeightInputPath(input.path)) {
|
|
3170
|
+
return false;
|
|
3171
|
+
}
|
|
3172
|
+
if (isPoseControlPath(input.path)) {
|
|
3173
|
+
return false;
|
|
3174
|
+
}
|
|
3175
|
+
return true;
|
|
3176
|
+
};
|
|
3177
|
+
const buildNormalizedAdditiveBlendNodeId = ({
|
|
3178
|
+
nodeIdPrefix,
|
|
3179
|
+
sourceNodeIds,
|
|
3180
|
+
baseline
|
|
3181
|
+
}) => {
|
|
3182
|
+
if (sourceNodeIds.length === 0) {
|
|
3183
|
+
const fallbackNodeId = `${nodeIdPrefix}_baseline`;
|
|
3184
|
+
nodes.push({
|
|
3185
|
+
id: fallbackNodeId,
|
|
3186
|
+
type: "constant",
|
|
3187
|
+
params: {
|
|
3188
|
+
value: baseline
|
|
3189
|
+
}
|
|
3190
|
+
});
|
|
3191
|
+
return fallbackNodeId;
|
|
3192
|
+
}
|
|
3193
|
+
if (sourceNodeIds.length === 1) {
|
|
3194
|
+
return sourceNodeIds[0];
|
|
3195
|
+
}
|
|
3196
|
+
const addNodeId = `${nodeIdPrefix}_add`;
|
|
3197
|
+
nodes.push({
|
|
3198
|
+
id: addNodeId,
|
|
3199
|
+
type: "add"
|
|
3200
|
+
});
|
|
3201
|
+
sourceNodeIds.forEach((sourceNodeId, index) => {
|
|
3202
|
+
edges.push({
|
|
3203
|
+
from: { nodeId: sourceNodeId },
|
|
3204
|
+
to: { nodeId: addNodeId, portId: `operand_${index + 1}` }
|
|
3205
|
+
});
|
|
3206
|
+
});
|
|
3207
|
+
const normalizedNodeId = `${nodeIdPrefix}_normalized_add`;
|
|
3208
|
+
nodes.push({
|
|
3209
|
+
id: normalizedNodeId,
|
|
3210
|
+
type: "subtract",
|
|
3211
|
+
inputDefaults: {
|
|
3212
|
+
rhs: (sourceNodeIds.length - 1) * baseline
|
|
3213
|
+
}
|
|
3214
|
+
});
|
|
3215
|
+
edges.push({
|
|
3216
|
+
from: { nodeId: addNodeId },
|
|
3217
|
+
to: { nodeId: normalizedNodeId, portId: "lhs" }
|
|
3218
|
+
});
|
|
3219
|
+
return normalizedNodeId;
|
|
3220
|
+
};
|
|
3221
|
+
const splitTopLevelCommaSeparated = (value) => {
|
|
3222
|
+
const segments = [];
|
|
3223
|
+
let depthParen = 0;
|
|
3224
|
+
let depthBracket = 0;
|
|
3225
|
+
let start = 0;
|
|
3226
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
3227
|
+
const char = value[index];
|
|
3228
|
+
if (char === "(") {
|
|
3229
|
+
depthParen += 1;
|
|
3230
|
+
continue;
|
|
3231
|
+
}
|
|
3232
|
+
if (char === ")") {
|
|
3233
|
+
depthParen = Math.max(0, depthParen - 1);
|
|
3234
|
+
continue;
|
|
3235
|
+
}
|
|
3236
|
+
if (char === "[") {
|
|
3237
|
+
depthBracket += 1;
|
|
3238
|
+
continue;
|
|
3239
|
+
}
|
|
3240
|
+
if (char === "]") {
|
|
3241
|
+
depthBracket = Math.max(0, depthBracket - 1);
|
|
3242
|
+
continue;
|
|
3243
|
+
}
|
|
3244
|
+
if (char === "," && depthParen === 0 && depthBracket === 0) {
|
|
3245
|
+
segments.push(value.slice(start, index));
|
|
3246
|
+
start = index + 1;
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
segments.push(value.slice(start));
|
|
3250
|
+
return segments;
|
|
3251
|
+
};
|
|
3252
|
+
const stripTopLevelAssignment = (value) => {
|
|
3253
|
+
let depthParen = 0;
|
|
3254
|
+
let depthBracket = 0;
|
|
3255
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
3256
|
+
const char = value[index];
|
|
3257
|
+
if (char === "(") {
|
|
3258
|
+
depthParen += 1;
|
|
3259
|
+
continue;
|
|
3260
|
+
}
|
|
3261
|
+
if (char === ")") {
|
|
3262
|
+
depthParen = Math.max(0, depthParen - 1);
|
|
3263
|
+
continue;
|
|
3264
|
+
}
|
|
3265
|
+
if (char === "[") {
|
|
3266
|
+
depthBracket += 1;
|
|
3267
|
+
continue;
|
|
3268
|
+
}
|
|
3269
|
+
if (char === "]") {
|
|
3270
|
+
depthBracket = Math.max(0, depthBracket - 1);
|
|
3271
|
+
continue;
|
|
3272
|
+
}
|
|
3273
|
+
if (char !== "=" || depthParen !== 0 || depthBracket !== 0) {
|
|
3274
|
+
continue;
|
|
3275
|
+
}
|
|
3276
|
+
const previous = value[index - 1];
|
|
3277
|
+
const next = value[index + 1];
|
|
3278
|
+
if (previous === "=" || next === "=") {
|
|
3279
|
+
continue;
|
|
3280
|
+
}
|
|
3281
|
+
return value.slice(index + 1).trim();
|
|
3282
|
+
}
|
|
3283
|
+
return value.trim();
|
|
3284
|
+
};
|
|
3285
|
+
const isNormalizedAdditiveFunctionName = (value) => {
|
|
3286
|
+
const normalized = value.trim().toLowerCase();
|
|
3287
|
+
return normalized === "normalizedadditive" || normalized === "normalizedaddative" || normalized === "noramalizedadditive" || normalized === "noramalizedaddative";
|
|
3288
|
+
};
|
|
3289
|
+
const buildNormalizedAdditiveExpression = (value) => {
|
|
3290
|
+
const args = splitTopLevelCommaSeparated(value).map(
|
|
3291
|
+
(entry) => entry.trim()
|
|
3292
|
+
);
|
|
3293
|
+
if (args.length === 0) {
|
|
3294
|
+
return "default";
|
|
3295
|
+
}
|
|
3296
|
+
const parentTerms = [];
|
|
3297
|
+
let baselineExpression = "default";
|
|
3298
|
+
const firstArg = args[0];
|
|
3299
|
+
if (firstArg && firstArg.startsWith("[") && firstArg.endsWith("]")) {
|
|
3300
|
+
const inner = firstArg.slice(1, -1).trim();
|
|
3301
|
+
if (inner.length > 0) {
|
|
3302
|
+
splitTopLevelCommaSeparated(inner).forEach((entry) => {
|
|
3303
|
+
const term = entry.trim();
|
|
3304
|
+
if (term.length > 0) {
|
|
3305
|
+
parentTerms.push(term);
|
|
3306
|
+
}
|
|
3307
|
+
});
|
|
3308
|
+
}
|
|
3309
|
+
args.slice(1).forEach((entry) => {
|
|
3310
|
+
const baselineMatch = entry.match(/^baseline\s*=\s*(.+)$/i);
|
|
3311
|
+
if (baselineMatch?.[1]) {
|
|
3312
|
+
baselineExpression = baselineMatch[1].trim();
|
|
3313
|
+
return;
|
|
3314
|
+
}
|
|
3315
|
+
const term = entry.trim();
|
|
3316
|
+
if (term.length > 0) {
|
|
3317
|
+
parentTerms.push(term);
|
|
3318
|
+
}
|
|
3319
|
+
});
|
|
3320
|
+
} else {
|
|
3321
|
+
args.forEach((entry) => {
|
|
3322
|
+
const baselineMatch = entry.match(/^baseline\s*=\s*(.+)$/i);
|
|
3323
|
+
if (baselineMatch?.[1]) {
|
|
3324
|
+
baselineExpression = baselineMatch[1].trim();
|
|
3325
|
+
return;
|
|
3326
|
+
}
|
|
3327
|
+
const term = entry.trim();
|
|
3328
|
+
if (term.length > 0) {
|
|
3329
|
+
parentTerms.push(term);
|
|
3330
|
+
}
|
|
3331
|
+
});
|
|
3332
|
+
}
|
|
3333
|
+
if (parentTerms.length === 0) {
|
|
3334
|
+
return `(${baselineExpression})`;
|
|
3335
|
+
}
|
|
3336
|
+
if (parentTerms.length === 1) {
|
|
3337
|
+
return `(${parentTerms[0]})`;
|
|
3338
|
+
}
|
|
3339
|
+
return `((${parentTerms.join(" + ")}) - (${parentTerms.length - 1}) * (${baselineExpression}))`;
|
|
3340
|
+
};
|
|
3341
|
+
const rewriteNormalizedAdditiveCalls = (value) => {
|
|
3342
|
+
let cursor = 0;
|
|
3343
|
+
let rewritten = "";
|
|
3344
|
+
while (cursor < value.length) {
|
|
3345
|
+
const remaining = value.slice(cursor);
|
|
3346
|
+
const match = remaining.match(
|
|
3347
|
+
/(normalizedadditive|normalizedaddative|noramalizedadditive|noramalizedaddative)\s*\(/i
|
|
3348
|
+
);
|
|
3349
|
+
if (!match || match.index === void 0) {
|
|
3350
|
+
rewritten += remaining;
|
|
3351
|
+
break;
|
|
3352
|
+
}
|
|
3353
|
+
const matchStart = cursor + match.index;
|
|
3354
|
+
const functionName = match[1] ?? "";
|
|
3355
|
+
const openParenIndex = value.indexOf(
|
|
3356
|
+
"(",
|
|
3357
|
+
matchStart + functionName.length
|
|
3358
|
+
);
|
|
3359
|
+
if (openParenIndex < 0) {
|
|
3360
|
+
rewritten += value.slice(cursor);
|
|
3361
|
+
break;
|
|
3362
|
+
}
|
|
3363
|
+
rewritten += value.slice(cursor, matchStart);
|
|
3364
|
+
let depth = 1;
|
|
3365
|
+
let closeParenIndex = openParenIndex + 1;
|
|
3366
|
+
while (closeParenIndex < value.length && depth > 0) {
|
|
3367
|
+
const char = value[closeParenIndex];
|
|
3368
|
+
if (char === "(") {
|
|
3369
|
+
depth += 1;
|
|
3370
|
+
} else if (char === ")") {
|
|
3371
|
+
depth -= 1;
|
|
3372
|
+
}
|
|
3373
|
+
closeParenIndex += 1;
|
|
3374
|
+
}
|
|
3375
|
+
if (depth !== 0) {
|
|
3376
|
+
rewritten += value.slice(matchStart);
|
|
3377
|
+
break;
|
|
3378
|
+
}
|
|
3379
|
+
const argsContent = value.slice(openParenIndex + 1, closeParenIndex - 1);
|
|
3380
|
+
if (isNormalizedAdditiveFunctionName(functionName)) {
|
|
3381
|
+
rewritten += buildNormalizedAdditiveExpression(argsContent);
|
|
3382
|
+
} else {
|
|
3383
|
+
rewritten += value.slice(matchStart, closeParenIndex);
|
|
3384
|
+
}
|
|
3385
|
+
cursor = closeParenIndex;
|
|
3386
|
+
}
|
|
3387
|
+
return rewritten;
|
|
3388
|
+
};
|
|
3389
|
+
const normalizeStagedFormulaExpression = (expression) => {
|
|
3390
|
+
const rhs = stripTopLevelAssignment(expression);
|
|
3391
|
+
return rewriteNormalizedAdditiveCalls(rhs);
|
|
3392
|
+
};
|
|
3393
|
+
const normalizeFormulaSignature = (expression) => normalizeStagedFormulaExpression(expression).replace(/\s+/g, "").toLowerCase();
|
|
3394
|
+
const buildDefaultParentTransformNodeId = (params) => {
|
|
3395
|
+
let transformedNodeId = params.sourceNodeId;
|
|
3396
|
+
if (params.scale !== 1) {
|
|
3397
|
+
const scaledNodeId = `input_parent_scale_${params.nodeSuffix}`;
|
|
3398
|
+
nodes.push({
|
|
3399
|
+
id: scaledNodeId,
|
|
3400
|
+
type: "multiply",
|
|
3401
|
+
inputDefaults: {
|
|
3402
|
+
operand_2: params.scale
|
|
3403
|
+
}
|
|
3404
|
+
});
|
|
3405
|
+
edges.push({
|
|
3406
|
+
from: { nodeId: transformedNodeId },
|
|
3407
|
+
to: { nodeId: scaledNodeId, portId: "operand_1" }
|
|
3408
|
+
});
|
|
3409
|
+
transformedNodeId = scaledNodeId;
|
|
3410
|
+
}
|
|
3411
|
+
if (params.offset !== 0) {
|
|
3412
|
+
const offsetNodeId = `input_parent_offset_${params.nodeSuffix}`;
|
|
3413
|
+
nodes.push({
|
|
3414
|
+
id: offsetNodeId,
|
|
3415
|
+
type: "add",
|
|
3416
|
+
inputDefaults: {
|
|
3417
|
+
operand_2: params.offset
|
|
3418
|
+
}
|
|
3419
|
+
});
|
|
3420
|
+
edges.push({
|
|
3421
|
+
from: { nodeId: transformedNodeId },
|
|
3422
|
+
to: { nodeId: offsetNodeId, portId: "operand_1" }
|
|
3423
|
+
});
|
|
3424
|
+
transformedNodeId = offsetNodeId;
|
|
3425
|
+
}
|
|
3426
|
+
return transformedNodeId;
|
|
3427
|
+
};
|
|
3428
|
+
const buildStagedFormulaNodeId = (params) => {
|
|
3429
|
+
const normalizedExpression = normalizeStagedFormulaExpression(
|
|
3430
|
+
params.expression
|
|
3431
|
+
);
|
|
3432
|
+
if (!normalizedExpression) {
|
|
3433
|
+
return params.fallbackNodeId;
|
|
3434
|
+
}
|
|
3435
|
+
const parseResult = parseControlExpression(normalizedExpression);
|
|
3436
|
+
const issues = [];
|
|
3437
|
+
if (!parseResult.node) {
|
|
3438
|
+
parseResult.errors.forEach((error) => {
|
|
3439
|
+
issues.push(
|
|
3440
|
+
`${params.issuePrefix}: ${error.message} (index ${error.index}).`
|
|
3441
|
+
);
|
|
3442
|
+
});
|
|
3443
|
+
}
|
|
3444
|
+
if (!parseResult.node || issues.length > 0) {
|
|
3445
|
+
const issueSet = bindingIssues.get(params.inputId) ?? /* @__PURE__ */ new Set();
|
|
3446
|
+
issues.forEach((issue) => issueSet.add(issue));
|
|
3447
|
+
if (issues.length > 0) {
|
|
3448
|
+
bindingIssues.set(params.inputId, issueSet);
|
|
3449
|
+
}
|
|
3450
|
+
return params.fallbackNodeId;
|
|
3451
|
+
}
|
|
3452
|
+
const exprContext = {
|
|
3453
|
+
componentSafeId: params.componentSafeId,
|
|
3454
|
+
nodes,
|
|
3455
|
+
edges,
|
|
3456
|
+
constants: /* @__PURE__ */ new Map(),
|
|
3457
|
+
counter: 1,
|
|
3458
|
+
reservedNodes: /* @__PURE__ */ new Map(),
|
|
3459
|
+
nodeValueTypes: /* @__PURE__ */ new Map(),
|
|
3460
|
+
graphReservedNodes,
|
|
3461
|
+
generateReservedNodeId
|
|
3462
|
+
};
|
|
3463
|
+
const variableTable = createExpressionVariableTable();
|
|
3464
|
+
const registerVariableName = (name, nodeId2) => {
|
|
3465
|
+
const trimmed = name.trim();
|
|
3466
|
+
if (!trimmed) {
|
|
3467
|
+
return;
|
|
3468
|
+
}
|
|
3469
|
+
variableTable.registerReservedVariable({
|
|
3470
|
+
name: trimmed,
|
|
3471
|
+
nodeId: nodeId2,
|
|
3472
|
+
description: "Staged pipeline formula variable"
|
|
3473
|
+
});
|
|
3474
|
+
const lower = trimmed.toLowerCase();
|
|
3475
|
+
if (lower !== trimmed) {
|
|
3476
|
+
variableTable.registerReservedVariable({
|
|
3477
|
+
name: lower,
|
|
3478
|
+
nodeId: nodeId2,
|
|
3479
|
+
description: "Staged pipeline formula variable"
|
|
3480
|
+
});
|
|
3481
|
+
}
|
|
3482
|
+
};
|
|
3483
|
+
Object.entries(params.variables).forEach(([name, variable]) => {
|
|
3484
|
+
const nodeId2 = variable.nodeId ?? (typeof variable.value === "number" && Number.isFinite(variable.value) ? getConstantNodeId(exprContext, variable.value) : null);
|
|
3485
|
+
if (!nodeId2) {
|
|
3486
|
+
return;
|
|
3487
|
+
}
|
|
3488
|
+
registerVariableName(name, nodeId2);
|
|
3489
|
+
});
|
|
3490
|
+
const references = collectExpressionReferences(parseResult.node);
|
|
3491
|
+
const missingVariables = variableTable.missing(references);
|
|
3492
|
+
if (missingVariables.length > 0) {
|
|
3493
|
+
const issueSet = bindingIssues.get(params.inputId) ?? /* @__PURE__ */ new Set();
|
|
3494
|
+
missingVariables.forEach((entry) => {
|
|
3495
|
+
issueSet.add(
|
|
3496
|
+
`${params.issuePrefix}: unknown formula variable "${entry.name}".`
|
|
3497
|
+
);
|
|
3498
|
+
});
|
|
3499
|
+
bindingIssues.set(params.inputId, issueSet);
|
|
3500
|
+
return params.fallbackNodeId;
|
|
3501
|
+
}
|
|
3502
|
+
validateLiteralParamArguments(parseResult.node, issues);
|
|
3503
|
+
const nodeId = materializeExpression(
|
|
3504
|
+
parseResult.node,
|
|
3505
|
+
exprContext,
|
|
3506
|
+
variableTable,
|
|
3507
|
+
issues
|
|
3508
|
+
);
|
|
3509
|
+
if (issues.length > 0) {
|
|
3510
|
+
const issueSet = bindingIssues.get(params.inputId) ?? /* @__PURE__ */ new Set();
|
|
3511
|
+
issues.forEach(
|
|
3512
|
+
(issue) => issueSet.add(`${params.issuePrefix}: ${issue}`)
|
|
3513
|
+
);
|
|
3514
|
+
bindingIssues.set(params.inputId, issueSet);
|
|
3515
|
+
return params.fallbackNodeId;
|
|
3516
|
+
}
|
|
3517
|
+
return nodeId;
|
|
3518
|
+
};
|
|
3519
|
+
const buildLegacyEffectiveInputNodeId = (input, directNodeId) => {
|
|
3520
|
+
if (!shouldComposeInputWithPoseControl(input)) {
|
|
3521
|
+
return directNodeId;
|
|
3522
|
+
}
|
|
3523
|
+
const safeInputId = sanitizeNodeId(input.id);
|
|
3524
|
+
const composeBaseline = Number.isFinite(input.defaultValue) ? input.defaultValue : 0;
|
|
3525
|
+
const poseControlNodeId = `input_pose_control_${safeInputId}`;
|
|
3526
|
+
nodes.push({
|
|
3527
|
+
id: poseControlNodeId,
|
|
3528
|
+
type: "input",
|
|
3529
|
+
params: {
|
|
3530
|
+
path: buildPoseControlInputPath(faceId, input.id),
|
|
3531
|
+
value: { float: composeBaseline }
|
|
3532
|
+
}
|
|
3533
|
+
});
|
|
3534
|
+
const composeAddNodeId = `input_compose_add_${safeInputId}`;
|
|
3535
|
+
nodes.push({
|
|
3536
|
+
id: composeAddNodeId,
|
|
3537
|
+
type: "add"
|
|
3538
|
+
});
|
|
3539
|
+
edges.push(
|
|
3540
|
+
{
|
|
3541
|
+
from: { nodeId: directNodeId },
|
|
3542
|
+
to: { nodeId: composeAddNodeId, portId: "operand_1" }
|
|
3543
|
+
},
|
|
3544
|
+
{
|
|
3545
|
+
from: { nodeId: poseControlNodeId },
|
|
3546
|
+
to: { nodeId: composeAddNodeId, portId: "operand_2" }
|
|
3547
|
+
}
|
|
3548
|
+
);
|
|
3549
|
+
const composeMode = composeModeByInputId.get(input.id) ?? "add";
|
|
3550
|
+
let composeOutputNodeId = composeAddNodeId;
|
|
3551
|
+
if (composeMode === "average") {
|
|
3552
|
+
composeOutputNodeId = `input_compose_average_${safeInputId}`;
|
|
3553
|
+
nodes.push({
|
|
3554
|
+
id: composeOutputNodeId,
|
|
3555
|
+
type: "divide",
|
|
3556
|
+
inputDefaults: { rhs: 2 }
|
|
3557
|
+
});
|
|
3558
|
+
edges.push({
|
|
3559
|
+
from: { nodeId: composeAddNodeId },
|
|
3560
|
+
to: { nodeId: composeOutputNodeId, portId: "lhs" }
|
|
3561
|
+
});
|
|
3562
|
+
} else {
|
|
3563
|
+
composeOutputNodeId = `input_compose_normalized_add_${safeInputId}`;
|
|
3564
|
+
nodes.push({
|
|
3565
|
+
id: composeOutputNodeId,
|
|
3566
|
+
type: "subtract",
|
|
3567
|
+
inputDefaults: { rhs: composeBaseline }
|
|
3568
|
+
});
|
|
3569
|
+
edges.push({
|
|
3570
|
+
from: { nodeId: composeAddNodeId },
|
|
3571
|
+
to: { nodeId: composeOutputNodeId, portId: "lhs" }
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3574
|
+
const minValue = Number.isFinite(input.range.min) ? input.range.min : -1;
|
|
3575
|
+
const maxValue = Number.isFinite(input.range.max) ? input.range.max : 1;
|
|
3576
|
+
const clampNodeId = `input_effective_${safeInputId}`;
|
|
3577
|
+
nodes.push({
|
|
3578
|
+
id: clampNodeId,
|
|
3579
|
+
type: "clamp",
|
|
3580
|
+
inputDefaults: { min: minValue, max: maxValue }
|
|
3581
|
+
});
|
|
3582
|
+
edges.push({
|
|
3583
|
+
from: { nodeId: composeOutputNodeId },
|
|
3584
|
+
to: { nodeId: clampNodeId, portId: "in" }
|
|
3585
|
+
});
|
|
3586
|
+
return clampNodeId;
|
|
3587
|
+
};
|
|
3588
|
+
const buildStagedEffectiveInputNodeId = (input, stagedConfig) => {
|
|
3589
|
+
const safeInputId = sanitizeNodeId(input.id);
|
|
3590
|
+
const composeBaseline = Number.isFinite(input.defaultValue) ? input.defaultValue : 0;
|
|
3591
|
+
const parentContributionNodes = [];
|
|
3592
|
+
const parentNodeIdByAlias = /* @__PURE__ */ new Map();
|
|
3593
|
+
stagedConfig.parents.forEach((parent, index) => {
|
|
3594
|
+
if (!parent.enabled) {
|
|
3595
|
+
return;
|
|
3596
|
+
}
|
|
3597
|
+
const resolvedParentInputId = resolveStandardRigInputId(
|
|
3598
|
+
parent.inputId,
|
|
3599
|
+
inputsById
|
|
3600
|
+
);
|
|
3601
|
+
const parentInput = ensureInputNode(resolvedParentInputId);
|
|
3602
|
+
if (!parentInput) {
|
|
3603
|
+
const issueSet = bindingIssues.get(input.id) ?? /* @__PURE__ */ new Set();
|
|
3604
|
+
issueSet.add(
|
|
3605
|
+
`Staged parent "${resolvedParentInputId}" missing for "${input.id}".`
|
|
3606
|
+
);
|
|
3607
|
+
bindingIssues.set(input.id, issueSet);
|
|
3608
|
+
return;
|
|
3609
|
+
}
|
|
3610
|
+
const nodeSuffix = `${safeInputId}_${index + 1}`;
|
|
3611
|
+
const fallbackParentNodeId = buildDefaultParentTransformNodeId({
|
|
3612
|
+
sourceNodeId: parentInput.nodeId,
|
|
3613
|
+
nodeSuffix,
|
|
3614
|
+
scale: parent.scale,
|
|
3615
|
+
offset: parent.offset
|
|
3616
|
+
});
|
|
3617
|
+
const defaultParentFormulaExpression = `${parent.alias} = parent * scale + offset`;
|
|
3618
|
+
const parentFormulaNodeId = normalizeFormulaSignature(parent.expression) === normalizeFormulaSignature(defaultParentFormulaExpression) ? fallbackParentNodeId : buildStagedFormulaNodeId({
|
|
3619
|
+
expression: parent.expression,
|
|
3620
|
+
fallbackNodeId: fallbackParentNodeId,
|
|
3621
|
+
componentSafeId: `staged_parent_${nodeSuffix}`,
|
|
3622
|
+
inputId: input.id,
|
|
3623
|
+
issuePrefix: `Parent formula "${parent.alias}"`,
|
|
3624
|
+
variables: {
|
|
3625
|
+
parent: { nodeId: parentInput.nodeId },
|
|
3626
|
+
scale: { value: parent.scale },
|
|
3627
|
+
offset: { value: parent.offset },
|
|
3628
|
+
default: { value: composeBaseline },
|
|
3629
|
+
baseline: { value: composeBaseline }
|
|
3630
|
+
}
|
|
3631
|
+
});
|
|
3632
|
+
parentContributionNodes.push(parentFormulaNodeId);
|
|
3633
|
+
parentNodeIdByAlias.set(parent.alias, parentFormulaNodeId);
|
|
3634
|
+
const normalizedAlias = parent.alias.toLowerCase();
|
|
3635
|
+
if (normalizedAlias !== parent.alias) {
|
|
3636
|
+
parentNodeIdByAlias.set(normalizedAlias, parentFormulaNodeId);
|
|
3637
|
+
}
|
|
3638
|
+
});
|
|
3639
|
+
const parentContributionNodeId = parentContributionNodes.length > 0 ? (() => {
|
|
3640
|
+
const defaultParentContributionNodeId = buildNormalizedAdditiveBlendNodeId({
|
|
3641
|
+
nodeIdPrefix: `input_parent_blend_${safeInputId}`,
|
|
3642
|
+
sourceNodeIds: parentContributionNodes,
|
|
3643
|
+
baseline: composeBaseline
|
|
3644
|
+
});
|
|
3645
|
+
const defaultParentContributionExpression = `parentContribution = normalizedAdditive([${stagedConfig.parents.filter((entry) => entry.enabled).map((entry) => entry.alias).join(", ")}], baseline=default)`;
|
|
3646
|
+
if (normalizeFormulaSignature(stagedConfig.parentBlend.expression) === normalizeFormulaSignature(defaultParentContributionExpression)) {
|
|
3647
|
+
return defaultParentContributionNodeId;
|
|
3648
|
+
}
|
|
3649
|
+
return buildStagedFormulaNodeId({
|
|
3650
|
+
expression: stagedConfig.parentBlend.expression,
|
|
3651
|
+
fallbackNodeId: defaultParentContributionNodeId,
|
|
3652
|
+
componentSafeId: `staged_parent_contribution_${safeInputId}`,
|
|
3653
|
+
inputId: input.id,
|
|
3654
|
+
issuePrefix: "Parent contribution formula",
|
|
3655
|
+
variables: {
|
|
3656
|
+
...Object.fromEntries(
|
|
3657
|
+
Array.from(parentNodeIdByAlias.entries()).map(
|
|
3658
|
+
([alias, nodeId]) => [alias, { nodeId }]
|
|
3659
|
+
)
|
|
3660
|
+
),
|
|
3661
|
+
default: { value: composeBaseline },
|
|
3662
|
+
baseline: { value: composeBaseline }
|
|
3663
|
+
}
|
|
3664
|
+
});
|
|
3665
|
+
})() : null;
|
|
3666
|
+
let poseContributionNodeId = null;
|
|
3667
|
+
const hasPoseContribution = stagedConfig.poseSource.targetIds.length > 0 || shouldComposeInputWithPoseControl(input);
|
|
3668
|
+
if (hasPoseContribution) {
|
|
3669
|
+
poseContributionNodeId = `input_pose_control_${safeInputId}`;
|
|
3670
|
+
nodes.push({
|
|
3671
|
+
id: poseContributionNodeId,
|
|
3672
|
+
type: "input",
|
|
3673
|
+
params: {
|
|
3674
|
+
path: buildPoseControlInputPath(faceId, input.id),
|
|
3675
|
+
value: { float: composeBaseline }
|
|
3676
|
+
}
|
|
3677
|
+
});
|
|
3678
|
+
}
|
|
3679
|
+
const sourceBranchNodeIds = [];
|
|
3680
|
+
if (parentContributionNodeId) {
|
|
3681
|
+
sourceBranchNodeIds.push(parentContributionNodeId);
|
|
3682
|
+
}
|
|
3683
|
+
if (poseContributionNodeId) {
|
|
3684
|
+
sourceBranchNodeIds.push(poseContributionNodeId);
|
|
3685
|
+
}
|
|
3686
|
+
if (stagedConfig.directInput.enabled) {
|
|
3687
|
+
const directNodeId = `input_direct_${safeInputId}`;
|
|
3688
|
+
nodes.push({
|
|
3689
|
+
id: directNodeId,
|
|
3690
|
+
type: "input",
|
|
3691
|
+
params: {
|
|
3692
|
+
path: stagedConfig.directInput.valuePath,
|
|
3693
|
+
value: { float: composeBaseline }
|
|
3694
|
+
}
|
|
3695
|
+
});
|
|
3696
|
+
sourceBranchNodeIds.push(directNodeId);
|
|
3697
|
+
}
|
|
3698
|
+
const sourceBlendNodeId = buildNormalizedAdditiveBlendNodeId({
|
|
3699
|
+
nodeIdPrefix: `input_source_blend_${safeInputId}`,
|
|
3700
|
+
sourceNodeIds: sourceBranchNodeIds,
|
|
3701
|
+
baseline: composeBaseline
|
|
3702
|
+
});
|
|
3703
|
+
const overrideEnabledNodeId = `input_override_enabled_${safeInputId}`;
|
|
3704
|
+
nodes.push({
|
|
3705
|
+
id: overrideEnabledNodeId,
|
|
3706
|
+
type: "input",
|
|
3707
|
+
params: {
|
|
3708
|
+
path: stagedConfig.override.enabledPath,
|
|
3709
|
+
value: { float: stagedConfig.override.enabledDefault ? 1 : 0 }
|
|
3710
|
+
}
|
|
3711
|
+
});
|
|
3712
|
+
const overrideValueNodeId = `input_override_value_${safeInputId}`;
|
|
3713
|
+
nodes.push({
|
|
3714
|
+
id: overrideValueNodeId,
|
|
3715
|
+
type: "input",
|
|
3716
|
+
params: {
|
|
3717
|
+
path: stagedConfig.override.valuePath,
|
|
3718
|
+
value: { float: stagedConfig.override.valueDefault }
|
|
3719
|
+
}
|
|
3720
|
+
});
|
|
3721
|
+
const overrideDeltaNodeId = `input_override_delta_${safeInputId}`;
|
|
3722
|
+
nodes.push({
|
|
3723
|
+
id: overrideDeltaNodeId,
|
|
3724
|
+
type: "subtract"
|
|
3725
|
+
});
|
|
3726
|
+
edges.push(
|
|
3727
|
+
{
|
|
3728
|
+
from: { nodeId: overrideValueNodeId },
|
|
3729
|
+
to: { nodeId: overrideDeltaNodeId, portId: "lhs" }
|
|
3730
|
+
},
|
|
3731
|
+
{
|
|
3732
|
+
from: { nodeId: sourceBlendNodeId },
|
|
3733
|
+
to: { nodeId: overrideDeltaNodeId, portId: "rhs" }
|
|
3734
|
+
}
|
|
3735
|
+
);
|
|
3736
|
+
const overrideScaleNodeId = `input_override_scale_${safeInputId}`;
|
|
3737
|
+
nodes.push({
|
|
3738
|
+
id: overrideScaleNodeId,
|
|
3739
|
+
type: "multiply"
|
|
3740
|
+
});
|
|
3741
|
+
edges.push(
|
|
3742
|
+
{
|
|
3743
|
+
from: { nodeId: overrideEnabledNodeId },
|
|
3744
|
+
to: { nodeId: overrideScaleNodeId, portId: "operand_1" }
|
|
3745
|
+
},
|
|
3746
|
+
{
|
|
3747
|
+
from: { nodeId: overrideDeltaNodeId },
|
|
3748
|
+
to: { nodeId: overrideScaleNodeId, portId: "operand_2" }
|
|
3749
|
+
}
|
|
3750
|
+
);
|
|
3751
|
+
const overrideSelectedNodeId = `input_override_selected_${safeInputId}`;
|
|
3752
|
+
nodes.push({
|
|
3753
|
+
id: overrideSelectedNodeId,
|
|
3754
|
+
type: "add"
|
|
3755
|
+
});
|
|
3756
|
+
edges.push(
|
|
3757
|
+
{
|
|
3758
|
+
from: { nodeId: sourceBlendNodeId },
|
|
3759
|
+
to: { nodeId: overrideSelectedNodeId, portId: "operand_1" }
|
|
3760
|
+
},
|
|
3761
|
+
{
|
|
3762
|
+
from: { nodeId: overrideScaleNodeId },
|
|
3763
|
+
to: { nodeId: overrideSelectedNodeId, portId: "operand_2" }
|
|
3764
|
+
}
|
|
3765
|
+
);
|
|
3766
|
+
if (!stagedConfig.clamp.enabled) {
|
|
3767
|
+
return overrideSelectedNodeId;
|
|
3768
|
+
}
|
|
3769
|
+
const minValue = Number.isFinite(input.range.min) ? input.range.min : -1;
|
|
3770
|
+
const maxValue = Number.isFinite(input.range.max) ? input.range.max : 1;
|
|
3771
|
+
const clampNodeId = `input_effective_${safeInputId}`;
|
|
3772
|
+
nodes.push({
|
|
3773
|
+
id: clampNodeId,
|
|
3774
|
+
type: "clamp",
|
|
3775
|
+
inputDefaults: { min: minValue, max: maxValue }
|
|
3776
|
+
});
|
|
3777
|
+
edges.push({
|
|
3778
|
+
from: { nodeId: overrideSelectedNodeId },
|
|
3779
|
+
to: { nodeId: clampNodeId, portId: "in" }
|
|
3780
|
+
});
|
|
3781
|
+
return clampNodeId;
|
|
3782
|
+
};
|
|
3053
3783
|
const ensureInputNode = (inputId) => {
|
|
3054
3784
|
const existing = inputNodes.get(inputId);
|
|
3055
3785
|
if (existing) {
|
|
@@ -3061,7 +3791,8 @@ function buildRigGraphSpec({
|
|
|
3061
3791
|
}
|
|
3062
3792
|
const defaultValue = Number.isFinite(input.defaultValue) ? input.defaultValue : 0;
|
|
3063
3793
|
const inputBindingRaw = inputBindings[inputId];
|
|
3064
|
-
|
|
3794
|
+
const isStagedInput = hasRigPipelineV1InputConfig(pipelineV1, inputId);
|
|
3795
|
+
if (isStagedInput || inputBindingRaw) {
|
|
3065
3796
|
if (buildingDerived.has(inputId)) {
|
|
3066
3797
|
const issueSet = bindingIssues.get(inputId) ?? /* @__PURE__ */ new Set();
|
|
3067
3798
|
issueSet.add("Derived input cycle detected.");
|
|
@@ -3070,6 +3801,21 @@ function buildRigGraphSpec({
|
|
|
3070
3801
|
}
|
|
3071
3802
|
buildingDerived.add(inputId);
|
|
3072
3803
|
try {
|
|
3804
|
+
if (isStagedInput) {
|
|
3805
|
+
const stagedConfig = resolveRigPipelineV1InputConfig({
|
|
3806
|
+
faceId,
|
|
3807
|
+
input,
|
|
3808
|
+
pipelineV1
|
|
3809
|
+
});
|
|
3810
|
+
stagedPipelineByInputId.set(input.id, stagedConfig);
|
|
3811
|
+
computedInputs.add(inputId);
|
|
3812
|
+
const record3 = {
|
|
3813
|
+
nodeId: buildStagedEffectiveInputNodeId(input, stagedConfig),
|
|
3814
|
+
input
|
|
3815
|
+
};
|
|
3816
|
+
inputNodes.set(inputId, record3);
|
|
3817
|
+
return record3;
|
|
3818
|
+
}
|
|
3073
3819
|
const target = bindingTargetFromInput(input);
|
|
3074
3820
|
const binding = ensureBindingStructure(inputBindingRaw, target);
|
|
3075
3821
|
const requiresSelf = binding.inputId === SELF_BINDING_ID2 || binding.slots.some((slot) => slot.inputId === SELF_BINDING_ID2);
|
|
@@ -3093,7 +3839,10 @@ function buildRigGraphSpec({
|
|
|
3093
3839
|
animatableId: inputId,
|
|
3094
3840
|
component: void 0,
|
|
3095
3841
|
safeId: sanitizeNodeId(inputId),
|
|
3842
|
+
enforceRigBoundaryRules: false,
|
|
3096
3843
|
context: {
|
|
3844
|
+
inputsById,
|
|
3845
|
+
inputBindings,
|
|
3097
3846
|
nodes,
|
|
3098
3847
|
edges,
|
|
3099
3848
|
ensureInputNode,
|
|
@@ -3113,12 +3862,18 @@ function buildRigGraphSpec({
|
|
|
3113
3862
|
value: input.defaultValue
|
|
3114
3863
|
}
|
|
3115
3864
|
});
|
|
3116
|
-
const record3 = {
|
|
3865
|
+
const record3 = {
|
|
3866
|
+
nodeId: buildLegacyEffectiveInputNodeId(input, constNodeId),
|
|
3867
|
+
input
|
|
3868
|
+
};
|
|
3117
3869
|
inputNodes.set(inputId, record3);
|
|
3118
3870
|
return record3;
|
|
3119
3871
|
}
|
|
3120
3872
|
computedInputs.add(inputId);
|
|
3121
|
-
const record2 = {
|
|
3873
|
+
const record2 = {
|
|
3874
|
+
nodeId: buildLegacyEffectiveInputNodeId(input, valueNodeId),
|
|
3875
|
+
input
|
|
3876
|
+
};
|
|
3122
3877
|
inputNodes.set(inputId, record2);
|
|
3123
3878
|
return record2;
|
|
3124
3879
|
} finally {
|
|
@@ -3134,7 +3889,10 @@ function buildRigGraphSpec({
|
|
|
3134
3889
|
value: { float: defaultValue }
|
|
3135
3890
|
}
|
|
3136
3891
|
});
|
|
3137
|
-
const record = {
|
|
3892
|
+
const record = {
|
|
3893
|
+
nodeId: buildLegacyEffectiveInputNodeId(input, nodeId),
|
|
3894
|
+
input
|
|
3895
|
+
};
|
|
3138
3896
|
inputNodes.set(inputId, record);
|
|
3139
3897
|
return record;
|
|
3140
3898
|
};
|
|
@@ -3175,7 +3933,10 @@ function buildRigGraphSpec({
|
|
|
3175
3933
|
animatableId: component.animatableId,
|
|
3176
3934
|
component: component.component,
|
|
3177
3935
|
safeId: component.safeId,
|
|
3936
|
+
enforceRigBoundaryRules: true,
|
|
3178
3937
|
context: {
|
|
3938
|
+
inputsById,
|
|
3939
|
+
inputBindings,
|
|
3179
3940
|
nodes,
|
|
3180
3941
|
edges,
|
|
3181
3942
|
ensureInputNode,
|
|
@@ -3323,6 +4084,61 @@ function buildRigGraphSpec({
|
|
|
3323
4084
|
const filteredSummaryBindings = summaryBindings.filter(
|
|
3324
4085
|
(binding) => outputs.has(binding.animatableId) || computedInputs.has(binding.animatableId)
|
|
3325
4086
|
);
|
|
4087
|
+
const pipelineV1ByInputId = stagedPipelineByInputId.size > 0 ? Object.fromEntries(
|
|
4088
|
+
Array.from(stagedPipelineByInputId.entries()).map(
|
|
4089
|
+
([inputId, stagedConfig]) => [
|
|
4090
|
+
inputId,
|
|
4091
|
+
{
|
|
4092
|
+
inputId: stagedConfig.inputId,
|
|
4093
|
+
parents: stagedConfig.parents.map((parent) => ({
|
|
4094
|
+
linkId: parent.linkId,
|
|
4095
|
+
inputId: parent.inputId,
|
|
4096
|
+
alias: parent.alias,
|
|
4097
|
+
scale: parent.scale,
|
|
4098
|
+
offset: parent.offset,
|
|
4099
|
+
enabled: parent.enabled,
|
|
4100
|
+
expression: parent.expression
|
|
4101
|
+
})),
|
|
4102
|
+
children: stagedConfig.children.map((child) => ({
|
|
4103
|
+
linkId: child.linkId,
|
|
4104
|
+
childInputId: child.childInputId
|
|
4105
|
+
})),
|
|
4106
|
+
parentBlend: {
|
|
4107
|
+
mode: stagedConfig.parentBlend.mode,
|
|
4108
|
+
expression: stagedConfig.parentBlend.expression
|
|
4109
|
+
},
|
|
4110
|
+
poseSource: {
|
|
4111
|
+
targetIds: [...stagedConfig.poseSource.targetIds]
|
|
4112
|
+
},
|
|
4113
|
+
directInput: {
|
|
4114
|
+
enabled: stagedConfig.directInput.enabled,
|
|
4115
|
+
valuePath: stagedConfig.directInput.valuePath
|
|
4116
|
+
},
|
|
4117
|
+
sourceBlend: {
|
|
4118
|
+
mode: stagedConfig.sourceBlend.mode
|
|
4119
|
+
},
|
|
4120
|
+
sourceFallback: {
|
|
4121
|
+
whenNoSources: stagedConfig.sourceFallback.whenNoSources
|
|
4122
|
+
},
|
|
4123
|
+
clamp: {
|
|
4124
|
+
enabled: stagedConfig.clamp.enabled
|
|
4125
|
+
},
|
|
4126
|
+
override: {
|
|
4127
|
+
enabledDefault: stagedConfig.override.enabledDefault,
|
|
4128
|
+
valueDefault: stagedConfig.override.valueDefault,
|
|
4129
|
+
enabledPath: stagedConfig.override.enabledPath,
|
|
4130
|
+
valuePath: stagedConfig.override.valuePath
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
]
|
|
4134
|
+
)
|
|
4135
|
+
) : void 0;
|
|
4136
|
+
const hasPipelineLinks = pipelineV1?.links && typeof pipelineV1.links === "object" && Object.keys(pipelineV1.links).length > 0;
|
|
4137
|
+
const pipelineV1Metadata = pipelineV1ByInputId || hasPipelineLinks ? {
|
|
4138
|
+
version: RIG_PIPELINE_V1_VERSION,
|
|
4139
|
+
...pipelineV1ByInputId ? { byInputId: pipelineV1ByInputId } : {},
|
|
4140
|
+
...hasPipelineLinks ? { links: cloneJsonLike2(pipelineV1?.links) } : {}
|
|
4141
|
+
} : void 0;
|
|
3326
4142
|
const vizijMetadata = {
|
|
3327
4143
|
vizij: {
|
|
3328
4144
|
faceId,
|
|
@@ -3359,7 +4175,8 @@ function buildRigGraphSpec({
|
|
|
3359
4175
|
valueType: binding.valueType,
|
|
3360
4176
|
issues: binding.issues ? [...binding.issues] : void 0,
|
|
3361
4177
|
metadata: binding.metadata ? cloneJsonLike2(binding.metadata) : void 0
|
|
3362
|
-
}))
|
|
4178
|
+
})),
|
|
4179
|
+
...pipelineV1Metadata ? { pipelineV1: pipelineV1Metadata } : {}
|
|
3363
4180
|
}
|
|
3364
4181
|
};
|
|
3365
4182
|
const issuesByTarget = {};
|
|
@@ -3755,6 +4572,9 @@ function normalizeRegistryVariadicSpec(spec) {
|
|
|
3755
4572
|
if (typeof spec.max === "number") {
|
|
3756
4573
|
normalized.max = spec.max;
|
|
3757
4574
|
}
|
|
4575
|
+
if (spec.keyed) {
|
|
4576
|
+
normalized.keyed = true;
|
|
4577
|
+
}
|
|
3758
4578
|
return normalized;
|
|
3759
4579
|
}
|
|
3760
4580
|
function normalizeRegistryParamSpec(param) {
|