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)); } }
/// <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); }