UNPKG

@polygonjs/polygonjs

Version:

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

99 lines (98 loc) 4.49 kB
"use strict"; import SKINNING from "./gl/skinning.glsl"; import { TypedGlNode } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { GlConnectionPointType, GlConnectionPoint } from "../utils/io/connections/Gl"; import { ShaderName } from "../utils/shaders/ShaderName"; import { ThreeToGl } from "../../../core/ThreeToGl"; import { expandShader } from "./code/utils/ExpandShader"; import { FunctionGLDefinition } from "./utils/GLDefinition"; const TEMPLATE = expandShader(SKINNING); const TO_REPLACE_INPUT_POS = `vec4( transformed, 1.0 )`; const TO_REPLACE_INPUT_NORMAL = `vec4( objectNormal, 0.0 )`; const TO_REPLACE_OUTPUT_POS = `transformed = `; const TO_REPLACE_OUTPUT_NORMAL = `objectNormal = `; const TO_REPLACE_OUTPUT_TANGENT = `objectTangent = `; const ARGS = { inputPos: { type: "vec3", name: "inputPos" }, inputNormal: { type: "vec3", name: "inputNormal" }, skinIndex: { type: "vec4", name: "skinIndex" } }; function createFunction(options) { const skinningStructName = `skinningOut`; let withReplaced = TEMPLATE.replace(TO_REPLACE_INPUT_POS, `vec4(${ARGS.inputPos.name}, 1.0)`).replace(TO_REPLACE_INPUT_NORMAL, `vec4(${ARGS.inputNormal.name}, 0.0)`).replace(TO_REPLACE_OUTPUT_POS, `${skinningStructName}.position = `).replace(TO_REPLACE_OUTPUT_NORMAL, `${skinningStructName}.normal = `).replace(TO_REPLACE_OUTPUT_TANGENT, `${skinningStructName}.tangent = `); const structDefinition = `struct ${options.structDefinitionName} { vec3 position; vec3 normal; vec3 tangent; };`; const argsInDefinition = Object.values(ARGS).map((arg) => `${arg.type} ${arg.name}`).join(", "); const functionDeclaration = ` ${structDefinition} ${options.structDefinitionName} ${options.functionName}(${argsInDefinition}){ ${options.structDefinitionName} ${skinningStructName}; ${withReplaced} return ${skinningStructName}; }`; return { functionDeclaration }; } var SkinningOutput = /* @__PURE__ */ ((SkinningOutput2) => { SkinningOutput2["POSITION"] = "position"; SkinningOutput2["NORMAL"] = "normal"; SkinningOutput2["TANGENT"] = "tangent"; return SkinningOutput2; })(SkinningOutput || {}); class SkinningGlParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.position = ParamConfig.VECTOR3([0, 0, 0]); this.normal = ParamConfig.VECTOR3([0, 1, 0]); } } const ParamsConfig = new SkinningGlParamsConfig(); export class SkinningGlNode extends TypedGlNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return "skinning"; } initializeNode() { super.initializeNode(); this.io.outputs.setNamedOutputConnectionPoints([ new GlConnectionPoint("position" /* POSITION */, GlConnectionPointType.VEC3), new GlConnectionPoint("normal" /* NORMAL */, GlConnectionPointType.VEC3), new GlConnectionPoint("tangent" /* TANGENT */, GlConnectionPointType.VEC3) ]); } setLines(linesController) { if (linesController.currentShaderName() == ShaderName.VERTEX) { const inputPosition = ThreeToGl.vector3(this.variableForInputParam(this.p.position)); const inputNormal = ThreeToGl.vector3(this.variableForInputParam(this.p.normal)); const outPosition = this.glVarName("position" /* POSITION */); const outNormal = this.glVarName("normal" /* NORMAL */); const outTangent = this.glVarName("tangent" /* TANGENT */); const outValue = this.glVarName("out"); const functionName = `computeSkinningData_${this.graphNodeId()}`; const structDefinitionName = `SkinningData_${this.graphNodeId()}`; const { functionDeclaration } = createFunction({ functionName, structDefinitionName }); const bodyLines = [ `#ifdef USE_SKINNING`, `${structDefinitionName} ${outValue} = ${functionName}(${inputPosition}, ${inputNormal}, ${ARGS.skinIndex.name})`, `vec3 ${outPosition} = ${outValue}.position;`, `vec3 ${outNormal} = ${outValue}.normal;`, `vec3 ${outTangent} = ${outValue}.tangent;`, `#else`, `vec3 ${outPosition} = ${inputPosition}`, `vec3 ${outNormal} = ${inputNormal}`, `vec3 ${outTangent} = vec3(0.)`, `#endif` ]; const definitionLines = []; definitionLines.push(new FunctionGLDefinition(this, functionDeclaration)); linesController.addBodyLines(this, bodyLines, ShaderName.VERTEX); linesController.addDefinitions(this, definitionLines); } } }