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.

559 lines (553 loc) 26.3 kB
import { j as _GetClassNameOf, F as FlowGraphBlock } from './KHR_interactivity-CnR665Qq.esm.js'; import { R as RichTypeAny, d as RichTypeNumber, h as RichTypeQuaternion, f as RichTypeVector3, a as RichTypeBoolean, i as RichTypeMatrix, g as getRichTypeByFlowGraphType, p as RichTypeVector2 } from './declarationMapper-mPOKbCS_.esm.js'; import { F as FlowGraphBinaryOperationBlock } from './flowGraphBinaryOperationBlock-5TY0sBGP.esm.js'; import { F as FlowGraphUnaryOperationBlock } from './flowGraphUnaryOperationBlock-DApXbJAT.esm.js'; import { F as FlowGraphTernaryOperationBlock } from './flowGraphTernaryOperationBlock-CIRJESGF.esm.js'; import { F as FlowGraphCachedOperationBlock } from './flowGraphCachedOperationBlock-DSj_4V2c.esm.js'; import { V as Vector3, aD as Quaternion, b3 as Vector2, M as Matrix, j as Clamp, bc as Vector4, u as RegisterClass } from './index-HyNDfLMI.esm.js'; import './objectModelMapping-OlchA9xj.esm.js'; import './spotLight.pure-C65PiYTZ.esm.js'; /** * Creates a string representation of the IVector2Like * @param vector defines the IVector2Like to stringify * @param decimalCount defines the number of decimals to use * @returns a string with the IVector2Like coordinates. */ /** * Computes the dot product of two IVector3Like objects. * @param a defines the first vector * @param b defines the second vector * @returns the dot product */ function Vector3Dot(a, b) { return a.x * b.x + a.y * b.y + a.z * b.z; } /** * Computes the dot product of two IVector4Like objects * @param a defines the first vector * @param b defines the second vector * @returns the dot product */ function Vector4Dot(a, b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } // *** NOTE *** // These functions should ideally go in math.vector.functions.ts, but they require math.vector.ts to // be imported which is big. To avoid the larger bundle size, they are kept inside flow graph for now. /** * Implementation-defined threshold used by the slerp and up/forward quaternion operations * to detect near-zero lengths and (anti)parallel vectors. */ const SlerpEpsilon = 1e-6; /** * Returns a unit vector perpendicular to the provided vector. * @param v the input vector (does not need to be unit length) * @returns a unit vector perpendicular to `v` */ function GetAnyPerpendicularVector(v) { const absX = Math.abs(v.x); const absY = Math.abs(v.y); const absZ = Math.abs(v.z); // Cross with whichever cardinal axis is least aligned with `v` to avoid a degenerate cross product. let other; if (absX <= absY && absX <= absZ) { other = Vector3.RightReadOnly; } else if (absY <= absZ) { other = Vector3.UpReadOnly; } else { other = Vector3.LeftHandedForwardReadOnly; } return Vector3.Cross(v, other).normalize(); } /** * Returns the angle in radians between two quaternions * @param q1 defines the first quaternion * @param q2 defines the second quaternion * @returns the angle in radians between the two quaternions */ function GetAngleBetweenQuaternions(q1, q2) { return Math.acos(Clamp(Vector4Dot(q1, q2), -1, 1)) * 2; } /** * Creates a quaternion from two direction vectors * @param a defines the first direction vector * @param b defines the second direction vector * @returns the target quaternion */ function GetQuaternionFromDirections(a, b) { const result = new Quaternion(); GetQuaternionFromDirectionsToRef(a, b, result); return result; } /** * Creates a quaternion from two direction vectors * @param a defines the first direction vector * @param b defines the second direction vector * @param result defines the target quaternion * @returns the target quaternion */ function GetQuaternionFromDirectionsToRef(a, b, result) { const dot = Vector3Dot(a, b); if (Number.isFinite(dot) && dot > 1 - SlerpEpsilon) { result.copyFromFloats(0, 0, 0, 1); return result; } if (Number.isFinite(dot) && dot < -1 + SlerpEpsilon) { const axis = GetAnyPerpendicularVector(a); result.copyFromFloats(axis.x, axis.y, axis.z, 0); return result; } const axis = Vector3.Cross(a, b).normalize(); const axisScale = Math.sqrt(0.5 - 0.5 * dot); result.copyFromFloats(axis.x * axisScale, axis.y * axisScale, axis.z * axisScale, Math.sqrt(0.5 + 0.5 * dot)); return result; } /** * Spherical linear interpolation between two 2D vectors. * NaN and infinity values are propagated through the arithmetic. * @param a the first vector * @param b the second vector * @param c the (unclamped) interpolation coefficient * @returns the interpolated 2D vector */ function GetVector2Slerp(a, b, c) { const lengthA = Math.sqrt(a.x * a.x + a.y * a.y); const lengthB = Math.sqrt(b.x * b.x + b.y * b.y); // If either vector is (close to) zero length the rotation is undefined; fall back to a linear interpolation. if (lengthA < SlerpEpsilon || lengthB < SlerpEpsilon) { return new Vector2((1 - c) * a.x + c * b.x, (1 - c) * a.y + c * b.y); } const aHatX = a.x / lengthA; const aHatY = a.y / lengthA; const bHatX = b.x / lengthB; const bHatY = b.y / lengthB; let theta = Math.acos(Clamp(aHatX * bHatX + aHatY * bHatY, -1, 1)); if (aHatX * bHatY - aHatY * bHatX < 0) { theta = -theta; } const length = (1 - c) * lengthA + c * lengthB; const cosCTheta = Math.cos(c * theta); const sinCTheta = Math.sin(c * theta); return new Vector2((aHatX * cosCTheta - aHatY * sinCTheta) * length, (aHatX * sinCTheta + aHatY * cosCTheta) * length); } /** * Spherical linear interpolation between two 3D vectors. * NaN and infinity values are propagated through the arithmetic. * @param a the first vector * @param b the second vector * @param c the (unclamped) interpolation coefficient * @returns the interpolated 3D vector */ function GetVector3Slerp(a, b, c) { const lengthA = a.length(); const lengthB = b.length(); const lerp = () => new Vector3((1 - c) * a.x + c * b.x, (1 - c) * a.y + c * b.y, (1 - c) * a.z + c * b.z); // If either vector is (close to) zero length the rotation is undefined; fall back to a linear interpolation. if (lengthA < SlerpEpsilon || lengthB < SlerpEpsilon) { return lerp(); } const aHat = new Vector3(a.x / lengthA, a.y / lengthA, a.z / lengthA); const bHat = new Vector3(b.x / lengthB, b.y / lengthB, b.z / lengthB); const dot = Vector3Dot(aHat, bHat); // Parallel vectors share a direction; a linear interpolation already produces the correct result. if (dot > 1 - SlerpEpsilon) { return lerp(); } let rotationAxis; if (dot < -1 + SlerpEpsilon) { // Anti-parallel vectors: any axis perpendicular to aHat is a valid rotation axis. rotationAxis = GetAnyPerpendicularVector(aHat); } else { rotationAxis = Vector3.Cross(aHat, bHat).normalize(); } const angle = c * Math.acos(Clamp(dot, -1, 1)); const rotation = Quaternion.RotationAxis(rotationAxis, angle); const length = (1 - c) * lengthA + c * lengthB; return aHat.applyRotationQuaternion(rotation).scaleInPlace(length); } /** * Creates a quaternion from the specified up and forward directions, as defined by the * up/forward quaternion operation. Both inputs are assumed to be unit length. * @param up the up direction * @param forward the forward direction * @returns the rotation quaternion */ function GetQuaternionFromUpForward(up, forward) { const r = new Vector3(forward.x, forward.y, forward.z); let s = Vector3.Cross(up, r); if (s.lengthSquared() < SlerpEpsilon * SlerpEpsilon) { // up and forward are colinear; pick any unit vector perpendicular to forward. s = GetAnyPerpendicularVector(r); } else { s.normalize(); } const t = Vector3.Cross(r, s); // Build the rotation matrix with columns s, t and r (Babylon matrices are column-major) and convert it. const matrix = Matrix.FromValues(s.x, s.y, s.z, 0, t.x, t.y, t.z, 0, r.x, r.y, r.z, 0, 0, 0, 0, 1); return Quaternion.FromRotationMatrix(matrix); } /** * The rotation orders accepted by the Euler-angle quaternion operation * (and {@link GetQuaternionFromEulerAngles}). The default order is `yxz`. */ const QuaternionEulerAngleOrders = ["xyz", "xzy", "yxz", "yzx", "zxy", "zyx"]; /** * Builds a rotation quaternion from three Tait–Bryan intrinsic Euler angles applied in the * specified order. * * Babylon only exposes the `yxz` order natively (via `Quaternion.RotationYawPitchRoll`), so the * result is composed from the individual per-axis rotations to support every order. For an * intrinsic order `o1o2o3` the result is the Hamilton product `q(o1) * q(o2) * q(o3)`, where each * `q(axis)` is a rotation about that axis; this matches the corresponding reference intrinsic * Tait–Bryan rotation matrices. NaN and infinite angle inputs propagate into the result. * @param order the rotation order, one of {@link QuaternionEulerAngleOrders}; any other value uses the default `yxz` * @param x rotation around the X axis, in radians * @param y rotation around the Y axis, in radians * @param z rotation around the Z axis, in radians * @returns the composed rotation quaternion */ function GetQuaternionFromEulerAngles(order, x, y, z) { const qx = Quaternion.RotationAxis(Vector3.RightReadOnly, x); const qy = Quaternion.RotationAxis(Vector3.UpReadOnly, y); const qz = Quaternion.RotationAxis(Vector3.LeftHandedForwardReadOnly, z); // `a.multiplyInPlace(b)` computes the Hamilton product `a * b` in place and returns `a`. switch (order) { case "xyz": return qx.multiplyInPlace(qy).multiplyInPlace(qz); case "xzy": return qx.multiplyInPlace(qz).multiplyInPlace(qy); case "yzx": return qy.multiplyInPlace(qz).multiplyInPlace(qx); case "zxy": return qz.multiplyInPlace(qx).multiplyInPlace(qy); case "zyx": return qz.multiplyInPlace(qy).multiplyInPlace(qx); case "yxz": default: // Default order. return qy.multiplyInPlace(qx).multiplyInPlace(qz); } } /** This file must only contain pure code and pure imports */ const AxisCacheName = "cachedOperationAxis"; const AngleCacheName = "cachedOperationAngle"; const CacheExecIdName = "cachedExecutionId"; /** * Vector length block. */ class FlowGraphLengthBlock extends FlowGraphUnaryOperationBlock { constructor(config) { super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicLength(a), "FlowGraphLengthBlock" /* FlowGraphBlockNames.Length */, config); } _polymorphicLength(a) { const aClassName = _GetClassNameOf(a); switch (aClassName) { case "Vector2" /* FlowGraphTypes.Vector2 */: case "Vector3" /* FlowGraphTypes.Vector3 */: case "Vector4" /* FlowGraphTypes.Vector4 */: case "Quaternion" /* FlowGraphTypes.Quaternion */: return a.length(); default: throw new Error(`Cannot compute length of value ${a}`); } } } /** * Vector normalize block. */ class FlowGraphNormalizeBlock extends FlowGraphCachedOperationBlock { constructor(config) { super(RichTypeAny, config); this.a = this.registerDataInput("a", RichTypeAny); } _doOperation(context) { return this._polymorphicNormalize(this.a.getValue(context)); } /** * A vector that cannot be normalized reports a vector of the same type with every component set * to zero, so the output stays type-consistent with the input instead of being left undefined. * @param context the graph context * @returns a zero vector matching the input's type */ _getInvalidOutputValue(context) { const a = this.a.getValue(context); switch (_GetClassNameOf(a)) { case "Vector2" /* FlowGraphTypes.Vector2 */: return new Vector2(0, 0); case "Vector4" /* FlowGraphTypes.Vector4 */: return new Vector4(0, 0, 0, 0); case "Quaternion" /* FlowGraphTypes.Quaternion */: return new Quaternion(0, 0, 0, 0); default: return new Vector3(0, 0, 0); } } _polymorphicNormalize(a) { const aClassName = _GetClassNameOf(a); switch (aClassName) { case "Vector2" /* FlowGraphTypes.Vector2 */: case "Vector3" /* FlowGraphTypes.Vector3 */: case "Vector4" /* FlowGraphTypes.Vector4 */: case "Quaternion" /* FlowGraphTypes.Quaternion */: { // Normalization is only valid when the length is a positive finite number. For zero, NaN, or // +Infinity length the operation is invalid: returning undefined makes the cached base report // isValid = false and deliver a zero vector of the same type on `value`. const length = a.length(); if (length === 0 || !Number.isFinite(length)) { if (this.config?.nanOnZeroLength) { // Legacy behavior preserved for consumers that opt into NaN output. const nanVector = a.normalizeToNew(); nanVector.setAll(NaN); return nanVector; } return undefined; } return a.normalizeToNew(); } default: throw new Error(`Cannot normalize value ${a}`); } } getClassName() { return "FlowGraphNormalizeBlock" /* FlowGraphBlockNames.Normalize */; } } /** * Dot product block. */ class FlowGraphDotBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeAny, RichTypeAny, RichTypeNumber, (a, b) => this._polymorphicDot(a, b), "FlowGraphDotBlock" /* FlowGraphBlockNames.Dot */, config); } _polymorphicDot(a, b) { const className = _GetClassNameOf(a); switch (className) { case "Vector2" /* FlowGraphTypes.Vector2 */: case "Vector3" /* FlowGraphTypes.Vector3 */: case "Vector4" /* FlowGraphTypes.Vector4 */: case "Quaternion" /* FlowGraphTypes.Quaternion */: // casting is needed because dot requires both to be the same type return a.dot(b); default: throw new Error(`Cannot get dot product of ${a} and ${b}`); } } } /** * Cross product block. */ class FlowGraphCrossBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeVector3, RichTypeVector3, (a, b) => Vector3.Cross(a, b), "FlowGraphCrossBlock" /* FlowGraphBlockNames.Cross */, config); } } /** * 2D rotation block. */ class FlowGraphRotate2DBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector2, RichTypeNumber, RichTypeVector2, (a, b) => a.rotate(b), "FlowGraphRotate2DBlock" /* FlowGraphBlockNames.Rotate2D */, config); } } /** * 3D rotation block. */ class FlowGraphRotate3DBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeQuaternion, RichTypeVector3, (a, b) => a.applyRotationQuaternion(b), "FlowGraphRotate3DBlock" /* FlowGraphBlockNames.Rotate3D */, config); } } function TransformVector(a, b) { const className = _GetClassNameOf(a); switch (className) { case "Vector2" /* FlowGraphTypes.Vector2 */: return b.transformVector(a); case "Vector3" /* FlowGraphTypes.Vector3 */: return b.transformVector(a); case "Vector4" /* FlowGraphTypes.Vector4 */: a = a; // transform the vector 4 with the matrix here. Vector4.TransformCoordinates transforms a 3D coordinate, not Vector4. // Babylon's Matrix stores its elements column-major (m[0..3] is the first column), and the incoming // float4x4 values are column-major as well, so M * a reads down the columns: value[i] = sum_j M[i][j] * a[j] // with M[i][j] = m[j * 4 + i]. return new Vector4(a.x * b.m[0] + a.y * b.m[4] + a.z * b.m[8] + a.w * b.m[12], a.x * b.m[1] + a.y * b.m[5] + a.z * b.m[9] + a.w * b.m[13], a.x * b.m[2] + a.y * b.m[6] + a.z * b.m[10] + a.w * b.m[14], a.x * b.m[3] + a.y * b.m[7] + a.z * b.m[11] + a.w * b.m[15]); default: throw new Error(`Cannot transform value ${a}`); } } /** * Transform a vector3 by a matrix. */ class FlowGraphTransformBlock extends FlowGraphBinaryOperationBlock { constructor(config) { const vectorType = config?.vectorType || "Vector3" /* FlowGraphTypes.Vector3 */; const matrixType = vectorType === "Vector2" /* FlowGraphTypes.Vector2 */ ? "Matrix2D" /* FlowGraphTypes.Matrix2D */ : vectorType === "Vector3" /* FlowGraphTypes.Vector3 */ ? "Matrix3D" /* FlowGraphTypes.Matrix3D */ : "Matrix" /* FlowGraphTypes.Matrix */; super(getRichTypeByFlowGraphType(vectorType), getRichTypeByFlowGraphType(matrixType), getRichTypeByFlowGraphType(vectorType), TransformVector, "FlowGraphTransformVectorBlock" /* FlowGraphBlockNames.TransformVector */, config); } } /** * Transform a vector3 by a matrix. */ class FlowGraphTransformCoordinatesBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeMatrix, RichTypeVector3, (a, b) => Vector3.TransformCoordinates(a, b), "FlowGraphTransformCoordinatesBlock" /* FlowGraphBlockNames.TransformCoordinates */, config); } } /** * Conjugate the quaternion. */ class FlowGraphConjugateBlock extends FlowGraphUnaryOperationBlock { constructor(config) { super(RichTypeQuaternion, RichTypeQuaternion, (a) => a.conjugate(), "FlowGraphConjugateBlock" /* FlowGraphBlockNames.Conjugate */, config); } } /** * Get the angle between two quaternions. */ class FlowGraphAngleBetweenBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeQuaternion, RichTypeQuaternion, RichTypeNumber, (a, b) => GetAngleBetweenQuaternions(a, b), "FlowGraphAngleBetweenBlock" /* FlowGraphBlockNames.AngleBetween */, config); } } /** * Get the quaternion from an axis and an angle. */ class FlowGraphQuaternionFromAxisAngleBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeNumber, RichTypeQuaternion, (a, b) => Quaternion.RotationAxis(a, b), "FlowGraphQuaternionFromAxisAngleBlock" /* FlowGraphBlockNames.QuaternionFromAxisAngle */, config); } } /** * Get the axis and angle from a quaternion. */ class FlowGraphAxisAngleFromQuaternionBlock extends FlowGraphBlock { constructor(config) { super(config); this.a = this.registerDataInput("a", RichTypeQuaternion); this.axis = this.registerDataOutput("axis", RichTypeVector3); this.angle = this.registerDataOutput("angle", RichTypeNumber); this.isValid = this.registerDataOutput("isValid", RichTypeBoolean); } /** @override */ _updateOutputs(context) { const cachedExecutionId = context._getExecutionVariable(this, CacheExecIdName, -1); const cachedAxis = context._getExecutionVariable(this, AxisCacheName, null); const cachedAngle = context._getExecutionVariable(this, AngleCacheName, null); if (cachedAxis !== undefined && cachedAxis !== null && cachedAngle !== undefined && cachedAngle !== null && cachedExecutionId === context.executionId) { this.axis.setValue(cachedAxis, context); this.angle.setValue(cachedAngle, context); } else { try { const { axis, angle } = this.a.getValue(context).toAxisAngle(); context._setExecutionVariable(this, AxisCacheName, axis); context._setExecutionVariable(this, AngleCacheName, angle); context._setExecutionVariable(this, CacheExecIdName, context.executionId); this.axis.setValue(axis, context); this.angle.setValue(angle, context); this.isValid.setValue(true, context); } catch (e) { this.isValid.setValue(false, context); } } } /** * Gets the class name * @override * @returns the class name */ getClassName() { return "FlowGraphAxisAngleFromQuaternionBlock" /* FlowGraphBlockNames.AxisAngleFromQuaternion */; } } /** * Get the quaternion from two direction vectors. */ class FlowGraphQuaternionFromDirectionsBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeVector3, RichTypeQuaternion, (a, b) => GetQuaternionFromDirections(a, b), "FlowGraphQuaternionFromDirectionsBlock" /* FlowGraphBlockNames.QuaternionFromDirections */, config); } } /** * Get a rotation quaternion from the specified up and forward directions. */ class FlowGraphQuaternionFromUpForwardBlock extends FlowGraphBinaryOperationBlock { constructor(config) { super(RichTypeVector3, RichTypeVector3, RichTypeQuaternion, (up, forward) => GetQuaternionFromUpForward(up, forward), "FlowGraphQuaternionFromUpForwardBlock" /* FlowGraphBlockNames.QuaternionFromUpForward */, config); } } /** * Spherical linear interpolation between two vectors. * Supports float2 and float3 vectors; the interpolation coefficient is a number. */ class FlowGraphVectorSlerpBlock extends FlowGraphTernaryOperationBlock { constructor(config) { super(RichTypeAny, RichTypeAny, RichTypeNumber, RichTypeAny, (a, b, c) => this._polymorphicSlerp(a, b, c), "FlowGraphVectorSlerpBlock" /* FlowGraphBlockNames.VectorSlerp */, config); } _polymorphicSlerp(a, b, c) { const className = _GetClassNameOf(a); switch (className) { case "Vector2" /* FlowGraphTypes.Vector2 */: return GetVector2Slerp(a, b, c); case "Vector3" /* FlowGraphTypes.Vector3 */: return GetVector3Slerp(a, b, c); default: throw new Error(`Cannot slerp value ${a}`); } } } /** * Creates a rotation quaternion from three Tait–Bryan intrinsic Euler angles applied in a * configurable order. * * Inputs `a`, `b`, `c` are the rotations (in radians) around the X, Y and Z axes respectively. * The `order` configuration selects the intrinsic rotation order; NaN and infinite inputs * propagate into the resulting quaternion components. */ class FlowGraphQuaternionFromAnglesBlock extends FlowGraphTernaryOperationBlock { constructor(config) { super(RichTypeNumber, RichTypeNumber, RichTypeNumber, RichTypeQuaternion, (a, b, c) => GetQuaternionFromEulerAngles(this._order, a, b, c), "FlowGraphQuaternionFromAnglesBlock" /* FlowGraphBlockNames.QuaternionFromAngles */, config); const order = config?.order; // A missing, non-string or unrecognized order falls back to the default `yxz`. this._order = typeof order === "string" && QuaternionEulerAngleOrders.indexOf(order) !== -1 ? order : "yxz"; } } let _Registered = false; /** * Register side effects for flowGraphVectorMathBlocks. * Safe to call multiple times; only the first call has an effect. */ function RegisterFlowGraphVectorMathBlocks() { if (_Registered) { return; } _Registered = true; RegisterClass("FlowGraphLengthBlock" /* FlowGraphBlockNames.Length */, FlowGraphLengthBlock); RegisterClass("FlowGraphNormalizeBlock" /* FlowGraphBlockNames.Normalize */, FlowGraphNormalizeBlock); RegisterClass("FlowGraphDotBlock" /* FlowGraphBlockNames.Dot */, FlowGraphDotBlock); RegisterClass("FlowGraphCrossBlock" /* FlowGraphBlockNames.Cross */, FlowGraphCrossBlock); RegisterClass("FlowGraphRotate2DBlock" /* FlowGraphBlockNames.Rotate2D */, FlowGraphRotate2DBlock); RegisterClass("FlowGraphRotate3DBlock" /* FlowGraphBlockNames.Rotate3D */, FlowGraphRotate3DBlock); RegisterClass("FlowGraphTransformVectorBlock" /* FlowGraphBlockNames.TransformVector */, FlowGraphTransformBlock); RegisterClass("FlowGraphTransformCoordinatesBlock" /* FlowGraphBlockNames.TransformCoordinates */, FlowGraphTransformCoordinatesBlock); RegisterClass("FlowGraphConjugateBlock" /* FlowGraphBlockNames.Conjugate */, FlowGraphConjugateBlock); RegisterClass("FlowGraphAngleBetweenBlock" /* FlowGraphBlockNames.AngleBetween */, FlowGraphAngleBetweenBlock); RegisterClass("FlowGraphQuaternionFromAxisAngleBlock" /* FlowGraphBlockNames.QuaternionFromAxisAngle */, FlowGraphQuaternionFromAxisAngleBlock); RegisterClass("FlowGraphAxisAngleFromQuaternionBlock" /* FlowGraphBlockNames.AxisAngleFromQuaternion */, FlowGraphAxisAngleFromQuaternionBlock); RegisterClass("FlowGraphQuaternionFromDirectionsBlock" /* FlowGraphBlockNames.QuaternionFromDirections */, FlowGraphQuaternionFromDirectionsBlock); RegisterClass("FlowGraphQuaternionFromUpForwardBlock" /* FlowGraphBlockNames.QuaternionFromUpForward */, FlowGraphQuaternionFromUpForwardBlock); RegisterClass("FlowGraphQuaternionFromAnglesBlock" /* FlowGraphBlockNames.QuaternionFromAngles */, FlowGraphQuaternionFromAnglesBlock); RegisterClass("FlowGraphVectorSlerpBlock" /* FlowGraphBlockNames.VectorSlerp */, FlowGraphVectorSlerpBlock); } /** * Re-exports pure implementation and applies runtime side effects. * Import flowGraphVectorMathBlocks.pure for tree-shakeable, side-effect-free usage. */ RegisterFlowGraphVectorMathBlocks(); export { FlowGraphAngleBetweenBlock, FlowGraphAxisAngleFromQuaternionBlock, FlowGraphConjugateBlock, FlowGraphCrossBlock, FlowGraphDotBlock, FlowGraphLengthBlock, FlowGraphNormalizeBlock, FlowGraphQuaternionFromAnglesBlock, FlowGraphQuaternionFromAxisAngleBlock, FlowGraphQuaternionFromDirectionsBlock, FlowGraphQuaternionFromUpForwardBlock, FlowGraphRotate2DBlock, FlowGraphRotate3DBlock, FlowGraphTransformBlock, FlowGraphTransformCoordinatesBlock, FlowGraphVectorSlerpBlock, RegisterFlowGraphVectorMathBlocks }; //# sourceMappingURL=flowGraphVectorMathBlocks-DvMUrnBo.esm.js.map