UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

134 lines (133 loc) 4.13 kB
"use strict"; import { PrimitiveMatNode } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { MaterialPersistedConfig } from "../gl/code/assemblers/materials/MaterialPersistedConfig"; import { NodeContext } from "../../poly/NodeContext"; import { isBooleanTrue } from "../../../core/BooleanValue"; export function BaseBuilderParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); /** @param if toggled on, the shader will be built from the gl nodes of another material. This can be useful to have multiple materials use the same gl network, but still set the uniforms differently */ this.setBuilderNode = ParamConfig.BOOLEAN(0, { callback: (node) => { TypedBuilderMatNode.PARAM_CALLBACK_setCompileRequired(node); } }); /** @param builder node */ this.builderNode = ParamConfig.NODE_PATH("", { visibleIf: { setBuilderNode: true }, callback: (node) => { TypedBuilderMatNode.PARAM_CALLBACK_setCompileRequired(node); } }); } }; } class MatBuilderParamsConfig extends BaseBuilderParamConfig(NodeParamsConfig) { } export class TypedBuilderMatNode extends PrimitiveMatNode { constructor() { super(...arguments); this._childrenControllerContext = NodeContext.GL; this.persisted_config = new MaterialPersistedConfig(this); } // // // MATERIAL // // createMaterial() { var _a; let material; if (this.persisted_config) { material = this.persisted_config.material(); } if (!material) { material = (_a = this.assemblerController()) == null ? void 0 : _a.assembler.createMaterial(); } return material; } // // // ASSEMBLER // // assemblerController() { return this._assemblerController = this._assemblerController || this._createAssemblerController(); } customMaterialRequested(customName) { return true; } createNode(node_class, options) { return super.createNode(node_class, options); } children() { return super.children(); } nodesByType(type) { return super.nodesByType(type); } childrenAllowed() { if (this.assemblerController()) { return super.childrenAllowed(); } return false; } sceneReadonly() { return this.assemblerController() == null; } // // // COMPILATION // // compileIfRequired(material) { var _a; if ((_a = this.assemblerController()) == null ? void 0 : _a.compileRequired()) { try { this._compile(material); } catch (err) { const message = err.message || "failed to compile"; this.states.error.set(message); } } } _compile(material) { const assemblerController = this.assemblerController(); if (material && assemblerController) { assemblerController.assembler.setGlParentNode(this); this._setAssemblerGlParentNode(assemblerController); assemblerController.assembler.compileMaterial(material); assemblerController.post_compile(); } } _setAssemblerGlParentNode(assemblerController) { if (!isBooleanTrue(this.pv.setBuilderNode)) { return; } const resolvedNode = this.pv.builderNode.nodeWithContext(NodeContext.MAT); if (!resolvedNode) { return; } const resolvedBuilderNode = resolvedNode; if (!resolvedBuilderNode.assemblerController()) { this.states.error.set(`resolved node '${resolvedNode.path()}' is not a builder node`); return; } if (resolvedBuilderNode.type() != this.type()) { this.states.error.set( `resolved node '${resolvedNode.path()}' does not have the same type '${resolvedNode.type()}' as current node '${this.type()}'` ); return; } assemblerController.assembler.setGlParentNode(resolvedBuilderNode); } static PARAM_CALLBACK_setCompileRequired(node) { node.PARAM_CALLBACK_setCompileRequired(); } PARAM_CALLBACK_setCompileRequired() { var _a; (_a = this.assemblerController()) == null ? void 0 : _a.setCompilationRequired(true); } }