UNPKG

@polygonjs/polygonjs

Version:

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

176 lines (175 loc) 6.79 kB
"use strict"; import { Vector3, BufferGeometry, Float32BufferAttribute } from "three"; import { QuadSopNode } from "./_BaseQuad"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { InputCloneMode } from "../../poly/InputCloneMode"; import { halfEdgeIndicesInCommonBetweenQuads, pointInCommonBetweenQuadsSharingPoint, quadGraphFromQuadObject } from "../../../core/geometry/modules/quad/graph/QuadGraphUtils"; import { QuadPrimitive } from "../../../core/geometry/modules/quad/QuadPrimitive"; import { Attribute } from "../../../core/geometry/Attribute"; import { ObjectType } from "../../../core/geometry/Constant"; import { arrayDifference } from "../../../core/ArrayUtils"; const _neighbourIdsSharingEdge = []; const _neighbourIdsSharingPoint = []; const _neighbourIdsSharingPointOnly = []; const _quadCenter0 = new Vector3(); const _quadCenter1 = new Vector3(); const _p0 = new Vector3(); const _p1 = new Vector3(); const _center = new Vector3(); const _halfEdgeIndices = { index0: -1, index1: -1 }; export var QuadConnectionMode = /* @__PURE__ */ ((QuadConnectionMode2) => { QuadConnectionMode2["NEIGHBOUR_INDEX"] = "neighbourIndex"; QuadConnectionMode2["QUAD_ID"] = "quadId"; return QuadConnectionMode2; })(QuadConnectionMode || {}); export const QUAD_CONNECTION_MODES = [ "neighbourIndex" /* NEIGHBOUR_INDEX */, "quadId" /* QUAD_ID */ ]; export var QuadConnectionType = /* @__PURE__ */ ((QuadConnectionType2) => { QuadConnectionType2["STRAIGHT"] = "straight"; QuadConnectionType2["DIAGONAL"] = "diagonal"; return QuadConnectionType2; })(QuadConnectionType || {}); export const QUAD_CONNECTION_TYPES = ["straight" /* STRAIGHT */, "diagonal" /* DIAGONAL */]; class QuadConnectionSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.mode = ParamConfig.INTEGER(QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */), { menu: { entries: QUAD_CONNECTION_MODES.map((name, value) => ({ name, value })) } }); this.type = ParamConfig.INTEGER(QUAD_CONNECTION_TYPES.indexOf("straight" /* STRAIGHT */), { menu: { entries: QUAD_CONNECTION_TYPES.map((name, value) => ({ name, value })) }, visibleIf: { mode: QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */) } }); this.quadId0 = ParamConfig.INTEGER(0, { range: [0, 100], rangeLocked: [true, false] }); this.quadId1 = ParamConfig.INTEGER(0, { range: [0, 100], rangeLocked: [true, false], visibleIf: { mode: QUAD_CONNECTION_MODES.indexOf("quadId" /* QUAD_ID */) } }); this.neighbourIndex = ParamConfig.INTEGER(0, { range: [0, 4], rangeLocked: [true, false], visibleIf: { mode: QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */) } }); } } const ParamsConfig = new QuadConnectionSopParamsConfig(); export class QuadConnectionSopNode extends QuadSopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return SopType.QUAD_CONNECTION; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.NEVER); } setConnectionMode(mode) { this.p.mode.set(QUAD_CONNECTION_MODES.indexOf(mode)); } connectionMode() { return QUAD_CONNECTION_MODES[this.pv.mode]; } setConnectionType(type) { this.p.type.set(QUAD_CONNECTION_TYPES.indexOf(type)); } connectionType() { return QUAD_CONNECTION_TYPES[this.pv.type]; } async cook(inputCoreGroups) { const coreGroup = inputCoreGroups[0]; const quadObjects = coreGroup.quadObjects(); const newGeometries = []; if (quadObjects) { for (const object of quadObjects) { const newGeometry = this._process(object); if (newGeometry) { newGeometries.push(newGeometry); } } } this.setGeometries(newGeometries, ObjectType.LINE_SEGMENTS); } _process(quadObject) { const graph = quadGraphFromQuadObject(quadObject); const { quadId0 } = this.pv; const mode = this.connectionMode(); if (graph.quadNode(quadId0) == null) { return; } const getQuadId1ByNeighbourIndex = () => { graph.neighbourIdsSharingEdge(quadId0, _neighbourIdsSharingEdge); const type2 = this.connectionType(); if (type2 == "straight" /* STRAIGHT */) { return _neighbourIdsSharingEdge[this.pv.neighbourIndex]; } else { graph.neighbourIdsSharingPoint(quadId0, _neighbourIdsSharingPoint); arrayDifference(_neighbourIdsSharingPoint, _neighbourIdsSharingEdge, _neighbourIdsSharingPointOnly); return _neighbourIdsSharingPointOnly[this.pv.neighbourIndex]; } }; const getConnectionTypeFromNeighbourId = (neighbourId) => { graph.neighbourIdsSharingEdge(quadId0, _neighbourIdsSharingEdge); graph.neighbourIdsSharingPoint(quadId0, _neighbourIdsSharingPoint); arrayDifference(_neighbourIdsSharingPoint, _neighbourIdsSharingEdge, _neighbourIdsSharingPointOnly); return _neighbourIdsSharingPointOnly.indexOf(neighbourId) >= 0 ? "diagonal" /* DIAGONAL */ : "straight" /* STRAIGHT */; }; const quadId1 = mode == "neighbourIndex" /* NEIGHBOUR_INDEX */ ? getQuadId1ByNeighbourIndex() : this.pv.quadId1; const type = mode == "neighbourIndex" /* NEIGHBOUR_INDEX */ ? this.connectionType() : getConnectionTypeFromNeighbourId(this.pv.quadId1); if (graph.quadNode(quadId1) == null) { return; } QuadPrimitive.position(quadObject, quadId0, _quadCenter0); QuadPrimitive.position(quadObject, quadId1, _quadCenter1); const srcPositions = quadObject.geometry.attributes[Attribute.POSITION].array; const geometry = new BufferGeometry(); if (type == "straight" /* STRAIGHT */) { halfEdgeIndicesInCommonBetweenQuads({ quadObject, quadId0, quadId1, target: _halfEdgeIndices }); _p0.fromArray(srcPositions, _halfEdgeIndices.index0 * 3); _p1.fromArray(srcPositions, _halfEdgeIndices.index1 * 3); _center.copy(_p0).add(_p1).multiplyScalar(0.5); } else { const sharedPointId = pointInCommonBetweenQuadsSharingPoint(graph, quadId0, quadId1); if (sharedPointId != null) { _center.fromArray(srcPositions, sharedPointId * 3); } } const positions = new Float32Array(9); _quadCenter0.toArray(positions, 0); _center.toArray(positions, 3); _quadCenter1.toArray(positions, 6); geometry.setAttribute("position", new Float32BufferAttribute(positions, 3)); geometry.setIndex([0, 1, 1, 2]); return geometry; } }