UNPKG

@polygonjs/polygonjs

Version:

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

293 lines (272 loc) 11.1 kB
import {BaseMathFunctionJsNode} from './_BaseMathFunction'; import { JsConnectionPointType, isJsConnectionPointPrimitive, JsConnectionPointTypeToArrayTypeMap, isJsConnectionPointArray, JsConnectionPointTypeFromArrayTypeMap, } from '../utils/io/connections/Js'; import {JsLinesCollectionController} from './code/utils/JsLinesCollectionController'; // import {LocalFunctionJsDefinition} from './utils/JsDefinition'; // import {PolyDictionary} from '../../../types/GlobalTypes'; // import {createVariable} from './code/assemblers/_BaseJsPersistedConfigUtils'; // import {FunctionUtils} from '../../functions/_FunctionUtils'; import {Poly} from '../../Poly'; import {createVariable} from './code/assemblers/_BaseJsPersistedConfigUtils'; import { _vectorFunctionName_1, VectorFunctionName, MathVectorFunction, MathVectorFunction1, MathVectorFunction2, MathPrimArray, MathVectorArray, _vectorFunctionName_2, MathFloat, MathVectorFunction3, _vectorFunctionName_3, MathVectorFunction4, _vectorFunctionName_4, MathVectorFunction5, _vectorFunctionName_5, } from '../../functions/_MathGeneric'; // import {jsFunctionName} from './code/assemblers/JsTypeUtils'; // import {JsNodeTriggerContext} from './_Base'; // import {Vector2, Vector3, Vector4} from 'three'; // const tmpV2 = new Vector2(); // const tmpV3 = new Vector3(); // const tmpV4 = new Vector4(); // abstract class ArgBaseMathFunctionJsNode extends BaseMathFunctionJsNode { // protected _inputValuesCount() { // 0; // } // } interface MathArg1OperationOptions { inputPrefix: string; out: string; allowed_in_types?: JsConnectionPointType[]; // functionArg?: string; } export interface MathFunctionData<MVF extends MathVectorFunction> { vectorFunctionNameFunction: VectorFunctionName<MVF>; mathFloat: MathFloat; mathPrimArray: MathPrimArray; mathVectorArray: MathVectorArray; } // type PrimitiveJsConnectionPointType = JsConnectionPointType.BOOL | JsConnectionPointType.FLOAT; export const PRIMITIVE_ALLOWED_TYPES = [ JsConnectionPointType.INT, JsConnectionPointType.COLOR, JsConnectionPointType.FLOAT, JsConnectionPointType.VECTOR2, JsConnectionPointType.VECTOR3, JsConnectionPointType.VECTOR4, ]; const ARRAY_ALLOWED_TYPES = PRIMITIVE_ALLOWED_TYPES.map((type) => JsConnectionPointTypeToArrayTypeMap[type]); export const DEFAULT_ALLOWED_TYPES = [...PRIMITIVE_ALLOWED_TYPES, ...ARRAY_ALLOWED_TYPES]; export const FUNC_ARG_NAME = '_mathFunc'; export function MathFunctionArgXOperationFactory<MVF extends MathVectorFunction>( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { const inputPrefix = options.inputPrefix || type; const outputName = options.out || 'val'; const allowed_in_types = options.allowed_in_types || DEFAULT_ALLOWED_TYPES; // const functionArg = options.functionArg || `Math.${type}`; return class Node extends BaseMathFunctionJsNode { static override type() { return type; } override 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)); } override setLines(shadersCollectionController: JsLinesCollectionController) { const varName = this.jsVarName(this._expectedOutputName(0)); const inputType = this._expectedInputTypes()[0]; const variable = createVariable(inputType); const tmpVarName = variable != null ? shadersCollectionController.addVariable(this, variable) : undefined; const mainFunction = this._mainFunction(shadersCollectionController, tmpVarName); if (!mainFunction) { return; } shadersCollectionController.addBodyOrComputed(this, [{dataType: inputType, varName, value: mainFunction}]); } private _mainFunction(shadersCollectionController: JsLinesCollectionController, tmpVarName?: string) { const functionData = this._functionData(); const {vectorFunctionNameFunction, mathFloat, mathPrimArray, mathVectorArray} = functionData; // const arg0 = this.variableForInput(shadersCollectionController, this._expectedInputName(0)); const args = this._inputArgs(shadersCollectionController); const inputType = this._expectedInputTypes()[0]; const isPrimitive = isJsConnectionPointPrimitive(inputType); const coreFunction = this._coreFunction(shadersCollectionController); // primitive if (isPrimitive) { return Poly.namedFunctionsRegister .getFunction(mathFloat, this, shadersCollectionController) .asString(...[coreFunction, ...args]); } if (!tmpVarName) { return; } // color / vector const vectorFunctionName = vectorFunctionNameFunction(inputType); if (vectorFunctionName) { return Poly.namedFunctionsRegister .getFunction(vectorFunctionName, this, shadersCollectionController) .asString(...[coreFunction, ...args, tmpVarName]); } // array if (isJsConnectionPointArray(inputType)) { const elementInputType = JsConnectionPointTypeFromArrayTypeMap[inputType]; const vectorElementInputFunctionName = vectorFunctionNameFunction(elementInputType); if (vectorElementInputFunctionName) { // array color / vector Poly.namedFunctionsRegister .getFunction(vectorElementInputFunctionName, this, shadersCollectionController) // we call .asString to ensure the function is added to the shadersCollectionController .asString('', '', ''); return Poly.namedFunctionsRegister .getFunction(mathVectorArray, this, shadersCollectionController) .asString(...[coreFunction, vectorElementInputFunctionName, ...args, tmpVarName]); } else { // array primitive return Poly.namedFunctionsRegister .getFunction(mathPrimArray, this, shadersCollectionController) .asString(...[coreFunction, ...args, tmpVarName]); } } } protected _coreFunction(shadersCollectionController: JsLinesCollectionController) { return `Math.${type}`; } protected _functionData(): MathFunctionData<MVF> { return { vectorFunctionNameFunction: _vectorFunctionName_1 as VectorFunctionName<MVF>, mathFloat: 'mathFloat_1', mathPrimArray: 'mathPrimArray_1', mathVectorArray: 'mathVectorArray_1', }; } protected _inputValuesCount() { const inputTypes = this._expectedInputTypes(); const inputValuesCount = inputTypes.length; return inputValuesCount; } private _inputArgs(shadersCollectionController: JsLinesCollectionController) { const inputValuesCount = this._inputValuesCount(); const inputArgs: string[] = []; for (let i = 0; i < inputValuesCount; i++) { const arg = this.variableForInput(shadersCollectionController, this._expectedInputName(i)); inputArgs.push(arg); } return inputArgs; } override _expectedInputName(index: number): string { return inputPrefix; } override _expectedOutputName(index: number): string { return outputName; } protected override _expectedInputTypes() { let first_input_type = this.io.connection_points.first_input_connection_type(); const connectionPoints = this.io.inputs.namedInputConnectionPoints(); if (first_input_type && connectionPoints) { if (!allowed_in_types.includes(first_input_type)) { // if the first input type is not allowed, either leave the connection point as is, // or use the default if there is none const first_connection = connectionPoints[0]; if (first_connection) { first_input_type = first_connection.type(); } } } const type = first_input_type || JsConnectionPointType.FLOAT; return [type]; } protected override _expectedOutputTypes() { return [this._expectedInputTypes()[0]]; } }; } export function MathFunctionArg1OperationFactory( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { return class Node extends MathFunctionArgXOperationFactory<MathVectorFunction1>(type, options) {}; } export function MathFunctionArg2OperationFactory( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { return class Node extends MathFunctionArgXOperationFactory<MathVectorFunction2>(type, options) { // TODO: this should ideally be inherited from the class created by MathFunctionArgXOperationFactory // and would therefore require an override statement, // and would then automatically have the return type FunctionData<MathVectorFunction2> protected _functionData(): MathFunctionData<MathVectorFunction2> { return { vectorFunctionNameFunction: _vectorFunctionName_2, mathFloat: 'mathFloat_2', mathPrimArray: 'mathPrimArray_2', mathVectorArray: 'mathVectorArray_2', }; } }; } export function MathFunctionArg3OperationFactory( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { return class Node extends MathFunctionArgXOperationFactory<MathVectorFunction3>(type, options) { // TODO: this should ideally be inherited from the class created by MathFunctionArgXOperationFactory // and would therefore require an override statement, // and would then automatically have the return type FunctionData<MathVectorFunction2> protected _functionData(): MathFunctionData<MathVectorFunction3> { return { vectorFunctionNameFunction: _vectorFunctionName_3, mathFloat: 'mathFloat_3', mathPrimArray: 'mathPrimArray_3', mathVectorArray: 'mathVectorArray_3', }; } }; } export function MathFunctionArg4OperationFactory( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { return class Node extends MathFunctionArgXOperationFactory<MathVectorFunction4>(type, options) { // TODO: this should ideally be inherited from the class created by MathFunctionArgXOperationFactory // and would therefore require an override statement, // and would then automatically have the return type FunctionData<MathVectorFunction2> protected _functionData(): MathFunctionData<MathVectorFunction4> { return { vectorFunctionNameFunction: _vectorFunctionName_4, mathFloat: 'mathFloat_4', mathPrimArray: 'mathPrimArray_4', mathVectorArray: 'mathVectorArray_4', }; } }; } export function MathFunctionArg5OperationFactory( type: string, options: MathArg1OperationOptions ): typeof BaseMathFunctionJsNode { return class Node extends MathFunctionArgXOperationFactory<MathVectorFunction5>(type, options) { // TODO: this should ideally be inherited from the class created by MathFunctionArgXOperationFactory // and would therefore require an override statement, // and would then automatically have the return type FunctionData<MathVectorFunction2> protected _functionData(): MathFunctionData<MathVectorFunction5> { return { vectorFunctionNameFunction: _vectorFunctionName_5, mathFloat: 'mathFloat_5', mathPrimArray: 'mathPrimArray_5', mathVectorArray: 'mathVectorArray_5', }; } }; }