Beispiel #1
0
    private void AddEdge()
    {
        // split the path into segments based on the split angle
        List <List <int>               > segments = new List <List <int>               >();
        List <Ferr2DT_TerrainDirection>  dirs     = new List <Ferr2DT_TerrainDirection>();
        List <int> order = new List <int>();

        segments = GetSegments(Path.GetVertsRaw(), out dirs);
        if (dirs.Count < segments.Count)
        {
            dirs.Add(directionOverrides[directionOverrides.Count - 1]);
        }
        for (int i = 0; i < segments.Count; i++)
        {
            order.Add(i);
        }

        order.Sort(
            new Ferr_LambdaComparer <int>(
                (x, y) => {
            Ferr2DT_TerrainDirection dirx = dirs[x] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[x], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[x];
            Ferr2DT_TerrainDirection diry = dirs[y] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[y], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[y];
            return(terrainMaterial.GetDescriptor(diry).zOffset.CompareTo(terrainMaterial.GetDescriptor(dirx).zOffset));
        }
                ));

        // process the segments into meshes
        for (int i = 0; i < order.Count; i++)
        {
            AddSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, segments[order[i]]), GetScalesFromIndices(segments[order[i]]), order.Count <= 1 && Path.closed, smoothPath, dirs[order[i]]);
        }
    }
    private void AddEdge()
    {
        // split the path into segments based on the split angle
        List <List <int>               > segments = new List <List <int>               >();
        List <Ferr2DT_TerrainDirection>  dirs     = new List <Ferr2DT_TerrainDirection>();
        List <int> order = new List <int>();

        segments = GetSegments(Path.GetVertsRaw(), out dirs);
        if (dirs.Count < segments.Count)
        {
            dirs.Add(directionOverrides[directionOverrides.Count - 1]);
        }
        for (int i = 0; i < segments.Count; i++)
        {
            order.Add(i);
        }

        order.Sort(
            new Ferr.LambdaComparer <int>(
                (x, y) => {
            Ferr2DT_TerrainDirection dirx = dirs[x] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[x], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[x];
            Ferr2DT_TerrainDirection diry = dirs[y] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[y], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[y];
            return(terrainMaterial.GetDescriptor(diry).zOffset.CompareTo(terrainMaterial.GetDescriptor(dirx).zOffset));
        }
                ));

        // process the segments into meshes
        for (int i = 0; i < order.Count; i++)
        {
            List <int> currSeg = segments[order[i]];
            List <int> prevSeg = order[i] - 1 < 0 ?  segments[segments.Count - 1] : segments[order[i] - 1];
            List <int> nextSeg = segments[(order[i] + 1) % segments.Count];

            int curr = currSeg[0];
            int prev = prevSeg[prevSeg.Count - 2];
            int next = currSeg[1];

            Vector2 p1        = Path.pathVerts[prev] - Path.pathVerts[curr];
            Vector2 p2        = Path.pathVerts[next] - Path.pathVerts[curr];
            bool    leftInner = Mathf.Atan2(p1.x * p2.y - p1.y * p2.x, Vector2.Dot(p1, p2)) < 0;

            curr = currSeg[currSeg.Count - 1];
            prev = currSeg[currSeg.Count - 2];
            next = nextSeg[1];

            p1 = Path.pathVerts[prev] - Path.pathVerts[curr];
            p2 = Path.pathVerts[next] - Path.pathVerts[curr];
            bool rightInner = Mathf.Atan2(p1.x * p2.y - p1.y * p2.x, Vector2.Dot(p1, p2)) < 0;

            AddSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, segments[order[i]]), leftInner, rightInner, GetScalesFromIndices(segments[order[i]]), order.Count <= 1 && Path.closed, smoothPath, dirs[order[i]]);
        }
    }
    private List <Vector2> GetSegmentsCombined(float aSplitDist)
    {
        List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>();
        List <Vector2> result = new List <Vector2>();
        List <List <int>               > list = GetSegments(Path.GetVertsRaw(), out dirs);

        for (int i = 0; i < list.Count; i++)
        {
            if (smoothPath && list[i].Count > 2)
            {
                result.AddRange(Ferr2D_Path.SmoothSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, list[i]), aSplitDist, false));
            }
            else
            {
                result.AddRange(Ferr2D_Path.IndicesToPath(Path.pathVerts, list[i]));
            }
        }
        return(result);
    }
    /// <summary>
    /// Retrieves a list of line segments that directly represent the collision volume of the terrain. This includes offsets and removed edges.
    /// </summary>
    /// <returns>A list of line segments.</returns>
    public List <List <Vector2> > GetColliderVerts()
    {
        List <Vector2> tVerts = Path.GetVertsRaw();

        // drop a skirt on skirt-based terrain
        if ((fill == Ferr2DT_FillMode.Skirt || fill == Ferr2DT_FillMode.FillOnlySkirt) && tVerts.Count > 0)
        {
            Vector2 start = tVerts[0];
            Vector2 end   = tVerts[tVerts.Count - 1];
            tVerts.Add(new Vector2(end.x, fillY));
            tVerts.Add(new Vector2(start.x, fillY));
            tVerts.Add(new Vector2(start.x, start.y));
        }

        float fillDist = (terrainMaterial.ToUV(terrainMaterial.GetBody((Ferr2DT_TerrainDirection)0, 0)).width *(terrainMaterial.edgeMaterial.mainTexture.width / pixelsPerUnit)) / (Mathf.Max(1, splitCount)) * splitDist;
        List <Ferr2DT_TerrainDirection> dirs   = new List <Ferr2DT_TerrainDirection>();
        List <List <Vector2> >          result = new List <List <Vector2>           >();
        List <List <int> > list = GetSegments(tVerts, out dirs);
        List <Vector2>     curr = new List <Vector2>();

        // remove segments that aren't on the terrain
        for (int i = 0; i < list.Count; i++)
        {
            if ((dirs[i] == Ferr2DT_TerrainDirection.Bottom && !collidersBottom) ||
                (dirs[i] == Ferr2DT_TerrainDirection.Left && !collidersLeft) ||
                (dirs[i] == Ferr2DT_TerrainDirection.Top && !collidersTop) ||
                (dirs[i] == Ferr2DT_TerrainDirection.Right && !collidersRight))
            {
                if (curr.Count > 0)
                {
                    result.Add(new List <Vector2>(curr));
                    curr.Clear(                       );
                }
            }
            else
            {
                // create a list of verts and scales for this edge
                List <float>   tScales = null;
                List <Vector2> tList   = null;
                Ferr2D_Path.IndicesToPath(tVerts, vertScales, list[i], out tList, out tScales);

                // smooth it!
                if (smoothPath && tList.Count > 2)
                {
                    Ferr2D_Path.SmoothSegment(tList, tScales, fillDist, false, out tList, out tScales);
                }

                // offset the verts based on scale and terrain edge info
                tList = OffsetColliderVerts(tList, tScales, dirs[i]);

                // sharpen corners properly!
                if (curr.Count > 0 && sharpCorners)
                {
                    MergeCorner(ref curr, ref tList);
                }

                curr.AddRange(tList);
            }
        }
        if (sharpCorners)
        {
            MergeCorner(ref curr, ref curr);
        }
        if (curr.Count > 0)
        {
            result.Add(curr);
        }

        return(result);
    }