@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
233 lines (212 loc) • 7.86 kB
text/typescript
/**
* 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) {}
}