@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
60 lines (59 loc) • 2.04 kB
JavaScript
;
import { Vector3, Ray, Triangle } from "three";
import { tetCenter } from "./tetCenter";
import { tetFaceTriangle } from "./tetTriangle";
import { tetNeighbour } from "./tetNeighboursHelper";
const _ray = new Ray();
const _triangle = new Triangle();
const _intersectionTarget = new Vector3();
function findNextFaceIndex(tetGeometry, tetIndex, ray, intersectionTarget) {
for (let faceIndex = 0; faceIndex < 4; faceIndex++) {
tetFaceTriangle(tetGeometry, tetIndex, faceIndex, _triangle);
const intersection = ray.intersectTriangle(_triangle.c, _triangle.b, _triangle.a, false, intersectionTarget);
if (intersection != null) {
if (intersection.distanceTo(ray.origin) <= ray.direction.length()) {
return faceIndex;
}
}
}
return null;
}
function selectRandomUnvisitedTet(tetGeometry, visitedTets) {
let selectedTetId = null;
tetGeometry.tetrahedrons.forEach((tet, tetId) => {
if (!visitedTets.has(tetId)) {
selectedTetId = tetId;
}
});
return selectedTetId;
}
const _stack = /* @__PURE__ */ new Set();
export function findTetContainingPosition(tetGeometry, position, rayOrigin, tetIdOrigin) {
_stack.clear();
let foundTetId = tetIdOrigin;
_stack.add(foundTetId);
let i = 0;
_ray.origin.copy(rayOrigin);
_ray.direction.copy(position).sub(_ray.origin);
const maxIterations = tetGeometry.tetsCount();
while (i < maxIterations) {
const nextFaceIndex = findNextFaceIndex(tetGeometry, foundTetId, _ray, _intersectionTarget);
if (nextFaceIndex == null) {
break;
}
const nextTetId = tetNeighbour(tetGeometry, foundTetId, nextFaceIndex);
if (nextTetId == null) {
const selectedTetId = selectRandomUnvisitedTet(tetGeometry, _stack);
if (selectedTetId != null) {
foundTetId = selectedTetId;
}
} else {
foundTetId = nextTetId;
}
_stack.add(foundTetId);
tetCenter(tetGeometry, foundTetId, _ray.origin);
_ray.direction.copy(position).sub(_ray.origin);
i++;
}
return foundTetId;
}