Esempio n. 1
0
        /// <summary>
        /// Marching squares over the given domain using the mesh defined via the dimensions
        ///    (wid,hei) to build a set of polygons such that f(x,y) less than 0, using the given number
        ///    'bin' for recursive linear inteprolation along cell boundaries.
        ///
        ///    if 'comb' is true, then the polygons will also be composited into larger possible concave
        ///    polygons.
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="cellWidth"></param>
        /// <param name="cellHeight"></param>
        /// <param name="f"></param>
        /// <param name="lerpCount"></param>
        /// <param name="combine"></param>
        /// <returns></returns>
        public static List <Vertices> DetectSquares(Box2D.AABB domain, float cellWidth, float cellHeight, sbyte[,] f,
                                                    int lerpCount, bool combine)
        {
            CxFastList <GeomPoly> ret = new CxFastList <GeomPoly>();

            List <Vertices> verticesList = new List <Vertices>();

            //NOTE: removed assignments as they were not used.
            List <GeomPoly> polyList;
            GeomPoly        gp;

            int  xn = (int)(domain.GetExtents().x * 2 / cellWidth);
            bool xp = xn == (domain.GetExtents().x * 2 / cellWidth);
            int  yn = (int)(domain.GetExtents().y * 2 / cellHeight);
            bool yp = yn == (domain.GetExtents().y * 2 / cellHeight);

            if (!xp)
            {
                xn++;
            }
            if (!yp)
            {
                yn++;
            }

            sbyte[,] fs       = new sbyte[xn + 1, yn + 1];
            GeomPolyVal[,] ps = new GeomPolyVal[xn + 1, yn + 1];

            //populate shared function lookups.
            for (int x = 0; x < xn + 1; x++)
            {
                int x0;
                if (x == xn)
                {
                    x0 = (int)domain.upperBound.x;
                }
                else
                {
                    x0 = (int)(x * cellWidth + domain.lowerBound.x);
                }
                for (int y = 0; y < yn + 1; y++)
                {
                    int y0;
                    if (y == yn)
                    {
                        y0 = (int)domain.upperBound.y;
                    }
                    else
                    {
                        y0 = (int)(y * cellHeight + domain.lowerBound.y);
                    }
                    fs[x, y] = f[x0, y0];
                }
            }

            //generate sub-polys and combine to scan lines
            for (int y = 0; y < yn; y++)
            {
                float y0 = y * cellHeight + domain.lowerBound.y;
                float y1;
                if (y == yn - 1)
                {
                    y1 = domain.upperBound.y;
                }
                else
                {
                    y1 = y0 + cellHeight;
                }
                GeomPoly pre = null;
                for (int x = 0; x < xn; x++)
                {
                    float x0 = x * cellWidth + domain.lowerBound.x;
                    float x1;
                    if (x == xn - 1)
                    {
                        x1 = domain.upperBound.x;
                    }
                    else
                    {
                        x1 = x0 + cellWidth;
                    }

                    gp = new GeomPoly();

                    int key = MarchSquare(f, fs, ref gp, x, y, x0, y0, x1, y1, lerpCount);
                    if (gp.Length != 0)
                    {
                        if (combine && pre != null && (key & 9) != 0)
                        {
                            combLeft(ref pre, ref gp);
                            gp = pre;
                        }
                        else
                        {
                            ret.Add(gp);
                        }
                        ps[x, y] = new GeomPolyVal(gp, key);
                    }
                    else
                    {
                        gp = null;
                    }
                    pre = gp;
                }
            }
            if (!combine)
            {
                polyList = ret.GetListOfElements();

                foreach (GeomPoly poly in polyList)
                {
                    verticesList.Add(new Vertices(poly.Points.GetListOfElements()));
                }

                return(verticesList);
            }

            //combine scan lines together
            for (int y = 1; y < yn; y++)
            {
                int x = 0;
                while (x < xn)
                {
                    GeomPolyVal p = ps[x, y];

                    //skip along scan line if no polygon exists at this point
                    if (p == null)
                    {
                        x++;
                        continue;
                    }

                    //skip along if current polygon cannot be combined above.
                    if ((p.Key & 12) == 0)
                    {
                        x++;
                        continue;
                    }

                    //skip along if no polygon exists above.
                    GeomPolyVal u = ps[x, y - 1];
                    if (u == null)
                    {
                        x++;
                        continue;
                    }

                    //skip along if polygon above cannot be combined with.
                    if ((u.Key & 3) == 0)
                    {
                        x++;
                        continue;
                    }

                    float ax = x * cellWidth + domain.lowerBound.x;
                    float ay = y * cellHeight + domain.lowerBound.y;

                    CxFastList <FVector2> bp = p.GeomP.Points;
                    CxFastList <FVector2> ap = u.GeomP.Points;

                    //skip if it's already been combined with above polygon
                    if (u.GeomP == p.GeomP)
                    {
                        x++;
                        continue;
                    }

                    //combine above (but disallow the hole thingies
                    CxFastListNode <FVector2> bi = bp.Begin();
                    while (Square(bi.Elem().Y - ay) > Box2D.Settings.b2_epsilon || bi.Elem().X < ax)
                    {
                        bi = bi.Next();
                    }

                    //NOTE: Unused
                    //Vector2 b0 = bi.elem();
                    FVector2 b1 = bi.Next().Elem();
                    if (Square(b1.Y - ay) > Box2D.Settings.b2_epsilon)
                    {
                        x++;
                        continue;
                    }

                    bool brk = true;
                    CxFastListNode <FVector2> ai = ap.Begin();
                    while (ai != ap.End())
                    {
                        if (VecDsq(ai.Elem(), b1) < Box2D.Settings.b2_epsilon)
                        {
                            brk = false;
                            break;
                        }
                        ai = ai.Next();
                    }
                    if (brk)
                    {
                        x++;
                        continue;
                    }

                    CxFastListNode <FVector2> bj = bi.Next().Next();
                    if (bj == bp.End())
                    {
                        bj = bp.Begin();
                    }
                    while (bj != bi)
                    {
                        ai = ap.Insert(ai, bj.Elem()); // .clone()
                        bj = bj.Next();
                        if (bj == bp.End())
                        {
                            bj = bp.Begin();
                        }
                        u.GeomP.Length++;
                    }
                    //u.p.simplify(float.Epsilon,float.Epsilon);
                    //
                    ax = x + 1;
                    while (ax < xn)
                    {
                        GeomPolyVal p2 = ps[(int)ax, y];
                        if (p2 == null || p2.GeomP != p.GeomP)
                        {
                            ax++;
                            continue;
                        }
                        p2.GeomP = u.GeomP;
                        ax++;
                    }
                    ax = x - 1;
                    while (ax >= 0)
                    {
                        GeomPolyVal p2 = ps[(int)ax, y];
                        if (p2 == null || p2.GeomP != p.GeomP)
                        {
                            ax--;
                            continue;
                        }
                        p2.GeomP = u.GeomP;
                        ax--;
                    }
                    ret.Remove(p.GeomP);
                    p.GeomP = u.GeomP;

                    x = (int)((bi.Next().Elem().X - domain.lowerBound.x) / cellWidth) + 1;
                    //x++; this was already commented out!
                }
            }

            polyList = ret.GetListOfElements();

            foreach (GeomPoly poly in polyList)
            {
                verticesList.Add(new Vertices(poly.Points.GetListOfElements()));
            }

            return(verticesList);
        }
Esempio n. 2
0
 /// <summary>
 /// Get all intersections between a line segment and an AABB.
 /// </summary>
 /// <param name="point1">The first point of the line segment to test</param>
 /// <param name="point2">The second point of the line segment to test.</param>
 /// <param name="aabb">The AABB that is used for testing intersection.</param>
 /// <param name="intersectionPoints">An list of intersection points. Any intersection points found will be added to this list.</param>
 public static void LineSegmentAABBIntersect(ref FVector2 point1, ref FVector2 point2, Box2D.AABB aabb,
                                             ref List <FVector2> intersectionPoints)
 {
     // LineSegmentVerticesIntersect(ref point1, ref point2, aabb.vVertices, ref intersectionPoints);
 }