private List <Vector2> LegacyOffsetColliderVerts(List <Vector2> aSegment, List <float> aSegmentScales, Ferr2DT_TerrainDirection aDir)
    {
        List <Vector2> result = new List <Vector2>(aSegment);
        int            count  = aSegment.Count;

        for (int v = count - 1; v >= 0; v--)
        {
            Vector2 norm      = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, v, 0, false) : Ferr2D_Path.GetNormal(aSegment, v, false);
            Vector2 segNormal = Ferr2D_Path.GetSegmentNormal(v, aSegment, false);
            float   scale     = v >= aSegmentScales.Count ? 1 : aSegmentScales[v];
            float   rootScale = smoothPath ? 1 : 1f / Mathf.Abs(Mathf.Cos(Vector2.Angle(-segNormal, norm) * Mathf.Deg2Rad));
            scale = scale * rootScale;

            if (fill == Ferr2DT_FillMode.None)
            {
                result.Add(aSegment[v] + new Vector2(norm.x * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]) * scale);
                result[v] += new Vector2(norm.x * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]) * scale;
            }
            else
            {
                float   dist   = surfaceOffset[(int)aDir];
                Vector2 offset = new Vector2(dist, dist);
                result[v] += new Vector2(norm.x * -offset.x, norm.y * -offset.y) * scale;
            }
        }
        return(result);
    }
Esempio n. 2
0
    List <Vector2> OffsetColliderVerts(List <Vector2> aSegment, List <float> aSegmentScales, Ferr2DT_TerrainDirection aDir)
    {
        List <Vector2> result = new List <Vector2>(aSegment);
        int            count  = aSegment.Count;

        for (int v = count - 1; v >= 0; v--)
        {
            Vector2 norm  = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, v, 0, false) : Ferr2D_Path.GetNormal(aSegment, v, false);
            float   scale = v >= aSegmentScales.Count ? 1 : aSegmentScales[v];
            if (fill == Ferr2DT_FillMode.None)
            {
                result.Add(aSegment[v] + new Vector2(norm.x * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top], norm.y * surfaceOffset[(int)Ferr2DT_TerrainDirection.Top]) * scale);
                result[v] += new Vector2(norm.x * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom], norm.y * -surfaceOffset[(int)Ferr2DT_TerrainDirection.Bottom]) * scale;
            }
            else
            {
                float   dist   = surfaceOffset[(int)aDir];
                Vector2 offset = new Vector2(dist, dist);
                result[v] += new Vector2(norm.x * -offset.x, norm.y * -offset.y) * scale;
            }
        }
        return(result);
    }
    private void LegacyAddVertexColumn(Ferr2DT_SegmentDescription aDesc, List <Vector2> aSegment, List <float> aSegmentScale, bool aClosed, Ferr2D_DynamicMesh mesh, Rect body, float d, float yOff, bool aConnectFace, float slicePercent, int ptLocal, float pctLocal, ref int p1, ref int p2, ref int p3)
    {
        Vector2 pos1 = smoothPath ? Ferr2D_Path.HermiteGetPt(aSegment, ptLocal, pctLocal, aClosed) : Ferr2D_Path.LinearGetPt(aSegment, ptLocal, pctLocal, aClosed);
        Vector2 n1   = smoothPath ? Ferr2D_Path.HermiteGetNormal(aSegment, ptLocal, pctLocal, aClosed) : Ferr2D_Path.LinearGetNormal(aSegment, ptLocal, pctLocal, aClosed);
        float   s    = aClosed    ? Mathf.Lerp(aSegmentScale[ptLocal], aSegmentScale[(ptLocal + 1) % aSegmentScale.Count], pctLocal) : Mathf.Lerp(aSegmentScale[ptLocal], aSegmentScale[Mathf.Min(ptLocal + 1, aSegmentScale.Count - 1)], pctLocal);

        // this compensates for scale distortion when corners are very sharp, but the normals are not long enough to keep the edge the appropriate width
        // not actually a problem for smooth paths
        if (!smoothPath)
        {
            n1.Normalize();
            float rootScale = 1f / Mathf.Abs(Mathf.Cos(Vector2.Angle(Ferr2D_Path.GetSegmentNormal(ptLocal, aSegment, aClosed), n1) * Mathf.Deg2Rad));
            s = s * rootScale;
        }

        int v1 = mesh.AddVertex(pos1.x + n1.x * (d * s + yOff), pos1.y + n1.y * (d * s + yOff), -slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
        int v2 = mesh.AddVertex(pos1.x - n1.x * (d * s - yOff), pos1.y - n1.y * (d * s - yOff), slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), fill == Ferr2DT_FillMode.InvertedClosed ? body.y : body.yMax);
        int v3 = splitMiddle ? mesh.AddVertex(pos1.x + n1.x * yOff, pos1.y + n1.y * yOff, aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, slicePercent), Mathf.Lerp(body.y, body.yMax, 0.5f)) : -1;

        if (aConnectFace)
        {
            if (!splitMiddle)
            {
                mesh.AddFace(v2, p2, p1, v1);
            }
            else
            {
                mesh.AddFace(v2, p2, p3, v3);
                mesh.AddFace(v3, p3, p1, v1);
            }
        }

        p1 = v1;
        p2 = v2;
        p3 = v3;
    }
