@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
116 lines (115 loc) • 4.75 kB
JavaScript
"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];
}
};
}