@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
272 lines (271 loc) • 9.52 kB
JavaScript
"use strict";
import { ParamJsonImporter } from "./Param";
import { Poly } from "../../../Poly";
import { OPERATIONS_COMPOSER_NODE_TYPE } from "../../../operations/_Base";
import { isString } from "../../../../core/Type";
export class OptimizedNodesJsonImporter {
constructor(_node) {
this._node = _node;
this._nodes = [];
this._optimized_root_node_names = /* @__PURE__ */ new Set();
this._operation_containers_by_name = /* @__PURE__ */ new Map();
this._node_inputs = [];
}
nodes() {
return this._nodes;
}
process_data(scene_importer, data) {
var _a, _b, _c;
if (!data) {
return;
}
if (!(this._node.childrenAllowed() && this._node.childrenController)) {
return;
}
const { optimized_names } = OptimizedNodesJsonImporter.child_names_by_optimized_state(data);
this._nodes = [];
this._optimized_root_node_names = /* @__PURE__ */ new Set();
for (let node_name of optimized_names) {
if (OptimizedNodesJsonImporter.is_optimized_root_node(data, node_name)) {
this._optimized_root_node_names.add(node_name);
}
}
for (let nodeName of this._optimized_root_node_names) {
const node_data = data[nodeName];
const nodeCreateOptions = {
nodeName
};
const node = this._node.createNode(OPERATIONS_COMPOSER_NODE_TYPE, nodeCreateOptions);
if (node) {
this._nodes.push(node);
if ((_a = node_data.flags) == null ? void 0 : _a.display) {
(_c = (_b = node.flags) == null ? void 0 : _b.display) == null ? void 0 : _c.set(true);
}
const operation_container = this._createOperationContainer(
scene_importer,
node,
node_data,
node.name()
);
node.setOutputOperationContainer(
operation_container
);
}
}
for (let node of this._nodes) {
const operation_container = node.outputOperationContainer();
if (operation_container) {
this._node_inputs = [];
this._add_optimized_node_inputs(
scene_importer,
node,
data,
node.name(),
operation_container
);
node.io.inputs.setCount(this._node_inputs.length);
for (let i = 0; i < this._node_inputs.length; i++) {
node.setInput(i, this._node_inputs[i]);
}
}
}
}
_add_optimized_node_inputs(scene_importer, node, data, node_name, current_operation_container) {
var _a;
const node_data = data[node_name];
const inputs_data = node_data["inputs"];
if (!inputs_data) {
return;
}
for (let input_data of inputs_data) {
if (isString(input_data)) {
const input_node_data = data[input_data];
if (input_node_data) {
if (OptimizedNodesJsonImporter.is_node_optimized(input_node_data) && !this._optimized_root_node_names.has(input_data)) {
let operation_container = this._operation_containers_by_name.get(input_data);
if (!operation_container) {
operation_container = this._createOperationContainer(
scene_importer,
node,
input_node_data,
input_data
);
if (operation_container) {
this._add_optimized_node_inputs(
scene_importer,
node,
data,
input_data,
operation_container
);
}
}
current_operation_container.addInput(operation_container);
} else {
const input_node = (_a = node.parent()) == null ? void 0 : _a.node(input_data);
if (input_node) {
this._node_inputs.push(input_node);
const node_input_index = this._node_inputs.length - 1;
node.addInputConfig(current_operation_container, {
operation_input_index: current_operation_container.currentInputIndex(),
node_input_index
});
current_operation_container.incrementInputIndex();
}
}
}
}
}
if (node_data.cloned_state_overriden == true) {
current_operation_container.overrideInputCloneState(node_data.cloned_state_overriden);
}
}
static child_names_by_optimized_state(data) {
const node_names = Object.keys(data);
const optimized_names = [];
const non_optimized_names = [];
for (let node_name of node_names) {
const node_data = data[node_name];
const optimized_state = Poly.playerMode() && this.is_node_optimized(node_data);
if (optimized_state) {
optimized_names.push(node_name);
} else {
non_optimized_names.push(node_name);
}
}
return { optimized_names, non_optimized_names };
}
// private _optimized_names_for_root(
// data: PolyDictionary<NodeJsonExporterData>,
// current_node_name: string,
// current_node_data: NodeJsonExporterData,
// input_names: string[] = []
// ) {
// input_names.push(current_node_name);
// const inputs = current_node_data['inputs'];
// if (inputs) {
// for (let input_data of inputs) {
// if (isString(input_data)) {
// const input_node_name = input_data;
// // if (input_node_name != current_node_name) {
// const input_node_data = data[input_node_name];
// if (input_node_data) {
// if (
// OptimizedNodesJsonImporter.is_node_optimized(input_node_data) &&
// !this._is_optimized_root_node(data, input_node_name, input_node_data)
// ) {
// this._optimized_names_for_root(data, input_node_name, input_node_data, input_names);
// }
// }
// // }
// }
// }
// }
// return input_names;
// }
// a node will be considered optimized root node if:
// - it has no output
// - at least one output is not optimized (as it if it has 2 outputs, and only 1 is optimized, it will not be considered root)
static is_optimized_root_node_generic(data) {
if (data.outputs_count == 0) {
return true;
}
if (data.non_optimized_count > 0) {
return true;
}
return false;
}
static is_optimized_root_node(data, current_node_name) {
const output_names = this.node_outputs(data, current_node_name);
let non_optimized_count = 0;
output_names.forEach((node_name) => {
const node_data = data[node_name];
if (!this.is_node_optimized(node_data)) {
non_optimized_count++;
}
});
return this.is_optimized_root_node_generic({
outputs_count: output_names.size,
non_optimized_count
});
}
// same algo as is_optimized_root_node, but for a node
static is_optimized_root_node_from_node(node) {
var _a, _b, _c, _d;
if (!((_b = (_a = node.flags) == null ? void 0 : _a.optimize) == null ? void 0 : _b.active())) {
return false;
}
const outputConnections = [];
node.io.connections.outputConnections(outputConnections);
const outputNodes = outputConnections.map((c) => c.nodeDest());
let non_optimized_count = 0;
for (let output_node of outputNodes) {
if (!((_d = (_c = output_node.flags) == null ? void 0 : _c.optimize) == null ? void 0 : _d.active())) {
non_optimized_count++;
}
}
return this.is_optimized_root_node_generic({
outputs_count: outputNodes.length,
non_optimized_count
});
}
static node_outputs(data, current_node_name) {
const node_names = Object.keys(data);
const output_node_names = /* @__PURE__ */ new Set();
for (let node_name of node_names) {
if (node_name != current_node_name) {
const node_data = data[node_name];
const inputs = node_data["inputs"];
if (inputs) {
for (let input_data of inputs) {
if (isString(input_data)) {
const input_node_name = input_data;
if (input_node_name == current_node_name) {
output_node_names.add(node_name);
}
}
}
}
}
}
return output_node_names;
}
_createOperationContainer(scene_importer, node, node_data, node_name) {
const paramsInitValueOverrides = ParamJsonImporter.non_spare_params_data_value(node_data["params"]);
const operation_type = OptimizedNodesJsonImporter.operation_type(node_data);
const createOptions = { paramsInitValueOverrides };
const operation_container = this._node.createOperationContainer(
operation_type,
node_name,
createOptions
);
if (operation_container) {
this._operation_containers_by_name.set(node_name, operation_container);
if (operation_container.pathParamResolveRequired()) {
node.addOperationContainerWithPathParamResolveRequired(operation_container);
scene_importer.add_operations_composer_node_with_path_param_resolve_required(node);
}
}
return operation_container;
}
static operation_type(node_data) {
if (OptimizedNodesJsonImporter.is_node_bypassed(node_data)) {
return "null";
}
return node_data["type"];
}
static is_node_optimized(node_data) {
const node_flags = node_data["flags"];
if (node_flags && node_flags["optimize"]) {
return true;
}
return false;
}
static is_node_bypassed(node_data) {
const node_flags = node_data["flags"];
if (node_flags && node_flags["bypass"]) {
return true;
}
return false;
}
}