Esempio n. 4
0
    private void AddCap(List <Vector2> aSegment, Ferr2DT_SegmentDescription aDesc, bool aInner, float aDir, float aScale, bool aSmooth)
    {
        int     index = 0;
        Vector2 dir   = Vector2.zero;

        if (aDir < 0)
        {
            index = 0;
            dir   = aSegment[0] - aSegment[1];
        }
        else
        {
            index = aSegment.Count - 1;
            dir   = aSegment[aSegment.Count - 1] - aSegment[aSegment.Count - 2];
        }
        dir.Normalize();
        Vector2 norm = aSmooth ? Ferr2D_Path.HermiteGetNormal(aSegment, index, 0, false): Ferr2D_Path.GetNormal(aSegment, index, false);
        Vector2 pos  = aSegment[index];
        float   yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;
        Rect    cap;

        if (aDir < 0)
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerRightCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerRightCap) : terrainMaterial.ToUV(aDesc.rightCap);
            }
            else
            {
                cap = (aInner && aDesc.innerLeftCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerLeftCap) : terrainMaterial.ToUV(aDesc.leftCap);
            }
        }
        else
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerLeftCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerLeftCap) : terrainMaterial.ToUV(aDesc.leftCap);
            }
            else
            {
                cap = (aInner && aDesc.innerRightCap.width > 0) ? terrainMaterial.ToUV(aDesc.innerRightCap) : terrainMaterial.ToUV(aDesc.rightCap);
            }
        }

        float width = cap.width * unitsPerUV.x;
        float scale = (cap.height / 2) * unitsPerUV.y * aScale;

        float minU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.xMax : cap.x;
        float maxU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.x    : cap.xMax;
        float minV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.yMax : cap.y;
        float maxV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.y    : cap.yMax;

        if (aDir >= 0)
        {
            float t = minU;
            minU = maxU;
            maxU = t;
        }

        int v1 = DMesh.AddVertex(pos + dir * width + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(minU, minV));
        int v2 = DMesh.AddVertex(pos + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(maxU, minV));

        int v15 = splitMiddle ? DMesh.AddVertex(pos + dir * width + (norm * yOff), aDesc.zOffset, new Vector2(minU, cap.y + (cap.height / 2))) : -1;
        int v25 = splitMiddle ? DMesh.AddVertex(pos + (norm * yOff), aDesc.zOffset, new Vector2(maxU, cap.y + (cap.height / 2))) : -1;

        int v3 = DMesh.AddVertex(pos - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(maxU, maxV));
        int v4 = DMesh.AddVertex(pos + dir * width - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(minU, maxV));

        if (splitMiddle && aDir < 0)
        {
            DMesh.AddFace(v1, v2, v25, v15);
            DMesh.AddFace(v15, v25, v3, v4);
        }
        else if (splitMiddle && aDir >= 0)
        {
            DMesh.AddFace(v2, v1, v15, v25);
            DMesh.AddFace(v25, v15, v4, v3);
        }
        else if (aDir < 0)
        {
            DMesh.AddFace(v1, v2, v3, v4);
        }
        else
        {
            DMesh.AddFace(v2, v1, v4, v3);
        }
    }
