UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

1,220 lines (1,215 loc) 96.6 kB
import { R as RegisterClass, a7 as Vector2, V as Vector3, C as Constants, Q as Quaternion, M as Matrix, i as Vector4, j as Color4, aH as Color3, L as Logger } from './index-FzOfPXLV.esm.js'; /** * Class that represents an integer value. */ class FlowGraphInteger { constructor(value) { this.value = this._toInt(value); } /** * Converts a float to an integer. * @param n the float to convert * @returns the result of n | 0 - converting it to a int */ _toInt(n) { return n | 0; } /** * Adds two integers together. * @param other the other integer to add * @returns a FlowGraphInteger with the result of the addition */ add(other) { return new FlowGraphInteger(this.value + other.value); } /** * Subtracts two integers. * @param other the other integer to subtract * @returns a FlowGraphInteger with the result of the subtraction */ subtract(other) { return new FlowGraphInteger(this.value - other.value); } /** * Multiplies two integers. * @param other the other integer to multiply * @returns a FlowGraphInteger with the result of the multiplication */ multiply(other) { return new FlowGraphInteger(Math.imul(this.value, other.value)); } /** * Divides two integers. * @param other the other integer to divide * @returns a FlowGraphInteger with the result of the division */ divide(other) { return new FlowGraphInteger(this.value / other.value); } /** * The class name of this type. * @returns */ getClassName() { return FlowGraphInteger.ClassName; } /** * Compares two integers for equality. * @param other the other integer to compare * @returns */ equals(other) { return this.value === other.value; } /** * Parses a FlowGraphInteger from a serialization object. * @param value te number to parse * @returns */ static FromValue(value) { return new FlowGraphInteger(value); } toString() { return this.value.toString(); } } FlowGraphInteger.ClassName = "FlowGraphInteger"; RegisterClass("FlowGraphInteger", FlowGraphInteger); // Note - the matrix classes are basically column-major, and work similarly to Babylon.js' Matrix class. /** * A 2x2 matrix. */ class FlowGraphMatrix2D { constructor(m = [1, 0, 0, 1]) { this._m = m; } get m() { return this._m; } transformVector(v) { return this.transformVectorToRef(v, new Vector2()); } transformVectorToRef(v, result) { result.x = v.x * this._m[0] + v.y * this._m[1]; result.y = v.x * this._m[2] + v.y * this._m[3]; return result; } asArray() { return this.toArray(); } toArray(emptyArray = []) { for (let i = 0; i < 4; i++) { emptyArray[i] = this._m[i]; } return emptyArray; } fromArray(array) { for (let i = 0; i < 4; i++) { this._m[i] = array[i]; } return this; } multiplyToRef(other, result) { const otherMatrix = other._m; const thisMatrix = this._m; const r = result._m; // other * this r[0] = otherMatrix[0] * thisMatrix[0] + otherMatrix[1] * thisMatrix[2]; r[1] = otherMatrix[0] * thisMatrix[1] + otherMatrix[1] * thisMatrix[3]; r[2] = otherMatrix[2] * thisMatrix[0] + otherMatrix[3] * thisMatrix[2]; r[3] = otherMatrix[2] * thisMatrix[1] + otherMatrix[3] * thisMatrix[3]; return result; } multiply(other) { return this.multiplyToRef(other, new FlowGraphMatrix2D()); } divideToRef(other, result) { const m = this._m; const o = other._m; const r = result._m; r[0] = m[0] / o[0]; r[1] = m[1] / o[1]; r[2] = m[2] / o[2]; r[3] = m[3] / o[3]; return result; } divide(other) { return this.divideToRef(other, new FlowGraphMatrix2D()); } addToRef(other, result) { const m = this._m; const o = other.m; const r = result.m; r[0] = m[0] + o[0]; r[1] = m[1] + o[1]; r[2] = m[2] + o[2]; r[3] = m[3] + o[3]; return result; } add(other) { return this.addToRef(other, new FlowGraphMatrix2D()); } subtractToRef(other, result) { const m = this._m; const o = other.m; const r = result.m; r[0] = m[0] - o[0]; r[1] = m[1] - o[1]; r[2] = m[2] - o[2]; r[3] = m[3] - o[3]; return result; } subtract(other) { return this.subtractToRef(other, new FlowGraphMatrix2D()); } transpose() { const m = this._m; return new FlowGraphMatrix2D([m[0], m[2], m[1], m[3]]); } determinant() { const m = this._m; return m[0] * m[3] - m[1] * m[2]; } inverse() { const det = this.determinant(); if (det === 0) { throw new Error("Matrix is not invertible"); } const m = this._m; const invDet = 1 / det; return new FlowGraphMatrix2D([m[3] * invDet, -m[1] * invDet, -m[2] * invDet, m[0] * invDet]); } equals(other, epsilon = 0) { const m = this._m; const o = other.m; if (epsilon === 0) { return m[0] === o[0] && m[1] === o[1] && m[2] === o[2] && m[3] === o[3]; } return Math.abs(m[0] - o[0]) < epsilon && Math.abs(m[1] - o[1]) < epsilon && Math.abs(m[2] - o[2]) < epsilon && Math.abs(m[3] - o[3]) < epsilon; } getClassName() { return "FlowGraphMatrix2D"; } toString() { return `FlowGraphMatrix2D(${this._m.join(", ")})`; } } /** * A 3x3 matrix. */ class FlowGraphMatrix3D { constructor(array = [1, 0, 0, 0, 1, 0, 0, 0, 1]) { this._m = array; } get m() { return this._m; } transformVector(v) { return this.transformVectorToRef(v, new Vector3()); } transformVectorToRef(v, result) { const m = this._m; result.x = v.x * m[0] + v.y * m[1] + v.z * m[2]; result.y = v.x * m[3] + v.y * m[4] + v.z * m[5]; result.z = v.x * m[6] + v.y * m[7] + v.z * m[8]; return result; } multiplyToRef(other, result) { const otherMatrix = other._m; const thisMatrix = this._m; const r = result.m; r[0] = otherMatrix[0] * thisMatrix[0] + otherMatrix[1] * thisMatrix[3] + otherMatrix[2] * thisMatrix[6]; r[1] = otherMatrix[0] * thisMatrix[1] + otherMatrix[1] * thisMatrix[4] + otherMatrix[2] * thisMatrix[7]; r[2] = otherMatrix[0] * thisMatrix[2] + otherMatrix[1] * thisMatrix[5] + otherMatrix[2] * thisMatrix[8]; r[3] = otherMatrix[3] * thisMatrix[0] + otherMatrix[4] * thisMatrix[3] + otherMatrix[5] * thisMatrix[6]; r[4] = otherMatrix[3] * thisMatrix[1] + otherMatrix[4] * thisMatrix[4] + otherMatrix[5] * thisMatrix[7]; r[5] = otherMatrix[3] * thisMatrix[2] + otherMatrix[4] * thisMatrix[5] + otherMatrix[5] * thisMatrix[8]; r[6] = otherMatrix[6] * thisMatrix[0] + otherMatrix[7] * thisMatrix[3] + otherMatrix[8] * thisMatrix[6]; r[7] = otherMatrix[6] * thisMatrix[1] + otherMatrix[7] * thisMatrix[4] + otherMatrix[8] * thisMatrix[7]; r[8] = otherMatrix[6] * thisMatrix[2] + otherMatrix[7] * thisMatrix[5] + otherMatrix[8] * thisMatrix[8]; return result; } multiply(other) { return this.multiplyToRef(other, new FlowGraphMatrix3D()); } divideToRef(other, result) { const m = this._m; const o = other.m; const r = result.m; r[0] = m[0] / o[0]; r[1] = m[1] / o[1]; r[2] = m[2] / o[2]; r[3] = m[3] / o[3]; r[4] = m[4] / o[4]; r[5] = m[5] / o[5]; r[6] = m[6] / o[6]; r[7] = m[7] / o[7]; r[8] = m[8] / o[8]; return result; } divide(other) { return this.divideToRef(other, new FlowGraphMatrix3D()); } addToRef(other, result) { const m = this._m; const o = other.m; const r = result.m; r[0] = m[0] + o[0]; r[1] = m[1] + o[1]; r[2] = m[2] + o[2]; r[3] = m[3] + o[3]; r[4] = m[4] + o[4]; r[5] = m[5] + o[5]; r[6] = m[6] + o[6]; r[7] = m[7] + o[7]; r[8] = m[8] + o[8]; return result; } add(other) { return this.addToRef(other, new FlowGraphMatrix3D()); } subtractToRef(other, result) { const m = this._m; const o = other.m; const r = result.m; r[0] = m[0] - o[0]; r[1] = m[1] - o[1]; r[2] = m[2] - o[2]; r[3] = m[3] - o[3]; r[4] = m[4] - o[4]; r[5] = m[5] - o[5]; r[6] = m[6] - o[6]; r[7] = m[7] - o[7]; r[8] = m[8] - o[8]; return result; } subtract(other) { return this.subtractToRef(other, new FlowGraphMatrix3D()); } toArray(emptyArray = []) { for (let i = 0; i < 9; i++) { emptyArray[i] = this._m[i]; } return emptyArray; } asArray() { return this.toArray(); } fromArray(array) { for (let i = 0; i < 9; i++) { this._m[i] = array[i]; } return this; } transpose() { const m = this._m; return new FlowGraphMatrix3D([m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]); } determinant() { const m = this._m; return m[0] * (m[4] * m[8] - m[5] * m[7]) - m[1] * (m[3] * m[8] - m[5] * m[6]) + m[2] * (m[3] * m[7] - m[4] * m[6]); } inverse() { const det = this.determinant(); if (det === 0) { throw new Error("Matrix is not invertible"); } const m = this._m; const invDet = 1 / det; return new FlowGraphMatrix3D([ (m[4] * m[8] - m[5] * m[7]) * invDet, (m[2] * m[7] - m[1] * m[8]) * invDet, (m[1] * m[5] - m[2] * m[4]) * invDet, (m[5] * m[6] - m[3] * m[8]) * invDet, (m[0] * m[8] - m[2] * m[6]) * invDet, (m[2] * m[3] - m[0] * m[5]) * invDet, (m[3] * m[7] - m[4] * m[6]) * invDet, (m[1] * m[6] - m[0] * m[7]) * invDet, (m[0] * m[4] - m[1] * m[3]) * invDet, ]); } equals(other, epsilon = 0) { const m = this._m; const o = other.m; // performance shortcut if (epsilon === 0) { return m[0] === o[0] && m[1] === o[1] && m[2] === o[2] && m[3] === o[3] && m[4] === o[4] && m[5] === o[5] && m[6] === o[6] && m[7] === o[7] && m[8] === o[8]; } return (Math.abs(m[0] - o[0]) < epsilon && Math.abs(m[1] - o[1]) < epsilon && Math.abs(m[2] - o[2]) < epsilon && Math.abs(m[3] - o[3]) < epsilon && Math.abs(m[4] - o[4]) < epsilon && Math.abs(m[5] - o[5]) < epsilon && Math.abs(m[6] - o[6]) < epsilon && Math.abs(m[7] - o[7]) < epsilon && Math.abs(m[8] - o[8]) < epsilon); } getClassName() { return "FlowGraphMatrix3D"; } toString() { return `FlowGraphMatrix3D(${this._m.join(", ")})`; } } /** * The types supported by the flow graph. */ var FlowGraphTypes; (function (FlowGraphTypes) { FlowGraphTypes["Any"] = "any"; FlowGraphTypes["String"] = "string"; FlowGraphTypes["Number"] = "number"; FlowGraphTypes["Boolean"] = "boolean"; FlowGraphTypes["Object"] = "object"; FlowGraphTypes["Integer"] = "FlowGraphInteger"; FlowGraphTypes["Vector2"] = "Vector2"; FlowGraphTypes["Vector3"] = "Vector3"; FlowGraphTypes["Vector4"] = "Vector4"; FlowGraphTypes["Quaternion"] = "Quaternion"; FlowGraphTypes["Matrix"] = "Matrix"; FlowGraphTypes["Matrix2D"] = "Matrix2D"; FlowGraphTypes["Matrix3D"] = "Matrix3D"; FlowGraphTypes["Color3"] = "Color3"; FlowGraphTypes["Color4"] = "Color4"; })(FlowGraphTypes || (FlowGraphTypes = {})); /** * A rich type represents extra information about a type, * such as its name and a default value constructor. */ class RichType { constructor( /** * The name given to the type. */ typeName, /** * The default value of the type. */ defaultValue, /** * [-1] The ANIMATIONTYPE of the type, if available */ animationType = -1) { this.typeName = typeName; this.defaultValue = defaultValue; this.animationType = animationType; } /** * Serializes this rich type into a serialization object. * @param serializationObject the object to serialize to */ serialize(serializationObject) { serializationObject.typeName = this.typeName; serializationObject.defaultValue = this.defaultValue; } } const RichTypeAny = new RichType("any" /* FlowGraphTypes.Any */, undefined); const RichTypeString = new RichType("string" /* FlowGraphTypes.String */, ""); const RichTypeNumber = new RichType("number" /* FlowGraphTypes.Number */, 0, Constants.ANIMATIONTYPE_FLOAT); const RichTypeBoolean = new RichType("boolean" /* FlowGraphTypes.Boolean */, false); const RichTypeVector2 = new RichType("Vector2" /* FlowGraphTypes.Vector2 */, Vector2.Zero(), Constants.ANIMATIONTYPE_VECTOR2); const RichTypeVector3 = new RichType("Vector3" /* FlowGraphTypes.Vector3 */, Vector3.Zero(), Constants.ANIMATIONTYPE_VECTOR3); const RichTypeVector4 = new RichType("Vector4" /* FlowGraphTypes.Vector4 */, Vector4.Zero()); const RichTypeMatrix = new RichType("Matrix" /* FlowGraphTypes.Matrix */, Matrix.Identity(), Constants.ANIMATIONTYPE_MATRIX); const RichTypeMatrix2D = new RichType("Matrix2D" /* FlowGraphTypes.Matrix2D */, new FlowGraphMatrix2D()); const RichTypeMatrix3D = new RichType("Matrix3D" /* FlowGraphTypes.Matrix3D */, new FlowGraphMatrix3D()); const RichTypeColor3 = new RichType("Color3" /* FlowGraphTypes.Color3 */, Color3.Black(), Constants.ANIMATIONTYPE_COLOR3); const RichTypeColor4 = new RichType("Color4" /* FlowGraphTypes.Color4 */, new Color4(0, 0, 0, 0), Constants.ANIMATIONTYPE_COLOR4); const RichTypeQuaternion = new RichType("Quaternion" /* FlowGraphTypes.Quaternion */, Quaternion.Identity(), Constants.ANIMATIONTYPE_QUATERNION); RichTypeQuaternion.typeTransformer = (value) => { if (value.getClassName) { if (value.getClassName() === "Vector4" /* FlowGraphTypes.Vector4 */) { return Quaternion.FromArray(value.asArray()); } else if (value.getClassName() === "Vector3" /* FlowGraphTypes.Vector3 */) { return Quaternion.FromEulerVector(value); } else if (value.getClassName() === "Matrix" /* FlowGraphTypes.Matrix */) { return Quaternion.FromRotationMatrix(value); } } return value; }; const RichTypeFlowGraphInteger = new RichType("FlowGraphInteger" /* FlowGraphTypes.Integer */, new FlowGraphInteger(0), Constants.ANIMATIONTYPE_FLOAT); /** * Given a value, try to deduce its rich type. * @param value the value to deduce the rich type from * @returns the value's rich type, or RichTypeAny if the type could not be deduced. */ // eslint-disable-next-line @typescript-eslint/naming-convention function getRichTypeFromValue(value) { const anyValue = value; switch (typeof value) { case "string" /* FlowGraphTypes.String */: return RichTypeString; case "number" /* FlowGraphTypes.Number */: return RichTypeNumber; case "boolean" /* FlowGraphTypes.Boolean */: return RichTypeBoolean; case "object" /* FlowGraphTypes.Object */: if (anyValue.getClassName) { switch (anyValue.getClassName()) { case "Vector2" /* FlowGraphTypes.Vector2 */: return RichTypeVector2; case "Vector3" /* FlowGraphTypes.Vector3 */: return RichTypeVector3; case "Vector4" /* FlowGraphTypes.Vector4 */: return RichTypeVector4; case "Matrix" /* FlowGraphTypes.Matrix */: return RichTypeMatrix; case "Color3" /* FlowGraphTypes.Color3 */: return RichTypeColor3; case "Color4" /* FlowGraphTypes.Color4 */: return RichTypeColor4; case "Quaternion" /* FlowGraphTypes.Quaternion */: return RichTypeQuaternion; case "FlowGraphInteger" /* FlowGraphTypes.Integer */: return RichTypeFlowGraphInteger; case "Matrix2D" /* FlowGraphTypes.Matrix2D */: return RichTypeMatrix2D; case "Matrix3D" /* FlowGraphTypes.Matrix3D */: return RichTypeMatrix3D; } } return RichTypeAny; default: return RichTypeAny; } } /** * Given a flow graph type, return the rich type that corresponds to it. * @param flowGraphType the flow graph type * @returns the rich type that corresponds to the flow graph type */ // eslint-disable-next-line @typescript-eslint/naming-convention function getRichTypeByFlowGraphType(flowGraphType) { switch (flowGraphType) { case "string" /* FlowGraphTypes.String */: return RichTypeString; case "number" /* FlowGraphTypes.Number */: return RichTypeNumber; case "boolean" /* FlowGraphTypes.Boolean */: return RichTypeBoolean; case "Vector2" /* FlowGraphTypes.Vector2 */: return RichTypeVector2; case "Vector3" /* FlowGraphTypes.Vector3 */: return RichTypeVector3; case "Vector4" /* FlowGraphTypes.Vector4 */: return RichTypeVector4; case "Matrix" /* FlowGraphTypes.Matrix */: return RichTypeMatrix; case "Color3" /* FlowGraphTypes.Color3 */: return RichTypeColor3; case "Color4" /* FlowGraphTypes.Color4 */: return RichTypeColor4; case "Quaternion" /* FlowGraphTypes.Quaternion */: return RichTypeQuaternion; case "FlowGraphInteger" /* FlowGraphTypes.Integer */: return RichTypeFlowGraphInteger; case "Matrix2D" /* FlowGraphTypes.Matrix2D */: return RichTypeMatrix2D; case "Matrix3D" /* FlowGraphTypes.Matrix3D */: return RichTypeMatrix3D; default: return RichTypeAny; } } /** * get the animation type for a given flow graph type * @param flowGraphType the flow graph type * @returns the animation type for this flow graph type */ // eslint-disable-next-line @typescript-eslint/naming-convention function getAnimationTypeByFlowGraphType(flowGraphType) { switch (flowGraphType) { case "number" /* FlowGraphTypes.Number */: return Constants.ANIMATIONTYPE_FLOAT; case "Vector2" /* FlowGraphTypes.Vector2 */: return Constants.ANIMATIONTYPE_VECTOR2; case "Vector3" /* FlowGraphTypes.Vector3 */: return Constants.ANIMATIONTYPE_VECTOR3; case "Matrix" /* FlowGraphTypes.Matrix */: return Constants.ANIMATIONTYPE_MATRIX; case "Color3" /* FlowGraphTypes.Color3 */: return Constants.ANIMATIONTYPE_COLOR3; case "Color4" /* FlowGraphTypes.Color4 */: return Constants.ANIMATIONTYPE_COLOR4; case "Quaternion" /* FlowGraphTypes.Quaternion */: return Constants.ANIMATIONTYPE_QUATERNION; default: return Constants.ANIMATIONTYPE_FLOAT; } } /** * Given an animation type, return the rich type that corresponds to it. * @param animationType the animation type * @returns the rich type that corresponds to the animation type */ // eslint-disable-next-line @typescript-eslint/naming-convention function getRichTypeByAnimationType(animationType) { switch (animationType) { case Constants.ANIMATIONTYPE_FLOAT: return RichTypeNumber; case Constants.ANIMATIONTYPE_VECTOR2: return RichTypeVector2; case Constants.ANIMATIONTYPE_VECTOR3: return RichTypeVector3; case Constants.ANIMATIONTYPE_MATRIX: return RichTypeMatrix; case Constants.ANIMATIONTYPE_COLOR3: return RichTypeColor3; case Constants.ANIMATIONTYPE_COLOR4: return RichTypeColor4; case Constants.ANIMATIONTYPE_QUATERNION: return RichTypeQuaternion; default: return RichTypeAny; } } function getMappingForFullOperationName(fullOperationName) { const [op, extension] = fullOperationName.split(":"); return getMappingForDeclaration({ op, extension }); } function getMappingForDeclaration(declaration, returnNoOpIfNotAvailable = true) { const mapping = declaration.extension ? gltfExtensionsToFlowGraphMapping[declaration.extension]?.[declaration.op] : gltfToFlowGraphMapping[declaration.op]; if (!mapping) { Logger.Warn(`No mapping found for operation ${declaration.op} and extension ${declaration.extension || "KHR_interactivity"}`); if (returnNoOpIfNotAvailable) { const inputs = {}; const outputs = { flows: {}, }; if (declaration.inputValueSockets) { inputs.values = {}; for (const key in declaration.inputValueSockets) { inputs.values[key] = { name: key, }; } } if (declaration.outputValueSockets) { outputs.values = {}; Object.keys(declaration.outputValueSockets).forEach((key) => { outputs.values[key] = { name: key, }; }); } return { blocks: [], // no blocks, just mapping inputs, outputs, }; } } return mapping; } /** * This function will add new mapping to glTF interactivity. * Other extensions can define new types of blocks, this is the way to let interactivity know how to parse them. * @param key the type of node, i.e. "variable/get" * @param extension the extension of the interactivity operation, i.e. "KHR_selectability" * @param mapping The mapping object. See documentation or examples below. */ function addNewInteractivityFlowGraphMapping(key, extension, mapping) { gltfExtensionsToFlowGraphMapping[extension] ||= {}; gltfExtensionsToFlowGraphMapping[extension][key] = mapping; } const gltfExtensionsToFlowGraphMapping = { /** * This is the BABYLON extension for glTF interactivity. * It defines babylon-specific blocks and operations. */ BABYLON: { /** * flow/log is a flow node that logs input to the console. * It has "in" and "out" flows, and takes a message as input. * The message can be any type of value. * The message is logged to the console when the "in" flow is triggered. * The "out" flow is triggered when the message is logged. */ "flow/log": { blocks: ["FlowGraphConsoleLogBlock" /* FlowGraphBlockNames.ConsoleLog */], inputs: { values: { message: { name: "message" }, }, }, }, }, }; // this mapper is just a way to convert the glTF nodes to FlowGraph nodes in terms of input/output connection names and values. const gltfToFlowGraphMapping = { "event/onStart": { blocks: ["FlowGraphSceneReadyEventBlock" /* FlowGraphBlockNames.SceneReadyEvent */], outputs: { flows: { out: { name: "done" }, }, }, }, "event/onTick": { blocks: ["FlowGraphSceneTickEventBlock" /* FlowGraphBlockNames.SceneTickEvent */], inputs: {}, outputs: { values: { timeSinceLastTick: { name: "deltaTime", gltfType: "number" /*, dataTransformer: (time: number) => time / 1000*/ }, }, flows: { out: { name: "done" }, }, }, }, "event/send": { blocks: ["FlowGraphSendCustomEventBlock" /* FlowGraphBlockNames.SendCustomEvent */], extraProcessor(gltfBlock, declaration, _mapping, parser, serializedObjects) { // set eventId and eventData. The configuration object of the glTF should have a single object. // validate that we are running it on the right block. if (declaration.op !== "event/send" || !gltfBlock.configuration || Object.keys(gltfBlock.configuration).length !== 1) { throw new Error("Receive event should have a single configuration object, the event itself"); } const eventConfiguration = gltfBlock.configuration["event"]; const eventId = eventConfiguration.value[0]; if (typeof eventId !== "number") { throw new Error("Event id should be a number"); } const event = parser.arrays.events[eventId]; const serializedObject = serializedObjects[0]; serializedObject.config ||= {}; serializedObject.config.eventId = event.eventId; serializedObject.config.eventData = event.eventData; return serializedObjects; }, }, "event/receive": { blocks: ["FlowGraphReceiveCustomEventBlock" /* FlowGraphBlockNames.ReceiveCustomEvent */], outputs: { flows: { out: { name: "done" }, }, }, validation(gltfBlock, interactivityGraph) { if (!gltfBlock.configuration) { Logger.Error("Receive event should have a configuration object"); return { valid: false, error: "Receive event should have a configuration object" }; } const eventConfiguration = gltfBlock.configuration["event"]; if (!eventConfiguration) { Logger.Error("Receive event should have a single configuration object, the event itself"); return { valid: false, error: "Receive event should have a single configuration object, the event itself" }; } const eventId = eventConfiguration.value[0]; if (typeof eventId !== "number") { Logger.Error("Event id should be a number"); return { valid: false, error: "Event id should be a number" }; } const event = interactivityGraph.events?.[eventId]; if (!event) { Logger.Error(`Event with id ${eventId} not found`); return { valid: false, error: `Event with id ${eventId} not found` }; } return { valid: true }; }, extraProcessor(gltfBlock, declaration, _mapping, parser, serializedObjects) { // set eventId and eventData. The configuration object of the glTF should have a single object. // validate that we are running it on the right block. if (declaration.op !== "event/receive" || !gltfBlock.configuration || Object.keys(gltfBlock.configuration).length !== 1) { throw new Error("Receive event should have a single configuration object, the event itself"); } const eventConfiguration = gltfBlock.configuration["event"]; const eventId = eventConfiguration.value[0]; if (typeof eventId !== "number") { throw new Error("Event id should be a number"); } const event = parser.arrays.events[eventId]; const serializedObject = serializedObjects[0]; serializedObject.config ||= {}; serializedObject.config.eventId = event.eventId; serializedObject.config.eventData = event.eventData; return serializedObjects; }, }, "math/e": getSimpleInputMapping("FlowGraphEBlock" /* FlowGraphBlockNames.E */), "math/pi": getSimpleInputMapping("FlowGraphPIBlock" /* FlowGraphBlockNames.PI */), "math/inf": getSimpleInputMapping("FlowGraphInfBlock" /* FlowGraphBlockNames.Inf */), "math/nan": getSimpleInputMapping("FlowGraphNaNBlock" /* FlowGraphBlockNames.NaN */), "math/abs": getSimpleInputMapping("FlowGraphAbsBlock" /* FlowGraphBlockNames.Abs */), "math/sign": getSimpleInputMapping("FlowGraphSignBlock" /* FlowGraphBlockNames.Sign */), "math/trunc": getSimpleInputMapping("FlowGraphTruncBlock" /* FlowGraphBlockNames.Trunc */), "math/floor": getSimpleInputMapping("FlowGraphFloorBlock" /* FlowGraphBlockNames.Floor */), "math/ceil": getSimpleInputMapping("FlowGraphCeilBlock" /* FlowGraphBlockNames.Ceil */), "math/round": { blocks: ["FlowGraphRoundBlock" /* FlowGraphBlockNames.Round */], configuration: {}, inputs: { values: { a: { name: "a" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(gltfBlock, declaration, _mapping, parser, serializedObjects) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; serializedObjects[0].config.roundHalfAwayFromZero = true; return serializedObjects; }, }, "math/fract": getSimpleInputMapping("FlowGraphFractBlock" /* FlowGraphBlockNames.Fraction */), "math/neg": getSimpleInputMapping("FlowGraphNegationBlock" /* FlowGraphBlockNames.Negation */), "math/add": getSimpleInputMapping("FlowGraphAddBlock" /* FlowGraphBlockNames.Add */, ["a", "b"], true), "math/sub": getSimpleInputMapping("FlowGraphSubtractBlock" /* FlowGraphBlockNames.Subtract */, ["a", "b"], true), "math/mul": { blocks: ["FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply */], extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; serializedObjects[0].config.useMatrixPerComponent = true; serializedObjects[0].config.preventIntegerFloatArithmetic = true; // try to infer the type or fallback to Integer // check the gltf block for the inputs, see if they have a type let type = -1; Object.keys(_gltfBlock.values || {}).find((value) => { if (_gltfBlock.values?.[value].type !== undefined) { type = _gltfBlock.values[value].type; return true; } return false; }); if (type !== -1) { serializedObjects[0].config.type = _parser.arrays.types[type].flowGraphType; } return serializedObjects; }, validation(gltfBlock) { if (gltfBlock.values) { // make sure types are the same return ValidateTypes(gltfBlock); } return { valid: true }; }, }, "math/div": getSimpleInputMapping("FlowGraphDivideBlock" /* FlowGraphBlockNames.Divide */, ["a", "b"], true), "math/rem": getSimpleInputMapping("FlowGraphModuloBlock" /* FlowGraphBlockNames.Modulo */, ["a", "b"]), "math/min": getSimpleInputMapping("FlowGraphMinBlock" /* FlowGraphBlockNames.Min */, ["a", "b"]), "math/max": getSimpleInputMapping("FlowGraphMaxBlock" /* FlowGraphBlockNames.Max */, ["a", "b"]), "math/clamp": getSimpleInputMapping("FlowGraphClampBlock" /* FlowGraphBlockNames.Clamp */, ["a", "b", "c"]), "math/saturate": getSimpleInputMapping("FlowGraphSaturateBlock" /* FlowGraphBlockNames.Saturate */), "math/mix": getSimpleInputMapping("FlowGraphMathInterpolationBlock" /* FlowGraphBlockNames.MathInterpolation */, ["a", "b", "c"]), "math/eq": getSimpleInputMapping("FlowGraphEqualityBlock" /* FlowGraphBlockNames.Equality */, ["a", "b"]), "math/lt": getSimpleInputMapping("FlowGraphLessThanBlock" /* FlowGraphBlockNames.LessThan */, ["a", "b"]), "math/le": getSimpleInputMapping("FlowGraphLessThanOrEqualBlock" /* FlowGraphBlockNames.LessThanOrEqual */, ["a", "b"]), "math/gt": getSimpleInputMapping("FlowGraphGreaterThanBlock" /* FlowGraphBlockNames.GreaterThan */, ["a", "b"]), "math/ge": getSimpleInputMapping("FlowGraphGreaterThanOrEqualBlock" /* FlowGraphBlockNames.GreaterThanOrEqual */, ["a", "b"]), "math/isnan": getSimpleInputMapping("FlowGraphIsNaNBlock" /* FlowGraphBlockNames.IsNaN */), "math/isinf": getSimpleInputMapping("FlowGraphIsInfBlock" /* FlowGraphBlockNames.IsInfinity */), "math/select": { blocks: ["FlowGraphConditionalBlock" /* FlowGraphBlockNames.Conditional */], inputs: { values: { condition: { name: "condition" }, // Should we validate those have the same type here, or assume it is already validated? a: { name: "onTrue" }, b: { name: "onFalse" }, }, }, outputs: { values: { value: { name: "output" }, }, }, }, "math/random": { blocks: ["FlowGraphRandomBlock" /* FlowGraphBlockNames.Random */], outputs: { values: { value: { name: "value" }, }, }, }, "math/sin": getSimpleInputMapping("FlowGraphSinBlock" /* FlowGraphBlockNames.Sin */), "math/cos": getSimpleInputMapping("FlowGraphCosBlock" /* FlowGraphBlockNames.Cos */), "math/tan": getSimpleInputMapping("FlowGraphTanBlock" /* FlowGraphBlockNames.Tan */), "math/asin": getSimpleInputMapping("FlowGraphASinBlock" /* FlowGraphBlockNames.Asin */), "math/acos": getSimpleInputMapping("FlowGraphACosBlock" /* FlowGraphBlockNames.Acos */), "math/atan": getSimpleInputMapping("FlowGraphATanBlock" /* FlowGraphBlockNames.Atan */), "math/atan2": getSimpleInputMapping("FlowGraphATan2Block" /* FlowGraphBlockNames.Atan2 */, ["a", "b"]), "math/sinh": getSimpleInputMapping("FlowGraphSinhBlock" /* FlowGraphBlockNames.Sinh */), "math/cosh": getSimpleInputMapping("FlowGraphCoshBlock" /* FlowGraphBlockNames.Cosh */), "math/tanh": getSimpleInputMapping("FlowGraphTanhBlock" /* FlowGraphBlockNames.Tanh */), "math/asinh": getSimpleInputMapping("FlowGraphASinhBlock" /* FlowGraphBlockNames.Asinh */), "math/acosh": getSimpleInputMapping("FlowGraphACoshBlock" /* FlowGraphBlockNames.Acosh */), "math/atanh": getSimpleInputMapping("FlowGraphATanhBlock" /* FlowGraphBlockNames.Atanh */), "math/exp": getSimpleInputMapping("FlowGraphExponentialBlock" /* FlowGraphBlockNames.Exponential */), "math/log": getSimpleInputMapping("FlowGraphLogBlock" /* FlowGraphBlockNames.Log */), "math/log2": getSimpleInputMapping("FlowGraphLog2Block" /* FlowGraphBlockNames.Log2 */), "math/log10": getSimpleInputMapping("FlowGraphLog10Block" /* FlowGraphBlockNames.Log10 */), "math/sqrt": getSimpleInputMapping("FlowGraphSquareRootBlock" /* FlowGraphBlockNames.SquareRoot */), "math/cbrt": getSimpleInputMapping("FlowGraphCubeRootBlock" /* FlowGraphBlockNames.CubeRoot */), "math/pow": getSimpleInputMapping("FlowGraphPowerBlock" /* FlowGraphBlockNames.Power */, ["a", "b"]), "math/length": getSimpleInputMapping("FlowGraphLengthBlock" /* FlowGraphBlockNames.Length */), "math/normalize": getSimpleInputMapping("FlowGraphNormalizeBlock" /* FlowGraphBlockNames.Normalize */), "math/dot": getSimpleInputMapping("FlowGraphDotBlock" /* FlowGraphBlockNames.Dot */, ["a", "b"]), "math/cross": getSimpleInputMapping("FlowGraphCrossBlock" /* FlowGraphBlockNames.Cross */, ["a", "b"]), "math/rotate2D": getSimpleInputMapping("FlowGraphRotate2DBlock" /* FlowGraphBlockNames.Rotate2D */, ["a", "b"]), "math/rotate3D": getSimpleInputMapping("FlowGraphRotate3DBlock" /* FlowGraphBlockNames.Rotate3D */, ["a", "b"]), "math/transform": { // glTF transform is vectorN with matrixN blocks: ["FlowGraphTransformVectorBlock" /* FlowGraphBlockNames.TransformVector */], inputs: { values: { a: { name: "a" }, b: { name: "b" }, }, }, outputs: { values: { value: { name: "value" }, }, }, }, "math/combine2": { blocks: ["FlowGraphCombineVector2Block" /* FlowGraphBlockNames.CombineVector2 */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, }, "math/combine3": { blocks: ["FlowGraphCombineVector3Block" /* FlowGraphBlockNames.CombineVector3 */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, c: { name: "input_2", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, }, "math/combine4": { blocks: ["FlowGraphCombineVector4Block" /* FlowGraphBlockNames.CombineVector4 */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, c: { name: "input_2", gltfType: "number" }, d: { name: "input_3", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, }, // one input, N outputs! outputs named using numbers. "math/extract2": { blocks: ["FlowGraphExtractVector2Block" /* FlowGraphBlockNames.ExtractVector2 */], inputs: { values: { a: { name: "input", gltfType: "number" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, }, }, }, "math/extract3": { blocks: ["FlowGraphExtractVector3Block" /* FlowGraphBlockNames.ExtractVector3 */], inputs: { values: { a: { name: "input", gltfType: "number" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, "2": { name: "output_2" }, }, }, }, "math/extract4": { blocks: ["FlowGraphExtractVector4Block" /* FlowGraphBlockNames.ExtractVector4 */], inputs: { values: { a: { name: "input", gltfType: "number" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, "2": { name: "output_2" }, "3": { name: "output_3" }, }, }, }, "math/transpose": getSimpleInputMapping("FlowGraphTransposeBlock" /* FlowGraphBlockNames.Transpose */), "math/determinant": getSimpleInputMapping("FlowGraphDeterminantBlock" /* FlowGraphBlockNames.Determinant */), "math/inverse": getSimpleInputMapping("FlowGraphInvertMatrixBlock" /* FlowGraphBlockNames.InvertMatrix */), "math/matmul": getSimpleInputMapping("FlowGraphMatrixMultiplicationBlock" /* FlowGraphBlockNames.MatrixMultiplication */, ["a", "b"]), "math/matCompose": { blocks: ["FlowGraphMatrixCompose" /* FlowGraphBlockNames.MatrixCompose */], inputs: { values: { translation: { name: "position", gltfType: "float3" }, rotation: { name: "rotationQuaternion", gltfType: "float4" }, scale: { name: "scaling", gltfType: "float3" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects, context) { // configure it to work the way glTF specifies const d = serializedObjects[0].dataInputs.find((input) => input.name === "rotationQuaternion"); if (!d) { throw new Error("Rotation quaternion input not found"); } // if value is defined, set the type to quaternion if (context._connectionValues[d.uniqueId]) { context._connectionValues[d.uniqueId].type = "Quaternion" /* FlowGraphTypes.Quaternion */; } return serializedObjects; }, }, "math/matDecompose": { blocks: ["FlowGraphMatrixDecompose" /* FlowGraphBlockNames.MatrixDecompose */], inputs: { values: { a: { name: "input", gltfType: "number" }, }, }, outputs: { values: { translation: { name: "position" }, rotation: { name: "rotationQuaternion" }, scale: { name: "scaling" }, }, }, }, "math/quatConjugate": getSimpleInputMapping("FlowGraphConjugateBlock" /* FlowGraphBlockNames.Conjugate */, ["a"]), "math/quatMul": { blocks: ["FlowGraphMultiplyBlock" /* FlowGraphBlockNames.Multiply */], inputs: { values: { a: { name: "a", gltfType: "vector4" }, b: { name: "b", gltfType: "vector4" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects) { serializedObjects[0].config ||= {}; serializedObjects[0].config.type = "Quaternion" /* FlowGraphTypes.Quaternion */; return serializedObjects; }, }, "math/quatAngleBetween": getSimpleInputMapping("FlowGraphAngleBetweenBlock" /* FlowGraphBlockNames.AngleBetween */, ["a", "b"]), "math/quatFromAxisAngle": { blocks: ["FlowGraphQuaternionFromAxisAngleBlock" /* FlowGraphBlockNames.QuaternionFromAxisAngle */], inputs: { values: { axis: { name: "a", gltfType: "float3" }, angle: { name: "b", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, }, "math/quatToAxisAngle": getSimpleInputMapping("FlowGraphAxisAngleFromQuaternionBlock" /* FlowGraphBlockNames.AxisAngleFromQuaternion */, ["a"]), "math/quatFromDirections": getSimpleInputMapping("FlowGraphQuaternionFromDirectionsBlock" /* FlowGraphBlockNames.QuaternionFromDirections */, ["a", "b"]), "math/combine2x2": { blocks: ["FlowGraphCombineMatrix2DBlock" /* FlowGraphBlockNames.CombineMatrix2D */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, c: { name: "input_2", gltfType: "number" }, d: { name: "input_3", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; serializedObjects[0].config.inputIsColumnMajor = true; return serializedObjects; }, }, "math/extract2x2": { blocks: ["FlowGraphExtractMatrix2DBlock" /* FlowGraphBlockNames.ExtractMatrix2D */], inputs: { values: { a: { name: "input", gltfType: "float2x2" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, "2": { name: "output_2" }, "3": { name: "output_3" }, }, }, }, "math/combine3x3": { blocks: ["FlowGraphCombineMatrix3DBlock" /* FlowGraphBlockNames.CombineMatrix3D */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, c: { name: "input_2", gltfType: "number" }, d: { name: "input_3", gltfType: "number" }, e: { name: "input_4", gltfType: "number" }, f: { name: "input_5", gltfType: "number" }, g: { name: "input_6", gltfType: "number" }, h: { name: "input_7", gltfType: "number" }, i: { name: "input_8", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; serializedObjects[0].config.inputIsColumnMajor = true; return serializedObjects; }, }, "math/extract3x3": { blocks: ["FlowGraphExtractMatrix3DBlock" /* FlowGraphBlockNames.ExtractMatrix3D */], inputs: { values: { a: { name: "input", gltfType: "float3x3" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, "2": { name: "output_2" }, "3": { name: "output_3" }, "4": { name: "output_4" }, "5": { name: "output_5" }, "6": { name: "output_6" }, "7": { name: "output_7" }, "8": { name: "output_8" }, }, }, }, "math/combine4x4": { blocks: ["FlowGraphCombineMatrixBlock" /* FlowGraphBlockNames.CombineMatrix */], inputs: { values: { a: { name: "input_0", gltfType: "number" }, b: { name: "input_1", gltfType: "number" }, c: { name: "input_2", gltfType: "number" }, d: { name: "input_3", gltfType: "number" }, e: { name: "input_4", gltfType: "number" }, f: { name: "input_5", gltfType: "number" }, g: { name: "input_6", gltfType: "number" }, h: { name: "input_7", gltfType: "number" }, i: { name: "input_8", gltfType: "number" }, j: { name: "input_9", gltfType: "number" }, k: { name: "input_10", gltfType: "number" }, l: { name: "input_11", gltfType: "number" }, m: { name: "input_12", gltfType: "number" }, n: { name: "input_13", gltfType: "number" }, o: { name: "input_14", gltfType: "number" }, p: { name: "input_15", gltfType: "number" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; serializedObjects[0].config.inputIsColumnMajor = true; return serializedObjects; }, }, "math/extract4x4": { blocks: ["FlowGraphExtractMatrixBlock" /* FlowGraphBlockNames.ExtractMatrix */], configuration: {}, inputs: { values: { a: { name: "input", gltfType: "number" }, }, }, outputs: { values: { "0": { name: "output_0" }, "1": { name: "output_1" }, "2": { name: "output_2" }, "3": { name: "output_3" }, "4": { name: "output_4" }, "5": { name: "output_5" }, "6": { name: "output_6" }, "7": { name: "output_7" }, "8": { name: "output_8" }, "9": { name: "output_9" }, "10": { name: "output_10" }, "11": { name: "output_11" }, "12": { name: "output_12" }, "13": { name: "output_13" }, "14": { name: "output_14" }, "15": { name: "output_15" }, }, }, }, "math/not": { blocks: ["FlowGraphBitwiseNotBlock" /* FlowGraphBlockNames.BitwiseNot */], inputs: { values: { a: { name: "a" }, }, }, outputs: { values: { value: { name: "value" }, }, }, extraProcessor(_gltfBlock, _declaration, _mapping, _parser, serializedObjects, context) { // configure it to work the way glTF specifies serializedObjects[0].config ||= {}; // try to infer the type or fallback to Integer const socketIn = serializedObjects[0].dataInputs[0]; serializedObjects[0].config.valueType = context._connectionValues[socketIn.uniqueId]?.type ?? "FlowGraphInteger" /* FlowGraphTypes.Integer */;