UNPKG

polygonjs-engine

Version:

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

99 lines (94 loc) 3.71 kB
import {PolyDictionary} from '../../../types/GlobalTypes'; import {BaseNodeGlMathFunctionArg2GlNode} from './_BaseMathFunction'; import {GlConnectionPointType} from '../utils/io/connections/Gl'; import {FunctionGLDefinition} from './utils/GLDefinition'; interface MathArg2Options { in?: [string, string]; out?: string; default_in_type?: GlConnectionPointType; allowed_in_types?: GlConnectionPointType[]; out_type?: GlConnectionPointType; method?: string; functions?: string[]; } export function MathFunctionArg2Factory(type: string, options: MathArg2Options = {}) { const gl_method_name = options.method || type; const gl_output_name = options.out || 'val'; const gl_input_names = options.in || ['in0', 'in1']; const default_in_type = options.default_in_type; const allowed_in_types = options.allowed_in_types; const out_type = options.out_type; const functions = options.functions || []; 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)); if (out_type) { this.io.connection_points.set_expected_output_types_function(() => [out_type]); } } _gl_input_name(index: number): string { return gl_input_names[index]; } _gl_output_name(index: number): string { return gl_output_name; } gl_method_name(): string { return gl_method_name; } gl_function_definitions(): FunctionGLDefinition[] { if (functions) { return functions.map((f) => new FunctionGLDefinition(this, f)); } else { return []; } } _expected_input_types() { 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)) { // 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 = this.io.inputs.named_input_connection_points[0]; if (first_connection) { first_input_type = first_connection.type(); } else { first_input_type = default_in_type; } } } const type = first_input_type || default_in_type || GlConnectionPointType.FLOAT; return [type, type]; } }; } export class DistanceGlNode extends MathFunctionArg2Factory('distance', { in: ['p0', 'p1'], default_in_type: GlConnectionPointType.VEC3, allowed_in_types: [GlConnectionPointType.VEC2, GlConnectionPointType.VEC3, GlConnectionPointType.VEC4], out_type: GlConnectionPointType.FLOAT, }) {} export class DotGlNode extends MathFunctionArg2Factory('dot', { in: ['vec0', 'vec1'], default_in_type: GlConnectionPointType.VEC3, allowed_in_types: [GlConnectionPointType.VEC2, GlConnectionPointType.VEC3, GlConnectionPointType.VEC4], out_type: GlConnectionPointType.FLOAT, }) {} export class MaxGlNode extends MathFunctionArg2Factory('max') {} export class MinGlNode extends MathFunctionArg2Factory('min') {} export class ModGlNode extends MathFunctionArg2Factory('mod') { param_default_value(name: string) { return ({in1: 1} as PolyDictionary<number>)[name]; } } export class PowGlNode extends MathFunctionArg2Factory('pow', {in: ['x', 'y']}) {} export class ReflectGlNode extends MathFunctionArg2Factory('reflect', { in: ['I', 'N'], default_in_type: GlConnectionPointType.VEC3, }) {} export class StepGlNode extends MathFunctionArg2Factory('step', {in: ['edge', 'x']}) {}