@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
185 lines (184 loc) • 6.05 kB
JavaScript
;
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 [];
}
}