public static bool buildMeshAdjacency(ushort[] polys, int npolys, int nverts, int vertsPerPoly) { // Based on code by Eric Lengyel from: // http://www.terathon.com/code/edges.php int maxEdgeCount = npolys * vertsPerPoly; ushort[] firstEdge = new ushort[nverts + maxEdgeCount];//(ushort*)rcAlloc(sizeof(ushort)*(nverts + maxEdgeCount), RC_ALLOC_TEMP); if (firstEdge == null) return false; //ushort* nextEdge = firstEdge + nverts; int nextEdgeIndex = nverts; int edgeCount = 0; //rcEdge* edges = (rcEdge*)rcAlloc(sizeof(rcEdge)*maxEdgeCount, RC_ALLOC_TEMP); rcEdge[] edges = new rcEdge[maxEdgeCount]; rccsArrayItemsCreate(edges); if (edges == null) { //rcFree(firstEdge); firstEdge = null; return false; } for (int i = 0; i < nverts; i++) { firstEdge[i] = RC_MESH_NULL_IDX; } for (int i = 0; i < npolys; ++i) { int tIndex = i * vertsPerPoly * 2; //ushort* t = &polys[i*vertsPerPoly*2]; for (int j = 0; j < vertsPerPoly; ++j) { if (polys[tIndex + j] == RC_MESH_NULL_IDX) break; ushort v0 = polys[tIndex + j]; ushort v1 = (j + 1 >= vertsPerPoly || polys[tIndex + j + 1] == RC_MESH_NULL_IDX) ? polys[tIndex + 0] : polys[tIndex + j + 1]; if (v0 < v1) { rcEdge edge = edges[edgeCount]; edge.vert[0] = v0; edge.vert[1] = v1; edge.poly[0] = (ushort)i; edge.polyEdge[0] = (ushort)j; edge.poly[1] = (ushort)i; edge.polyEdge[1] = 0; // Insert edge firstEdge[nextEdgeIndex + edgeCount] = firstEdge[v0]; firstEdge[v0] = (ushort)edgeCount; edgeCount++; } } } for (int i = 0; i < npolys; ++i) { //ushort* t = &polys[i*vertsPerPoly*2]; int tIndex = i * vertsPerPoly * 2; for (int j = 0; j < vertsPerPoly; ++j) { if (polys[tIndex + j] == RC_MESH_NULL_IDX) break; ushort v0 = polys[tIndex + j]; ushort v1 = (j + 1 >= vertsPerPoly || polys[tIndex + j + 1] == RC_MESH_NULL_IDX) ? polys[tIndex + 0] : polys[tIndex + j + 1]; if (v0 > v1) { for (ushort e = firstEdge[v1]; e != RC_MESH_NULL_IDX; e = firstEdge[nextEdgeIndex + e]) { rcEdge edge = edges[e]; if (edge.vert[1] == v0 && edge.poly[0] == edge.poly[1]) { edge.poly[1] = (ushort)i; edge.polyEdge[1] = (ushort)j; break; } } } } } // Store adjacency for (int i = 0; i < edgeCount; ++i) { rcEdge e = edges[i]; if (e.poly[0] != e.poly[1]) { //ushort* p0 = &polys[e.poly[0]*vertsPerPoly*2]; //ushort* p1 = &polys[e.poly[1]*vertsPerPoly*2]; //p0[vertsPerPoly + e.polyEdge[0]] = e.poly[1]; //p1[vertsPerPoly + e.polyEdge[1]] = e.poly[0]; polys[e.poly[0] * vertsPerPoly * 2 + vertsPerPoly + e.polyEdge[0]] = e.poly[1]; polys[e.poly[1] * vertsPerPoly * 2 + vertsPerPoly + e.polyEdge[1]] = e.poly[0]; } } //rcFree(firstEdge); //rcFree(edges); return true; }
static bool BuildAdjacency(int nverts, int npolys, ref ushort[] tris) { int maxEdgeCount = npolys * nvp; ushort[] firstEdge = new ushort[nverts + maxEdgeCount]; int edgeCount = 0; rcEdge[] edges = new rcEdge[maxEdgeCount]; for (int i = 0; i < maxEdgeCount; i++) { edges[i] = new rcEdge(); edges[i].vert = new ushort[2] { 0, 0 }; edges[i].polyEdge = new ushort[2] { 0, 0 }; edges[i].poly = new ushort[2] { 0, 0 }; } for (int i = 0; i < nverts; i++) { firstEdge[i] = RC_MESH_NULL_IDX; } const int un = nvp * 2; for (int i = 0; i < npolys; ++i) { for (int j = 0; j < nvp; ++j) { if (tris[i * un + j] == RC_MESH_NULL_IDX) { break; } ushort v0 = tris[i * un + j]; ushort v1 = ((j + 1 >= nvp) || (tris[i * un + j + 1] == RC_MESH_NULL_IDX)) ? tris[i * un] : tris[i * un + j + 1]; if (v0 < v1) { rcEdge edge = edges[edgeCount]; edge.vert[0] = v0; edge.vert[1] = v1; edge.poly[0] = (ushort)i; edge.polyEdge[0] = (ushort)j; edge.poly[1] = (ushort)i; edge.polyEdge[1] = 0; // Insert edge firstEdge[nverts + edgeCount] = firstEdge[v0]; firstEdge[v0] = (ushort)edgeCount; edgeCount++; } } } for (int i = 0; i < npolys; ++i) { for (int j = 0; j < nvp; ++j) { if (tris[i * un + j] == RC_MESH_NULL_IDX) { break; } ushort v0 = tris[i * un + j]; ushort v1 = ((j + 1 >= nvp) || (tris[i * un + j + 1] == RC_MESH_NULL_IDX)) ? tris[i * un] : tris[i * un + j + 1]; if (v0 > v1) { for (ushort e = firstEdge[v1]; e != RC_MESH_NULL_IDX; e = firstEdge[nverts + e]) { rcEdge edge = edges[e]; if (edge.vert[1] == v0 && edge.poly[0] == edge.poly[1]) { edge.poly[1] = (ushort)i; edge.polyEdge[1] = (ushort)j; break; } } } } } // Store adjacency for (int i = 0; i < edgeCount; ++i) { rcEdge e = edges[i]; if (e.poly[0] != e.poly[1]) { tris[e.poly[0] * un + nvp + e.polyEdge[0]] = e.poly[1]; tris[e.poly[1] * un + nvp + e.polyEdge[1]] = e.poly[0]; } } return(true); }