Ejemplo n.º 1
0
    private void AddSegment(List <Vector2> aSegment, bool aClosed, Ferr2DT_TerrainDirection aDir = Ferr2DT_TerrainDirection.None)
    {
        Ferr2DT_SegmentDescription desc = GetDescription(aSegment);

        if (aDir != Ferr2DT_TerrainDirection.None)
        {
            desc = terrainMaterial.GetDescriptor(aDir);
        }
        int   bodyID    = UnityEngine.Random.Range(0, desc.body.Length);
        Rect  body      = terrainMaterial.ToUV(desc.body[bodyID]);
        float bodyWidth = body.width * unitsPerUV.x;

        int tSeed = UnityEngine.Random.seed;

        Vector2 capLeftSlideDir  = (aSegment[1] - aSegment[0]);
        Vector2 capRightSlideDir = (aSegment[aSegment.Count - 2] - aSegment[aSegment.Count - 1]);

        capLeftSlideDir.Normalize();
        capRightSlideDir.Normalize();
        aSegment[0] -= capLeftSlideDir * desc.capOffset;
        aSegment[aSegment.Count - 1] -= capRightSlideDir * desc.capOffset;

        for (int i = 0; i < aSegment.Count - 1; i++)
        {
            Vector2 norm1   = Vector2.zero;
            Vector2 norm2   = Vector2.zero;
            float   length  = Vector2.Distance(aSegment[i + 1], aSegment[i]);
            int     repeats = Mathf.Max(1, Mathf.FloorToInt(length / bodyWidth + stretchThreshold));

            norm1 = Ferr2D_Path.GetNormal(aSegment, i, aClosed);
            norm2 = Ferr2D_Path.GetNormal(aSegment, i + 1, aClosed);

            for (int t = 1; t < repeats + 1; t++)
            {
                UnityEngine.Random.seed = (int)(transform.position.x * 100000 + transform.position.y * 10000 + i * 100 + t);
                body = terrainMaterial.ToUV(desc.body[UnityEngine.Random.Range(0, desc.body.Length)]);
                Vector2 pos1, pos2, n1, n2;

                pos1 = Vector2.Lerp(aSegment[i], aSegment[i + 1], (float)(t - 1) / repeats);
                pos2 = Vector2.Lerp(aSegment[i], aSegment[i + 1], (float)t / repeats);
                n1   = Vector2.Lerp(norm1, norm2, (float)(t - 1) / repeats);
                n2   = Vector2.Lerp(norm1, norm2, (float)t / repeats);

                float d    = (body.height / 2) * unitsPerUV.y;
                float yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -desc.yOffset : desc.yOffset;
                int   v1   = dMesh.AddVertex(pos1.x + n1.x * (d + yOff), pos1.y + n1.y * (d + yOff), desc.zOffset, body.x, fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
                int   v2   = dMesh.AddVertex(pos1.x - n1.x * (d - yOff), pos1.y - n1.y * (d - yOff), desc.zOffset, body.x, fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
                int   v3   = dMesh.AddVertex(pos2.x + n2.x * (d + yOff), pos2.y + n2.y * (d + yOff), desc.zOffset, body.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? body.yMax : body.y);
                int   v4   = dMesh.AddVertex(pos2.x - n2.x * (d - yOff), pos2.y - n2.y * (d - yOff), desc.zOffset, body.xMax, fill == Ferr2DT_FillMode.InvertedClosed ? body.y    : body.yMax);
                dMesh.AddFace(v1, v3, v4, v2);
            }
        }
        if (!aClosed)
        {
            AddCap(aSegment, desc, -1);
            AddCap(aSegment, desc, 1);
        }
        UnityEngine.Random.seed = tSeed;
    }
    public static Rect AtlasField(Ferr2DT_TerrainMaterial aMat, Rect aRect, Texture aTexture)
    {
        EditorGUILayout.BeginHorizontal(GUILayout.Height(64));
        GUILayout.Space(5);
        GUILayout.Space(64);

        Rect  r   = GUILayoutUtility.GetLastRect();
        float max = Mathf.Max(1, Mathf.Max(aRect.width, aRect.height));

        r.width  = Mathf.Max(1, (aRect.width / max) * 64);
        r.height = Mathf.Max(1, (aRect.height / max) * 64);

        GUI.DrawTexture(new Rect(r.x - 1, r.y - 1, r.width + 2, 1), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.x - 1, r.yMax + 1, r.width + 2, 1), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.x - 1, r.y - 1, 1, r.height + 2), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.xMax, r.y - 1, 1, r.height + 2), EditorGUIUtility.whiteTexture);
        GUI.DrawTextureWithTexCoords(r, aTexture, aMat.ToUV(aRect));
        GUILayout.Space(10);

        Rect result = aMat.ToNative(EditorGUILayout.RectField(aMat.ToPixels(aRect)));

        EditorGUILayout.EndHorizontal();

        return(result);
    }
    public static Rect AtlasField          (Ferr2DT_TerrainMaterial aMat, Rect aRect, Texture aTexture) {
		EditorGUILayout.BeginHorizontal(GUILayout.Height(64));
		GUILayout.Space(5);
		GUILayout.Space(64);
		
		Rect  r   = GUILayoutUtility.GetLastRect();
		float max = Mathf.Max (1, Mathf.Max ( aRect.width, aRect.height ));
		r.width   = Mathf.Max (1, (aRect.width  / max) * 64);
		r.height  = Mathf.Max (1, (aRect.height / max) * 64);
		
		GUI      .DrawTexture(new Rect(r.x-1,  r.y-1,    r.width+2, 1),          EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.x-1,  r.yMax+1, r.width+2, 1),          EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.x-1,  r.y-1,    1,         r.height+2), EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.xMax, r.y-1,    1,         r.height+2), EditorGUIUtility.whiteTexture);
		GUI      .DrawTextureWithTexCoords(r, aTexture, aMat.ToUV(aRect));
		GUILayout.Space(10);

        Rect result = aMat.ToNative(EditorGUILayout.RectField(aMat.ToPixels(aRect)));
		EditorGUILayout.EndHorizontal();
		
		return result;
	}
    public static void ShowSample(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, float aWidth)
    {
        if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null)  return;

        Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir];
        float totalWidth                = desc.leftCap.width + desc.rightCap.width + (desc.body[0].width * 3);
        float sourceHeight              = MaxHeight(desc);

        float scale = Mathf.Min(aWidth/totalWidth, 64 / sourceHeight);

        GUILayout.Space(sourceHeight* scale);
        float x = 0;
        float y = GUILayoutUtility.GetLastRect().y;
        if (desc.leftCap.width != 0) {
            float yOff = ((sourceHeight - desc.leftCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(0,y+yOff,desc.leftCap.width * scale, desc.leftCap.height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.leftCap));
            x += desc.leftCap.width * scale;
        }
        for (int i = 0; i < 3; i++)
        {
            int id = (2-i) % desc.body.Length;
            float yOff = ((sourceHeight - desc.body[id].height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x,y+yOff,desc.body[id].width * scale, desc.body[id].height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.body[id]));
            x += desc.body[id].width * scale;
        }
        if (desc.leftCap.width != 0) {
            float yOff = ((sourceHeight - desc.rightCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x,y+yOff,desc.rightCap.width * scale, desc.rightCap.height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.rightCap));
        }
    }
    public static void ShowSample(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, float aWidth)
    {
        if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null)
        {
            return;
        }

        Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir);
        float totalWidth   = desc.leftCap.width + desc.rightCap.width + (desc.body[0].width * 3);
        float sourceHeight = MaxHeight(desc);

        float scale = Mathf.Min(aWidth / totalWidth, 64 / sourceHeight);

        GUILayout.Space(sourceHeight * scale);
        float x = GUILayoutUtility.GetLastRect().x;
        float y = GUILayoutUtility.GetLastRect().y;

        if (desc.leftCap.width != 0)
        {
            float yOff = ((sourceHeight - desc.leftCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.leftCap.width * scale, desc.leftCap.height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.leftCap));
            x += desc.leftCap.width * scale;
        }
        for (int i = 0; i < 3; i++)
        {
            int   id   = (2 - i) % desc.body.Length;
            float yOff = ((sourceHeight - desc.body[id].height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.body[id].width * scale, desc.body[id].height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.body[id]));
            x += desc.body[id].width * scale;
        }
        if (desc.leftCap.width != 0)
        {
            float yOff = ((sourceHeight - desc.rightCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.rightCap.width * scale, desc.rightCap.height * scale), aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture, aMat.ToUV(desc.rightCap));
        }
    }
Ejemplo n.º 6
0
    /// <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);
    }