Exemple #1
0
            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);
                        }
                    }
                }
            }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
            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));
            }