UNPKG

@polygonjs/polygonjs

Version:

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

151 lines (135 loc) 5.16 kB
/** * Steps through a particles simulation * * */ import {TypedJsNode} from './_Base'; import {inputObject3D, setObject3DOutputLine} from './_BaseObject3D'; import {JsLinesCollectionController} from './code/utils/JsLinesCollectionController'; import {Poly} from '../../Poly'; import {ParamConfig} from '../utils/params/ParamsConfig'; import {PolyNodeParamsConfig} from '../utils/poly/PolyNodeParamsConfig'; import {JsConnectionPointType} from '../utils/io/connections/Js'; import {GPUComputationConfigRefString} from '../../../core/particles/gpuCompute/GPUComputationRenderer'; import {ConstantJsDefinition} from './utils/JsDefinition'; import {rangeStartEnd} from '../../../core/ArrayUtils'; import {StringParam} from '../../params/String'; import {TEXTURE_ALLOCATION_PREFIX} from '../gl/code/utils/TextureAllocation'; function visibleIfTexturessCountAtLeast(index: number) { return { visibleIf: rangeStartEnd(index + 1, 10).map((i) => ({texturesCount: i})), }; } function textureNameParam(index: number) { return ParamConfig.STRING('', { ...visibleIfTexturessCountAtLeast(index), }); } class ParticlesSystemStepSimulationJsParamsConfig extends PolyNodeParamsConfig { texturesCount = ParamConfig.INTEGER(1, { range: [0, 10], rangeLocked: [true, false], }); textureName0 = textureNameParam(0); textureName1 = textureNameParam(1); textureName2 = textureNameParam(2); textureName3 = textureNameParam(3); textureName4 = textureNameParam(4); textureName5 = textureNameParam(5); textureName6 = textureNameParam(6); textureName7 = textureNameParam(7); textureName8 = textureNameParam(8); textureName9 = textureNameParam(9); } const ParamsConfig = new ParticlesSystemStepSimulationJsParamsConfig(); export class ParticlesSystemStepSimulationJsNode extends TypedJsNode<ParticlesSystemStepSimulationJsParamsConfig> { override readonly paramsConfig = ParamsConfig; static override type() { return 'particlesSystemStepSimulation'; } override initializeNode() { this.io.connection_points.set_input_name_function(this._expectedInputName.bind(this)); this.io.connection_points.set_expected_input_types_function(this._expectedInputTypes.bind(this)); this.io.connection_points.set_expected_output_types_function(this._expectedOutputTypes.bind(this)); this.io.connection_points.set_output_name_function(this._expectedOutputName.bind(this)); } protected _textureNameParams(): StringParam[] { return [ this.p.textureName0, this.p.textureName1, this.p.textureName2, this.p.textureName3, this.p.textureName4, this.p.textureName5, this.p.textureName6, this.p.textureName7, this.p.textureName8, this.p.textureName9, ]; } setTextureName(index: number, textureName: string) { const param = this._textureNameParams()[index]; if (!param) { return; } param.set(textureName); } private _expectedInputTypes(): JsConnectionPointType[] { return [JsConnectionPointType.TRIGGER, JsConnectionPointType.OBJECT_3D]; } private _expectedInputName(index: number) { return this._expectedInputTypes()[index]; } private _expectedOutputTypes() { const count = this.pv.texturesCount; return this._expectedInputTypes().concat( rangeStartEnd(0, count).map((value, i) => JsConnectionPointType.TEXTURE) ); } private _expectedOutputName(index: number) { if (index <= 1) { return this._expectedInputName(index); } else { return this._textureNameParams()[index - 2].value; } } override setLines(linesController: JsLinesCollectionController) { this._addRefs(linesController); setObject3DOutputLine(this, linesController); } override setTriggerableLines(linesController: JsLinesCollectionController) { const object3D = inputObject3D(this, linesController); const configRef = this._addRefs(linesController); const func = Poly.namedFunctionsRegister.getFunction('particlesSystemStepSimulation', this, linesController); const bodyLine = func.asString(object3D, this._refToString(configRef)); linesController.addTriggerableLines(this, [bodyLine]); } private _refToString(refs: GPUComputationConfigRefString): string { const keys = Object.keys(refs); const data: string[] = []; for (const key of keys) { data.push(`${key}:this.${(refs as any)[key]}`); } return `{${data.join(',')}}`; } private _addRefs(linesController: JsLinesCollectionController): GPUComputationConfigRefString { const count = this.pv.texturesCount; const textureParams = this._textureNameParams(); const textureNames = rangeStartEnd(0, count).map((value, i) => `${textureParams[i].value}`); // const varNames = textureNames.map((textureName) => this.jsVarName(textureName)); for (const texture of varNames) { linesController.addDefinitions(this, [ new ConstantJsDefinition(this, linesController, JsConnectionPointType.TEXTURE, texture, `null`), ]); } const ref: GPUComputationConfigRefString = {}; for (let i = 0; i < count; i++) { const textureName = textureNames[i]; const textureNameWithPrefix = `${TEXTURE_ALLOCATION_PREFIX}${textureName}`; const varName = varNames[i]; ref[textureNameWithPrefix] = varName; } return ref; } }