private static void BuildGeometryFromClipPaths(VectorUtils.Geometry geom, List <List <IntPoint> > paths, List <Vector2> outVerts, List <UInt16> outInds, ref UInt16 maxIndex) { var vertices = new List <Vector2>(100); var indices = new List <UInt16>(vertices.Capacity * 3); var vertexIndex = new Dictionary <IntPoint, UInt16>(); foreach (var path in paths) { if (path.Count == 3) { // Triangle case, no need to tessellate foreach (var pt in path) { StoreClipVertex(vertexIndex, vertices, indices, pt, ref maxIndex); } } else if (path.Count > 3) { // Generic polygon case, we need to tessellate first var tess = new Tess(); var contour = new ContourVertex[path.Count]; for (int i = 0; i < path.Count; ++i) { contour[i] = new ContourVertex() { Position = new Vec3() { X = path[i].X, Y = path[i].Y, Z = 0.0f } } } ; tess.AddContour(contour, ContourOrientation.Original); var windingRule = WindingRule.NonZero; tess.Tessellate(windingRule, ElementType.Polygons, 3); foreach (var e in tess.Elements) { var v = tess.Vertices[e]; var pt = new IntPoint(v.Position.X, v.Position.Y); StoreClipVertex(vertexIndex, vertices, indices, pt, ref maxIndex); } } } var invMatrix = geom.WorldTransform.Inverse(); outVerts.AddRange(vertices.Select(v => invMatrix * v)); outInds.AddRange(indices); }
private static List <List <IntPoint> > BuildTriangleClipPaths(VectorUtils.Geometry geom) { var paths = new List <List <IntPoint> >(geom.Indices.Length / 3); var verts = geom.Vertices; var inds = geom.Indices; var indexCount = geom.Indices.Length; var matrix = geom.WorldTransform; for (int i = 0; i < indexCount; i += 3) { var v0 = matrix * verts[inds[i]]; var v1 = matrix * verts[inds[i + 1]]; var v2 = matrix * verts[inds[i + 2]]; var tri = new List <IntPoint>(3); tri.Add(new IntPoint(v0.x * k_ClipperScale, v0.y * k_ClipperScale)); tri.Add(new IntPoint(v1.x * k_ClipperScale, v1.y * k_ClipperScale)); tri.Add(new IntPoint(v2.x * k_ClipperScale, v2.y * k_ClipperScale)); paths.Add(tri); } return(paths); }
internal static void ClipGeometry(VectorUtils.Geometry geom) { UnityEngine.Profiling.Profiler.BeginSample("ClipGeometry"); var clipper = new Clipper(); foreach (var clipperPaths in m_ClipStack) { var vertices = new List <Vector2>(geom.Vertices.Length); var indices = new List <UInt16>(geom.Indices.Length); var paths = BuildTriangleClipPaths(geom); var result = new List <List <IntPoint> >(); UInt16 maxIndex = 0; foreach (var path in paths) { clipper.AddPaths(clipperPaths, PolyType.ptClip, true); clipper.AddPath(path, PolyType.ptSubject, true); clipper.Execute(ClipType.ctIntersection, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero); if (result.Count > 0) { BuildGeometryFromClipPaths(geom, result, vertices, indices, ref maxIndex); } clipper.Clear(); result.Clear(); } geom.Vertices = vertices.ToArray(); geom.Indices = indices.ToArray(); } UnityEngine.Profiling.Profiler.EndSample(); }