@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
99 lines (98 loc) • 4.49 kB
JavaScript
;
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);
}
}
}