UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

138 lines (105 loc) 4.36 kB
import { INTERNAL_RND_SORT_SEED } from "./constants/INTERNAL_RND_SORT_SEED.js"; import { QuickSortEdges } from "./QuickSortEdges.js"; import { vec3 } from "gl-matrix"; import { GetEdge } from "./GetEdge.js"; /** * * @param {STriInfo[]} pTriInfos * @param {number[]|Float32Array} pEdges * @param {number[]} piTriListIn * @param {number} iNrTrianglesIn * @returns {void} */ export function BuildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn) { // build array of edges const uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed? for (let f = 0; f < iNrTrianglesIn; f++) { for (let i = 0; i < 3; i++) { const edge_index = f * 3 + i; const i0 = piTriListIn[edge_index]; const i1 = piTriListIn[f * 3 + (i < 2 ? (i + 1) : 0)]; pEdges[edge_index * 3] = i0 < i1 ? i0 : i1; // put minimum index in i0 pEdges[edge_index * 3 + 1] = !(i0 < i1) ? i0 : i1; // put maximum index in i1 pEdges[edge_index * 3 + 2] = f; // record face number } } // sort over all edges by i0, this is a pricey one. QuickSortEdges(pEdges, 0, iNrTrianglesIn * 3 - 1, 0, uSeed); // sort channel 0 which is i0 // sub sort over i1, should be fast. // could replace this with a 64 bit int sort over (i0,i1) // with i0 as msb in the quicksort call above. const iEntries = iNrTrianglesIn * 3; let iCurStartIndex = 0; for (let i = 1; i < iEntries; i++) { if (pEdges[iCurStartIndex * 3] !== pEdges[i * 3]) { const iL = iCurStartIndex; const iR = i - 1; //const int iElems = i-iL; iCurStartIndex = i; QuickSortEdges(pEdges, iL, iR, 1, uSeed); // sort channel 1 which is i1 } } // sub sort over f, which should be fast. // this step is to remain compliant with BuildNeighborsSlow() when // more than 2 triangles use the same edge (such as a butterfly topology). iCurStartIndex = 0; for (let i = 1; i < iEntries; i++) { if ( pEdges[iCurStartIndex * 3] !== pEdges[i * 3] || pEdges[iCurStartIndex * 3 + 1] !== pEdges[i * 3 + 1] ) { const iL = iCurStartIndex; const iR = i - 1; //const int iElems = i-iL; iCurStartIndex = i; QuickSortEdges(pEdges, iL, iR, 2, uSeed); // sort channel 2 which is f } } const temp_edge_A = vec3.create(); const temp_edge_B = vec3.create(); // pair up, adjacent triangles for (let i = 0; i < iEntries; i++) { const i0 = pEdges[i * 3]; const i1 = pEdges[i * 3 + 1]; const f = pEdges[i * 3 + 2]; GetEdge(temp_edge_A, 0, piTriListIn, f * 3, i0, i1); // resolve index ordering and edge_num const i0_A = temp_edge_A[0]; const i1_A = temp_edge_A[1]; const edgenum_A = temp_edge_A[2]; const bUnassigned_A = pTriInfos[f].FaceNeighbors[edgenum_A] === -1; if (!bUnassigned_A) { continue; } let j = i + 1; while ( j < iEntries && i0 === pEdges[j * 3] && i1 === pEdges[j * 3 + 1] ) { const t = pEdges[j * 3 + 2]; GetEdge( temp_edge_B, 0, piTriListIn, t * 3, pEdges[j * 3], pEdges[j * 3 + 1] ); // resolve index ordering and edge_num // flip i0_B and i1_B const i0_B = temp_edge_B[1]; const i1_B = temp_edge_B[2]; const edgenum_B = temp_edge_B[2]; //assert(!(i0_A==i1_B && i1_A==i0_B)); const bUnassigned_B = pTriInfos[t].FaceNeighbors[edgenum_B] === -1; if (i0_A === i0_B && i1_A === i1_B && bUnassigned_B) { const t = pEdges[j * 3 + 2]; pTriInfos[f].FaceNeighbors[edgenum_A] = t; //assert(pTriInfos[t].FaceNeighbors[edgenum_B]==-1); pTriInfos[t].FaceNeighbors[edgenum_B] = f; break; } else { ++j; } } } }