Esempio n. 5
0
    private void SlicedQuad(List <Vector2> aSegment, int aVert, float aStart, float aEnd, int aCuts, bool aSmoothed, bool aClosed, Ferr2DT_SegmentDescription aDesc, float aStartScale, float aEndScale)
    {
        Vector2[] pos    = new Vector2[aCuts];
        Vector2[] norm   = new Vector2[aCuts];
        float  [] scales = new float  [aCuts];
        Vector3   tn1    = Ferr2D_Path.GetNormal(aSegment, aVert, aClosed);
        Vector3   tn2    = Ferr2D_Path.GetNormal(aSegment, aVert + 1, aClosed);

        // get the data needed to make the quad
        for (int i = 0; i < aCuts; i++)
        {
            float percent = aStart + (i / (float)(aCuts - 1)) * (aEnd - aStart);
            if (aSmoothed)
            {
                pos [i] = Ferr2D_Path.HermiteGetPt(aSegment, aVert, percent, aClosed);
                norm[i] = Ferr2D_Path.HermiteGetNormal(aSegment, aVert, percent, aClosed);
            }
            else
            {
                pos [i] = Vector2.Lerp(aSegment[aVert], aSegment[aVert + 1], percent);
                norm[i] = Vector2.Lerp(tn1, tn2, percent);
            }
            scales[i] = Mathf.Lerp(aStartScale, aEndScale, (i / (float)(aCuts - 1)));
        }

        int tSeed = 0;

        if (randomByWorldCoordinates)
        {
            tSeed = UnityEngine.Random.seed;
            UnityEngine.Random.seed = (int)(pos[0].x * 700000 + pos[0].y * 30000);
        }

        Rect  body = terrainMaterial.ToUV(aDesc.body[UnityEngine.Random.Range(0, aDesc.body.Length)]);
        float d    = (body.height / 2) * unitsPerUV.y;
        float yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;

        if (randomByWorldCoordinates)
        {
            UnityEngine.Random.seed = tSeed;
        }

        // put the data together into a mesh
        int p1 = 0, p2 = 0, p3 = 0;

        for (int i = 0; i < aCuts; i++)
        {
            float percent = (i / (float)(aCuts - 1));

            Vector3 pos1 = pos [i];
            Vector3 n1   = norm[i];
            int     v1   = DMesh.AddVertex(pos1.x + n1.x * (d * scales[i] + yOff), pos1.y + n1.y * (d * scales[i] + yOff), -slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
            int     v2   = DMesh.AddVertex(pos1.x - n1.x * (d * scales[i] - yOff), pos1.y - n1.y * (d * scales[i] - yOff), slantAmount + aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
            int     v3   = splitMiddle ? DMesh.AddVertex(pos1.x + n1.x * yOff, pos1.y + n1.y * yOff, aDesc.zOffset, Mathf.Lerp(body.x, body.xMax, percent), Mathf.Lerp(body.y, body.yMax, 0.5f)) : -1;

            if (i != 0)
            {
                if (!splitMiddle)
                {
                    DMesh.AddFace(v2, p2, p1, v1);
                }
                else
                {
                    DMesh.AddFace(v2, p2, p3, v3);
                    DMesh.AddFace(v3, p3, p1, v1);
                }
            }

            p1 = v1;
            p2 = v2;
            p3 = v3;
        }
    }