@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
91 lines (80 loc) • 2.58 kB
text/typescript
import {BaseOperationContainer} from './_Base';
import {BaseSopOperation} from '../sop/_Base';
import {ParamsInitData} from '../../../engine/nodes/utils/io/IOController';
import {CoreGroup} from '../../../core/geometry/Group';
import {NodeContext} from '../../poly/NodeContext';
export type OperationInputsMap = WeakMap<SopOperationContainer, Map<number, number>>;
export class SopOperationContainer extends BaseOperationContainer<NodeContext.SOP> {
constructor(
protected override operation: BaseSopOperation,
protected override name: string,
protected init_params: ParamsInitData
) {
super(operation, name, init_params);
}
operationType() {
return this.operation.type();
}
// TODO: there may a better to overload add_input
protected override _inputs: SopOperationContainer[] = [];
private _currentInputIndex: number = 0;
addInput(input: SopOperationContainer) {
super.setInput(this._currentInputIndex, input);
this.incrementInputIndex();
}
incrementInputIndex() {
this._currentInputIndex++;
}
currentInputIndex() {
return this._currentInputIndex;
}
private _computeResult: CoreGroup | undefined;
private _dirty: boolean = true;
setDirty() {
if (this._dirty) {
return;
}
this._computeResult = undefined;
for (let i = 0; i < this._inputs.length; i++) {
const inputOperation = this._inputs[i];
inputOperation.setDirty();
}
}
async compute(input_contents: CoreGroup[], operation_inputs_map: OperationInputsMap) {
if (this._computeResult) {
return this._computeResult;
}
const operationInputContents: CoreGroup[] = [];
// process node inputs
const nodeInputsMap = operation_inputs_map.get(this);
if (nodeInputsMap) {
nodeInputsMap.forEach((node_input_index: number, operation_input_index: number) => {
operationInputContents[operation_input_index] = input_contents[node_input_index];
});
}
// process operation inputs
for (let i = 0; i < this._inputs.length; i++) {
const inputOperation = this._inputs[i];
let result = await inputOperation.compute(input_contents, operation_inputs_map);
if (result) {
if (this.inputCloneRequired(i)) {
result = result.clone();
}
operationInputContents[i] = result;
}
}
// cook and store result
const result = this.operation.cook(operationInputContents, this.params);
if (result) {
if (result instanceof Promise) {
this._computeResult = await result;
} else {
this._computeResult = result;
}
} else {
this._computeResult = undefined;
}
this._dirty = false;
return this._computeResult;
}
}