UNPKG

@polygonjs/polygonjs

Version:

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

164 lines (163 loc) 6.26 kB
"use strict"; import { BaseNodeGlMathFunctionArg2GlNode } from "./_BaseMathFunction"; import { GlConnectionPointType } from "../utils/io/connections/Gl"; import { ThreeToGl } from "../../../core/ThreeToGl"; function MathFunctionArg2OperationFactory(type, options) { const in_prefix = options.in_prefix || type; const output_name = options.out || "val"; const operation = options.operation; const allowed_in_types = options.allowed_in_types; return class Node extends BaseNodeGlMathFunctionArg2GlNode { static type() { return type; } initializeNode() { super.initializeNode(); this.io.connection_points.set_input_name_function(this._gl_input_name.bind(this)); this.io.connection_points.set_output_name_function(this._gl_output_name.bind(this)); this.io.connection_points.set_expected_input_types_function(this._expected_input_types.bind(this)); this.io.connection_points.set_expected_output_types_function(this._expected_output_types.bind(this)); } setLines(shaders_collection_controller) { const inputConnectionPoints = this.io.inputs.namedInputConnectionPoints(); const outputConnectionPoints = this.io.outputs.namedOutputConnectionPoints(); if (!(inputConnectionPoints && outputConnectionPoints)) { return; } const firstConnectionPoint = outputConnectionPoints[0]; if (!firstConnectionPoint) { return; } const var_type = firstConnectionPoint.type(); const args = inputConnectionPoints.map((connection, i) => { const name = connection.name(); const variable = this.variableForInput(name); if (variable) { return ThreeToGl.any(variable); } }); const joined_args = args.join(` ${this.gl_operation()} `); const sum = this.glVarName(this.io.connection_points.output_name(0)); const body_line = `${var_type} ${sum} = ${this.gl_method_name()}(${joined_args})`; shaders_collection_controller.addBodyLines(this, [body_line]); } _gl_input_name(index) { return `${in_prefix}${index}`; } _gl_output_name(index) { return output_name; } gl_operation() { return operation; } _expected_input_types() { const inputConnectionPoints = this.io.inputs.namedInputConnectionPoints(); if (!inputConnectionPoints) { return []; } let first_input_type = this.io.connection_points.first_input_connection_type(); if (first_input_type && allowed_in_types) { if (!allowed_in_types.includes(first_input_type)) { const first_connection = inputConnectionPoints[0]; if (first_connection) { first_input_type = first_connection.type(); } } } const type2 = first_input_type || GlConnectionPointType.FLOAT; const current_connections = this.io.connections.existingInputConnections(); const expected_count = current_connections ? Math.max(current_connections.length + 1, 2) : 2; const expected_input_types = []; for (let i = 0; i < expected_count; i++) { expected_input_types.push(type2); } return expected_input_types; } _expected_output_types() { const input_types = this._expected_input_types(); const type2 = input_types[1] || input_types[0] || GlConnectionPointType.FLOAT; return [type2]; } }; } export class AddGlNode extends MathFunctionArg2OperationFactory("add", { in_prefix: "add", out: "sum", operation: "+" }) { } export class DivideGlNode extends MathFunctionArg2OperationFactory("divide", { in_prefix: "div", out: "divide", operation: "/" }) { paramDefaultValue(name) { return 1; } } export class SubtractGlNode extends MathFunctionArg2OperationFactory("subtract", { in_prefix: "sub", out: "subtract", operation: "-" }) { } export class MultGlNode extends MathFunctionArg2OperationFactory("mult", { in_prefix: "mult", out: "product", operation: "*" }) { static type() { return "mult"; } paramDefaultValue(name) { return 1; } initializeNode() { super.initializeNode(); this.io.connection_points.set_expected_input_types_function(this._expected_input_types.bind(this)); this.io.connection_points.set_expected_output_types_function(this._expected_output_types.bind(this)); } _expected_output_type() { const input_types = this._expected_input_types(); const type = input_types[input_types.length - 1]; return [type]; } _expected_input_types() { const input_connections = this.io.connections.existingInputConnections(); if (input_connections) { const first_connection = input_connections[0]; if (first_connection) { const firstConnectionOutputConnectionPoints = first_connection.nodeSrc().io.outputs.namedOutputConnectionPoints(); if (!firstConnectionOutputConnectionPoints) { return []; } const connection_point_for_first_connection = firstConnectionOutputConnectionPoints[first_connection.outputIndex()]; const type = connection_point_for_first_connection.type(); const expected_count = Math.max(input_connections.length + 1, 2); const empty_array = new Array(expected_count); if (type == GlConnectionPointType.FLOAT) { const second_connection = input_connections[1]; if (second_connection) { const secondConnectionOuputConnectionPoints = second_connection.nodeSrc().io.outputs.namedOutputConnectionPoints(); if (!secondConnectionOuputConnectionPoints) { return []; } const connection_point_for_second_connection = secondConnectionOuputConnectionPoints[second_connection.outputIndex()]; const second_type = connection_point_for_second_connection.type(); if (second_type == GlConnectionPointType.FLOAT) { return empty_array.fill(type); } else { return [type, second_type]; } } else { return [type, type]; } } else { return empty_array.fill(type); } } else { } } return [GlConnectionPointType.FLOAT, GlConnectionPointType.FLOAT]; } }