UNPKG

@polygonjs/polygonjs

Version:

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

185 lines (184 loc) 6.05 kB
"use strict"; import { BaseJsShaderAssembler, INSERT_DEFINE_AFTER, INSERT_CONSTRUCTOR_AFTER, INSERT_BODY_AFTER, INSERT_MEMBERS_AFTER } from "../_Base"; import { JsFunctionName } from "../../../../utils/shaders/ShaderName"; import { connectedTriggerableNodes, findTriggeringNodes, inputNodesExceptTrigger } from "./ActorAssemblerUtils"; import { setToArray } from "../../../../../../core/SetUtils"; import { PrettierController } from "../../../../../../core/code/PrettierController"; import { ActorAssemblerConstant } from "./ActorAssemblerCommon"; import { isFunction, isArray } from "../../../../../../core/Type"; import { JsConnectionPointType } from "../../../../utils/io/connections/Js"; import { ParamType } from "../../../../../poly/ParamType"; import { JsShaderConfig } from "../../configs/ShaderConfig"; const TEMPLATE = ` ${INSERT_DEFINE_AFTER} class CustomActorEvaluator extends ActorEvaluator { ${INSERT_MEMBERS_AFTER} constructor(node, object3D){ super(node, object3D); ${INSERT_CONSTRUCTOR_AFTER} } ${INSERT_BODY_AFTER} `; const CLOSE_CLASS_DEFINITION = `}; return CustomActorEvaluator;`; const _tmp = []; export class JsAssemblerActor extends BaseJsShaderAssembler { makeFunctionNodeDirtyOnChange() { return false; } templateShader() { return { main: TEMPLATE }; } inputNamesForShaderName(rootNode, shaderName) { return (rootNode.io.inputs.namedInputConnectionPoints() || []).filter((cp) => cp.type() != JsConnectionPointType.TRIGGER).map((cp) => cp.name()); } computedVariablesAllowed() { return true; } spareParamsOptions(options) { const { type } = options; const _options = { spare: true, computeOnDirty: type != ParamType.PARAM_PATH, cook: false // dependentOnFoundNode: true, // there is no point in setting the callback option here, // as it would then not be present when reloading the scene // callback: (node, param) => { // touchParamRef(node, param.name()); // }, }; return _options; } defaultObjectVariable() { return ActorAssemblerConstant.OBJECT_3D; } defaultObject3DMaterialVariable() { return ActorAssemblerConstant.MATERIAL; } defaultPrimitiveGraph() { return ActorAssemblerConstant.PRIMITIVE_GRAPH; } createFunctionData(additionalRootNodes) { const node = this.currentJsParentNode(); this._reset(); const triggeringNodes = findTriggeringNodes(node); const triggerableNodes = /* @__PURE__ */ new Set(); connectedTriggerableNodes({ triggeringNodes, triggerableNodes, recursive: true }); const shaderNames = this.shaderNames(); const functionData = this._createFunctionData( additionalRootNodes, triggeringNodes, triggerableNodes, shaderNames ); return functionData; } _createFunctionData(additionalRootNodes, triggeringNodes, triggerableNodes, shaderNames) { var _a; const functionNode = this.currentJsParentNode(); const _addComputedProps = () => { const rootNodesSet = /* @__PURE__ */ new Set(); triggerableNodes.forEach((trigerrableNode) => { const rootNodes2 = inputNodesExceptTrigger(trigerrableNode, _tmp); for (const rootNode of rootNodes2) { rootNodesSet.add(rootNode); } }); setToArray(rootNodesSet, _tmp); const rootNodes = _tmp.concat(additionalRootNodes); this.set_root_nodes(rootNodes); this.buildCodeFromNodes(this._root_nodes, { actor: { functionNode, triggeringNodes, triggerableNodes } }); this._buildLines(); for (const shaderName of shaderNames) { const lines = this._lines.get(shaderName); if (lines) { this._shaders_by_name.set(shaderName, lines.join("\n")); } } }; _addComputedProps(); const _buildFunctionBody = () => { const bodyLines = this._shaders_by_name.get(JsFunctionName.MAIN) || TEMPLATE; const functionBodyElements = [bodyLines, CLOSE_CLASS_DEFINITION]; const functionBody2 = PrettierController.formatJs(functionBodyElements.join("\n")); return functionBody2; }; const functionBody = _buildFunctionBody(); const variableNames = []; const functionNames = []; const variablesByName = {}; const functionsByName = {}; this.traverseRegisteredVariables((variable, varName) => { variableNames.push(varName); variablesByName[varName] = variable; }); this.traverseRegisteredFunctions((namedFunction) => { functionNames.push(namedFunction.type()); functionsByName[namedFunction.type()] = namedFunction.func.bind(namedFunction); }); const paramConfigs = this.param_configs(); const variables = []; const functions = []; for (const variableName of variableNames) { const variable = variablesByName[variableName]; variables.push(variable); } for (const functionName of functionNames) { const _func = functionsByName[functionName]; functions.push(_func); } const eventDatas = []; (_a = this.currentJsParentNode().childrenController) == null ? void 0 : _a.traverseChildren((child) => { const eventDataFunction = child.eventData; if (eventDataFunction && isFunction(eventDataFunction)) { const eventData = child.eventData(); if (eventData) { if (isArray(eventData)) { eventDatas.push(...eventData); } else { eventDatas.push(eventData); } } } }); const functionData = { functionBody, variableNames, variablesByName, functionNames, functionsByName, paramConfigs: [...paramConfigs], eventDatas }; return functionData; } rootNodesByShaderName(shaderName, rootNodes) { return rootNodes; } // // // CONFIGS // // create_shader_configs() { return [new JsShaderConfig(JsFunctionName.MAIN, [], [])]; } create_variable_configs() { return []; } }