private void AddEdge() { // split the path into segments based on the split angle List <List <int> > segments = new List <List <int> >(); List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>(); List <int> order = new List <int>(); segments = GetSegments(Path.GetVertsRaw(), out dirs); if (dirs.Count < segments.Count) { dirs.Add(directionOverrides[directionOverrides.Count - 1]); } for (int i = 0; i < segments.Count; i++) { order.Add(i); } order.Sort( new Ferr_LambdaComparer <int>( (x, y) => { Ferr2DT_TerrainDirection dirx = dirs[x] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[x], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[x]; Ferr2DT_TerrainDirection diry = dirs[y] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[y], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[y]; return(terrainMaterial.GetDescriptor(diry).zOffset.CompareTo(terrainMaterial.GetDescriptor(dirx).zOffset)); } )); // process the segments into meshes for (int i = 0; i < order.Count; i++) { AddSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, segments[order[i]]), GetScalesFromIndices(segments[order[i]]), order.Count <= 1 && Path.closed, smoothPath, dirs[order[i]]); } }
private void AddEdge() { // split the path into segments based on the split angle List <List <int> > segments = new List <List <int> >(); List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>(); List <int> order = new List <int>(); segments = GetSegments(Path.GetVertsRaw(), out dirs); if (dirs.Count < segments.Count) { dirs.Add(directionOverrides[directionOverrides.Count - 1]); } for (int i = 0; i < segments.Count; i++) { order.Add(i); } order.Sort( new Ferr.LambdaComparer <int>( (x, y) => { Ferr2DT_TerrainDirection dirx = dirs[x] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[x], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[x]; Ferr2DT_TerrainDirection diry = dirs[y] == Ferr2DT_TerrainDirection.None ? Ferr2D_Path.GetDirection(Path.pathVerts, segments[y], 0, fill == Ferr2DT_FillMode.InvertedClosed) : dirs[y]; return(terrainMaterial.GetDescriptor(diry).zOffset.CompareTo(terrainMaterial.GetDescriptor(dirx).zOffset)); } )); // process the segments into meshes for (int i = 0; i < order.Count; i++) { List <int> currSeg = segments[order[i]]; List <int> prevSeg = order[i] - 1 < 0 ? segments[segments.Count - 1] : segments[order[i] - 1]; List <int> nextSeg = segments[(order[i] + 1) % segments.Count]; int curr = currSeg[0]; int prev = prevSeg[prevSeg.Count - 2]; int next = currSeg[1]; Vector2 p1 = Path.pathVerts[prev] - Path.pathVerts[curr]; Vector2 p2 = Path.pathVerts[next] - Path.pathVerts[curr]; bool leftInner = Mathf.Atan2(p1.x * p2.y - p1.y * p2.x, Vector2.Dot(p1, p2)) < 0; curr = currSeg[currSeg.Count - 1]; prev = currSeg[currSeg.Count - 2]; next = nextSeg[1]; p1 = Path.pathVerts[prev] - Path.pathVerts[curr]; p2 = Path.pathVerts[next] - Path.pathVerts[curr]; bool rightInner = Mathf.Atan2(p1.x * p2.y - p1.y * p2.x, Vector2.Dot(p1, p2)) < 0; AddSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, segments[order[i]]), leftInner, rightInner, GetScalesFromIndices(segments[order[i]]), order.Count <= 1 && Path.closed, smoothPath, dirs[order[i]]); } }
private List <Vector2> GetSegmentsCombined(float aSplitDist) { List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>(); List <Vector2> result = new List <Vector2>(); List <List <int> > list = GetSegments(Path.GetVertsRaw(), out dirs); for (int i = 0; i < list.Count; i++) { if (smoothPath && list[i].Count > 2) { result.AddRange(Ferr2D_Path.SmoothSegment(Ferr2D_Path.IndicesToPath(Path.pathVerts, list[i]), aSplitDist, false)); } else { result.AddRange(Ferr2D_Path.IndicesToPath(Path.pathVerts, list[i])); } } return(result); }
/// <summary> /// Retrieves a list of line segments that directly represent the collision volume of the terrain. This includes offsets and removed edges. /// </summary> /// <returns>A list of line segments.</returns> public List <List <Vector2> > GetColliderVerts() { List <Vector2> tVerts = Path.GetVertsRaw(); // drop a skirt on skirt-based terrain if ((fill == Ferr2DT_FillMode.Skirt || fill == Ferr2DT_FillMode.FillOnlySkirt) && tVerts.Count > 0) { Vector2 start = tVerts[0]; Vector2 end = tVerts[tVerts.Count - 1]; tVerts.Add(new Vector2(end.x, fillY)); tVerts.Add(new Vector2(start.x, fillY)); tVerts.Add(new Vector2(start.x, start.y)); } float fillDist = (terrainMaterial.ToUV(terrainMaterial.GetBody((Ferr2DT_TerrainDirection)0, 0)).width *(terrainMaterial.edgeMaterial.mainTexture.width / pixelsPerUnit)) / (Mathf.Max(1, splitCount)) * splitDist; List <Ferr2DT_TerrainDirection> dirs = new List <Ferr2DT_TerrainDirection>(); List <List <Vector2> > result = new List <List <Vector2> >(); List <List <int> > list = GetSegments(tVerts, out dirs); List <Vector2> curr = new List <Vector2>(); // remove segments that aren't on the terrain for (int i = 0; i < list.Count; i++) { if ((dirs[i] == Ferr2DT_TerrainDirection.Bottom && !collidersBottom) || (dirs[i] == Ferr2DT_TerrainDirection.Left && !collidersLeft) || (dirs[i] == Ferr2DT_TerrainDirection.Top && !collidersTop) || (dirs[i] == Ferr2DT_TerrainDirection.Right && !collidersRight)) { if (curr.Count > 0) { result.Add(new List <Vector2>(curr)); curr.Clear( ); } } else { // create a list of verts and scales for this edge List <float> tScales = null; List <Vector2> tList = null; Ferr2D_Path.IndicesToPath(tVerts, vertScales, list[i], out tList, out tScales); // smooth it! if (smoothPath && tList.Count > 2) { Ferr2D_Path.SmoothSegment(tList, tScales, fillDist, false, out tList, out tScales); } // offset the verts based on scale and terrain edge info tList = OffsetColliderVerts(tList, tScales, dirs[i]); // sharpen corners properly! if (curr.Count > 0 && sharpCorners) { MergeCorner(ref curr, ref tList); } curr.AddRange(tList); } } if (sharpCorners) { MergeCorner(ref curr, ref curr); } if (curr.Count > 0) { result.Add(curr); } return(result); }