@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
114 lines (113 loc) • 3.72 kB
JavaScript
"use strict";
import { SolverIterationStamp } from "./utils/SolverIterationStamp";
import { NetworkNodeType } from "./../../poly/NodeContext";
import { SubnetSopNodeLike, SopSubnetChildrenDisplayController } from "./utils/subnet/SopSubnetChildrenDisplayController";
import { InputCloneMode } from "../../poly/InputCloneMode";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { DisplayNodeController } from "../utils/DisplayNodeController";
class SolverSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param number of times the nodes inside this node will process the input */
this.iterations = ParamConfig.INTEGER(2, {
range: [0, 5],
rangeLocked: [true, false]
});
/** @param Currently, when the child nodes are updated, the solver node does not know that it should recook. Clicking this button forces it to recompute */
this.reload = ParamConfig.BUTTON(null, {
callback: (node) => {
SolverSopNode.PARAM_CALLBACK_reload(node);
}
});
}
}
const ParamsConfig = new SolverSopParamsConfig();
export class SolverSopNode extends SubnetSopNodeLike {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this.childrenDisplayController = new SopSubnetChildrenDisplayController(this, { dependsOnDisplayNode: false });
this.displayNodeController = new DisplayNodeController(
this,
{
onDisplayNodeRemove: () => {
},
onDisplayNodeSet: () => {
},
onDisplayNodeUpdate: () => {
}
},
{ dependsOnDisplayNode: false }
);
}
static type() {
return NetworkNodeType.SOLVER;
}
initializeNode() {
this.io.inputs.setCount(0, 4);
this.io.inputs.initInputsClonedState(InputCloneMode.NEVER);
}
iterationStamp() {
return this._iterationStamp = this._iterationStamp || this._createStampNode();
}
_createStampNode() {
const stampNode = new SolverIterationStamp(this.scene());
stampNode.setForbiddenTriggerNodes(this);
return stampNode;
}
previousFrameCoreGroup() {
return this._previousFrameCoreGroup;
}
async cook(inputCoreGroups) {
this._reset();
if (this.pv.iterations == 0) {
this.setCoreGroup(inputCoreGroups[0]);
return;
}
await this._computeSolverMultipleTimes(this.pv.iterations);
}
_reset() {
this._previousFrameCoreGroup = void 0;
if (this.iterationStamp().iteration() == 0) {
this.iterationStamp().setIteration(-1);
}
}
async _computeSolverMultipleTimes(iterationsCount) {
for (let i = 0; i < iterationsCount; i++) {
this.iterationStamp().setIteration(i);
await this.computeSolver(i == iterationsCount - 1);
}
}
async computeSolver(isLastIteration) {
const childOutputNode = this.childrenDisplayController.outputNode();
let coreContent;
if (childOutputNode) {
const container = await childOutputNode.compute();
coreContent = container.coreContent();
if (coreContent) {
this._previousFrameCoreGroup = coreContent;
} else {
if (childOutputNode.states.error.active()) {
this.states.error.set(childOutputNode.states.error.message());
} else {
this._previousFrameCoreGroup = void 0;
}
}
} else {
this.states.error.set("no output node found inside subnet");
}
if (isLastIteration) {
if (coreContent) {
this.setCoreGroup(coreContent);
} else {
this.setObjects([]);
}
}
}
static PARAM_CALLBACK_reload(node) {
node.param_callback_reload();
}
param_callback_reload() {
this.p.iterations.setDirty();
}
}