private static float GetEdgeHeuristic(TrianglePathCache cache, float4[] planes, float3[] vertices, int vi0, int vi1, int vi2) { if (!cache.HardEdges.TryGetValue(VertPair.Create(vi0, vi1), out int polygonIndex)) { return(0); } if (polygonIndex < 0 || polygonIndex >= planes.Length) { return(float.PositiveInfinity); } var error = math.dot(planes[polygonIndex].xyz, vertices[vi2] - vertices[vi1]) - 1; return(error * error); }
private static Triangle[] SplitNonPlanarPolygon(BrushMesh subMesh, ref Polygon polygon) { var sTrianglePathCache = new TrianglePathCache(); var halfEdges = subMesh.halfEdges; var vertices = subMesh.vertices; var surfaces = subMesh.planes; var halfEdgePolygonIndices = subMesh.halfEdgePolygonIndices; var firstEdge = polygon.firstEdge; var edgeCount = polygon.edgeCount; var lastEdge = firstEdge + edgeCount; for (var e = firstEdge; e < lastEdge; e++) { var twinIndex = halfEdges[e].twinIndex; var curVertexIndex = halfEdges[e].vertexIndex; var polygonIndex = halfEdgePolygonIndices[e]; var twinVertexIndex = halfEdges[twinIndex].vertexIndex; var pair = VertPair.Create(curVertexIndex, twinVertexIndex); sTrianglePathCache.HardEdges[pair] = polygonIndex; } var sPolyVerts = new int[edgeCount]; for (var i = 0; i < edgeCount; i++) { sPolyVerts[i] = halfEdges[i + firstEdge].vertexIndex; } SplitAtEdge(out int[] foundTriangleIndices, sTrianglePathCache, sPolyVerts, edgeCount, vertices, surfaces); var sNewTriangles = new List <Triangle>(); while (foundTriangleIndices != null && foundTriangleIndices.Length > 0) { if (foundTriangleIndices.Length == 1) { sNewTriangles.Add(sTrianglePathCache.AllTriangles[foundTriangleIndices[0]]); break; } var found = -1; var foundEdgeCount = 0; for (var t = 0; t < foundTriangleIndices.Length; t++) { var triangle = sTrianglePathCache.AllTriangles[foundTriangleIndices[t]]; var vertPair1 = VertPair.Create(triangle.vertexIndices[0], triangle.vertexIndices[1]); var vertPair2 = VertPair.Create(triangle.vertexIndices[1], triangle.vertexIndices[2]); var vertPair3 = VertPair.Create(triangle.vertexIndices[2], triangle.vertexIndices[0]); var hardEdgeCount = 0; if (sTrianglePathCache.HardEdges.ContainsKey(vertPair1)) { hardEdgeCount++; } if (sTrianglePathCache.HardEdges.ContainsKey(vertPair2)) { hardEdgeCount++; } if (sTrianglePathCache.HardEdges.ContainsKey(vertPair3)) { hardEdgeCount++; } if (hardEdgeCount <= foundEdgeCount) { continue; } foundEdgeCount = hardEdgeCount; found = t; } if (found == -1) { Debug.LogWarning("Failed to find appropriate triangle to clip during triangulation"); return(null); } { var triangle = sTrianglePathCache.AllTriangles[foundTriangleIndices[found]]; var vertPair1 = VertPair.Create(triangle.vertexIndices[0], triangle.vertexIndices[1]); var vertPair2 = VertPair.Create(triangle.vertexIndices[1], triangle.vertexIndices[2]); var vertPair3 = VertPair.Create(triangle.vertexIndices[2], triangle.vertexIndices[0]); sNewTriangles.Add(triangle); // TODO: optimize var list = new List <int>(foundTriangleIndices); list.RemoveAt(found); foundTriangleIndices = list.ToArray(); //found_triangles.RemoveAt(found); if (!sTrianglePathCache.HardEdges.ContainsKey(vertPair1)) { sTrianglePathCache.HardEdges.Add(vertPair1, -1); } if (!sTrianglePathCache.HardEdges.ContainsKey(vertPair2)) { sTrianglePathCache.HardEdges.Add(vertPair2, -1); } if (!sTrianglePathCache.HardEdges.ContainsKey(vertPair3)) { sTrianglePathCache.HardEdges.Add(vertPair3, -1); } } } return(sNewTriangles.ToArray()); }