private void ProcessEdge(GroundEdge edge) { IEnumerable <PotentialDiagonal> potentialDiagonals = grid.GetPotentialDiagonals(edge); foreach (PotentialDiagonal potentialDiagonal in potentialDiagonals) { if (!unavailableDiagonals.Contains(potentialDiagonal.Key)) { if (availableDiagonals.ContainsKey(potentialDiagonal.Key)) { PotentialDiagonal otherHalf = availableDiagonals[potentialDiagonal.Key]; if (potentialDiagonal.SharedPoint != otherHalf.SharedPoint) { GroundQuad newQuad = new GroundQuad(potentialDiagonal.EdgeA, potentialDiagonal.EdgeB, otherHalf.EdgeA, otherHalf.EdgeB); RegisterNewQuad(newQuad); quads.Add(newQuad); } } else { availableDiagonals.Add(potentialDiagonal.Key, potentialDiagonal); } } } }
private static void mergeRegionHoles(Context ctx, ContourRegion region) { // Sort holes from left to right. for (int i = 0; i < region.nholes; i++) { int[] minleft = findLeftMostVertex(region.holes[i].contour); region.holes[i].minx = minleft[0]; region.holes[i].minz = minleft[1]; region.holes[i].leftmost = minleft[2]; } Array.Sort(region.holes, new CompareHoles()); int maxVerts = region.outline.nverts; for (int i = 0; i < region.nholes; i++) { maxVerts += region.holes[i].contour.nverts; } PotentialDiagonal[] diags = new PotentialDiagonal[maxVerts]; for (int pd = 0; pd < maxVerts; pd++) { diags[pd] = new PotentialDiagonal(); } Contour outline = region.outline; // Merge holes into the outline one by one. for (int i = 0; i < region.nholes; i++) { Contour hole = region.holes[i].contour; int index = -1; int bestVertex = region.holes[i].leftmost; for (int iter = 0; iter < hole.nverts; iter++) { // Find potential diagonals. // The 'best' vertex must be in the cone described by 3 cosequtive vertices of the outline. // ..o j-1 // | // | * best // | // j o-----o j+1 // : int ndiags = 0; int corner = bestVertex * 4; for (int j = 0; j < outline.nverts; j++) { if (inCone(j, outline.nverts, outline.verts, corner, hole.verts)) { int dx = outline.verts[j * 4 + 0] - hole.verts[corner + 0]; int dz = outline.verts[j * 4 + 2] - hole.verts[corner + 2]; diags[ndiags].vert = j; diags[ndiags].dist = dx * dx + dz * dz; ndiags++; } } // Sort potential diagonals by distance, we want to make the connection as short as possible. Array.Sort(diags, 0, ndiags, new CompareDiagDist()); // Find a diagonal that is not intersecting the outline not the remaining holes. index = -1; for (int j = 0; j < ndiags; j++) { int pt = diags[j].vert * 4; bool intersect = intersectSegCountour(pt, corner, diags[i].vert, outline.nverts, outline.verts, outline.verts, hole.verts); for (int k = i; k < region.nholes && !intersect; k++) { intersect |= intersectSegCountour(pt, corner, -1, region.holes[k].contour.nverts, region.holes[k].contour.verts, outline.verts, hole.verts); } if (!intersect) { index = diags[j].vert; break; } } // If found non-intersecting diagonal, stop looking. if (index != -1) { break; } // All the potential diagonals for the current vertex were intersecting, try next vertex. bestVertex = (bestVertex + 1) % hole.nverts; } if (index == -1) { ctx.warn("mergeHoles: Failed to find merge points for"); continue; } mergeContours(region.outline, hole, index, bestVertex); } }
private IEnumerable <string> GetKeysFor(GroundQuad quad) { yield return(PotentialDiagonal.GetKey(quad.Points[0].Index, quad.Points[2].Index)); yield return(PotentialDiagonal.GetKey(quad.Points[1].Index, quad.Points[3].Index)); }