@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
143 lines (142 loc) • 5.29 kB
JavaScript
"use strict";
import { QuadHalfEdge } from "./QuadHalfEdge";
import { QuadNode } from "./QuadNode";
import { quadHalfEdgeIndices, NEIGHBOUR_INDICES } from "./QuadGraphCommon";
import { addToMapAtEntry, getMapElementAtEntry } from "../../../../../core/MapUtils";
import { PrimitiveGraph } from "../../../entities/primitive/PrimitiveGraph";
import { setToArray } from "../../../../SetUtils";
const _indices = { index0: 0, index1: 0 };
const _neighbourIdsSet = /* @__PURE__ */ new Set();
const _neighbourIdsArray = [];
export class QuadGraph extends PrimitiveGraph {
constructor() {
super(...arguments);
this._quadsById = /* @__PURE__ */ new Map();
this._edgesByIndex = /* @__PURE__ */ new Map();
this._halfEdgeByHalfEdge = /* @__PURE__ */ new Map();
this._halfEdgeByQuadId = /* @__PURE__ */ new Map();
this._quadIdsByPointIndex = /* @__PURE__ */ new Map();
}
addQuad(quadId, quadIndices) {
const quadNode = new QuadNode(quadId, quadIndices);
this._quadsById.set(quadId, quadNode);
for (let i = 0; i < 4; i++) {
quadHalfEdgeIndices(quadIndices, i, _indices);
const edge = new QuadHalfEdge({
quadId,
index0: _indices.index0,
index1: _indices.index1,
sideIndex: i
});
addToMapAtEntry(this._edgesByIndex, _indices.index0, _indices.index1, edge);
const oppositeHalfEdge = getMapElementAtEntry(this._edgesByIndex, _indices.index1, _indices.index0);
if (oppositeHalfEdge) {
this._halfEdgeByHalfEdge.set(edge, oppositeHalfEdge);
this._halfEdgeByHalfEdge.set(oppositeHalfEdge, edge);
addToMapAtEntry(this._halfEdgeByQuadId, quadNode.id, oppositeHalfEdge.quadId, edge);
addToMapAtEntry(this._halfEdgeByQuadId, oppositeHalfEdge.quadId, quadNode.id, oppositeHalfEdge);
}
}
for (const index of quadIndices) {
let quadIds = this._quadIdsByPointIndex.get(index);
if (!quadIds) {
quadIds = /* @__PURE__ */ new Set();
this._quadIdsByPointIndex.set(index, quadIds);
}
quadIds.add(quadId);
}
return quadNode;
}
quadNode(quadId) {
return this._quadsById.get(quadId);
}
quadIdsByPointIndex(pointIndex) {
return this._quadIdsByPointIndex.get(pointIndex);
}
neighbourData(quadId, sideIndex, target) {
const quadNode = this._quadsById.get(quadId);
if (!quadNode) {
target.quadNode = null;
target.neighbourIndex = null;
return;
}
quadHalfEdgeIndices(quadNode.indices, sideIndex, _indices);
const halfEdge = getMapElementAtEntry(this._edgesByIndex, _indices.index0, _indices.index1);
const oppositeHalfEdge = this._halfEdgeByHalfEdge.get(halfEdge);
if (!oppositeHalfEdge) {
target.quadNode = null;
target.neighbourIndex = null;
return;
}
const oppositeQuadId = oppositeHalfEdge.quadId;
target.quadNode = this._quadsById.get(oppositeQuadId);
target.neighbourIndex = oppositeHalfEdge.sideIndex;
}
// private _hasNeighbourSharingEdge(quadId: number, sideIndex: NeighbourIndex): boolean {
// const quadNode = this._quadsById.get(quadId);
// if (!quadNode) {
// return false;
// }
// quadHalfEdgeIndices(quadNode.indices, sideIndex, _indices);
// const halfEdge = getMapElementAtEntry(this._edgesByIndex, _indices.index0, _indices.index1)!;
// return this._halfEdgeByHalfEdge.has(halfEdge);
// }
neighbourIdsSharingEdge(quadId, target) {
target.length = 0;
const quadNode = this._quadsById.get(quadId);
if (!quadNode) {
return;
}
_neighbourIdsSet.clear();
for (const i of NEIGHBOUR_INDICES) {
quadHalfEdgeIndices(quadNode.indices, i, _indices);
const halfEdge = getMapElementAtEntry(this._edgesByIndex, _indices.index0, _indices.index1);
const oppositeHalfEdge = this._halfEdgeByHalfEdge.get(halfEdge);
if (oppositeHalfEdge) {
const oppositeQuadId = oppositeHalfEdge.quadId;
_neighbourIdsSet.add(oppositeQuadId);
}
}
setToArray(_neighbourIdsSet, target);
}
neighbourIdsSharingPoint(quadId, target) {
target.length = 0;
const quadNode = this._quadsById.get(quadId);
if (!quadNode) {
return;
}
_neighbourIdsSet.clear();
const indices = quadNode.indices;
for (const index of indices) {
const neighbourIndices = this._quadIdsByPointIndex.get(index);
if (neighbourIndices) {
for (const neighbourIndex of neighbourIndices) {
if (neighbourIndex != quadId) {
_neighbourIdsSet.add(neighbourIndex);
}
}
}
}
setToArray(_neighbourIdsSet, target);
}
neighbourIndex(quadId, neighbourIndex, withSharedEdge) {
if (withSharedEdge == true) {
this.neighbourIdsSharingEdge(quadId, _neighbourIdsArray);
} else {
this.neighbourIdsSharingPoint(quadId, _neighbourIdsArray);
}
const neighbourId = _neighbourIdsArray[neighbourIndex];
if (neighbourId != null) {
return neighbourId;
}
return -1;
}
neighboursCount(quadId, withSharedEdge) {
if (withSharedEdge == true) {
this.neighbourIdsSharingEdge(quadId, _neighbourIdsArray);
} else {
this.neighbourIdsSharingPoint(quadId, _neighbourIdsArray);
}
return _neighbourIdsArray.length;
}
}