private void UpdateCaveBackground(Vector2[][] segments) { var outerSteps = Mathf.FloorToInt(outerRadius * Mathf.PI * 2 / 4); var outerPolygon = Enumerable.Range(0, outerSteps).Select(i => { var angle = 2f * Mathf.PI * i / outerSteps; return(new Vector2(Mathf.Sin(angle), Mathf.Cos(angle)) * outerRadius); }); var innerSteps = Mathf.FloorToInt(innerRadius * Mathf.PI * 2 / 4); var innerPolygon = Enumerable.Range(0, innerSteps).Select(i => { var angle = -2f * Mathf.PI * i / innerSteps; return(new Vector2(Mathf.Sin(angle), Mathf.Cos(angle)) * innerRadius); }); var area = new List <IEnumerable <Vector2> >(2); area.Add(outerPolygon); area.Add(innerPolygon); var constraint = new ConstraintOptions(); constraint.ConformingDelaunay = true; var quality = new QualityOptions(); quality.MaximumArea = 10; var data = segments.AsParallel().Select(segment => { var segmentPolygon = new PSPolygon(segment); var doNotWrapUV = segmentPolygon.Bounds.center.x < 0 && segmentPolygon.Bounds.center.y < 0; var poly = new Polygon(); foreach (var polygon in PSClipperHelper.intersection(area, segment)) { poly.Add(createContour(polygon)); } var imesh = poly.Triangulate(constraint, quality); var vertices = new List <Vector2>(); var triangles = new List <int>(); getTriangles(imesh, ref vertices, ref triangles); var uv = vertices.Select(v => getUV(v, doNotWrapUV)).ToList(); var colors = vertices.Select(v => (Color32)backgroundTintColor(v, doNotWrapUV)).ToList(); return(new { vertices, triangles, uv, colors }); }).ToList(); var currentIndex = 0; var tris = new List <int>(); foreach (var d in data) { tris.AddRange(d.triangles.Select(i => currentIndex + i)); currentIndex += d.vertices.Count; } UpdateMesh( caveBackground, data.SelectMany(d => d.vertices).Select(v => (Vector3)v), data.SelectMany(d => d.uv), null, data.SelectMany(d => d.colors), tris); }
public static IEnumerable <PSPolygon> FragmentPolygons(IEnumerable <PSPolygon> contours, IEnumerable <Vector2> clip) { return(PSClipperHelper.intersection(contours.Select(c => c.points), clip).Select(p => new PSPolygon(p))); }
private MeshData UpdateMeshData(MeshData oldData, IClipShape clipShape) { var clipPolygon = clipShape.ClipPolygon(); var oldVertices = oldData.vertices; var oldTriangles = oldData.triangles; var oldPaths = oldData.paths; var newVertices = new List <Vector2>(oldVertices.Length); var vertexIndex = new Dictionary <int, int>(oldVertices.Length); Vector2 v; for (int i = 0; i < oldVertices.Length; i++) { v = oldVertices[i]; if (clipPolygon.PointInPolygon(v)) { vertexIndex.Add(i, -1); } else { vertexIndex.Add(i, newVertices.Count); newVertices.Add(v); } } var newTriangles = new List <int>(oldTriangles.Length); var clippedTriangles = new List <int[]>(); List <int> oldTriangle = new List <int>(3); for (int i = 0; i < oldTriangles.Length / 3; i++) { oldTriangle.Clear(); oldTriangle.Add(oldTriangles[3 * i]); oldTriangle.Add(oldTriangles[3 * i + 1]); oldTriangle.Add(oldTriangles[3 * i + 2]); var newTriangle = oldTriangle.Select(oldIndex => vertexIndex[oldIndex]).ToArray(); if (newTriangle.Any(newIndex => newIndex > -1)) { if (newTriangle.All(newIndex => newIndex > -1) && !clipShape.ShouldClipTriangle(newTriangle.Select(newIndex => newVertices[newIndex]))) { newTriangles.AddRange(newTriangle); } else { clippedTriangles.Add(oldTriangle.ToArray()); } } } var newPolygons = clippedTriangles .Select(t => t.Select(oldIndex => (Vector2)oldVertices[oldIndex])) .SelectMany(t => PSClipperHelper.difference(t, clipPolygon.points)); var mesher = new GenericMesher(); foreach (var points in newPolygons) { var poly = new Polygon(); poly.Add(TerrainMesh.createContour(points)); var imesh = mesher.Triangulate(poly); TerrainMesh.getTriangles(imesh, ref newVertices, ref newTriangles); } var newPaths = oldPaths .SelectMany(p => PSClipperHelper.difference(p, clipPolygon.points)) .Select(p => p.ToArray()) .ToArray(); var particles = oldPaths .SelectMany(p => PSClipperHelper.intersection(p, clipPolygon.points)) .Select(p => GenerateParticles(new PSPolygon(p))) .ToArray(); return(new MeshData( newVertices.Select(c => new Vector3(c.x, c.y, 0)).ToArray(), newVertices.Select(c => (Color32)terrainMesh.terrainTintColor(c, doNotWrapUV)).ToArray(), newVertices.Select(c => terrainMesh.getUV(c, doNotWrapUV)).ToArray(), newVertices.Select(c => terrainMesh.getUV2(c, doNotWrapUV, floorEdges)).ToArray(), newTriangles.ToArray(), newPaths, particles)); }