UNPKG

@polygonjs/polygonjs

Version:

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

233 lines (212 loc) 7.86 kB
/** * creates a for loop, executing the nodes inside it on each loop * * * */ import {TypedSubnetGlNode, TypedSubnetGlParamsConfigMixin} from './Subnet'; // import {GlConnectionPointType} from '../utils/io/connections/Gl'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {ShadersCollectionController} from './code/utils/ShadersCollectionController'; import {ThreeToGl} from '../../../core/ThreeToGl'; import {SubnetInputGlNode} from './SubnetInput'; import {PolyDictionary} from '../../../types/GlobalTypes'; import {GlConnectionPointType} from '../utils/io/connections/Gl'; import {isBooleanTrue} from '../../../core/Type'; import {GlType} from '../../poly/registers/nodes/types/Gl'; // import {ArrayUtils} from '../../../core/ArrayUtils'; enum ForLoopInput { START = 'start', MAX = 'max', STEP = 'step', I = 'i', } const DEFAULT_VALUES: PolyDictionary<number> = { [ForLoopInput.START]: 0, [ForLoopInput.MAX]: 10, [ForLoopInput.STEP]: 1, }; const OFFSET = 0; class ForLoopGlParamsConfig extends TypedSubnetGlParamsConfigMixin(NodeParamsConfig) { start = ParamConfig.FLOAT(0); max = ParamConfig.FLOAT(10, { range: [0, 100], rangeLocked: [false, false], }); step = ParamConfig.FLOAT(1); asFloat = ParamConfig.BOOLEAN(0, { separatorAfter: true, // hide the param until I can find a way for the subnet outputs // to change type when asFloat is true hidden: true, }); } const ParamsConfig = new ForLoopGlParamsConfig(); export class ForLoopGlNode extends TypedSubnetGlNode<ForLoopGlParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return GlType.FOR_LOOP; } override paramDefaultValue(name: string) { return DEFAULT_VALUES[name]; } override childExpectedInputConnectionPointTypes() { const {glType} = this._typesData(); const forLoopInputTypes: GlConnectionPointType[] = [glType, glType, glType, glType]; return forLoopInputTypes.concat(super._expectedInputTypes()); } override childExpectedInputConnectionPointName(index: number) { const forLoopInputNames: string[] = ['start', 'end', 'step', 'i']; if (index <= 3) { return forLoopInputNames[index]; } else { return super._expectedInputName(index - 4); } } // protected override _expectedInputsCount() { // const current_connections = this.io.connections.inputConnections(); // return current_connections ? ArrayUtils.compact(current_connections).length + 1 : 1; // } // protected override _expectedInputTypes(): GlConnectionPointType[] { // const types: GlConnectionPointType[] = [ // // GlConnectionPointType.FLOAT, // // GlConnectionPointType.FLOAT, // // GlConnectionPointType.FLOAT, // ]; // const default_type = GlConnectionPointType.FLOAT; // const current_connections = this.io.connections.inputConnections(); // const expected_count = this._expectedInputsCount(); // for (let i = OFFSET; i < expected_count; i++) { // if (current_connections) { // const connection = current_connections[i]; // if (connection) { // const type = connection.src_connection_point().type(); // types.push(type); // } else { // types.push(default_type); // } // } else { // types.push(default_type); // } // } // return types; // } // protected override _expectedOutputTypes() { // const types: GlConnectionPointType[] = []; // const input_types = this._expectedInputTypes(); // for (let i = OFFSET; i < input_types.length; i++) { // types.push(input_types[i]); // } // return types; // } // protected override _expectedInputName(index: number) { // // switch (index) { // // case 0: // // return ForLoopInput.START_INDEX; // // case 1: // // return ForLoopInput.MAX; // // case 2: // // return ForLoopInput.STEP; // // default: { // const connection = this.io.connections.inputConnection(index); // if (connection) { // const name = connection.src_connection_point().name(); // return name; // } else { // return `in${index}`; // } // // } // // } // } // protected override _expectedOutputName(index: number) { // return this._expectedInputName(index + OFFSET); // } // // // set_lines // // protected override setLinesBlockStart(shaders_collection_controller: ShadersCollectionController) { const body_lines: string[] = []; // const connection_points = this.io.inputs.namedInputConnectionPoints(); // for (let i = OFFSET; i < connection_points.length; i++) { // const connection_point = connection_points[i]; // const gl_type = connection_point.type(); // const out = this.glVarName(connection_point.name()); // const in_value = ThreeToGl.any(this.variableForInput(connection_point.name())); // const body_line = `${gl_type} ${out} = ${in_value}`; // body_lines.push(body_line); // } // const connections = this.io.connections.inputConnections(); // if (connections) { // for (let connection of connections) { // if (connection) { // if (connection.input_index >= OFFSET) { // const connection_point = connection.dest_connection_point(); // const in_value = ThreeToGl.any(this.variableForInput(connection_point.name())); // const gl_type = connection_point.type(); // const out = this.glVarName(connection_point.name()); // const body_line = `${gl_type} ${out} = ${in_value}`; // body_lines.push(body_line); // } // } // } // } const start: number = this.pv.start; const max: number = this.pv.max; const step: number = this.pv.step; const {glType, convertMethod} = this._typesData(); const start_str = convertMethod(start); const max_str = convertMethod(max); const step_str = convertMethod(step); const iterator_name = this.glVarName(ForLoopInput.I); const open_for_loop_line = `for(${glType} ${iterator_name} = ${start_str}; ${iterator_name} < ${max_str}; ${iterator_name}+= ${step_str}){`; body_lines.push(open_for_loop_line); shaders_collection_controller.addBodyLines(this, body_lines); } override setSubnetInputLines( shadersCollectionController: ShadersCollectionController, childNode: SubnetInputGlNode ) { const {glType, convertMethod} = this._typesData(); const body_lines: string[] = []; // i const iterator_name = this.glVarName(ForLoopInput.I); const i = childNode.glVarName(ForLoopInput.I); body_lines.push(` ${glType} ${i} = ${iterator_name}`); // start const start = childNode.glVarName(ForLoopInput.START); body_lines.push(` ${glType} ${start} = ${convertMethod(this.pv.start)}`); // end const max = childNode.glVarName(ForLoopInput.MAX); body_lines.push(` ${glType} ${max} = ${convertMethod(this.pv.max)}`); // step const step = childNode.glVarName(ForLoopInput.STEP); body_lines.push(` ${glType} ${step} = ${convertMethod(this.pv.step)}`); const connections = this.io.connections.inputConnections(); if (connections) { for (const connection of connections) { if (connection) { if (connection.inputIndex() >= OFFSET) { const connection_point = connection.destConnectionPoint(); if (connection_point) { const in_value = this.glVarName(connection_point.name()); const gl_type = connection_point.type(); const out = childNode.glVarName(connection_point.name()); const body_line = ` ${gl_type} ${out} = ${in_value}`; body_lines.push(body_line); } } } } } shadersCollectionController.addBodyLines(childNode, body_lines); } private _typesData() { const asFloat = isBooleanTrue(this.pv.asFloat); const convertMethod = asFloat ? ThreeToGl.float : ThreeToGl.integer; const glType = asFloat ? GlConnectionPointType.FLOAT : GlConnectionPointType.INT; return {convertMethod, glType}; } // override setLines(shaders_collection_controller: ShadersCollectionController) {} }