public static void Intersect(List <UIVertex> vertices, List <int> indices, List <UIVertex> mask, System.Func <UIVertex, UIVertex, UIVertex> blend) { var indicesOriginalCount = indices.Count; var pertexPack = new IndexedVerticesOffset(vertices, indices); var maskPack = new VerticesOffset(mask); var vertices2d = new Vector2[3]; var mask2d = new Vector2[3]; for (int m = 0, mMax = maskPack.vertices.Count; m < mMax; m += 3) { for (int k = 0, kMax = 3; k < kMax; ++k) { mask2d[k] = maskPack.vertices[m + k].position; } maskPack.start = m; if (!IsDegeneracy(mask2d)) { for (int i = 0, iMax = indicesOriginalCount; i < iMax; i += 3) { for (int k = 0, kMax = 3; k < kMax; ++k) { vertices2d[k] = pertexPack.vertices[pertexPack.indices[i + k]].position; } if (!IsDegeneracy(vertices2d)) { pertexPack.start = i; MaskTriangles(pertexPack, vertices2d, maskPack, mask2d, blend); } } } } indices.RemoveRange(0, indicesOriginalCount); }
private static UIVertex PickupUIVertexFromTriangle(Vector2 pickupPosition, VerticesOffset vertexPack, Vector2[] vertices2d) { var inverseArea = 1.0f / GetAreaOfTriangle(vertices2d[0], vertices2d[1], vertices2d[2]); var vertices = vertexPack.GetEnumerable(); var weights = new Array3 <float>(GetAreaOfTriangle(pickupPosition, vertices2d[1], vertices2d[2]) * inverseArea , GetAreaOfTriangle(vertices2d[0], pickupPosition, vertices2d[2]) * inverseArea , GetAreaOfTriangle(vertices2d[0], vertices2d[1], pickupPosition) * inverseArea ).GetEnumerable(); var result = WeightedAverage(vertices, weights); return(result); }
private static int AddCrossPoint(IndexedVerticesOffset vertexPack, Vector2[] vertices2d, VerticesOffset maskPack, Vector2[] mask2d, System.Func <UIVertex, UIVertex, UIVertex> blend) { var result = 0; for (int i = 0, iMax = 3; i < iMax; ++i) { var iNext = i + 1; if (iMax <= iNext) { iNext = 0; } for (int k = 0, kMax = 3; k < kMax; ++k) { var kNext = k + 1; if (kMax <= kNext) { kNext = 0; } var crossPoint = GetCrossPointWithoutPoint(vertexPack.vertices[vertexPack.indices[vertexPack.start + i]] , vertexPack.vertices[vertexPack.indices[vertexPack.start + iNext]] , maskPack.vertices[maskPack.start + k] , maskPack.vertices[maskPack.start + kNext] , blend ); if (crossPoint.HasValue) { vertexPack.indices.Add(vertexPack.vertices.Count); vertexPack.vertices.Add(crossPoint.Value); ++result; } } } return(result); }
private static int AddContainsMask(IndexedVerticesOffset vertexPack, Vector2[] vertices2d, VerticesOffset maskPack, Vector2[] mask2d, System.Func <UIVertex, UIVertex, UIVertex> blend) { var result = 0; for (int i = 0, iMax = 3; i < iMax; ++i) { if (ContainsInConvexHull(vertices2d, mask2d[i])) { var vertex = PickupUIVertexFromTriangle(mask2d[i], vertexPack, vertices2d); vertexPack.indices.Add(vertexPack.vertices.Count); vertexPack.vertices.Add(blend(vertex, maskPack.vertices[maskPack.start + i])); ++result; } } return(result); }
private static void MaskTriangles(IndexedVerticesOffset vertexPack, Vector2[] vertices2d, VerticesOffset maskPack, Vector2[] mask2d, System.Func <UIVertex, UIVertex, UIVertex> blend) { var indicesBaseCount = vertexPack.indices.Count; var addCount = AddContainsVertex(vertexPack, vertices2d, maskPack, mask2d, blend); if (addCount == 3) { return; } addCount += AddContainsMask(vertexPack, vertices2d, maskPack, mask2d, blend); addCount += AddCrossPoint(vertexPack, vertices2d, maskPack, mask2d, blend); if (3 < addCount) { var center = Vector2.zero; var positions = Enumerable.Range(indicesBaseCount, addCount) .Select(x => (Vector2)vertexPack.vertices[vertexPack.indices[x]].position); foreach (var position in positions) { center.x += position.x; center.y += position.y; } center *= 1.0f / addCount; vertexPack.indices.Sort(indicesBaseCount, addCount, new CounterClockWiseUIVertex(vertexPack.vertices, center)); for (var i = 2; i < addCount; ++i) { vertexPack.indices.Add(vertexPack.indices[indicesBaseCount + 0]); vertexPack.indices.Add(vertexPack.indices[indicesBaseCount + i - 1]); vertexPack.indices.Add(vertexPack.indices[indicesBaseCount + i]); } } else if ((addCount == 0) || (addCount == 3)) { return; } vertexPack.indices.RemoveRange(indicesBaseCount, addCount); }
private static int AddContainsVertex(IndexedVerticesOffset vertexPack, Vector2[] vertices2d, VerticesOffset maskPack, Vector2[] mask2d) { var result = 0; for (int i = 0, iMax = 3; i < iMax; ++i) { if (ContainsInConvexHull(mask2d, vertices2d[i])) { vertexPack.indices.Add(vertexPack.vertices.Count); var vertex = vertexPack.vertices[vertexPack.indices[vertexPack.start + i]]; var maskVertex = PickupUIVertexFromTriangle(vertex.position, maskPack, mask2d); vertexPack.vertices.Add(MultiplyVertexColor(vertex, maskVertex)); ++result; } } return(result); }
private static void MaskTriangles(IndexedVerticesOffset vertexPack, Vector2[] vertices2d, VerticesOffset maskPack, Vector2[] mask2d) { var indicesBaseCount = vertexPack.indices.Count; var addCount = AddContainsVertex(vertexPack, vertices2d, maskPack, mask2d); if (addCount == 3) { return; } addCount += AddContainsMask(vertexPack, vertices2d, maskPack, mask2d); addCount += AddCrossPoint(vertexPack, vertices2d, maskPack, mask2d); if ((3 < addCount) && (addCount <= 6)) { var center = Vector2.zero; foreach (var position in vertices2d) { center.x += position.x; center.y += position.y; } center *= 1.0f / 3.0f; vertexPack.indices.Sort(indicesBaseCount, addCount, new CounterClockWiseUIVertex(vertexPack.vertices, center)); vertexPack.indices.AddRange(k_SmallConvexHullVertexIndices[addCount - 4].Select(x => vertexPack.indices[indicesBaseCount + x])); } else if ((addCount == 0) || (addCount == 3)) { return; } vertexPack.indices.RemoveRange(indicesBaseCount, addCount); }