public void FromJSON(Ferr_JSONValue aJSON) { Ferr_JSONValue json = new Ferr_JSONValue(); applyTo = (Ferr2DT_TerrainDirection)aJSON["applyTo", (int)Ferr2DT_TerrainDirection.Top]; zOffset = aJSON["zOffset",0f]; yOffset = aJSON["yOffset",0f]; capOffset = aJSON["capOffset",0f]; leftCap = new Rect( aJSON["leftCap.x", 0f], aJSON["leftCap.y", 0f], aJSON["leftCap.xMax", 0f], aJSON["leftCap.yMax", 0f]); rightCap = new Rect( aJSON["rightCap.x", 0f], aJSON["rightCap.y", 0f], aJSON["rightCap.xMax", 0f], aJSON["rightCap.yMax", 0f]); Ferr_JSONValue bodyArr = json["body"]; body = new Rect[bodyArr.Length]; for (int i = 0; i < body.Length; i++) { body[i] = new Rect( bodyArr[i]["x", 0 ], bodyArr[i]["y", 0 ], bodyArr[i]["xMax", 50], bodyArr[i]["yMax", 50]); } }
public void ShowPreviewDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, Rect aBounds) { Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir]; for (int i = 0; i < desc.body.Length; i++) { DrawRect(aMat.ToScreen( desc.body[i] ), aBounds); } DrawRect(aMat.ToScreen( desc.leftCap ), aBounds); DrawRect(aMat.ToScreen( desc.rightCap ), aBounds); }
public static void ShowPreview (Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, bool aSimpleUVs, bool aEditable, float aWidth) { if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null) return; GUILayout.Label(aMat.edgeMaterial.mainTexture, GUILayout.Width(Screen.width-aWidth)); Rect texRect = GUILayoutUtility.GetLastRect(); texRect.width = Mathf.Min(Screen.width-aWidth, aMat.edgeMaterial.mainTexture.width); texRect.height = (texRect.width / aMat.edgeMaterial.mainTexture.width) * aMat.edgeMaterial.mainTexture.height; ShowPreviewDirection(aMat, aDir, texRect, aSimpleUVs, aEditable); }
void ShowDirection(IFerr2DTMaterial aMat, Ferr2DT_TerrainDirection aDir) { Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir); desc.zOffset = EditorGUILayout.FloatField("Z Offset", desc.zOffset); desc.yOffset = EditorGUILayout.FloatField("Y Offset", desc.yOffset); desc.capOffset = EditorGUILayout.FloatField("Cap Offset", desc.capOffset); simpleUVs = EditorGUILayout.Toggle("Simple", simpleUVs); if (simpleUVs) { Ferr2DT_TerrainMaterialUtility.EditUVsSimple(aMat, desc); } else { Ferr2DT_TerrainMaterialUtility.EditUVsComplex(aMat, desc, width, ref currBody); } }
private CapFunction GetDirIcon(Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top) { return(CapDotTop); } else if (aDir == Ferr2DT_TerrainDirection.Right) { return(CapDotRight); } else if (aDir == Ferr2DT_TerrainDirection.Left) { return(CapDotLeft); } else if (aDir == Ferr2DT_TerrainDirection.Bottom) { return(CapDotBottom); } return(CapDotAuto); }
private Ferr2DT_TerrainDirection NextDir(Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top) { return(Ferr2DT_TerrainDirection.Right); } else if (aDir == Ferr2DT_TerrainDirection.Right) { return(Ferr2DT_TerrainDirection.Bottom); } else if (aDir == Ferr2DT_TerrainDirection.Left) { return(Ferr2DT_TerrainDirection.Top); } else if (aDir == Ferr2DT_TerrainDirection.Bottom) { return(Ferr2DT_TerrainDirection.None); } return(Ferr2DT_TerrainDirection.Left); }
private Texture2D GetDirIcon(Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top) { return(texTop); } else if (aDir == Ferr2DT_TerrainDirection.Right) { return(texRight); } else if (aDir == Ferr2DT_TerrainDirection.Left) { return(texLeft); } else if (aDir == Ferr2DT_TerrainDirection.Bottom) { return(texBottom); } return(texAuto); }
bool ColliderNormValid(Ferr2DT_PathTerrain aSprite, Vector2 aOne, Vector2 aTwo) { Ferr2DT_TerrainDirection dir = Ferr2D_Path.GetDirection(aTwo, aOne); if (dir == Ferr2DT_TerrainDirection.Top && aSprite.collidersTop) { return(true); } if (dir == Ferr2DT_TerrainDirection.Left && aSprite.collidersLeft) { return(true); } if (dir == Ferr2DT_TerrainDirection.Right && aSprite.collidersRight) { return(true); } if (dir == Ferr2DT_TerrainDirection.Bottom && aSprite.collidersBottom) { return(true); } return(false); }
public static void ShowSample(IFerr2DTMaterial 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 + (Mathf.Max(0, desc.body[0].width) * 3); float sourceHeight = MaxHeight(desc); Texture tex = aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture; float scale = Mathf.Min(aWidth / totalWidth, 64 / sourceHeight); float aspect = tex.height / tex.width; GUILayout.Space(sourceHeight * scale * aspect); 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 * aspect), tex, 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 * aspect), tex, 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 * aspect), tex, aMat.ToUV(desc.rightCap)); } }
/// <summary> /// Finds out if we actually have a descriptor for the given direction /// </summary> /// <param name="aDirection">Duh.</param> /// <returns>is it there, or is it not?</returns> public bool Has(Ferr2DT_TerrainDirection aDirection) { for (int i = 0; i < descriptors.Length; i++) { if (descriptors[i].applyTo == aDirection) return true; } return false; }
public int GetBodyCount(Ferr2DT_TerrainDirection aDirection) { return GetDescriptor(aDirection).body.Length; }
public Rect GetLCap(Ferr2DT_TerrainDirection aDirection) { return GetDescriptor(aDirection).leftCap; }
public Rect GetRCap(Ferr2DT_TerrainDirection aDirection) { return(GetDescriptor(aDirection).rightCap); }
private Ferr2DT_TerrainDirection NextDir (Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top ) return Ferr2DT_TerrainDirection.Right; else if (aDir == Ferr2DT_TerrainDirection.Right ) return Ferr2DT_TerrainDirection.Bottom; else if (aDir == Ferr2DT_TerrainDirection.Left ) return Ferr2DT_TerrainDirection.Top; else if (aDir == Ferr2DT_TerrainDirection.Bottom) return Ferr2DT_TerrainDirection.None; return Ferr2DT_TerrainDirection.Left; }
public void LegacyUpgrade() { if (!IsLegacy) { return; } #if UNITY_EDITOR UnityEditor.Undo.RecordObject(gameObject, "Upgrade Ferr2D Terrain"); #endif Ferr2D_Path oldPath = GetComponent <Ferr2D_Path>(); MatchOverrides(); // upgrade the path pathData = new Ferr2DPath(); pathData.Closed = oldPath.closed; for (int i = 0; i < oldPath.pathVerts.Count; i++) { int next = Ferr.PathUtil.WrapIndex(i - 1, Path.Count, Path.closed); Ferr.PointType pointType = Ferr.PointType.Sharp; if (smoothPath) { Ferr2DT_TerrainDirection prevSegmentDirection = Ferr2D_Path.GetDirection(Path.pathVerts, next, fill == Ferr2DT_FillMode.InvertedClosed, Path.closed, directionOverrides); Ferr2DT_TerrainDirection nextSegmentDirection = Ferr2D_Path.GetDirection(Path.pathVerts, i, fill == Ferr2DT_FillMode.InvertedClosed, Path.closed, directionOverrides); if (prevSegmentDirection == nextSegmentDirection) { pointType = Ferr.PointType.Auto; } } Ferr2D_PointData data = new Ferr2D_PointData(); data.scale = vertScales[next]; data.directionOverride = (int)directionOverrides[next]; data.cutOverrides = cutOverrides[next].data; pathData.Add(oldPath.pathVerts[i], data, pointType); } pathData.ReverseSelf(); pathData.SetDirty(); // remove old path values directionOverrides = null; cutOverrides = null; vertScales = null; // upgrade collider settings if (createCollider) { if (useEdgeCollider) { colliderMode = Ferr2D_ColliderMode.Edge2D; } else if (create3DCollider) { colliderMode = Ferr2D_ColliderMode.Mesh3D; } else { colliderMode = Ferr2D_ColliderMode.Polygon2D; } } else { colliderMode = Ferr2D_ColliderMode.None; } // upgrade the fill settings switch (fill) { case Ferr2DT_FillMode.None: edgeMode = Ferr2D_SectionMode.Normal; fillMode = Ferr2D_SectionMode.None; break; case Ferr2DT_FillMode.Closed: edgeMode = Ferr2D_SectionMode.Normal; fillMode = Ferr2D_SectionMode.Normal; break; case Ferr2DT_FillMode.InvertedClosed: edgeMode = Ferr2D_SectionMode.Invert; fillMode = Ferr2D_SectionMode.Invert; break; case Ferr2DT_FillMode.FillOnlyClosed: edgeMode = Ferr2D_SectionMode.None; fillMode = Ferr2D_SectionMode.Normal; break; case Ferr2DT_FillMode.Skirt: edgeMode = Ferr2D_SectionMode.Normal; fillMode = Ferr2D_SectionMode.Normal; useSkirt = true; break; case Ferr2DT_FillMode.FillOnlySkirt: edgeMode = Ferr2D_SectionMode.None; fillMode = Ferr2D_SectionMode.Normal; useSkirt = true; break; } isLegacy = false; #if UNITY_EDITOR UnityEditor.Undo.DestroyObjectImmediate(oldPath); #else Destroy(oldPath); #endif Build(true); #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif }
private void DoCutOverrideModeHandles(Ferr2D_Path path, Ferr2DT_PathTerrain terrain, Matrix4x4 mat, Transform camTransform) { List <List <int> > segments = new List <List <int> >(); List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>(); List <Vector2> rawVerts = path.GetVertsRaw(); // cut the terrain into segments, we need segment info to draw these points segments = terrain.GetSegments(rawVerts, out dirs); for (int s = 0; s < segments.Count; s++) { List <int> currSeg = segments[s]; List <Vector2> currVerts = Ferr2D_Path.IndicesToList(rawVerts, currSeg); List <Ferr2DT_PathTerrain.CutOverrides> overrides = Ferr2D_Path.IndicesToList(terrain.cutOverrides, currSeg); // find information about this segment Ferr2DT_TerrainDirection currDir = dirs[s]; Ferr2DT_SegmentDescription desc = default(Ferr2DT_SegmentDescription); if (currDir != Ferr2DT_TerrainDirection.None) { desc = terrain.TerrainMaterial.GetDescriptor(currDir); } else { desc = terrain.GetDescription(currSeg); } // if there's no body segment choices, don't bother with the rest of this if (desc.body.Length < 2) { continue; } Vector2 capLeftSlideDir = (currVerts[1] - currVerts[0]); Vector2 capRightSlideDir = (currVerts[currVerts.Count - 2] - currVerts[currVerts.Count - 1]); capLeftSlideDir.Normalize(); capRightSlideDir.Normalize(); currVerts[0] -= capLeftSlideDir * desc.capOffset; currVerts[currVerts.Count - 1] -= capRightSlideDir * desc.capOffset; float distance = Ferr2D_Path.GetSegmentLength(currVerts); // how many texture cuts are there on the segment float bodyWidth = desc.body[0].width * (terrain.TerrainMaterial.edgeMaterial.mainTexture.width / terrain.pixelsPerUnit); int textureCuts = Mathf.Max(1, Mathf.FloorToInt(distance / bodyWidth + 0.5f)); // data is attached to the points still, check if we've switched to a new point int activePt = -1; int activeLocalCut = -1; for (int c = 0; c < textureCuts; c++) { float pctGlobal = c / (float)textureCuts; int ptLocal = 0; float pctLocal = 0; Ferr2D_Path.PathGlobalPercentToLocal(currVerts, pctGlobal, out ptLocal, out pctLocal, distance, false); if (ptLocal != activePt) { // if they size down, we need to shorten the data too if (activePt != -1) { CapListSize <int>(ref overrides[activePt].data, activeLocalCut + 3); } activePt = ptLocal; activeLocalCut = 0; if (overrides[activePt].data == null) { overrides[activePt].data = new List <int>(); } } while (activeLocalCut >= overrides[activePt].data.Count) { overrides[activePt].data.Add(0); } CapFunction cap = CapDotAuto; int activeOverride = overrides[activePt].data[activeLocalCut]; if (activeOverride != 0) { if (activeOverride == 1) { cap = CapDot1; } else if (activeOverride == 2) { cap = CapDot2; } else if (activeOverride == 3) { cap = CapDot3; } else if (activeOverride == 4) { cap = CapDot4; } else if (activeOverride == 5) { cap = CapDot5; } else if (activeOverride >= 6) { cap = CapDotN; } } if (Event.current.alt) { cap = CapDotReset; } int ptShow = 0; float pctShow = 0; Ferr2D_Path.PathGlobalPercentToLocal(currVerts, pctGlobal + (1f / textureCuts) * 0.5f, out ptShow, out pctShow, distance, false); Vector2 pt = Ferr2D_Path.LinearGetPt(currVerts, ptShow, pctShow, false); Vector3 pos = mat.MultiplyPoint3x4(pt); float sc = HandleScale(pos) * 0.5f; if (Handles.Button(pos, camTransform.rotation, sc, sc, cap)) { Undo.RecordObject(terrain, "Lock Texture Segment"); overrides[activePt].data[activeLocalCut] = Event.current.alt ? 0 : (activeOverride + 1) % (desc.body.Length + 1); EditorUtility.SetDirty(terrain); GUI.changed = true; } activeLocalCut += 1; } if (activePt != -1) { CapListSize <int>(ref overrides[activePt].data, activeLocalCut + 3); } } }
private void AddSegment(List <Vector2> aSegment, bool aLeftInner, bool aRightInner, List <float> aScale, bool aClosed, bool aSmooth, Ferr2DT_TerrainDirection aDir = Ferr2DT_TerrainDirection.None) { Ferr2DT_SegmentDescription desc; if (aDir != Ferr2DT_TerrainDirection.None) { desc = terrainMaterial.GetDescriptor(aDir); } else { desc = GetDescription(aSegment); } int tSeed = UnityEngine.Random.seed; Rect body = terrainMaterial.ToUV(desc.body[0]); float bodyWidth = body.width * unitsPerUV.x; Vector3 point1, point2; float distance; int cuts; UnityEngine.Random.seed = (int)(aSegment[0].x * 100000 + aSegment[0].y * 10000); 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; point2 = aSegment[0]; for (int i = 0; i < aSegment.Count - 1; i++) { point1 = point2; point2 = aSegment[i + 1]; distance = Vector3.Distance(point1, point2); cuts = Mathf.Max(1, Mathf.FloorToInt(distance / bodyWidth + stretchThreshold)); for (int t = 0; t < cuts; t++) { float p1 = (float)(t) / cuts; float p2 = (float)(t + 1) / cuts; SlicedQuad(aSegment, i, p1, p2, Mathf.Max(2, splitCount + 2), aSmooth, aClosed, desc, Mathf.Lerp(aScale[i], aScale[i + 1], p1), Mathf.Lerp(aScale[i], aScale[i + 1], p2)); } } if (!aClosed) { AddCap(aSegment, desc, aLeftInner, -1, aScale[0], aSmooth); AddCap(aSegment, desc, aRightInner, 1, aScale[aScale.Count - 1], aSmooth); } UnityEngine.Random.seed = tSeed; }
void OnGUI() { if (material == null) { return; } // if this was an undo, repaint it if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": Repaint(); return; } } Undo.RecordObject(material, "Modified Terrain Material"); if (Ferr.EditorTools.ResetHandles()) { GUI.changed = true; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(GUILayout.Width(width)); Ferr.EditorTools.Box(5, () => { if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowSample(material, currDir, width - 10); } Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Top")) { currDir = Ferr2DT_TerrainDirection.Top; } if (currDir == Ferr2DT_TerrainDirection.Top) { if (prevDir != currDir) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); } bool showTop = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Top), "Use Top"); material.Set(Ferr2DT_TerrainDirection.Top, showTop); if (showTop) { ShowDirection(material, currDir); } } }, width - 10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Left")) { currDir = Ferr2DT_TerrainDirection.Left; } if (currDir == Ferr2DT_TerrainDirection.Left) { if (prevDir != currDir) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); } bool showLeft = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Left), "Use Left"); material.Set(Ferr2DT_TerrainDirection.Left, showLeft); if (showLeft) { ShowDirection(material, currDir); } } }, width - 10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Right")) { currDir = Ferr2DT_TerrainDirection.Right; } if (currDir == Ferr2DT_TerrainDirection.Right) { if (prevDir != currDir) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); } bool showRight = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Right), "Use Right"); material.Set(Ferr2DT_TerrainDirection.Right, showRight); if (showRight) { ShowDirection(material, currDir); } } }, width - 10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Bottom")) { currDir = Ferr2DT_TerrainDirection.Bottom; } if (currDir == Ferr2DT_TerrainDirection.Bottom) { if (prevDir != currDir) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); } bool showBottom = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Bottom), "Use Bottom"); material.Set(Ferr2DT_TerrainDirection.Bottom, showBottom); if (showBottom) { ShowDirection(material, currDir); } } }, width - 10, 0); }, 0, (int)this.position.height); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); scroll = EditorGUILayout.BeginScrollView(scroll); if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowPreview(material, currDir, simpleUVs, true, width); } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDrag) { Repaint(); } if (GUI.changed) { EditorUtility.SetDirty(material); Ferr2DT_PathTerrain[] terrain = GameObject.FindObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[]; for (int i = 0; i < terrain.Length; i++) { if (terrain[i].TerrainMaterial == material) { terrain[i].Build(true); } } } prevDir = currDir; }
private void AddSegment(List<Vector2> aSegment, bool aLeftInner, bool aRightInner, List<float> aScale, bool aClosed, bool aSmooth, Ferr2DT_TerrainDirection aDir = Ferr2DT_TerrainDirection.None) { Ferr2DT_SegmentDescription desc; if (aDir != Ferr2DT_TerrainDirection.None) { desc = terrainMaterial.GetDescriptor(aDir); } else { desc = GetDescription(aSegment); } int tSeed = UnityEngine.Random.seed; Rect body = terrainMaterial.ToUV( desc.body[0] ); float bodyWidth = body.width * unitsPerUV.x; Vector3 point1, point2; float distance; int cuts; UnityEngine.Random.seed = (int)(aSegment[0].x * 100000 + aSegment[0].y * 10000); 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; point2 = aSegment[0]; for (int i = 0; i < aSegment.Count-1; i++) { point1 = point2; point2 = aSegment[i+1]; distance = Vector3.Distance(point1, point2); cuts = Mathf.Max(1,Mathf.FloorToInt(distance / bodyWidth + stretchThreshold)); for (int t = 0; t < cuts; t++) { float p1 = (float)(t) / cuts; float p2 = (float)(t + 1) / cuts; SlicedQuad(aSegment, i, p1, p2, Mathf.Max(2, splitCount + 2), aSmooth, aClosed, desc, Mathf.Lerp(aScale[i], aScale[i + 1], p1), Mathf.Lerp(aScale[i], aScale[i + 1], p2)); } } if (!aClosed) { AddCap(aSegment, desc, aLeftInner, -1, aScale[0], aSmooth); AddCap(aSegment, desc, aRightInner, 1, aScale[aScale.Count-1], aSmooth); } UnityEngine.Random.seed = tSeed; }
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); }
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; }
void OnGUI() { if (material == null) return; // if this was an undo, repaint it if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": Repaint (); return; } } Undo.RecordObject(material, "Modified Terrain Material"); if (Ferr.EditorTools.ResetHandles()) { GUI.changed = true; } EditorGUILayout .BeginHorizontal (); EditorGUILayout .BeginVertical (GUILayout.Width(width)); Ferr.EditorTools.Box(5, () => { if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowSample(material, currDir, width-10); } Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Top")) currDir = Ferr2DT_TerrainDirection.Top; if (currDir == Ferr2DT_TerrainDirection.Top) { if (prevDir != currDir) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); bool showTop = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Top), "Use Top"); material.Set(Ferr2DT_TerrainDirection.Top, showTop); if (showTop) ShowDirection(material, currDir); } }, width-10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Left")) currDir = Ferr2DT_TerrainDirection.Left; if (currDir == Ferr2DT_TerrainDirection.Left) { if (prevDir != currDir) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); bool showLeft = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Left), "Use Left"); material.Set(Ferr2DT_TerrainDirection.Left, showLeft); if (showLeft) ShowDirection(material, currDir); } }, width - 10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Right")) currDir = Ferr2DT_TerrainDirection.Right; if (currDir == Ferr2DT_TerrainDirection.Right) { if (prevDir != currDir) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); bool showRight = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Right), "Use Right"); material.Set(Ferr2DT_TerrainDirection.Right, showRight); if (showRight) ShowDirection(material, currDir); } }, width - 10, 0); Ferr.EditorTools.Box(2, () => { if (GUILayout.Button("Bottom")) currDir = Ferr2DT_TerrainDirection.Bottom; if (currDir == Ferr2DT_TerrainDirection.Bottom) { if (prevDir != currDir) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.GetDescriptor(currDir)); bool showBottom = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Bottom), "Use Bottom"); material.Set(Ferr2DT_TerrainDirection.Bottom, showBottom); if (showBottom) ShowDirection(material, currDir); } }, width - 10, 0); }, 0, (int)this.position.height); EditorGUILayout.EndVertical (); EditorGUILayout.BeginVertical(); scroll = EditorGUILayout.BeginScrollView(scroll); if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowPreview(material, currDir, simpleUVs, true, width); } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical (); EditorGUILayout.EndHorizontal(); if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDrag) Repaint (); if (GUI.changed) { EditorUtility.SetDirty(material); Ferr2DT_PathTerrain[] terrain = GameObject.FindObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[]; for (int i = 0; i < terrain.Length; i++) { if(terrain[i].TerrainMaterial == material) terrain[i].Build(true); } } prevDir = currDir; }
private void LegacyAddSegment(List <Vector2> aSegment, bool aLeftInner, bool aRightInner, List <float> aScale, List <CutOverrides> aCutOverrides, bool aClosed, bool aSmooth, Ferr2DT_TerrainDirection aDir = Ferr2DT_TerrainDirection.None) { Ferr2DT_SegmentDescription desc; if (aDir != Ferr2DT_TerrainDirection.None) { desc = TerrainMaterial.GetDescriptor(aDir); } else { desc = GetDescription(aSegment); } #if UNITY_5_4_OR_NEWER UnityEngine.Random.State tSeed = UnityEngine.Random.state; #else int tSeed = UnityEngine.Random.seed; #endif Rect body = TerrainMaterial.ToUV(desc.body[0]); float bodyWidth = body.width * unitsPerUV.x; #if UNITY_5_4_OR_NEWER UnityEngine.Random.InitState((int)(aSegment[0].x * 100000 + aSegment[0].y * 10000)); #else UnityEngine.Random.seed = (int)(aSegment[0].x * 100000 + aSegment[0].y * 10000); #endif 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; LegacyCreateBody(desc, aSegment, aScale, aCutOverrides, bodyWidth, Mathf.Max(2, splitCount + 2), aClosed); if (!aClosed) { LegacyAddCap(aSegment, desc, aLeftInner, -1, aScale[0], aSmooth); LegacyAddCap(aSegment, desc, aRightInner, 1, aScale[aScale.Count - 1], aSmooth); } #if UNITY_5_4_OR_NEWER UnityEngine.Random.state = tSeed; #else UnityEngine.Random.seed = tSeed; #endif }
public Ferr2DT_SegmentDescription() { body = new Rect[] { new Rect(0,0,50,50) }; applyTo = Ferr2DT_TerrainDirection.Top; }
public static void ShowPreviewDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, Rect aBounds, bool aSimpleUVs, bool aEditable) { Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir); if (!aMat.Has(aDir)) { return; } if (!aEditable) { for (int i = 0; i < desc.body.Length; i++) { Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.body[i]), aBounds); } Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.leftCap), aBounds); Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.rightCap), aBounds); Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.innerLeftCap), aBounds); Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.innerRightCap), aBounds); } else if (aSimpleUVs) { float height = MaxHeight(desc); float capWidth = Mathf.Max(desc.leftCap.width, desc.rightCap.width); float bodyWidth = desc.body[0].width; int bodyCount = desc.body.Length; float texWidth = aMat.edgeMaterial.mainTexture != null ? aMat.edgeMaterial.mainTexture.width : 1; float texHeight = aMat.edgeMaterial.mainTexture != null ? aMat.edgeMaterial.mainTexture.height : 1; Vector2 pos = new Vector2(desc.leftCap.x, desc.leftCap.y); if (desc.leftCap.width == 0 && desc.leftCap.height == 0) { pos = new Vector2(desc.body[0].x, desc.body[0].y); } Rect bounds = new Rect(pos.x, pos.y, capWidth * 2 + bodyWidth * bodyCount, height); bounds = aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(bounds), aBounds)); bounds = ClampRect(bounds, (Texture2D)aMat.edgeMaterial.mainTexture); Ferr.EditorTools.DrawVLine(new Vector2((pos.x + capWidth) * texWidth + aBounds.x, (pos.y * texHeight) + 2), height * texHeight); for (int i = 1; i <= desc.body.Length; i++) { Ferr.EditorTools.DrawVLine(new Vector2((pos.x + capWidth + bodyWidth * i) * texWidth + aBounds.x, (pos.y * texHeight) + 2), height * texHeight); } height = bounds.height; bodyWidth = (bounds.width - capWidth * 2) / bodyCount; pos.x = bounds.x; pos.y = bounds.y; float currX = pos.x; desc.leftCap.x = currX; desc.leftCap.y = pos.y; desc.leftCap.width = capWidth; desc.leftCap.height = capWidth == 0 ? 0 : height; currX += capWidth; for (int i = 0; i < desc.body.Length; i++) { desc.body[i].x = currX; desc.body[i].y = pos.y; desc.body[i].width = bodyWidth; desc.body[i].height = height; currX += bodyWidth; } desc.rightCap.x = currX; desc.rightCap.y = pos.y; desc.rightCap.width = capWidth; desc.rightCap.height = capWidth == 0 ? 0 : height; } else { for (int i = 0; i < desc.body.Length; i++) { desc.body[i] = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.body[i]), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture); } if (desc.leftCap.width != 0 && desc.leftCap.height != 0) { desc.leftCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.leftCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture); } if (desc.rightCap.width != 0 && desc.rightCap.height != 0) { desc.rightCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.rightCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture); } if (desc.innerLeftCap.width != 0 && desc.innerLeftCap.height != 0) { desc.innerLeftCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.innerLeftCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture); } if (desc.innerRightCap.width != 0 && desc.innerRightCap.height != 0) { desc.innerRightCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.innerRightCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture); } } }
public Ferr2DT_SegmentDescription() { body = new Rect[] { new Rect(0, 0, 50, 50) }; applyTo = Ferr2DT_TerrainDirection.Top; }
private void DoHandles(Ferr2D_Path path, GUIStyle iconStyle) { Ferr2DT_PathTerrain terrain = path.gameObject.GetComponent <Ferr2DT_PathTerrain>(); if (terrain) { terrain.MatchOverrides(); } Quaternion inv = Quaternion.Inverse(path.transform.rotation); Handles.color = new Color(1, 1, 1, 0); for (int i = 0; i < path.pathVerts.Count; i++) { Vector3 pos = path.transform.position + path.transform.rotation * Vector3.Scale(new Vector3(path.pathVerts[i].x, path.pathVerts[i].y, 0), path.transform.localScale); Vector3 posOff = pos + offset; bool isSelected = false; if (selectedPoints != null) { isSelected = selectedPoints.Contains(i); } // check if we want to remove points if (Event.current.alt) { float handleScale = HandleScale(posOff); if (IsVisible(posOff)) { SetScale(posOff, texMinus, ref iconStyle); //Handles.Label(posOff, new GUIContent((isSelected || selectedPoints.Count <= 0) ? texMinusSelected : texMinus), iconStyle); } if (Handles.Button(posOff, SceneView.lastActiveSceneView.camera.transform.rotation, handleScale, handleScale, Handles.CircleCap)) { if (!isSelected && selectedPoints != null) { selectedPoints.Clear(); selectedPoints.Add(i); } if (selectedPoints != null) { for (int s = 0; s < selectedPoints.Count; s++) { if (terrain) { terrain.RemovePoint(selectedPoints[s]); } else { path.pathVerts.RemoveAt(selectedPoints[s]); } if (selectedPoints[s] <= i) { i--; } for (int u = 0; u < selectedPoints.Count; u++) { if (selectedPoints[u] > selectedPoints[s]) { selectedPoints[u] -= 1; } } } } if (selectedPoints != null) { selectedPoints.Clear(); } GUI.changed = true; } else if (Ferr2DT_SceneOverlay.editMode != Ferr2DT_EditMode.None) { if (terrain && i + 1 < path.pathVerts.Count) { float scale = handleScale * 0.5f; Vector3 dirOff = GetTickerOffset(path, pos, i); Vector3 posDirOff = posOff + dirOff; if (IsVisible(posDirOff)) { Texture2D icon = null; if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override) { icon = GetDirIcon(terrain.directionOverrides[i]); } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { icon = texScale; } if (Event.current.alt) { icon = texReset; } SetScale(posDirOff, icon, ref iconStyle, 0.5f); Handles.Label(posDirOff, new GUIContent(icon), iconStyle); if (Handles.Button(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, scale, Handles.CircleCap) && selectedPoints != null) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } for (int s = 0; s < selectedPoints.Count; s++) { if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override) { terrain.directionOverrides[selectedPoints[s]] = Ferr2DT_TerrainDirection.None; } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { terrain.vertScales[selectedPoints[s]] = 1; } } GUI.changed = true; } } } } } else { // check for moving the point Texture2D tex = null; if (Event.current.control) { tex = isSelected ? texDotSelectedSnap : texDotSnap; } else { tex = isSelected ? texDotSelected : texDot; } if (IsVisible(posOff)) { SetScale(posOff, texMinus, ref iconStyle); Handles.Label(posOff, new GUIContent(tex), iconStyle); } Vector3 snap = Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapRelative ? new Vector3(EditorPrefs.GetFloat("MoveSnapX"), EditorPrefs.GetFloat("MoveSnapY"), EditorPrefs.GetFloat("MoveSnapZ")) : Vector3.zero; Vector3 result = Handles.FreeMoveHandle( posOff, SceneView.lastActiveSceneView.camera.transform.rotation, HandleScale(pos + offset), snap, Handles.CircleCap); if (result != posOff) { if (selectedPoints != null) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } } if (!(Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapRelative)) { result = GetRealPoint(result, path.transform.position.z); } Vector3 global = (result - offset); if (Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapGlobal) { global = SnapVector(global); } Vector3 local = inv * (global - path.transform.position); if (Event.current.control && Ferr_Menu.SnapMode == Ferr2DT_SnapMode.SnapLocal) { local = SnapVector(local); } if (!Event.current.control && Ferr2DT_SceneOverlay.smartSnap && selectedPoints != null) { local = SmartSnap(local, path.pathVerts, selectedPoints, Ferr_Menu.SmartSnapDist); } Vector2 relative = new Vector2( local.x / path.transform.localScale.x, local.y / path.transform.localScale.y) - path.pathVerts[i]; if (selectedPoints != null) { for (int s = 0; s < selectedPoints.Count; s++) { path.pathVerts[selectedPoints[s]] += relative; } } } // if using terrain, check to see for any edge overrides if (Ferr2DT_SceneOverlay.showIndices) { Vector3 labelPos = posOff + (Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed); Handles.color = Color.white; Handles.Label(labelPos, "" + i); Handles.color = new Color(1, 1, 1, 0); } if (terrain) {// && i+1 < path.pathVerts.Count) { float scale = HandleScale(pos + offset) * 0.5f; Vector3 dirOff = GetTickerOffset(path, pos, i); Vector3 posDirOff = posOff + dirOff; if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override && i + 1 < path.pathVerts.Count) { if (IsVisible(posDirOff)) { SetScale(posDirOff, texMinus, ref iconStyle, 0.5f); Handles.Label(posDirOff, new GUIContent(Event.current.alt ? texReset : GetDirIcon(terrain.directionOverrides[i])), iconStyle); if (Handles.Button(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, scale, Handles.CircleCap) && selectedPoints != null) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]); for (int s = 0; s < selectedPoints.Count; s++) { terrain.directionOverrides[selectedPoints[s]] = dir; } GUI.changed = true; } } } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { if (IsVisible(posDirOff)) { SetScale(posDirOff, texMinus, ref iconStyle, 0.5f); Handles.Label(posDirOff, new GUIContent(Event.current.alt ? texReset : texScale), iconStyle); Vector3 scaleMove = Handles.FreeMoveHandle(posDirOff, SceneView.lastActiveSceneView.camera.transform.rotation, scale, Vector3.zero, Handles.CircleCap); float scaleAmt = scaleMove.y - posDirOff.y; if (Mathf.Abs(scaleAmt) > 0.01f) { if (selectedPoints != null && selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } float vertScale = terrain.vertScales[i] - Event.current.delta.y / 100f; vertScale = Mathf.Clamp(vertScale, 0.2f, 3f); if (selectedPoints != null) { for (int s = 0; s < selectedPoints.Count; s++) { terrain.vertScales[selectedPoints[s]] = vertScale; } } GUI.changed = true; } } } } // make sure we can add new point at the midpoints! if (i + 1 < path.pathVerts.Count || path.closed == true) { int index = path.closed && i + 1 == path.pathVerts.Count ? 0 : i + 1; Vector3 pos2 = path.transform.position + path.transform.rotation * Vector3.Scale(new Vector3(path.pathVerts[index].x, path.pathVerts[index].y, 0), path.transform.localScale); Vector3 mid = (pos + pos2) / 2; float handleScale = HandleScale(mid + offset); if (Handles.Button(mid + offset, SceneView.lastActiveSceneView.camera.transform.rotation, handleScale, handleScale, Handles.CircleCap)) { Vector2 pt = inv * new Vector2((mid.x - path.transform.position.x) / path.transform.localScale.x, (mid.y - path.transform.position.y) / path.transform.localScale.y); if (terrain) { terrain.AddPoint(pt, index); } else { path.pathVerts.Insert(index, pt); } } if (IsVisible(mid + offset)) { SetScale(mid + offset, texDotPlus, ref iconStyle); Handles.Label(mid + offset, new GUIContent(texDotPlus), iconStyle); } } } } if (selectedPoints != null && Event.current.type == EventType.keyDown && Event.current.keyCode == KeyCode.Delete && selectedPoints.Count > 0) { for (int s = 0; s < selectedPoints.Count; s++) { if (terrain) { terrain.RemovePoint(selectedPoints[s]); } else { path.pathVerts.RemoveAt(selectedPoints[s]); } for (int u = 0; u < selectedPoints.Count; u++) { if (selectedPoints[u] > selectedPoints[s]) { selectedPoints[u] -= 1; } } } selectedPoints.Clear(); GUI.changed = true; Event.current.Use(); } }
private void DoNormalModeHandles(Ferr2D_Path path, Ferr2DT_PathTerrain terrain, int i, Matrix4x4 mat, Matrix4x4 invMat, Transform camTransform) { int nextId = i == path.Count - 1?(path.closed?0:i - 1):i + 1; Vector3 pos = mat.MultiplyPoint3x4(path.pathVerts[i]); Vector3 posNext = mat.MultiplyPoint3x4(path.pathVerts[nextId]); Vector3 normal = -(Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed); bool isSelected = false; if (selectedPoints != null) { isSelected = selectedPoints.Contains(i); } // check for moving the point CapFunction cap = CapDot; if (Event.current.control) { cap = isSelected ? (CapFunction)CapDotSelectedSnap : (CapFunction)CapDotSnap; } else { cap = isSelected ? (CapFunction)CapDotSelected : (CapFunction)CapDot; } Vector3 result = Handles.FreeMoveHandle(pos, camTransform.rotation, HandleScale(pos), snap, cap); if (result != pos) { EnsureVertSelected(i, ref isSelected); Vector2 relative = GetRelativeMovementWithSnap(result, invMat, i, path); for (int s = 0; s < selectedPoints.Count; s++) { path.pathVerts[selectedPoints[s]] += relative; } } if (Ferr2DT_SceneOverlay.showIndices) { Vector3 labelPos = pos + normal; Handles.color = Color.white; Handles.Label(labelPos, "" + i); } if (!Ferr2DT_SceneOverlay.segmentLockMode) { float scale = HandleScale(pos) * 0.5f; Vector3 displayPos = pos; if (path.closed || i + 1 < path.pathVerts.Count) { displayPos = GetOverridePos(i, path, mat, pos, posNext); if (IsVisible(displayPos) && terrain.directionOverrides != null) { cap = Event.current.alt ? (CapFunction)CapDotReset : GetDirIcon(terrain.directionOverrides[i]); if (Handles.Button(displayPos, camTransform.rotation, scale, scale, cap)) { EnsureVertSelected(i, ref isSelected); Undo.RecordObject(terrain, "Override Vert Direction"); Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]); for (int s = 0; s < selectedPoints.Count; s++) { terrain.directionOverrides[selectedPoints[s]] = dir; } EditorUtility.SetDirty(terrain); GUI.changed = true; } } } displayPos = pos + normal * terrain.vertScales[i] * 2 * Ferr2DT_Menu.PathScale; if (IsVisible(displayPos)) { cap = Event.current.alt ? (CapFunction)CapDotReset : (CapFunction)CapDotScale; Vector3 scaleMove = Handles.FreeMoveHandle(displayPos, camTransform.rotation, scale, Vector3.zero, cap); float scaleAmt = Vector3.Distance(displayPos, scaleMove); if (Mathf.Abs(scaleAmt) > 0.01f) { EnsureVertSelected(i, ref isSelected); Undo.RecordObject(terrain, "Scale Path Vert"); float vertScale = Vector3.Distance(scaleMove, pos) / 2 / Ferr2DT_Menu.PathScale; vertScale = Mathf.Clamp(vertScale, 0.2f, 3f); for (int s = 0; s < selectedPoints.Count; s++) { terrain.vertScales[selectedPoints[s]] = vertScale; } EditorUtility.SetDirty(terrain); GUI.changed = true; } } // make sure we can add new point at the midpoints! if (i + 1 < path.pathVerts.Count || path.closed == true) { Vector3 mid = (pos + posNext) / 2; float handleScale = HandleScale(mid); if (Handles.Button(mid, camTransform.rotation, handleScale, handleScale, CapDotPlus)) { Vector2 pt = invMat.MultiplyPoint3x4(mid); terrain.AddPoint(pt, nextId); EditorUtility.SetDirty(terrain); GUI.changed = true; } } } }
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); }
public int GetBodyCount(Ferr2DT_TerrainDirection aDirection) { return(GetDescriptor(aDirection).body.Length); }
private void ShowDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir) { Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir]; desc.zOffset = EditorGUILayout.FloatField( "Z Offset", desc.zOffset ); desc.yOffset = EditorGUILayout.FloatField( "Y Offset", desc.yOffset ); desc.capOffset = EditorGUILayout.FloatField( "Cap Offset", desc.capOffset); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Body", GUILayout.Width(40f)); int bodyID = Mathf.Clamp(currBody, 0, desc.body.Length); if (GUILayout.Button("<", GUILayout.Width(20f))) currBody = Mathf.Clamp(currBody - 1, 0, desc.body.Length - 1); EditorGUILayout.LabelField("" + bodyID, GUILayout.Width(12f)); if (GUILayout.Button(">", GUILayout.Width(20f))) currBody = Mathf.Clamp(currBody + 1, 0, desc.body.Length - 1); bodyID = Mathf.Clamp(currBody, 0, desc.body.Length-1); int length = Math.Max(1, EditorGUILayout.IntField(desc.body.Length, GUILayout.Width(32f))); EditorGUILayout.LabelField("Total", GUILayout.Width(40f)); if (length != desc.body.Length) Array.Resize<Rect>(ref desc.body, length); EditorGUILayout.EndHorizontal(); desc.body[bodyID] = AtlasField(aMat, desc.body[bodyID] , aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture); EditorGUILayout.LabelField("Left Cap"); desc.leftCap = AtlasField(aMat, desc.leftCap , aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture); EditorGUILayout.LabelField("Right Cap"); desc.rightCap = AtlasField(aMat, desc.rightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture); }
private Handles.DrawCapFunction GetDirIcon(Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top ) return CapDotTop; else if (aDir == Ferr2DT_TerrainDirection.Right ) return CapDotRight; else if (aDir == Ferr2DT_TerrainDirection.Left ) return CapDotLeft; else if (aDir == Ferr2DT_TerrainDirection.Bottom) return CapDotBottom; return CapDotAuto; }
public static void ShowPreviewDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, Rect aBounds, bool aSimpleUVs, bool aEditable) { Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir]; if (!aMat.Has(aDir)) return; if (!aEditable) { for (int i = 0; i < desc.body.Length; i++) { Ferr_EditorTools.DrawRect(aMat.ToScreen( desc.body[i] ), aBounds); } Ferr_EditorTools.DrawRect(aMat.ToScreen( desc.leftCap ), aBounds); Ferr_EditorTools.DrawRect(aMat.ToScreen( desc.rightCap ), aBounds); } else if (aSimpleUVs) { float height = MaxHeight(desc); float capWidth = Mathf.Max(desc.leftCap.width, desc.rightCap.width); float bodyWidth = desc.body[0].width; int bodyCount = desc.body.Length; Vector2 pos = new Vector2(desc.leftCap.x, desc.leftCap.y); if (desc.leftCap.width == 0 && desc.leftCap.height == 0) pos = new Vector2(desc.body[0].x, desc.body[0].y); Rect bounds = new Rect(pos.x, pos.y, capWidth*2+bodyWidth*bodyCount, height); bounds = Ferr_EditorTools.UVRegionRect(bounds, aBounds); bounds = ClampRect(bounds, (Texture2D)aMat.edgeMaterial.mainTexture); Ferr_EditorTools.DrawVLine(new Vector2(pos.x + capWidth + aBounds.x, pos.y+1), height); for (int i = 1; i <= desc.body.Length; i++) { Ferr_EditorTools.DrawVLine(new Vector2(pos.x + capWidth + bodyWidth*i + aBounds.x, pos.y+1), height); } height = bounds.height; bodyWidth = (bounds.width - capWidth * 2) / bodyCount; pos.x = bounds.x; pos.y = bounds.y; float currX = pos.x; desc.leftCap.x = currX; desc.leftCap.y = pos.y; desc.leftCap.width = capWidth; desc.leftCap.height = capWidth == 0 ? 0 : height; currX += capWidth; for (int i = 0; i < desc.body.Length; i++) { desc.body[i].x = currX; desc.body[i].y = pos.y; desc.body[i].width = bodyWidth; desc.body[i].height = height; currX += bodyWidth; } desc.rightCap.x = currX; desc.rightCap.y = pos.y; desc.rightCap.width = capWidth; desc.rightCap.height = capWidth == 0 ? 0 : height; } else { for (int i = 0; i < desc.body.Length; i++) { desc.body[i] = ClampRect(Ferr_EditorTools.UVRegionRect(desc.body[i], aBounds), (Texture2D)aMat.edgeMaterial.mainTexture); } if (desc.leftCap.width != 0 && desc.leftCap.height != 0) desc.leftCap = ClampRect(Ferr_EditorTools.UVRegionRect(desc.leftCap, aBounds), (Texture2D)aMat.edgeMaterial.mainTexture); if (desc.rightCap.width != 0 && desc.rightCap.height != 0) desc.rightCap = ClampRect(Ferr_EditorTools.UVRegionRect(desc.rightCap, aBounds), (Texture2D)aMat.edgeMaterial.mainTexture); } }
public Rect GetBody(Ferr2DT_TerrainDirection aDirection, int aBodyID) { return GetDescriptor(aDirection).body[aBodyID]; }
void OnGUI() { if (material == null) return; // if this was an undo, repaint it if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": Repaint (); return; } } #if !(UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.RecordObject(material, "Modified Terrain Material"); #else Undo.SetSnapshotTarget(material, "Modified Terrain Material"); if (!Ferr_EditorTools.HandlesMoving()) { Undo.CreateSnapshot(); } #endif if (Ferr_EditorTools.ResetHandles()) { GUI.changed = true; } EditorGUILayout .BeginHorizontal (); EditorGUILayout .BeginVertical (GUILayout.Width(width)); if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Top, "Top", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Top) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Top]); currDir = Ferr2DT_TerrainDirection.Top; bool showTop = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Top), "Use Top"); material.Set(Ferr2DT_TerrainDirection.Top, showTop); if (showTop) ShowDirection(material, currDir); } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Left, "Left", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Left) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Left]); currDir = Ferr2DT_TerrainDirection.Left; bool showLeft = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Left), "Use Left"); material.Set(Ferr2DT_TerrainDirection.Left, showLeft); if (showLeft) ShowDirection(material, currDir); } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Right, "Right", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Right) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Right]); currDir = Ferr2DT_TerrainDirection.Right; bool showRight = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Right), "Use Right"); material.Set(Ferr2DT_TerrainDirection.Right, showRight); if (showRight) ShowDirection(material, currDir); } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Bottom, "Bottom", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Bottom) simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Bottom]); currDir = Ferr2DT_TerrainDirection.Bottom; bool showBottom = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Bottom), "Use Bottom"); material.Set(Ferr2DT_TerrainDirection.Bottom, showBottom); if (showBottom) ShowDirection(material, currDir); } EditorGUILayout.EndVertical (); EditorGUILayout.BeginVertical(); if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowPreview(material, currDir, simpleUVs, true, width); } EditorGUILayout.EndVertical (); EditorGUILayout.EndHorizontal(); if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDrag) Repaint (); if (GUI.changed) { EditorUtility.SetDirty(material); #if (UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.RegisterSnapshot(); #endif Ferr2DT_PathTerrain[] terrain = GameObject.FindObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[]; for (int i = 0; i < terrain.Length; i++) { if(terrain[i].TerrainMaterial == material) terrain[i].RecreatePath(); } } #if (UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.ClearSnapshotTarget(); #endif }
/// <summary> /// Gets the edge descriptor for the given edge, defaults to the Top, if none by that type exists, or an empty one, if none are defined at all. /// </summary> /// <param name="aDirection">Direction to get.</param> /// <returns>The given direction, or the first direction, or a default, based on what actually exists.</returns> public Ferr2DT_SegmentDescription GetDescriptor(Ferr2DT_TerrainDirection aDirection) { ConvertToPercentage(); for (int i = 0; i < descriptors.Length; i++) { if (descriptors[i].applyTo == aDirection) return descriptors[i]; } if (descriptors.Length > 0) { return descriptors[0]; } return new Ferr2DT_SegmentDescription(); }
void OnGUI() { if (material == null) { return; } // if this was an undo, repaint it if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": Repaint(); return; } } #if !(UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.RecordObject(material, "Modified Terrain Material"); #else Undo.SetSnapshotTarget(material, "Modified Terrain Material"); if (!Ferr_EditorTools.HandlesMoving()) { Undo.CreateSnapshot(); } #endif if (Ferr_EditorTools.ResetHandles()) { GUI.changed = true; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(GUILayout.Width(width)); if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Top, "Top", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Top) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Top]); } currDir = Ferr2DT_TerrainDirection.Top; bool showTop = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Top), "Use Top"); material.Set(Ferr2DT_TerrainDirection.Top, showTop); if (showTop) { ShowDirection(material, currDir); } } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Left, "Left", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Left) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Left]); } currDir = Ferr2DT_TerrainDirection.Left; bool showLeft = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Left), "Use Left"); material.Set(Ferr2DT_TerrainDirection.Left, showLeft); if (showLeft) { ShowDirection(material, currDir); } } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Right, "Right", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Right) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Right]); } currDir = Ferr2DT_TerrainDirection.Right; bool showRight = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Right), "Use Right"); material.Set(Ferr2DT_TerrainDirection.Right, showRight); if (showRight) { ShowDirection(material, currDir); } } if (EditorGUILayout.Foldout(currDir == Ferr2DT_TerrainDirection.Bottom, "Bottom", foldoutStyle)) { if (currDir != Ferr2DT_TerrainDirection.Bottom) { simpleUVs = Ferr2DT_TerrainMaterialUtility.IsSimple(material.descriptors[(int)Ferr2DT_TerrainDirection.Bottom]); } currDir = Ferr2DT_TerrainDirection.Bottom; bool showBottom = GUILayout.Toggle(material.Has(Ferr2DT_TerrainDirection.Bottom), "Use Bottom"); material.Set(Ferr2DT_TerrainDirection.Bottom, showBottom); if (showBottom) { ShowDirection(material, currDir); } } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); if (currDir != Ferr2DT_TerrainDirection.None) { Ferr2DT_TerrainMaterialUtility.ShowPreview(material, currDir, simpleUVs, true, width); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDrag) { Repaint(); } if (GUI.changed) { EditorUtility.SetDirty(material); #if (UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.RegisterSnapshot(); #endif Ferr2DT_PathTerrain[] terrain = GameObject.FindObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[]; for (int i = 0; i < terrain.Length; i++) { if (terrain[i].TerrainMaterial == material) { terrain[i].RecreatePath(); } } } #if (UNITY_4_2 || UNITY_4_1 || UNITY_4_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_1 || UNITY_3_0) Undo.ClearSnapshotTarget(); #endif }
public Rect GetRCap(Ferr2DT_TerrainDirection aDirection) { return GetDescriptor(aDirection).rightCap; }
private Ferr2DT_SegmentDescription GetDescription(List <Vector2> aSegment) { Ferr2DT_TerrainDirection dir = Ferr2D_Path.GetDirection(aSegment, 0, fill == Ferr2DT_FillMode.InvertedClosed); return(terrainMaterial.GetDescriptor(dir)); }
/// <summary> /// Sets a particular direction as having a valid descriptor. Or not. That's a bool. /// </summary> /// <param name="aDirection">The direction!</param> /// <param name="aActive">To active, or not to active? That is the question!</param> public void Set(Ferr2DT_TerrainDirection aDirection, bool aActive) { if (aActive) { if (descriptors[(int)aDirection].applyTo != aDirection) { descriptors[(int)aDirection] = new Ferr2DT_SegmentDescription(); descriptors[(int)aDirection].applyTo = aDirection; } } else if (descriptors[(int)aDirection].applyTo != Ferr2DT_TerrainDirection.Top) { descriptors[(int)aDirection] = new Ferr2DT_SegmentDescription(); } }
private Texture2D GetDirIcon(Ferr2DT_TerrainDirection aDir) { if (aDir == Ferr2DT_TerrainDirection.Top ) return texTop; else if (aDir == Ferr2DT_TerrainDirection.Right ) return texRight; else if (aDir == Ferr2DT_TerrainDirection.Left ) return texLeft; else if (aDir == Ferr2DT_TerrainDirection.Bottom) return texBottom; return texAuto; }
public Rect GetLCap(Ferr2DT_TerrainDirection aDirection) { return(GetDescriptor(aDirection).leftCap); }
private void Start() { terrain = GetComponent <Ferr2DT_PathTerrain>(); ferr2DPath = terrain.PathData; List <Vector2> rawPath = ferr2DPath.GetPathRaw(); List <Vector2> finalPath = ferr2DPath.GetFinalPath(); //List<FloorNode> floorNodeList = new List<FloorNode>(finalPath.Count); FloorNode[] floorNodeArray = new FloorNode[finalPath.Count]; // Create Walk Nodes for (int i = 0; i < finalPath.Count; i++) { Ferr2DT_TerrainDirection dir = Ferr2DT_PathTerrain.GetSegmentDirection(ferr2DPath, i); if (dir == Ferr2DT_TerrainDirection.Top) { if (i == finalPath.Count - 1) { floorNodeArray[i] = InstantiateFloorNode(finalPath[0], finalPath[i]); } else { floorNodeArray[i] = InstantiateFloorNode(finalPath[i + 1], finalPath[i]); } floorNodeArray[i].owner = this; ownedFloorNodes.Add(floorNodeArray[i]); } } // Check if there are any consecutive walk nodes // if so, set them as neighbors for (int i = 1; i < floorNodeArray.Length; i++) { if (floorNodeArray[i] != null && floorNodeArray[i - 1] != null) { // found consecutive walk nodes // set their neighboringness with regards to their x-coordinate if (floorNodeArray[i - 1].gameObject.transform.position.x < floorNodeArray[i].gameObject.transform.position.x) { floorNodeArray[i - 1].SetRightNeighbor(floorNodeArray[i]); floorNodeArray[i].SetLeftNeighbor(floorNodeArray[i - 1]); } else { floorNodeArray[i].SetRightNeighbor(floorNodeArray[i - 1]); floorNodeArray[i - 1].SetLeftNeighbor(floorNodeArray[i]); } } } // the edge case if (floorNodeArray[0] != null && floorNodeArray[floorNodeArray.Length - 1] != null) { if (floorNodeArray[0].gameObject.transform.position.x < floorNodeArray[floorNodeArray.Length - 1].gameObject.transform.position.x) { floorNodeArray[0].SetRightNeighbor(floorNodeArray[floorNodeArray.Length - 1]); floorNodeArray[floorNodeArray.Length - 1].SetLeftNeighbor(floorNodeArray[0]); } else { floorNodeArray[floorNodeArray.Length - 1].SetRightNeighbor(floorNodeArray[0]); floorNodeArray[0].SetLeftNeighbor(floorNodeArray[floorNodeArray.Length - 1]); } } foreach (FloorNode w in floorNodeArray) { if (w != null) { w.CheckIntersections(); } } }
/// <summary> /// This method will close a list of split segments, merging and adding points to the end chunks. /// </summary> /// <param name="aSegmentList">List of split segments that make up the path.</param> /// <param name="aCorners">If there are corners or not.</param> /// <returns>A closed loop of segments.</returns> public static bool CloseEnds(List <Vector2> aPath, ref List <List <int> > aSegmentList, ref List <Ferr2DT_TerrainDirection> aSegmentDirections, bool aCorners, bool aInverted) { int startID = aSegmentList[0][0]; Vector2 start = aPath[startID]; Vector2 startNext = aPath[aSegmentList[0][1]]; int endID = aSegmentList[aSegmentList.Count - 1][aSegmentList[aSegmentList.Count - 1].Count - 1]; Vector2 end = aPath[endID]; Vector2 endPrev = aPath[aSegmentList[aSegmentList.Count - 1][aSegmentList[aSegmentList.Count - 1].Count - 2]]; if (aCorners == false) { aSegmentList[0].Add(startID); return(true); } bool endCorner = Ferr2D_Path.GetDirection(endPrev, end) != Ferr2D_Path.GetDirection(end, start); bool startCorner = Ferr2D_Path.GetDirection(end, start) != Ferr2D_Path.GetDirection(start, startNext); if (endCorner && startCorner) { List <int> lastSeg = new List <int>(); lastSeg.Add(endID); lastSeg.Add(startID); aSegmentList.Add(lastSeg); Ferr2DT_TerrainDirection dir = GetDirection(start, end); if (aInverted && dir == Ferr2DT_TerrainDirection.Top) { dir = Ferr2DT_TerrainDirection.Bottom; } if (aInverted && dir == Ferr2DT_TerrainDirection.Bottom) { dir = Ferr2DT_TerrainDirection.Top; } if (aInverted && dir == Ferr2DT_TerrainDirection.Right) { dir = Ferr2DT_TerrainDirection.Left; } if (aInverted && dir == Ferr2DT_TerrainDirection.Left) { dir = Ferr2DT_TerrainDirection.Right; } aSegmentDirections.Add(dir); } else if (endCorner && !startCorner) { aSegmentList[0].Insert(0, endID); } else if (!endCorner && startCorner) { aSegmentList[aSegmentList.Count - 1].Add(startID); } else { aSegmentList[0].InsertRange(0, aSegmentList[aSegmentList.Count - 1]); aSegmentList.RemoveAt(aSegmentList.Count - 1); aSegmentDirections.RemoveAt(aSegmentDirections.Count - 1); } return(true); }
public Ferr2DT_SegmentDescription GetDescription(List <int> aSegment) { Ferr2DT_TerrainDirection dir = Ferr2D_Path.GetDirection(Path.pathVerts, aSegment, 0, fill == Ferr2DT_FillMode.InvertedClosed); return(TerrainMaterial.GetDescriptor(dir)); }
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 Rect GetBody(Ferr2DT_TerrainDirection aDirection, int aBodyID) { return(GetDescriptor(aDirection).body[aBodyID]); }
void ShowDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir) { Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir]; desc.zOffset = EditorGUILayout.FloatField( "Z Offset", desc.zOffset ); desc.yOffset = EditorGUILayout.FloatField( "Y Offset", desc.yOffset ); desc.capOffset = EditorGUILayout.FloatField( "Cap Offset", desc.capOffset); Ferr2DT_TerrainMaterialUtility.ShowSample(aMat, aDir, width); simpleUVs = EditorGUILayout.Toggle("Simple", simpleUVs); if (simpleUVs) { Ferr2DT_TerrainMaterialUtility.EditUVsSimple(desc); } else { Ferr2DT_TerrainMaterialUtility.EditUVsComplex(aMat, desc, width, ref currBody); } }
private void DoHandles(Ferr2D_Path path, GUIStyle iconStyle) { Vector3 snap = Event.current.control ? new Vector3(EditorPrefs.GetFloat("MoveSnapX"), EditorPrefs.GetFloat("MoveSnapY"), EditorPrefs.GetFloat("MoveSnapZ")) : Vector3.zero; Transform transform = path.transform; Matrix4x4 mat = transform.localToWorldMatrix; Matrix4x4 invMat = transform.worldToLocalMatrix; Transform camTransform = SceneView.lastActiveSceneView.camera.transform; Ferr2DT_PathTerrain terrain = path.GetComponent <Ferr2DT_PathTerrain>(); if (terrain) { terrain.MatchOverrides(); } Handles.color = new Color(1, 1, 1, 1); for (int i = 0; i < path.pathVerts.Count; i++) { Vector3 pos = mat.MultiplyPoint3x4(path.pathVerts[i]); Vector3 posStart = pos; bool isSelected = false; if (selectedPoints != null) { isSelected = selectedPoints.Contains(i); } // check if we want to remove points if (Event.current.alt) { float handleScale = HandleScale(posStart); Handles.DrawCapFunction cap = (isSelected || selectedPoints.Count <= 0) ? (Handles.DrawCapFunction)CapDotMinusSelected : (Handles.DrawCapFunction)CapDotMinus; if (Handles.Button(posStart, camTransform.rotation, handleScale, handleScale, cap)) { if (!isSelected) { selectedPoints.Clear(); selectedPoints.Add(i); } for (int s = 0; s < selectedPoints.Count; s++) { if (terrain) { terrain.RemovePoint(selectedPoints[s]); } else { path.pathVerts.RemoveAt(selectedPoints[s]); } if (selectedPoints[s] <= i) { i--; } for (int u = 0; u < selectedPoints.Count; u++) { if (selectedPoints[u] > selectedPoints[s]) { selectedPoints[u] -= 1; } } } selectedPoints.Clear(); GUI.changed = true; } else if (Ferr2DT_SceneOverlay.editMode != Ferr2DT_EditMode.None) { if (terrain && i + 1 < path.pathVerts.Count) { float scale = handleScale * 0.5f; Vector3 dirOff = GetTickerOffset(path, pos, i); Vector3 posDirOff = posStart + dirOff; if (IsVisible(posDirOff)) { cap = null; if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override) { cap = GetDirIcon(terrain.directionOverrides[i]); } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { cap = CapDotScale; } if (Event.current.alt) { cap = CapDotReset; } if (Handles.Button(posDirOff, camTransform.rotation, scale, scale, cap)) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } for (int s = 0; s < selectedPoints.Count; s++) { if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override) { terrain.directionOverrides[selectedPoints[s]] = Ferr2DT_TerrainDirection.None; } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { terrain.vertScales [selectedPoints[s]] = 1; } } GUI.changed = true; } } } } } else { // check for moving the point Handles.DrawCapFunction cap = CapDot; if (Event.current.control) { cap = isSelected ? (Handles.DrawCapFunction)CapDotSelectedSnap : (Handles.DrawCapFunction)CapDotSnap; } else { cap = isSelected ? (Handles.DrawCapFunction)CapDotSelected : (Handles.DrawCapFunction)CapDot; } Vector3 result = Handles.FreeMoveHandle( posStart, camTransform.rotation, HandleScale(pos), snap, cap); if (result != posStart) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } if (!(Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapRelative)) { result = GetRealPoint(result, transform); } Vector3 global = result; if (Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapGlobal) { global = SnapVector(global, snap); } Vector3 local = invMat.MultiplyPoint3x4(global); if (Event.current.control && Ferr2DT_Menu.SnapMode == Ferr2DT_Menu.SnapType.SnapLocal) { local = SnapVector(local, snap); } if (!Event.current.control && Ferr2DT_SceneOverlay.smartSnap) { local = SmartSnap(local, path.pathVerts, selectedPoints, Ferr2DT_Menu.SmartSnapDist); } Vector2 relative = new Vector2(local.x, local.y) - path.pathVerts[i]; for (int s = 0; s < selectedPoints.Count; s++) { path.pathVerts[selectedPoints[s]] += relative; } } // if using terrain, check to see for any edge overrides if (Ferr2DT_SceneOverlay.showIndices) { Vector3 labelPos = posStart + (Vector3)Ferr2D_Path.GetNormal(path.pathVerts, i, path.closed); Handles.color = Color.white; Handles.Label(labelPos, "" + i); Handles.color = new Color(1, 1, 1, 0); } if (terrain) { float scale = HandleScale(pos) * 0.5f; Vector3 dirOff = GetTickerOffset(path, pos, i); Vector3 posDirOff = posStart + dirOff; if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Override && i + 1 < path.pathVerts.Count) { if (IsVisible(posDirOff) && terrain.directionOverrides != null) { cap = Event.current.alt ? (Handles.DrawCapFunction)CapDotReset : GetDirIcon(terrain.directionOverrides[i]); if (Handles.Button(posDirOff, camTransform.rotation, scale, scale, cap)) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } Ferr2DT_TerrainDirection dir = NextDir(terrain.directionOverrides[i]); for (int s = 0; s < selectedPoints.Count; s++) { terrain.directionOverrides[selectedPoints[s]] = dir; } GUI.changed = true; } } } else if (Ferr2DT_SceneOverlay.editMode == Ferr2DT_EditMode.Scale) { if (IsVisible(posDirOff)) { cap = Event.current.alt ? (Handles.DrawCapFunction)CapDotReset : (Handles.DrawCapFunction)CapDotScale; Vector3 scaleMove = Handles.FreeMoveHandle(posDirOff, camTransform.rotation, scale, Vector3.zero, cap); float scaleAmt = scaleMove.y - posDirOff.y; if (Mathf.Abs(scaleAmt) > 0.01f) { if (selectedPoints.Count < 2 || isSelected == false) { selectedPoints.Clear(); selectedPoints.Add(i); isSelected = true; } float vertScale = terrain.vertScales[i] - Event.current.delta.y / 100f; vertScale = Mathf.Clamp(vertScale, 0.2f, 3f); for (int s = 0; s < selectedPoints.Count; s++) { terrain.vertScales[selectedPoints[s]] = vertScale; } GUI.changed = true; } } } } // make sure we can add new point at the midpoints! if (i + 1 < path.pathVerts.Count || path.closed == true) { int index = path.closed && i + 1 == path.pathVerts.Count ? 0 : i + 1; Vector3 pos2 = mat.MultiplyPoint3x4(path.pathVerts[index]); Vector3 mid = (pos + pos2) / 2; float handleScale = HandleScale(mid); if (Handles.Button(mid, camTransform.rotation, handleScale, handleScale, CapDotPlus)) { Vector2 pt = invMat.MultiplyPoint3x4(mid); if (terrain) { terrain.AddPoint(pt, index); } else { path.pathVerts.Insert(index, pt); } } } } } if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && selectedPoints.Count > 0) { for (int s = 0; s < selectedPoints.Count; s++) { if (terrain) { terrain.RemovePoint(selectedPoints[s]); } else { path.pathVerts.RemoveAt(selectedPoints[s]); } for (int u = 0; u < selectedPoints.Count; u++) { if (selectedPoints[u] > selectedPoints[s]) { selectedPoints[u] -= 1; } } } selectedPoints.Clear(); GUI.changed = true; Event.current.Use(); } }