UNPKG

@polygonjs/polygonjs

Version:

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

233 lines (232 loc) 7.85 kB
"use strict"; import { BaseJsShaderAssembler, INSERT_DEFINE_AFTER, INSERT_BODY_AFTER, INSERT_MEMBERS_AFTER, INSERT_CONSTRUCTOR_AFTER } from "../_Base"; import { ThreeToGl } from "../../../../../../core/ThreeToGl"; import { JsShaderConfig } from "../../configs/ShaderConfig"; import { VariableConfig } from "../../configs/VariableConfig"; import { JsFunctionName } from "../../../../utils/shaders/ShaderName"; import { JsConnectionPointType, JsConnectionPoint } from "../../../../utils/io/connections/Js"; import { Vector3 } from "three"; import { PrettierController } from "../../../../../../core/code/PrettierController"; export var SoftBodyVariable = /* @__PURE__ */ ((SoftBodyVariable2) => { SoftBodyVariable2["P"] = "position"; SoftBodyVariable2["V"] = "velocity"; SoftBodyVariable2["COLLISION_SDF"] = "collisionSDF"; SoftBodyVariable2["TIME"] = "time"; SoftBodyVariable2["DELTA"] = "delta"; return SoftBodyVariable2; })(SoftBodyVariable || {}); const TEMPLATE_VELOCITY = ` ${INSERT_DEFINE_AFTER} ${INSERT_MEMBERS_AFTER} ${INSERT_CONSTRUCTOR_AFTER} const SoftBodyVelocity = function(){ ${INSERT_BODY_AFTER} `; const CLOSE_CLASS_DEFINITION_VELOCITY = `}; return SoftBodyVelocity;`; const TEMPLATE_COLLIDER = ` ${INSERT_DEFINE_AFTER} ${INSERT_MEMBERS_AFTER} ${INSERT_CONSTRUCTOR_AFTER} const SoftBodyCollider = function(){ ${INSERT_BODY_AFTER} `; const CLOSE_CLASS_DEFINITION_COLLIDER = `}; return SoftBodyCollider;`; export class JsAssemblerSoftBody extends BaseJsShaderAssembler { makeFunctionNodeDirtyOnChange() { return true; } defaultObjectVariable() { return "null"; } defaultObject3DMaterialVariable() { return "null"; } defaultPrimitiveGraph() { return "null"; } templateShader() { return { velocity: TEMPLATE_VELOCITY, collider: TEMPLATE_COLLIDER }; } spareParamsOptions(options) { const _options = { spare: true, // computeOnDirty: true, // not needed if cook option is not set cook: false, // for Softbody, the node must not recook // important for texture nodes // that compute after being found by the nodepath param dependentOnFoundNode: true }; return _options; } functionData() { const _buildFunctionBody = (functionName, closeDef) => { const bodyLines = this._shaders_by_name.get(functionName) || TEMPLATE_VELOCITY; const functionBodyElements = [ bodyLines, // triggerableFunctionLines.join('\n'), // triggerFunctionLines.join('\n'), closeDef ]; const functionBody = PrettierController.formatJs(functionBodyElements.join("\n")); return functionBody; }; const functionBodyVelocity = _buildFunctionBody(JsFunctionName.VELOCITY, CLOSE_CLASS_DEFINITION_VELOCITY); const functionBodyCollider = _buildFunctionBody(JsFunctionName.COLLIDER, CLOSE_CLASS_DEFINITION_COLLIDER); if (!(functionBodyVelocity && functionBodyCollider)) { return; } 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(); return { functionBody: { velocity: functionBodyVelocity, collider: functionBodyCollider }, variableNames, variablesByName, functionNames, functionsByName, paramConfigs: [...paramConfigs] }; } updateFunction() { super.updateFunction(); this._lines = /* @__PURE__ */ new Map(); this._shaders_by_name = /* @__PURE__ */ new Map(); const shaderNames = this.shaderNames(); if (this._root_nodes.length > 0) { this.buildCodeFromNodes(this._root_nodes); this._buildLines(); } for (const shaderName of shaderNames) { const lines = this._lines.get(shaderName); if (lines) { this._shaders_by_name.set(shaderName, lines.join("\n")); } } } // // // CHILDREN NODES PARAMS // // add_output_inputs(output_child) { output_child.io.inputs.setNamedInputConnectionPoints([ new JsConnectionPoint("velocity" /* V */, JsConnectionPointType.VECTOR3), new JsConnectionPoint("collisionSDF" /* COLLISION_SDF */, JsConnectionPointType.FLOAT) ]); } add_globals_outputs(globals_node) { globals_node.io.outputs.setNamedOutputConnectionPoints([ new JsConnectionPoint("position" /* P */, JsConnectionPointType.VECTOR3), new JsConnectionPoint("velocity" /* V */, JsConnectionPointType.VECTOR3), new JsConnectionPoint("time" /* TIME */, JsConnectionPointType.FLOAT), new JsConnectionPoint("delta" /* DELTA */, JsConnectionPointType.FLOAT) ]); } // // // CONFIGS // // create_shader_configs() { return [ new JsShaderConfig(JsFunctionName.VELOCITY, ["velocity" /* V */], []), new JsShaderConfig(JsFunctionName.COLLIDER, ["collisionSDF" /* COLLISION_SDF */], []) ]; } create_variable_configs() { return [ new VariableConfig("velocity" /* V */, { prefix: "return " }), new VariableConfig("collisionSDF" /* COLLISION_SDF */, { prefix: "return " }) ]; } setNodeLinesOutput(outputNode, linesController) { const inputNames = this.inputNamesForShaderName( outputNode, linesController.currentShaderName() ); if (inputNames) { for (const inputName of inputNames) { const input = outputNode.io.inputs.named_input(inputName); const glVar = outputNode.variableForInput(linesController, inputName); switch (inputName) { case "velocity" /* V */: { const _defaultVar = () => { const tmpVarName = linesController.addVariable(outputNode, new Vector3(0, 0.1, 0)); return `return ${tmpVarName}`; }; const bodyLine = input ? `return ${ThreeToGl.any(glVar)}` : _defaultVar(); linesController._addBodyLines(outputNode, [bodyLine]); break; } case "collisionSDF" /* COLLISION_SDF */: { const bodyLine = input ? `return ${ThreeToGl.any(glVar)}` : `return 100`; linesController._addBodyLines(outputNode, [bodyLine]); break; } } } } } setNodeLinesGlobals(globalsNode, shadersCollectionController) { const shaderName = shadersCollectionController.currentShaderName(); const shaderConfig = this.shader_config(shaderName); if (!shaderConfig) { return; } const bodyLines = []; const usedOutputNames = globalsNode.io.outputs.used_output_names(); for (const outputName of usedOutputNames) { const varName = globalsNode.jsVarName(outputName); switch (outputName) { case "position": { shadersCollectionController.addVariable(globalsNode, new Vector3(), varName); bodyLines.push(`${varName}.copy(${outputName})`); break; } case "velocity" /* V */: { shadersCollectionController.addVariable(globalsNode, new Vector3(), varName); bodyLines.push(`${varName}.copy(${outputName})`); break; } case "time" /* TIME */: { bodyLines.push(`const ${varName} = ${"time" /* TIME */}`); break; } case "delta" /* DELTA */: { bodyLines.push(`const ${varName} = ${"delta" /* DELTA */}`); break; } } } shadersCollectionController._addBodyLines(globalsNode, bodyLines); } }