@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
159 lines (158 loc) • 5.05 kB
JavaScript
"use strict";
import { DisplayNodeController } from "../../../utils/DisplayNodeController";
import { SubnetOutputSopNode } from "../../SubnetOutput";
import { CoreGraphNode } from "../../../../../core/graph/CoreGraphNode";
import { TypedSopNode } from "../../_Base";
import { NodeContext } from "../../../../poly/NodeContext";
import { GeoObjNode } from "../../../../nodes/obj/Geo";
export class SubnetSopNodeLike extends TypedSopNode {
constructor() {
super(...arguments);
this._overrideOutputNode = false;
// display_node and children_display controllers
this.childrenDisplayController = new SopSubnetChildrenDisplayController(this);
this.displayNodeController = new DisplayNodeController(
this,
this.childrenDisplayController.displayNodeControllerCallbacks()
);
//
this._childrenControllerContext = NodeContext.SOP;
}
initializeBaseNode() {
super.initializeBaseNode();
this.childrenDisplayController.initializeNode();
this.cookController.disallowInputsEvaluation();
}
createNode(node_class, options) {
return super.createNode(node_class, options);
}
children() {
return super.children();
}
nodesByType(type) {
return super.nodesByType(type);
}
async cook(inputCoreGroups) {
const childOutputNode = this.outputNode();
if (childOutputNode) {
await this._cookFromChildOutputNode(childOutputNode);
} else {
if (!this._overrideOutputNode) {
this.states.error.set("no output node found inside subnet");
}
}
}
async _cookFromChildOutputNode(childOutputNode) {
const container = await childOutputNode.compute();
const coreContent = container.coreContent();
if (coreContent) {
this.setCoreGroup(coreContent);
} else {
if (childOutputNode.states.error.active()) {
this.states.error.set(childOutputNode.states.error.message());
} else {
this.setObjects([]);
}
}
}
outputNode() {
return this._overrideOutputNode ? this.displayNodeController.displayNode() : this.childrenDisplayController.outputNode();
}
setOverrideOutputNode(overrideOutputNode) {
if (this._overrideOutputNode == overrideOutputNode) {
return;
}
this._overrideOutputNode = overrideOutputNode;
const parent = this.parent();
if (parent) {
if (parent instanceof SubnetSopNodeLike) {
const parentSubnet = parent;
parentSubnet.setOverrideOutputNode(overrideOutputNode);
}
if (parent instanceof GeoObjNode || parent instanceof SubnetSopNodeLike) {
const parentGeoObjNode = parent;
if (overrideOutputNode) {
parentGeoObjNode.displayNodeController.setDisplayNodeOverride(this);
} else {
parentGeoObjNode.displayNodeController.setDisplayNodeOverride(void 0);
}
}
}
this.setDirty();
}
}
const DEFAULT_OPTIONS = {
dependsOnDisplayNode: true
};
export class SopSubnetChildrenDisplayController {
constructor(node, options = DEFAULT_OPTIONS) {
this.node = node;
this.options = options;
this._outputNodeNeedsUpdate = true;
}
dispose() {
var _a;
(_a = this._graphNode) == null ? void 0 : _a.dispose();
}
displayNodeControllerCallbacks() {
return {
onDisplayNodeRemove: () => {
this.node.setDirty();
},
onDisplayNodeSet: () => {
this.node.setDirty();
},
onDisplayNodeUpdate: () => {
if (this.node.isDirty()) {
return;
}
this.node.setDirty();
}
};
}
outputNode() {
if (this._outputNodeNeedsUpdate) {
this._updateOutputNode();
}
return this._outputNode;
}
initializeNode() {
var _a;
const displayFlag = (_a = this.node.flags) == null ? void 0 : _a.display;
if (displayFlag) {
displayFlag.onUpdate(() => {
if (displayFlag.active()) {
this.node.setDirty();
}
});
}
this.node.lifecycle.onChildAdd(() => {
this._outputNodeNeedsUpdate = true;
this.node.setDirty();
});
this.node.lifecycle.onChildRemove(() => {
this._outputNodeNeedsUpdate = true;
this.node.setDirty();
});
}
_updateOutputNode() {
const foundNode = this.node.nodesByType(SubnetOutputSopNode.type())[0];
if (this._outputNode == null || foundNode == null || this._outputNode.graphNodeId() != foundNode.graphNodeId()) {
if (this._graphNode && this._outputNode) {
this._graphNode.removeGraphInput(this._outputNode);
}
this._outputNode = foundNode;
if (this._outputNode && this.options.dependsOnDisplayNode) {
this._graphNode = this._graphNode || this._createGraphNode();
this._graphNode.addGraphInput(this._outputNode);
}
}
}
_createGraphNode() {
const graphNode = new CoreGraphNode(this.node.scene(), `subnetChildrenDisplayController-${this.node.name()}`);
graphNode.addPostDirtyHook("subnetChildrenDisplayController", () => {
this.node.setDirty();
});
return graphNode;
}
}