UNPKG

@polygonjs/polygonjs

Version:

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

355 lines (354 loc) 15 kB
"use strict"; import { TypedSubnetGlNode, TypedSubnetGlParamsConfigMixin, ADD_BODY_LINES_OPTIONS } from "./Subnet"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { ThreeToGl } from "../../../core/ThreeToGl"; import { GlConnectionPointType } from "../utils/io/connections/Gl"; import { AttribAdjacency, adjacencyAttribName } from "../../../core/geometry/operation/Adjacency"; import { TypeAssert } from "../../poly/Assert"; import GET_UV from "./gl/geometryAttributes/geometryAttributesLookupUv.glsl"; import { FunctionGLDefinition } from "./utils/GLDefinition"; import { AttribLookup } from "../../../core/geometry/operation/TextureFromAttribute"; import { GlType } from "../../poly/registers/nodes/types/Gl"; export var ComputeNormalsInput = /* @__PURE__ */ ((ComputeNormalsInput2) => { ComputeNormalsInput2["P"] = "P"; ComputeNormalsInput2["N"] = "N"; ComputeNormalsInput2["TEXTURE_SIZE"] = "textureSize"; ComputeNormalsInput2["UV"] = "adjacencyUv"; ComputeNormalsInput2["ID"] = "adjacencyId"; return ComputeNormalsInput2; })(ComputeNormalsInput || {}); var ForLoopVar = /* @__PURE__ */ ((ForLoopVar2) => { ForLoopVar2["ADJACENCY_ATTRIBUTES_ARRAY"] = "adjacencyAttributesArray"; ForLoopVar2["FACE_INDEX"] = "faceIndex"; ForLoopVar2["VERTEX_INDEX"] = "vertexIndex"; ForLoopVar2["CURRENT_ADJACENT_ID_FOR_FACE"] = "currentAdjacentIdForFace"; ForLoopVar2["CURRENT_ADJACENT_ID"] = "currentAdjacentId"; ForLoopVar2["ADJACENT_POS0"] = "adjacentPos0"; ForLoopVar2["ADJACENT_POS1"] = "adjacentPos1"; ForLoopVar2["COMPUTED_NORMAL"] = "computedNormal"; return ForLoopVar2; })(ForLoopVar || {}); const CONSTANT = { START: 0, STEP: 1 }; const SUBNET_INPUT_CONNECTIONS_OFFSET = 3; const CURRENT_POINT_GL_VAR_NAME_SUFFIX = "currentPoint"; var VariablesLookupMode = /* @__PURE__ */ ((VariablesLookupMode2) => { VariablesLookupMode2["CURRENT_POINT"] = "currentPoint"; VariablesLookupMode2["ADJACENT_POINT"] = "adjacentPoint"; return VariablesLookupMode2; })(VariablesLookupMode || {}); class ComputeNormalsGlParamsConfig extends TypedSubnetGlParamsConfigMixin(NodeParamsConfig) { constructor() { super(...arguments); this.adjacencyCount = ParamConfig.FLOAT(6, { range: [0, 8], rangeLocked: [true, false] }); this.adjacencyBaseName = ParamConfig.STRING(AttribAdjacency.BASE_NAME); } } const ParamsConfig = new ComputeNormalsGlParamsConfig(); export class ComputeNormalsGlNode extends TypedSubnetGlNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; // // // set_lines // // // _varNameSuffix: string | undefined; this._variableLookupMode = "currentPoint" /* CURRENT_POINT */; } static type() { return GlType.COMPUTE_NORMALS; } _expectedOutputTypes() { return [ GlConnectionPointType.VEC3, GlConnectionPointType.VEC3, GlConnectionPointType.VEC2, ...super._expectedOutputTypes() ]; } _expectedInputTypes() { return [ GlConnectionPointType.VEC3, GlConnectionPointType.VEC3, GlConnectionPointType.VEC2, ...super._expectedInputTypes() ]; } _expectedOutputName(index) { return this._expectedInputName(index); } _expectedInputName(index) { return ["P" /* P */, "N" /* N */, "textureSize" /* TEXTURE_SIZE */][index] || super._expectedInputName(index - 3); } childExpectedInputConnectionPointTypes() { return [ // GlConnectionPointType.VEC3, // GlConnectionPointType.VEC3, GlConnectionPointType.VEC2, GlConnectionPointType.INT, ...super._expectedInputTypes() ]; } childExpectedInputConnectionPointName(index) { return [ // ComputeNormalsInput.P, // ComputeNormalsInput.N, "adjacencyUv" /* UV */, "adjacencyId" /* ID */ ][index] || super._expectedInputName(index - 2); } childExpectedOutputConnectionPointTypes() { return [GlConnectionPointType.VEC3, ...super._expectedInputTypes()]; } childExpectedOutputConnectionPointName(index) { switch (index) { case 0: { return "P" /* P */; } default: { return super._expectedInputName(index - 1); } } } _glVarNameBase() { const varName = super._glVarNameBase(); switch (this._variableLookupMode) { case "currentPoint" /* CURRENT_POINT */: { return `${varName}_${CURRENT_POINT_GL_VAR_NAME_SUFFIX}`; } case "adjacentPoint" /* ADJACENT_POINT */: { return varName; } } } _withCurrentPoint(callback) { this._variableLookupMode = "currentPoint" /* CURRENT_POINT */; const result = callback(); this._variableLookupMode = "adjacentPoint" /* ADJACENT_POINT */; return result; } _adjacencyLookupId() { switch (this._variableLookupMode) { case "currentPoint" /* CURRENT_POINT */: { return AttribLookup.ID; } case "adjacentPoint" /* ADJACENT_POINT */: { return this.glVarName("currentAdjacentId" /* CURRENT_ADJACENT_ID */); } } TypeAssert.unreachable(this._variableLookupMode); } _adjacencyLookupUv() { switch (this._variableLookupMode) { case "currentPoint" /* CURRENT_POINT */: { return AttribLookup.UV; } case "adjacentPoint" /* ADJACENT_POINT */: { const id = this._adjacencyLookupId(); const textureSize = ThreeToGl.vector2(this.variableForInput("textureSize" /* TEXTURE_SIZE */)); return `geometryAttributesLookupUv(float(${id}), ${textureSize})`; } } TypeAssert.unreachable(this._variableLookupMode); } setLinesBlockStart(linesController) { const start = CONSTANT.START; const step = CONSTANT.STEP; const glType = GlConnectionPointType.INT; const convertMethod = ThreeToGl.integer; const startStr = convertMethod(start); const stepStr = convertMethod(step); const bodyLines = []; const varNameAttributesArray = this.glVarName("adjacencyAttributesArray" /* ADJACENCY_ATTRIBUTES_ARRAY */); const faceIndexIteratorName = this.glVarName("faceIndex" /* FACE_INDEX */); const vertexIndexIteratorName = this.glVarName("vertexIndex" /* VERTEX_INDEX */); const varNameCurrentAdjacentIdForFace = this.glVarName("currentAdjacentIdForFace" /* CURRENT_ADJACENT_ID_FOR_FACE */); const varNameP = this.glVarName("P" /* P */); const varNameN = this.glVarName("N" /* N */); const varNamesForInputs = {}; const traverseInputs = (callback) => { const inputTypes = this._expectedInputTypes(); const inputsCount = inputTypes.length; for (let i = 2; i < inputsCount; i++) { const inputName = this._expectedInputName(i); const inputType = inputTypes[i]; const varName = this.glVarName(inputName); callback(inputType, inputName, varName); } }; traverseInputs((inputType, inputName, varName) => { varNamesForInputs[inputName] = varName; }); this._withCurrentPoint(() => { const linesForCurrentPoint = this.linesBlockContent(linesController); if (linesForCurrentPoint) { bodyLines.push(`${GlConnectionPointType.VEC3} ${this.glVarName("P" /* P */)} = ${varNameP};`); bodyLines.push(`${GlConnectionPointType.VEC3} ${this.glVarName("N" /* N */)} = ${varNameN};`); bodyLines.push( `${GlConnectionPointType.VEC2} ${this.glVarName("adjacencyUv" /* UV */)} = ${AttribLookup.UV};` ); bodyLines.push( `${GlConnectionPointType.INT} ${this.glVarName("adjacencyId" /* ID */)} = ${AttribLookup.ID};` ); traverseInputs((inputType, inputName, varName) => { bodyLines.push(`${inputType} ${this.glVarName(inputName)} = ${varNamesForInputs[inputName]};`); }); bodyLines.push(...linesForCurrentPoint); } }); const _initAdjacentPos = () => { const adjacentPos0 = this.glVarName("adjacentPos0" /* ADJACENT_POS0 */); const adjacentPos1 = this.glVarName("adjacentPos1" /* ADJACENT_POS1 */); const glType2 = GlConnectionPointType.VEC3; return [`${glType2} ${adjacentPos0}`, `${glType2} ${adjacentPos1}`]; }; const _initComputedNormal = () => { const computedNormal = this.glVarName("computedNormal" /* COMPUTED_NORMAL */); const glType2 = GlConnectionPointType.VEC3; return [`${glType2} ${computedNormal} = vec3(0.)`]; }; const _getAdjacencyAttributeArray = () => { const adjacencyCount = this.pv.adjacencyCount; const adjacencyBaseName = this.pv.adjacencyBaseName; const adjacencyAttributeNames = []; for (let i = 0; i < adjacencyCount; i++) { const attribName = adjacencyAttribName(adjacencyBaseName, i); adjacencyAttributeNames.push(attribName); } const glType2 = GlConnectionPointType.VEC2; return `${glType2} ${varNameAttributesArray}[${adjacencyCount}] = vec2[${adjacencyCount}](${adjacencyAttributeNames.join( "," )})`; }; const _forLoopFaces = () => { const max = this.pv.adjacencyCount; const maxStr = convertMethod(max); const bodyLine = `for(${glType} ${faceIndexIteratorName} = ${startStr}; ${faceIndexIteratorName} < ${maxStr}; ${faceIndexIteratorName}+= ${stepStr}){`; return bodyLine; }; const _getAdjacencyAttributeForFace = () => { const glType2 = GlConnectionPointType.VEC2; return `${glType2} ${varNameCurrentAdjacentIdForFace} = ${varNameAttributesArray}[${faceIndexIteratorName}]`; }; const _forLoopVertices = () => { const max = 2; const maxStr = convertMethod(max); const bodyLine = `for(${glType} ${vertexIndexIteratorName} = ${startStr}; ${vertexIndexIteratorName} < ${maxStr}; ${vertexIndexIteratorName}+= ${stepStr}){`; return bodyLine; }; const _getAdjacencyAttribute = () => { const glType2 = GlConnectionPointType.INT; const varName = this.glVarName("currentAdjacentId" /* CURRENT_ADJACENT_ID */); return `${glType2} ${varName} = ${vertexIndexIteratorName}==0 ? int(${varNameCurrentAdjacentIdForFace}.x) : int(${varNameCurrentAdjacentIdForFace}.y)`; }; const _ifAdjacencyIdValid = () => { return `if(${varNameCurrentAdjacentIdForFace}.x > -0.5 && ${varNameCurrentAdjacentIdForFace}.y >= -0.5){`; }; bodyLines.push(..._initAdjacentPos()); bodyLines.push(..._initComputedNormal()); bodyLines.push(_getAdjacencyAttributeArray()); bodyLines.push(_forLoopFaces()); bodyLines.push(_getAdjacencyAttributeForFace()); bodyLines.push(_ifAdjacencyIdValid()); bodyLines.push(_forLoopVertices()); bodyLines.push(_getAdjacencyAttribute()); linesController.addBodyLines(this, bodyLines, void 0, ADD_BODY_LINES_OPTIONS); linesController.addDefinitions(this, [new FunctionGLDefinition(this, GET_UV)]); } setLinesBlockEnd(shadersCollectionController) { const vertexIndexIteratorName = this.glVarName("vertexIndex" /* VERTEX_INDEX */); const adjacentPos0 = this.glVarName("adjacentPos0" /* ADJACENT_POS0 */); const adjacentPos1 = this.glVarName("adjacentPos1" /* ADJACENT_POS1 */); const currentPos = this.glVarName("P" /* P */); const computedNormal = this.glVarName("computedNormal" /* COMPUTED_NORMAL */); const varNameP = this._withCurrentPoint(() => this.glVarName("P" /* P */)); const assignAdjacentPos = `if( ${vertexIndexIteratorName} == 0 ){ ${adjacentPos0}=${currentPos}; } else { ${adjacentPos1}=${currentPos}; }`; const closeIf = `}`; const closeFacePair = `}`; const addFaceNormal = `${computedNormal} += cross( normalize(${adjacentPos0} - ${varNameP}), normalize(${adjacentPos1} - ${varNameP}) );`; const closeAdjacencies = `}`; const useCurrentP = `${this.glVarName("P" /* P */)} = ${varNameP}`; const useComputedN = `${this.glVarName("N" /* N */)} = normalize(${computedNormal})`; shadersCollectionController.addBodyLines(this, [ assignAdjacentPos, closeIf, closeFacePair, addFaceNormal, closeAdjacencies, useCurrentP, useComputedN ]); } setSubnetInputLines(linesController, childNode) { const bodyLines = []; const assembler = linesController.assembler(); const _declareAdjacency = () => { var _a; const adjacencyCount = this.pv.adjacencyCount; const adjacencyBaseName = this.pv.adjacencyBaseName; for (let i = 0; i < adjacencyCount; i++) { const glType = GlConnectionPointType.VEC2; const attribName = adjacencyAttribName(adjacencyBaseName, i); (_a = assembler.globalsHandler()) == null ? void 0 : _a.readAttribute(this, glType, attribName, linesController); } }; const _declareUv = () => { var _a; const glType = GlConnectionPointType.VEC2; const attribName = AttribLookup.UV; (_a = assembler.globalsHandler()) == null ? void 0 : _a.readAttribute(this, glType, attribName, linesController); }; const _declareId = () => { var _a; const glType = GlConnectionPointType.INT; const attribName = AttribLookup.ID; (_a = assembler.globalsHandler()) == null ? void 0 : _a.readAttribute(this, glType, attribName, linesController); }; _declareAdjacency(); _declareUv(); _declareId(); const _addAdjacencyLookupId = () => { const adjacencyLookupId = this._adjacencyLookupId(); const id = childNode.glVarName("adjacencyId" /* ID */); bodyLines.push(` ${GlConnectionPointType.INT} ${id} = ${adjacencyLookupId}`); }; const _addAdjacencyLookupUv = () => { const adjacencyLookupUv = this._adjacencyLookupUv(); const uv = childNode.glVarName("adjacencyUv" /* UV */); bodyLines.push(` ${GlConnectionPointType.VEC2} ${uv} = ${adjacencyLookupUv}`); }; _addAdjacencyLookupId(); _addAdjacencyLookupUv(); const connections = this.io.connections.inputConnections(); if (connections) { for (const connection of connections) { if (connection) { if (connection.inputIndex() >= SUBNET_INPUT_CONNECTIONS_OFFSET) { const connection_point = connection.destConnectionPoint(); if (connection_point) { const in_value = this.glVarName(connection_point.name()); const gl_type = connection_point.type(); const out = childNode.glVarName(connection_point.name()); const body_line = ` ${gl_type} ${out} = ${in_value}`; bodyLines.push(body_line); } } } } } linesController.addBodyLines(childNode, bodyLines); } // override subnetOutputLines(childNode: SubnetOutputGlNode) { // const bodyLines: string[] = super.subnetOutputLines(childNode); // const varNameP = this._withCurrentPoint(() => this.glVarName(ComputeNormalsInput.P)); // bodyLines.push(` ${this.glVarName(ComputeNormalsInput.P)} = ${varNameP}`); // return bodyLines; // } }