UNPKG

@polygonjs/polygonjs

Version:

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

60 lines (59 loc) 2.04 kB
"use strict"; 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; }