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