UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

116 lines (115 loc) 4.75 kB
"use strict"; import { BaseMathFunctionJsNode } from "./_BaseMathFunction"; import { JsConnectionPointType, isJsConnectionPointPrimitive, isJsConnectionPointVector, isJsConnectionPointNumber } from "../utils/io/connections/Js"; import { Poly } from "../../Poly"; const VECTOR_TYPES = [JsConnectionPointType.VECTOR2, JsConnectionPointType.VECTOR3, JsConnectionPointType.VECTOR4]; export function MathFunctionArgNOperationFactory(type, options) { const inputPrefix = options.inputPrefix || type; const outputName = options.out || "val"; const allowedInTypes = options.allowedInTypes; const operator = options.operator; return class Node extends BaseMathFunctionJsNode { static type() { return type; } initializeNode() { super.initializeNode(); this.io.connection_points.set_input_name_function(this._expectedInputName.bind(this)); this.io.connection_points.set_output_name_function(this._expectedOutputName.bind(this)); this.io.connection_points.set_expected_input_types_function(this._expectedInputTypes.bind(this)); this.io.connection_points.set_expected_output_types_function(this._expectedOutputTypes.bind(this)); } setLines(linesController) { const firstType = this._expectedInputTypes()[0]; const varName = this.jsVarName(outputName); const funcString = this._functionString(linesController); if (!funcString) { console.warn("no function found"); return; } linesController.addBodyOrComputed(this, [ { dataType: firstType, varName, value: funcString } ]); } _functionString(linesController) { const values = []; const connectionPoints = this.io.inputs.namedInputConnectionPoints(); if (!connectionPoints) { return; } for (let connectionPoint of connectionPoints) { const connectionPointName = connectionPoint.name(); const value = this.variableForInput(linesController, connectionPointName); values.push(value); } const expectedTypes = this._expectedInputTypes(); const firstType = expectedTypes[0]; const secondInputType = expectedTypes[1]; const isPrimitive = isJsConnectionPointPrimitive(firstType); if (isPrimitive) { return Poly.namedFunctionsRegister.getFunction(operator.primitive, this, linesController).asString(...values); } const isFirstInputVector = isJsConnectionPointVector(firstType); const isSecondInputScalar = secondInputType != null && isJsConnectionPointNumber(secondInputType); const isVectorScalar = isFirstInputVector && isSecondInputScalar; if (isVectorScalar) { return Poly.namedFunctionsRegister.getFunction(operator.vectorScalar, this, linesController).asString(values[0], values[1]); } if (operator.vector) { return Poly.namedFunctionsRegister.getFunction(operator.vector, this, linesController).asString(...values); } } _expectedInputName(index) { return `${inputPrefix}${index}`; } _expectedOutputName(index) { return outputName; } _expectedInputTypes() { let firstInputType = this.io.connection_points.first_input_connection_type(); const connectionPoints = this.io.inputs.namedInputConnectionPoints(); if (firstInputType && allowedInTypes && connectionPoints) { if (!allowedInTypes.includes(firstInputType)) { const firstConnection = connectionPoints[0]; if (firstConnection) { firstInputType = firstConnection.type(); } } } const type2 = firstInputType || JsConnectionPointType.FLOAT; if (VECTOR_TYPES.includes(type2)) { const secondInputType = this.io.connection_points.input_connection_type(1); if (secondInputType != null && secondInputType == JsConnectionPointType.FLOAT) { const expectedInputTypes2 = [type2, secondInputType]; return expectedInputTypes2; } } const currentConnections = this.io.connections.existingInputConnections(); const expectedCount = currentConnections ? Math.max(currentConnections.length + 1, 2) : 2; const expectedInputTypes = []; for (let i = 0; i < expectedCount; i++) { if (i == 0) { expectedInputTypes.push(type2); } else { const nextType = operator.vector != null ? type2 : JsConnectionPointType.FLOAT; expectedInputTypes.push(nextType); } } return expectedInputTypes; } _expectedOutputTypes() { const inputTypes = this._expectedInputTypes(); const type2 = inputTypes[0] || JsConnectionPointType.FLOAT; return [type2]; } }; }