@babylonjs/loaders 9.26.0 → 9.26.2
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/FBX/fbxConstraintBehavior.d.ts +188 -0
- package/FBX/fbxConstraintBehavior.js +532 -0
- package/FBX/fbxConstraintBehavior.js.map +1 -0
- package/FBX/fbxFileLoader.pure.d.ts +175 -6
- package/FBX/fbxFileLoader.pure.js +1521 -286
- package/FBX/fbxFileLoader.pure.js.map +1 -1
- package/FBX/index.d.ts +4 -1
- package/FBX/index.js +1 -0
- package/FBX/index.js.map +1 -1
- package/FBX/interpreter/animation.d.ts +73 -33
- package/FBX/interpreter/animation.js +620 -223
- package/FBX/interpreter/animation.js.map +1 -1
- package/FBX/interpreter/animationCurve.d.ts +91 -0
- package/FBX/interpreter/animationCurve.js +623 -0
- package/FBX/interpreter/animationCurve.js.map +1 -0
- package/FBX/interpreter/blendShapes.js +9 -18
- package/FBX/interpreter/blendShapes.js.map +1 -1
- package/FBX/interpreter/connections.d.ts +1 -1
- package/FBX/interpreter/connections.js +173 -34
- package/FBX/interpreter/connections.js.map +1 -1
- package/FBX/interpreter/constraints.d.ts +68 -0
- package/FBX/interpreter/constraints.js +143 -0
- package/FBX/interpreter/constraints.js.map +1 -0
- package/FBX/interpreter/fbxInterpreter.d.ts +89 -4
- package/FBX/interpreter/fbxInterpreter.js +474 -122
- package/FBX/interpreter/fbxInterpreter.js.map +1 -1
- package/FBX/interpreter/geometry.d.ts +1 -1
- package/FBX/interpreter/geometry.js +150 -92
- package/FBX/interpreter/geometry.js.map +1 -1
- package/FBX/interpreter/legacyDocument.d.ts +11 -0
- package/FBX/interpreter/legacyDocument.js +425 -0
- package/FBX/interpreter/legacyDocument.js.map +1 -0
- package/FBX/interpreter/materialModel.d.ts +71 -0
- package/FBX/interpreter/materialModel.js +622 -0
- package/FBX/interpreter/materialModel.js.map +1 -0
- package/FBX/interpreter/materials.d.ts +13 -1
- package/FBX/interpreter/materials.js +88 -5
- package/FBX/interpreter/materials.js.map +1 -1
- package/FBX/interpreter/nodeTransform.d.ts +32 -0
- package/FBX/interpreter/nodeTransform.js +54 -0
- package/FBX/interpreter/nodeTransform.js.map +1 -0
- package/FBX/interpreter/nurbs.d.ts +99 -0
- package/FBX/interpreter/nurbs.js +627 -0
- package/FBX/interpreter/nurbs.js.map +1 -0
- package/FBX/interpreter/propertyTemplates.d.ts +23 -0
- package/FBX/interpreter/propertyTemplates.js +109 -2
- package/FBX/interpreter/propertyTemplates.js.map +1 -1
- package/FBX/interpreter/rig.js +16 -0
- package/FBX/interpreter/rig.js.map +1 -1
- package/FBX/interpreter/sceneDiagnostics.js +28 -3
- package/FBX/interpreter/sceneDiagnostics.js.map +1 -1
- package/FBX/interpreter/skeleton.d.ts +4 -18
- package/FBX/interpreter/skeleton.js +16 -94
- package/FBX/interpreter/skeleton.js.map +1 -1
- package/FBX/parsers/fbxAsciiParser.js +119 -9
- package/FBX/parsers/fbxAsciiParser.js.map +1 -1
- package/FBX/parsers/fbxBinaryParser.js +74 -22
- package/FBX/parsers/fbxBinaryParser.js.map +1 -1
- package/FBX/pure.d.ts +1 -0
- package/FBX/pure.js +1 -0
- package/FBX/pure.js.map +1 -1
- package/FBX/types/fbxTypes.d.ts +18 -2
- package/FBX/types/fbxTypes.js +40 -12
- package/FBX/types/fbxTypes.js.map +1 -1
- package/SPLAT/gaussianSplattingStream.d.ts +79 -25
- package/SPLAT/gaussianSplattingStream.js +320 -95
- package/SPLAT/gaussianSplattingStream.js.map +1 -1
- package/USD/usdCommandProtocol.d.ts +20 -4
- package/USD/usdCommandProtocol.js +25 -3
- package/USD/usdCommandProtocol.js.map +1 -1
- package/USD/usdFileLoader.pure.js +2 -0
- package/USD/usdFileLoader.pure.js.map +1 -1
- package/USD/usdSceneMaterializer.js +430 -92
- package/USD/usdSceneMaterializer.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.d.ts +110 -3
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js +468 -74
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.d.ts +47 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.js +68 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.js +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.d.ts +24 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.js +38 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.d.ts +41 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.js +63 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.d.ts +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.d.ts +112 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.js +773 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.d.ts +18 -10
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js +299 -54
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.d.ts +2 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js +7 -2
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.d.ts +24 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.js +89 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +55 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js +124 -76
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +18 -1
- package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +2 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +114 -56
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +2 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +80 -35
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -1
- package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js +3 -2
- package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js.map +1 -1
- package/glTF/2.0/Extensions/objectModelMapping.d.ts +4 -2
- package/glTF/2.0/Extensions/objectModelMapping.js +33 -4
- package/glTF/2.0/Extensions/objectModelMapping.js.map +1 -1
- package/glTF/2.0/glTFLoader.pure.d.ts +1 -1
- package/glTF/2.0/glTFLoader.pure.js +9 -4
- package/glTF/2.0/glTFLoader.pure.js.map +1 -1
- package/glTF/2.0/glTFLoaderExtension.d.ts +2 -1
- package/glTF/2.0/glTFLoaderExtension.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import { getMappingForDeclaration,
|
|
1
|
+
import { getMappingForDeclaration, getNoOpMappingForDeclaration, ParseDebugLogTemplate } from "./declarationMapper.js";
|
|
2
2
|
import { Logger } from "@babylonjs/core/Misc/logger.js";
|
|
3
3
|
import { RandomGUID } from "@babylonjs/core/Misc/guid.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
float4: { length: 4, flowGraphType: "Vector4" /* FlowGraphTypes.Vector4 */, elementType: "number" },
|
|
11
|
-
float4x4: { length: 16, flowGraphType: "Matrix" /* FlowGraphTypes.Matrix */, elementType: "number" },
|
|
12
|
-
float2x2: { length: 4, flowGraphType: "Matrix2D" /* FlowGraphTypes.Matrix2D */, elementType: "number" },
|
|
13
|
-
float3x3: { length: 9, flowGraphType: "Matrix3D" /* FlowGraphTypes.Matrix3D */, elementType: "number" },
|
|
14
|
-
int: { length: 1, flowGraphType: "FlowGraphInteger" /* FlowGraphTypes.Integer */, elementType: "number" },
|
|
15
|
-
// KHR_interactivity opaque reference type. Represented as a JSON Pointer string
|
|
16
|
-
// (e.g. "/nodes/17/") that addresses a glTF object. The empty string is the
|
|
17
|
-
// canonical "null reference" sentinel used by the parser.
|
|
18
|
-
ref: { length: 1, flowGraphType: "string" /* FlowGraphTypes.String */, elementType: "string" },
|
|
19
|
-
};
|
|
4
|
+
import { CloneKHRInteractivityGraph, CreateEffectiveKHRInteractivityGraph, gltfTypeToBabylonType } from "./interactivityGraphModel.js";
|
|
5
|
+
import { DelayReferencePrefix, EventReferencePrefix } from "./interactivityReferences.js";
|
|
6
|
+
export { gltfTypeToBabylonType } from "./interactivityGraphModel.js";
|
|
7
|
+
function _GetOwnMapping(mapping, key) {
|
|
8
|
+
return mapping && Object.prototype.hasOwnProperty.call(mapping, key) ? mapping[key] : undefined;
|
|
9
|
+
}
|
|
20
10
|
/**
|
|
21
11
|
* Parses a KHR_interactivity graph definition (the raw glTF JSON object) into
|
|
22
12
|
* the serialized FlowGraph form consumed by {@link ParseFlowGraphAsync}.
|
|
@@ -26,10 +16,12 @@ export const gltfTypeToBabylonType = {
|
|
|
26
16
|
* {@link serializeToFlowGraph}.
|
|
27
17
|
*/
|
|
28
18
|
export class InteractivityGraphToFlowGraphParser {
|
|
29
|
-
constructor(
|
|
30
|
-
this._interactivityGraph = _interactivityGraph;
|
|
19
|
+
constructor(interactivityGraph, _gltf, _animationTargetFps = 60, _graphIndex = 0, _supportedExtensions, _declarationModels) {
|
|
31
20
|
this._gltf = _gltf;
|
|
32
21
|
this._animationTargetFps = _animationTargetFps;
|
|
22
|
+
this._graphIndex = _graphIndex;
|
|
23
|
+
this._supportedExtensions = _supportedExtensions;
|
|
24
|
+
this._declarationModels = _declarationModels;
|
|
33
25
|
/**
|
|
34
26
|
* Note - the graph should be rejected if the same type is defined twice.
|
|
35
27
|
* We currently don't validate that.
|
|
@@ -47,6 +39,9 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
47
39
|
* the last block) is not disturbed, then concatenated into the serialized graph.
|
|
48
40
|
*/
|
|
49
41
|
this._insertedBlocks = [];
|
|
42
|
+
this._interactivityGraph = this._declarationModels
|
|
43
|
+
? CreateEffectiveKHRInteractivityGraph(interactivityGraph, this._declarationModels, this._gltf.nodes?.length ?? 0)
|
|
44
|
+
: CloneKHRInteractivityGraph(interactivityGraph);
|
|
50
45
|
// start with types
|
|
51
46
|
this._parseTypes();
|
|
52
47
|
// continue with declarations
|
|
@@ -55,6 +50,74 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
55
50
|
this._parseEvents();
|
|
56
51
|
this._parseNodes();
|
|
57
52
|
}
|
|
53
|
+
get _strictValidation() {
|
|
54
|
+
return !!this._declarationModels;
|
|
55
|
+
}
|
|
56
|
+
_hasDefaultFlowInput(operation) {
|
|
57
|
+
if (operation === "flow/waitAll") {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return (operation.startsWith("flow/") ||
|
|
61
|
+
operation.startsWith("animation/") ||
|
|
62
|
+
operation === "pointer/set" ||
|
|
63
|
+
operation === "pointer/interpolate" ||
|
|
64
|
+
operation === "variable/set" ||
|
|
65
|
+
operation === "variable/interpolate" ||
|
|
66
|
+
operation === "event/send" ||
|
|
67
|
+
operation === "event/stopPropagation" ||
|
|
68
|
+
operation === "flow/log:BABYLON");
|
|
69
|
+
}
|
|
70
|
+
_getAllowedDynamicValueSockets(operation, node, direction) {
|
|
71
|
+
if ((operation === "debug/log" || operation === "flow/log:BABYLON") && direction === "input") {
|
|
72
|
+
const message = node.configuration?.[operation === "debug/log" ? "message" : "messageTemplate"]?.value?.[0];
|
|
73
|
+
return new Set(typeof message === "string" ? ParseDebugLogTemplate(message).sockets : []);
|
|
74
|
+
}
|
|
75
|
+
if ((operation === "event/send" && direction === "input") || (operation === "event/receive" && direction === "output")) {
|
|
76
|
+
const eventIndex = node.configuration?.event?.value?.[0];
|
|
77
|
+
if (typeof eventIndex === "number") {
|
|
78
|
+
return new Set(Object.keys(this._interactivityGraph.events?.[eventIndex]?.values ?? {}));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (operation === "variable/set" && direction === "input") {
|
|
82
|
+
return new Set((node.configuration?.variables?.value ?? []).map(String));
|
|
83
|
+
}
|
|
84
|
+
if (operation === "math/switch" && direction === "input") {
|
|
85
|
+
return new Set((node.configuration?.cases?.value ?? []).map(String));
|
|
86
|
+
}
|
|
87
|
+
if ((operation === "pointer/get" || operation === "pointer/set" || operation === "pointer/interpolate") && direction === "input") {
|
|
88
|
+
const pointer = node.configuration?.pointer?.value?.[0];
|
|
89
|
+
if (typeof pointer === "string") {
|
|
90
|
+
return new Set(pointer
|
|
91
|
+
.split("/")
|
|
92
|
+
.filter((segment) => (segment.startsWith("[") && !segment.startsWith("[[")) || (segment.startsWith("{") && !segment.startsWith("{{")))
|
|
93
|
+
.map((segment) => segment
|
|
94
|
+
.substring(1, segment.length - 1)
|
|
95
|
+
.replace(/~1/g, "/")
|
|
96
|
+
.replace(/~0/g, "~")));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
_getAllowedDynamicFlowSockets(node, mapping, direction) {
|
|
102
|
+
for (const [key, property] of Object.entries(mapping.configuration ?? {})) {
|
|
103
|
+
const generatesSockets = direction === "input" ? property.generatesInputFlowSockets : property.generatesOutputFlowSockets;
|
|
104
|
+
if (!generatesSockets) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const configuredValues = node.configuration?.[key]?.value;
|
|
108
|
+
const validValues = configuredValues &&
|
|
109
|
+
configuredValues.length > 0 &&
|
|
110
|
+
(property.configurationType !== "int" || configuredValues.length === 1) &&
|
|
111
|
+
configuredValues.every((value) => typeof value === "number" && Number.isInteger(value) && value >= (property.minimum ?? -2147483648) && value <= (property.maximum ?? 2147483647));
|
|
112
|
+
const values = validValues ? configuredValues : property.defaultValue;
|
|
113
|
+
if (direction === "input") {
|
|
114
|
+
const count = Array.isArray(values) && typeof values[0] === "number" ? values[0] : 0;
|
|
115
|
+
return new Set(Array.from({ length: count }, (_, index) => String(index)));
|
|
116
|
+
}
|
|
117
|
+
return new Set(Array.isArray(values) ? values.map(String) : []);
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
58
121
|
get arrays() {
|
|
59
122
|
return {
|
|
60
123
|
types: this._types,
|
|
@@ -76,10 +139,15 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
76
139
|
if (!this._interactivityGraph.declarations) {
|
|
77
140
|
return;
|
|
78
141
|
}
|
|
79
|
-
for (
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
142
|
+
for (let index = 0; index < this._interactivityGraph.declarations.length; index++) {
|
|
143
|
+
const declaration = this._interactivityGraph.declarations[index];
|
|
144
|
+
const declarationModel = this._declarationModels?.[index];
|
|
145
|
+
const extensionEnabled = !declaration.extension || !this._supportedExtensions || this._supportedExtensions.has(declaration.extension);
|
|
146
|
+
const supportedMapping = declarationModel?.support === "unsupported-extension" ? undefined : extensionEnabled ? getMappingForDeclaration(declaration, false) : undefined;
|
|
147
|
+
if (!supportedMapping && !declaration.extension) {
|
|
148
|
+
throw new Error(`Unknown core KHR_interactivity operation "${declaration.op}".`);
|
|
149
|
+
}
|
|
150
|
+
const mapping = supportedMapping ?? (declaration.extension ? getNoOpMappingForDeclaration(declaration) : undefined);
|
|
83
151
|
if (!mapping) {
|
|
84
152
|
Logger.Error(["No mapping found for declaration", declaration]);
|
|
85
153
|
throw new Error("Error parsing declarations");
|
|
@@ -87,6 +155,13 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
87
155
|
this._mappings.push({
|
|
88
156
|
flowGraphMapping: mapping,
|
|
89
157
|
fullOperationName: declaration.extension ? declaration.op + ":" + declaration.extension : declaration.op,
|
|
158
|
+
declaration: declarationModel ??
|
|
159
|
+
{
|
|
160
|
+
index,
|
|
161
|
+
operation: declaration.extension ? `${declaration.op}:${declaration.extension}` : declaration.op,
|
|
162
|
+
support: supportedMapping ? (declaration.extension ? "extension" : "core") : "unsupported-extension",
|
|
163
|
+
source: declaration,
|
|
164
|
+
},
|
|
90
165
|
});
|
|
91
166
|
}
|
|
92
167
|
}
|
|
@@ -107,12 +182,12 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
107
182
|
throw new Error("Error parsing variables");
|
|
108
183
|
}
|
|
109
184
|
if (variable.value) {
|
|
110
|
-
if (variable.value.length !== type.length) {
|
|
185
|
+
if (this._interactivityGraph.types?.[variable.type]?.signature !== "custom" && variable.value.length !== type.length) {
|
|
111
186
|
Logger.Error(["Invalid value length for variable", variable, type]);
|
|
112
187
|
throw new Error("Error parsing variables");
|
|
113
188
|
}
|
|
114
189
|
}
|
|
115
|
-
const value = variable.value
|
|
190
|
+
const value = variable.value ? variable.value.slice() : [];
|
|
116
191
|
if (!value.length) {
|
|
117
192
|
switch (type.flowGraphType) {
|
|
118
193
|
case "boolean" /* FlowGraphTypes.Boolean */:
|
|
@@ -137,13 +212,17 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
137
212
|
case "Vector4" /* FlowGraphTypes.Vector4 */:
|
|
138
213
|
case "Matrix2D" /* FlowGraphTypes.Matrix2D */:
|
|
139
214
|
case "Quaternion" /* FlowGraphTypes.Quaternion */:
|
|
140
|
-
value.
|
|
215
|
+
value.push(NaN, NaN, NaN, NaN);
|
|
141
216
|
break;
|
|
142
217
|
case "Matrix" /* FlowGraphTypes.Matrix */:
|
|
143
|
-
|
|
218
|
+
for (let i = 0; i < 16; i++) {
|
|
219
|
+
value.push(NaN);
|
|
220
|
+
}
|
|
144
221
|
break;
|
|
145
222
|
case "Matrix3D" /* FlowGraphTypes.Matrix3D */:
|
|
146
|
-
|
|
223
|
+
for (let i = 0; i < 9; i++) {
|
|
224
|
+
value.push(NaN);
|
|
225
|
+
}
|
|
147
226
|
break;
|
|
148
227
|
default:
|
|
149
228
|
break;
|
|
@@ -153,15 +232,52 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
153
232
|
if (type.elementType === "number" && typeof value[0] === "string") {
|
|
154
233
|
value[0] = parseFloat(value[0]);
|
|
155
234
|
}
|
|
235
|
+
else if (type.flowGraphType === "string" /* FlowGraphTypes.String */ && typeof value[0] === "string") {
|
|
236
|
+
value[0] = this._normalizeStaticReference(value[0]);
|
|
237
|
+
}
|
|
156
238
|
return { type: type.flowGraphType, value: dataTransform ? dataTransform(value, this) : value };
|
|
157
239
|
}
|
|
240
|
+
_normalizeStaticReference(reference) {
|
|
241
|
+
if (!reference || reference.startsWith(EventReferencePrefix) || reference.startsWith(DelayReferencePrefix)) {
|
|
242
|
+
return "";
|
|
243
|
+
}
|
|
244
|
+
if (!reference.startsWith("/")) {
|
|
245
|
+
return "";
|
|
246
|
+
}
|
|
247
|
+
let current = this._gltf;
|
|
248
|
+
for (const rawSegment of reference.substring(1).split("/")) {
|
|
249
|
+
const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
250
|
+
if (Array.isArray(current)) {
|
|
251
|
+
if (!/^(0|[1-9]\d*)$/.test(segment)) {
|
|
252
|
+
return "";
|
|
253
|
+
}
|
|
254
|
+
current = current[parseInt(segment, 10)];
|
|
255
|
+
}
|
|
256
|
+
else if (current !== null && typeof current === "object" && Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
257
|
+
current = current[segment];
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
return "";
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return current !== null && typeof current === "object" ? reference : "";
|
|
264
|
+
}
|
|
158
265
|
_parseEvents() {
|
|
159
266
|
if (!this._interactivityGraph.events) {
|
|
160
267
|
return;
|
|
161
268
|
}
|
|
269
|
+
const eventIds = new Set(this._interactivityGraph.events.flatMap((event) => (event.id === undefined ? [] : [event.id])));
|
|
270
|
+
const internalPrefix = `__babylon_khr_internal_${this._graphIndex}_`;
|
|
162
271
|
for (const event of this._interactivityGraph.events) {
|
|
272
|
+
let generatedEventId;
|
|
273
|
+
if (event.id === undefined) {
|
|
274
|
+
do {
|
|
275
|
+
generatedEventId = internalPrefix + this._internalEventsCounter++;
|
|
276
|
+
} while (eventIds.has(generatedEventId));
|
|
277
|
+
eventIds.add(generatedEventId);
|
|
278
|
+
}
|
|
163
279
|
const converted = {
|
|
164
|
-
eventId: event.id
|
|
280
|
+
eventId: event.id ?? generatedEventId,
|
|
165
281
|
};
|
|
166
282
|
if (event.values) {
|
|
167
283
|
converted.eventData = Object.keys(event.values).map((key) => {
|
|
@@ -191,7 +307,8 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
191
307
|
if (!this._interactivityGraph.nodes) {
|
|
192
308
|
return;
|
|
193
309
|
}
|
|
194
|
-
for (
|
|
310
|
+
for (let nodeIndex = 0; nodeIndex < this._interactivityGraph.nodes.length; nodeIndex++) {
|
|
311
|
+
const node = this._interactivityGraph.nodes[nodeIndex];
|
|
195
312
|
// some validation
|
|
196
313
|
if (typeof node.declaration !== "number") {
|
|
197
314
|
Logger.Error(["No declaration found for node", node]);
|
|
@@ -209,16 +326,20 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
209
326
|
}
|
|
210
327
|
}
|
|
211
328
|
const blocks = [];
|
|
329
|
+
if (mapping.declaration.support === "unsupported-extension") {
|
|
330
|
+
blocks.push(this._createUnsupportedExtensionBlock(node, nodeIndex, mapping));
|
|
331
|
+
}
|
|
212
332
|
// create block(s) for this node using the mapping
|
|
213
|
-
for (
|
|
214
|
-
const
|
|
333
|
+
for (let role = 0; role < mapping.flowGraphMapping.blocks.length; role++) {
|
|
334
|
+
const blockType = mapping.flowGraphMapping.blocks[role];
|
|
335
|
+
const block = this._getEmptyBlock(blockType, mapping.fullOperationName, nodeIndex, node.declaration, role);
|
|
215
336
|
this._parseNodeConfiguration(node, block, mapping.flowGraphMapping, blockType);
|
|
216
337
|
blocks.push(block);
|
|
217
338
|
}
|
|
218
339
|
this._nodes.push({ blocks, fullOperationName: mapping.fullOperationName });
|
|
219
340
|
}
|
|
220
341
|
}
|
|
221
|
-
_getEmptyBlock(className, type) {
|
|
342
|
+
_getEmptyBlock(className, type, nodeIndex, declarationIndex, role) {
|
|
222
343
|
return {
|
|
223
344
|
uniqueId: RandomGUID(),
|
|
224
345
|
className,
|
|
@@ -228,8 +349,55 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
228
349
|
signalOutputs: [],
|
|
229
350
|
config: {},
|
|
230
351
|
type,
|
|
231
|
-
metadata:
|
|
352
|
+
metadata: nodeIndex === undefined
|
|
353
|
+
? {}
|
|
354
|
+
: {
|
|
355
|
+
khrInteractivity: {
|
|
356
|
+
graphIndex: this._graphIndex,
|
|
357
|
+
nodeIndex,
|
|
358
|
+
declarationIndex,
|
|
359
|
+
operation: type,
|
|
360
|
+
role: role ?? 0,
|
|
361
|
+
sourcePath: `/extensions/KHR_interactivity/graphs/${this._graphIndex}/nodes/${nodeIndex}`,
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
_createUnsupportedExtensionBlock(node, nodeIndex, mapping) {
|
|
367
|
+
const block = this._getEmptyBlock("KHR_interactivity/FlowGraphUnsupportedInteractivityBlock", mapping.fullOperationName, nodeIndex, node.declaration, 0);
|
|
368
|
+
const inputFlowSockets = new Set();
|
|
369
|
+
for (const sourceNode of this._interactivityGraph.nodes ?? []) {
|
|
370
|
+
for (const flow of Object.values(sourceNode.flows ?? {})) {
|
|
371
|
+
if (flow.node === nodeIndex) {
|
|
372
|
+
inputFlowSockets.add(flow.socket ?? "in");
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const toSockets = (sockets) => Object.entries(sockets ?? {}).map(([name, definition]) => ({
|
|
377
|
+
name,
|
|
378
|
+
type: this._types[definition.type]?.flowGraphType,
|
|
379
|
+
signature: this._interactivityGraph.types?.[definition.type]?.signature,
|
|
380
|
+
}));
|
|
381
|
+
block.config = {
|
|
382
|
+
operation: mapping.fullOperationName,
|
|
383
|
+
inputValueSockets: toSockets(mapping.declaration.source.inputValueSockets),
|
|
384
|
+
outputValueSockets: toSockets(mapping.declaration.source.outputValueSockets),
|
|
385
|
+
inputFlowSockets: Array.from(inputFlowSockets).sort(),
|
|
386
|
+
outputFlowSockets: Object.keys(node.flows ?? {}).sort(),
|
|
232
387
|
};
|
|
388
|
+
for (const socket of block.config.inputValueSockets) {
|
|
389
|
+
block.dataInputs.push(this._createNewSocketConnection(socket.name));
|
|
390
|
+
}
|
|
391
|
+
for (const socket of block.config.outputValueSockets) {
|
|
392
|
+
block.dataOutputs.push(this._createNewSocketConnection(socket.name, true));
|
|
393
|
+
}
|
|
394
|
+
for (const socket of block.config.inputFlowSockets) {
|
|
395
|
+
block.signalInputs.push(this._createNewSocketConnection(socket));
|
|
396
|
+
}
|
|
397
|
+
for (const socket of block.config.outputFlowSockets) {
|
|
398
|
+
block.signalOutputs.push(this._createNewSocketConnection(socket, true));
|
|
399
|
+
}
|
|
400
|
+
return block;
|
|
233
401
|
}
|
|
234
402
|
_parseNodeConfiguration(node, block, nodeMapping, blockType) {
|
|
235
403
|
const gltfConfiguration = node.configuration;
|
|
@@ -240,6 +408,12 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
240
408
|
throw new Error("Error parsing node configuration");
|
|
241
409
|
}
|
|
242
410
|
const propertyMapping = nodeMapping.configuration?.[key];
|
|
411
|
+
if (!propertyMapping && this._strictValidation) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
if (propertyMapping?.validationOnly) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
243
417
|
const belongsToBlock = propertyMapping && propertyMapping.toBlock ? propertyMapping.toBlock === blockType : nodeMapping.blocks.indexOf(blockType) === 0;
|
|
244
418
|
if (belongsToBlock) {
|
|
245
419
|
let value = propertyMapping?.defaultValue;
|
|
@@ -297,8 +471,31 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
297
471
|
// connect the flows
|
|
298
472
|
for (const flowKey of flowsKeys) {
|
|
299
473
|
const flow = flowsFromGLTF[flowKey];
|
|
300
|
-
|
|
301
|
-
|
|
474
|
+
let flowMapping = _GetOwnMapping(outputMapper.flowGraphMapping.outputs?.flows, flowKey);
|
|
475
|
+
if (this._strictValidation && flowMapping?.compatibilityOnly) {
|
|
476
|
+
flowMapping = undefined;
|
|
477
|
+
}
|
|
478
|
+
let outputArrayMapping = false;
|
|
479
|
+
if (!flowMapping) {
|
|
480
|
+
for (const key in outputMapper.flowGraphMapping.outputs?.flows) {
|
|
481
|
+
if (key.startsWith("[") && key.endsWith("]")) {
|
|
482
|
+
const wildcardMapping = outputMapper.flowGraphMapping.outputs?.flows?.[key];
|
|
483
|
+
if (!this._strictValidation || !wildcardMapping?.compatibilityOnly) {
|
|
484
|
+
outputArrayMapping = true;
|
|
485
|
+
flowMapping = wildcardMapping;
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const allowedDynamicOutputs = outputArrayMapping ? this._getAllowedDynamicFlowSockets(gltfNode, outputMapper.flowGraphMapping, "output") : undefined;
|
|
492
|
+
if (this._strictValidation && allowedDynamicOutputs && !allowedDynamicOutputs.has(flowKey)) {
|
|
493
|
+
flowMapping = undefined;
|
|
494
|
+
}
|
|
495
|
+
if (!flowMapping && !this._isUnsupportedExtensionBlock(flowGraphBlocks.blocks[0])) {
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
const socketOutName = flowMapping ? (outputArrayMapping ? flowMapping.name.replace("$1", flowKey) : flowMapping.name) : flowKey;
|
|
302
499
|
// get the input node of this block
|
|
303
500
|
const inputNodeId = flow.node;
|
|
304
501
|
const nodeIn = this._nodes[inputNodeId];
|
|
@@ -314,24 +511,42 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
314
511
|
continue;
|
|
315
512
|
}
|
|
316
513
|
// create a serialized socket
|
|
317
|
-
const socketOut = this._createNewSocketConnection(socketOutName, true);
|
|
318
514
|
const block = (flowMapping && flowMapping.toBlock && flowGraphBlocks.blocks.find((b) => b.className === flowMapping.toBlock)) || flowGraphBlocks.blocks[0];
|
|
319
|
-
block.signalOutputs.
|
|
515
|
+
const socketOut = block.signalOutputs.find((socket) => socket.name === socketOutName) ?? this._createNewSocketConnection(socketOutName, true);
|
|
516
|
+
if (!block.signalOutputs.includes(socketOut)) {
|
|
517
|
+
block.signalOutputs.push(socketOut);
|
|
518
|
+
}
|
|
320
519
|
// get the mapper for the input node - in case it mapped to multiple blocks
|
|
321
|
-
const inputMapper =
|
|
520
|
+
const inputMapper = this._mappings[this._interactivityGraph.nodes[inputNodeId].declaration]?.flowGraphMapping;
|
|
322
521
|
if (!inputMapper) {
|
|
323
522
|
Logger.Error(["No mapping found for input node", nodeIn]);
|
|
324
523
|
throw new Error("Error parsing node connections");
|
|
325
524
|
}
|
|
326
|
-
let flowInMapping = inputMapper.inputs?.flows
|
|
525
|
+
let flowInMapping = _GetOwnMapping(inputMapper.inputs?.flows, flow.socket || "in");
|
|
526
|
+
if (this._strictValidation && flowInMapping?.compatibilityOnly) {
|
|
527
|
+
flowInMapping = undefined;
|
|
528
|
+
}
|
|
327
529
|
let arrayMapping = false;
|
|
328
530
|
if (!flowInMapping) {
|
|
329
531
|
for (const key in inputMapper.inputs?.flows) {
|
|
330
532
|
if (key.startsWith("[") && key.endsWith("]")) {
|
|
331
|
-
|
|
332
|
-
|
|
533
|
+
const wildcardMapping = inputMapper.inputs?.flows?.[key];
|
|
534
|
+
if (!this._strictValidation || !wildcardMapping?.compatibilityOnly) {
|
|
535
|
+
arrayMapping = true;
|
|
536
|
+
flowInMapping = wildcardMapping;
|
|
537
|
+
}
|
|
333
538
|
}
|
|
334
539
|
}
|
|
540
|
+
const allowedDynamicInputs = arrayMapping ? this._getAllowedDynamicFlowSockets(this._interactivityGraph.nodes[inputNodeId], inputMapper, "input") : undefined;
|
|
541
|
+
if (this._strictValidation && allowedDynamicInputs && !allowedDynamicInputs.has(flow.socket ?? "in")) {
|
|
542
|
+
flowInMapping = undefined;
|
|
543
|
+
}
|
|
544
|
+
if (!flowInMapping && (flow.socket ?? "in") === "in" && this._hasDefaultFlowInput(nodeIn.fullOperationName)) {
|
|
545
|
+
flowInMapping = { name: "in" };
|
|
546
|
+
}
|
|
547
|
+
if (!flowInMapping && !this._isUnsupportedExtensionBlock(nodeIn.blocks[0])) {
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
335
550
|
}
|
|
336
551
|
const nodeInSocketName = flowInMapping ? (arrayMapping ? flowInMapping.name.replace("$1", flow.socket || "") : flowInMapping.name) : flow.socket || "in";
|
|
337
552
|
const inputBlock = (flowInMapping && flowInMapping.toBlock && nodeIn.blocks.find((b) => b.className === flowInMapping.toBlock)) || nodeIn.blocks[0];
|
|
@@ -351,21 +566,33 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
351
566
|
const valuesKeys = Object.keys(valuesFromGLTF);
|
|
352
567
|
for (const valueKey of valuesKeys) {
|
|
353
568
|
const value = valuesFromGLTF[valueKey];
|
|
354
|
-
let valueMapping = outputMapper.flowGraphMapping.inputs?.values
|
|
569
|
+
let valueMapping = _GetOwnMapping(outputMapper.flowGraphMapping.inputs?.values, valueKey);
|
|
570
|
+
if (this._strictValidation && valueMapping?.compatibilityOnly) {
|
|
571
|
+
valueMapping = undefined;
|
|
572
|
+
}
|
|
355
573
|
let arrayMapping = false;
|
|
356
574
|
if (!valueMapping) {
|
|
357
575
|
for (const key in outputMapper.flowGraphMapping.inputs?.values) {
|
|
358
576
|
if (key.startsWith("[") && key.endsWith("]")) {
|
|
359
|
-
|
|
360
|
-
|
|
577
|
+
const wildcardMapping = outputMapper.flowGraphMapping.inputs?.values?.[key];
|
|
578
|
+
if (!this._strictValidation || !wildcardMapping?.compatibilityOnly) {
|
|
579
|
+
arrayMapping = true;
|
|
580
|
+
valueMapping = wildcardMapping;
|
|
581
|
+
}
|
|
361
582
|
}
|
|
362
583
|
}
|
|
363
584
|
}
|
|
585
|
+
const allowedDynamicInputs = arrayMapping ? this._getAllowedDynamicValueSockets(outputMapper.fullOperationName, gltfNode, "input") : undefined;
|
|
586
|
+
if (!valueMapping || (allowedDynamicInputs && !allowedDynamicInputs.has(valueKey))) {
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
364
589
|
const socketInName = valueMapping ? (arrayMapping ? valueMapping.name.replace("$1", valueKey) : valueMapping.name) : valueKey;
|
|
365
590
|
// create a serialized socket
|
|
366
|
-
const socketIn = this._createNewSocketConnection(socketInName);
|
|
367
591
|
const block = (valueMapping && valueMapping.toBlock && flowGraphBlocks.blocks.find((b) => b.className === valueMapping.toBlock)) || flowGraphBlocks.blocks[0];
|
|
368
|
-
block.dataInputs.
|
|
592
|
+
const socketIn = block.dataInputs.find((socket) => socket.name === socketInName) ?? this._createNewSocketConnection(socketInName);
|
|
593
|
+
if (!block.dataInputs.includes(socketIn)) {
|
|
594
|
+
block.dataInputs.push(socketIn);
|
|
595
|
+
}
|
|
369
596
|
// Captured before the connected branch below shadows `valueMapping`. When set and the
|
|
370
597
|
// value is supplied by a connection, the seconds→frames `dataTransformer` cannot run
|
|
371
598
|
// (it is parse-time only), so the raw connected value is scaled by a runtime multiply.
|
|
@@ -390,22 +617,34 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
390
617
|
Logger.Warn(`Dropping value connection from no-op node #${nodeOutId} (unsupported operation: ${nodeOut.fullOperationName}) into node #${i} "${valueKey}"; consumer will use type-default value`);
|
|
391
618
|
continue;
|
|
392
619
|
}
|
|
393
|
-
const outputMapper =
|
|
620
|
+
const outputMapper = this._mappings[this._interactivityGraph.nodes[nodeOutId].declaration]?.flowGraphMapping;
|
|
394
621
|
if (!outputMapper) {
|
|
395
622
|
Logger.Error(["No mapping found for output socket reference", value]);
|
|
396
623
|
throw new Error("Error parsing node connections");
|
|
397
624
|
}
|
|
398
|
-
let valueMapping = outputMapper.outputs?.values
|
|
625
|
+
let valueMapping = _GetOwnMapping(outputMapper.outputs?.values, nodeOutSocketName);
|
|
626
|
+
if (this._strictValidation && valueMapping?.compatibilityOnly) {
|
|
627
|
+
valueMapping = undefined;
|
|
628
|
+
}
|
|
399
629
|
let arrayMapping = false;
|
|
400
630
|
// check if there is an array mapping defined
|
|
401
631
|
if (!valueMapping) {
|
|
402
632
|
// search for a value mapping that has an array mapping
|
|
403
633
|
for (const key in outputMapper.outputs?.values) {
|
|
404
634
|
if (key.startsWith("[") && key.endsWith("]")) {
|
|
405
|
-
|
|
406
|
-
|
|
635
|
+
const wildcardMapping = outputMapper.outputs?.values?.[key];
|
|
636
|
+
if (!this._strictValidation || !wildcardMapping?.compatibilityOnly) {
|
|
637
|
+
arrayMapping = true;
|
|
638
|
+
valueMapping = wildcardMapping;
|
|
639
|
+
}
|
|
407
640
|
}
|
|
408
641
|
}
|
|
642
|
+
const allowedDynamicOutputs = arrayMapping
|
|
643
|
+
? this._getAllowedDynamicValueSockets(nodeOut.fullOperationName, this._interactivityGraph.nodes[nodeOutId], "output")
|
|
644
|
+
: undefined;
|
|
645
|
+
if (!valueMapping || (allowedDynamicOutputs && !allowedDynamicOutputs.has(nodeOutSocketName))) {
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
409
648
|
}
|
|
410
649
|
const socketOutName = valueMapping ? (arrayMapping ? valueMapping.name.replace("$1", nodeOutSocketName) : valueMapping?.name) : nodeOutSocketName;
|
|
411
650
|
const outBlock = (valueMapping && valueMapping.toBlock && nodeOut.blocks.find((b) => b.className === valueMapping.toBlock)) || nodeOut.blocks[0];
|
|
@@ -417,7 +656,7 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
417
656
|
}
|
|
418
657
|
// connect the sockets
|
|
419
658
|
if (convertConnectedTimeToFrames) {
|
|
420
|
-
this._connectWithSecondsToFramesConversion(context, socketOut, socketIn);
|
|
659
|
+
this._connectWithSecondsToFramesConversion(context, socketOut, socketIn, i, gltfNode.declaration);
|
|
421
660
|
}
|
|
422
661
|
else {
|
|
423
662
|
socketIn.connectedPointIds.push(socketOut.uniqueId);
|
|
@@ -456,6 +695,9 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
456
695
|
connectedPointIds: [],
|
|
457
696
|
};
|
|
458
697
|
}
|
|
698
|
+
_isUnsupportedExtensionBlock(block) {
|
|
699
|
+
return block?.className === "KHR_interactivity/FlowGraphUnsupportedInteractivityBlock";
|
|
700
|
+
}
|
|
459
701
|
/**
|
|
460
702
|
* Wires an upstream data output into a downstream data input through a runtime multiply block that
|
|
461
703
|
* scales the value by the animation target fps. This converts a KHR animation time (seconds),
|
|
@@ -465,9 +707,11 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
465
707
|
* @param context the serialized flow graph context that stores literal socket values
|
|
466
708
|
* @param upstreamOutput the data output socket providing the time value (in seconds)
|
|
467
709
|
* @param downstreamInput the data input socket that expects the time in frames
|
|
710
|
+
* @param nodeIndex source node receiving the converted value
|
|
711
|
+
* @param declarationIndex source declaration used by the receiving node
|
|
468
712
|
*/
|
|
469
|
-
_connectWithSecondsToFramesConversion(context, upstreamOutput, downstreamInput) {
|
|
470
|
-
const multiplyBlock = this._getEmptyBlock("FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply */, "FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply
|
|
713
|
+
_connectWithSecondsToFramesConversion(context, upstreamOutput, downstreamInput, nodeIndex, declarationIndex) {
|
|
714
|
+
const multiplyBlock = this._getEmptyBlock("FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply */, "FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply */, nodeIndex, declarationIndex, -1);
|
|
471
715
|
// Scalar (float) multiply; matches how the `math/mul` mapping configures the block.
|
|
472
716
|
multiplyBlock.config = { type: "number" /* FlowGraphTypes.Number */ };
|
|
473
717
|
const inputA = this._createNewSocketConnection("a");
|
|
@@ -531,6 +775,7 @@ export class InteractivityGraphToFlowGraphParser {
|
|
|
531
775
|
}
|
|
532
776
|
const allBlocks = this._nodes.reduce((acc, val) => acc.concat(val.blocks), []).concat(this._insertedBlocks);
|
|
533
777
|
return {
|
|
778
|
+
name: this._interactivityGraph.name ?? `Graph ${this._graphIndex + 1}`,
|
|
534
779
|
rightHanded: true,
|
|
535
780
|
allBlocks,
|
|
536
781
|
executionContexts: [context],
|