UNPKG

@polygonjs/polygonjs

Version:

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

100 lines (88 loc) 3.5 kB
/** * test the input value and checks if the number is infinite or Nan. * If the input is a vector, the output will be true if any of its component is infinite or Nan. * * * */ import {COMPONENTS_BY_GL_TYPE, ThreeToGl} from '../../../core/ThreeToGl'; import {ShadersCollectionController} from './code/utils/ShadersCollectionController'; import {GlConnectionPointType} from '../utils/io/connections/Gl'; import {FunctionGLDefinition} from './utils/GLDefinition'; // from https://www.shadertoy.com/view/lsjBDy const IS_INF_DEFINE = '#define isInf(x) ( (x) == (x)+1. )'; const IS_NAN_DEFINE = '#define isNaN(x) ( (x) != (x) )'; const DEFINES = [IS_INF_DEFINE, IS_NAN_DEFINE].join('\n'); const ALLOWED_INPUTS: GlConnectionPointType[] = [ GlConnectionPointType.FLOAT, GlConnectionPointType.VEC2, GlConnectionPointType.VEC3, GlConnectionPointType.VEC4, ]; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {TypedGlNode} from './_Base'; import {isBooleanTrue} from '../../../core/Type'; class IsInfOrNanGlParamsConfig extends NodeParamsConfig { testIsInf = ParamConfig.BOOLEAN(1); testIsNan = ParamConfig.BOOLEAN(1); } const ParamsConfig = new IsInfOrNanGlParamsConfig(); export class IsInfOrNanGlNode extends TypedGlNode<IsInfOrNanGlParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return 'isInfOrNan'; } static OUTPUT = 'out'; static INPUT = 'in'; override initializeNode() { super.initializeNode(); this.io.connection_points.set_input_name_function(() => IsInfOrNanGlNode.INPUT); this.io.connection_points.set_output_name_function(() => IsInfOrNanGlNode.OUTPUT); this.io.connection_points.set_expected_input_types_function(this._expected_input_types.bind(this)); this.io.connection_points.set_expected_output_types_function(() => [GlConnectionPointType.BOOL]); } private _expected_input_types() { const type = this.io.connection_points.first_input_connection_type() || GlConnectionPointType.FLOAT; if (ALLOWED_INPUTS.includes(type)) { return [type]; } else { return [GlConnectionPointType.FLOAT]; } } override setLines(shadersCollectionController: ShadersCollectionController) { const glOutType = GlConnectionPointType.BOOL; const out = this.glVarName(this.io.connection_points.output_name(0)); const bodyLine = `${glOutType} ${out} = ${this._functionCalls()}`; shadersCollectionController.addBodyLines(this, [bodyLine]); shadersCollectionController.addDefinitions(this, [new FunctionGLDefinition(this, DEFINES)]); } private _functionCalls() { const inValue = ThreeToGl.any(this.variableForInput(IsInfOrNanGlNode.INPUT)); const connectionPoints = this.io.inputs.namedInputConnectionPoints() if(!connectionPoints){return} const glInType = connectionPoints[0].type(); const testFunction = (inputVal: string) => { const functions: string[] = []; if (isBooleanTrue(this.pv.testIsInf)) { functions.push(`isInf(${inputVal})`); } if (isBooleanTrue(this.pv.testIsNan)) { functions.push(`isNaN(${inputVal})`); } if (functions.length > 0) { return functions.join(' || '); } else { return true; } }; const testFunctionsForComponents = (components: string[]) => { return components.map((c) => testFunction(`${inValue}.${c}`)).join(' || '); }; const components = COMPONENTS_BY_GL_TYPE[glInType]; if (components) { return testFunctionsForComponents(components); } else { return testFunction(inValue); } } }