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