/// <summary> /// Get the list of triangles containing the given vertex. /// </summary> /// <param name="index"></param> /// <returns></returns> public List <Triangle> GetTrianglesContainingVertex(VertexIndex index) { triangles.Clear(); for (int i = 0; i < numTrianglesByIndex[index]; i++) { triangles.Add(triangleLookup[index, i]); } return(triangles); }
bool IsOutlineEdge(VertexIndex vertexA, VertexIndex vertexB) { if (vertexA == vertexB) { return(false); } return(!DoVerticesShareMultipleTriangles(vertexA, vertexB)); }
void FollowOutline(VertexIndex vertexIndex, List <VertexIndex> outline) { outline.Add(vertexIndex); visited[vertexIndex] = true; VertexIndex nextVertexIndex; if (TryGetConnectedOutlineVertex(vertexIndex, out nextVertexIndex)) { FollowOutline(nextVertexIndex, outline); } }
VertexIndex GetThirdPoint(VertexIndex indexA, VertexIndex indexB, Triangle triangle) { foreach (int triangleIndex in triangle.vertices) { VertexIndex vertexIndex = triangles[triangleIndex]; if (vertexIndex != indexA && vertexIndex != indexB) { return(vertexIndex); } } throw new ArgumentException("Unexpected error: outline generation failed."); }
Outline GenerateOutlineFromPoint(VertexIndex startVertexIndex) { visited[startVertexIndex] = true; outlineTemp.Clear(); outlineTemp.Add(startVertexIndex); VertexIndex nextVertexIndex = GetInitialConnectedOutlineVertex(startVertexIndex); FollowOutline(nextVertexIndex, outlineTemp); outlineTemp.Add(startVertexIndex); return(new Outline(outlineTemp)); }
/// <summary> /// Generate and return the outlines based on the data passed in during instantiation. /// </summary> public IList <Outline> GenerateOutlines() { var outlines = new List <Outline>(); visited = new bool[vertices.Length]; for (VertexIndex index = 0; index < vertices.Length; index++) { if (!visited[index] && MustBeOutlineVertex(index)) { outlines.Add(GenerateOutlineFromPoint(index)); } } return(outlines.AsReadOnly()); }
bool DoVerticesShareMultipleTriangles(VertexIndex vertexA, VertexIndex vertexB) { int sharedTriangleCount = 0; List <Triangle> containingTriangles = triangleLookup.GetTrianglesContainingVertex(vertexA); for (int i = 0; i < containingTriangles.Count; i++) { if (IsVertexContainedInTriangle(containingTriangles[i], vertexB)) { sharedTriangleCount++; if (sharedTriangleCount > 1) { return(true); } } } return(false); }
VertexIndex GetInitialConnectedOutlineVertex(VertexIndex startIndex) { List <Triangle> containingTriangles = triangleLookup.GetTrianglesContainingVertex(startIndex); for (int i = 0; i < containingTriangles.Count; i++) { Triangle triangle = containingTriangles[i]; int[] triangleIndices = ExtractTriangleIndices(triangle); foreach (int nextIndex in triangleIndices) { VertexIndex vertexIndex = triangles[nextIndex]; if (IsOutlineEdge(startIndex, vertexIndex) && IsCorrectOrientation(startIndex, vertexIndex, triangle)) { return(vertexIndex); } } } throw new InvalidOperationException("Failed to initialize outline during mesh generation."); }
bool TryGetConnectedOutlineVertex(VertexIndex currentIndex, out VertexIndex nextIndex) { List <Triangle> containingTriangles = triangleLookup.GetTrianglesContainingVertex(currentIndex); for (int i = 0; i < containingTriangles.Count; i++) { int[] triangleIndices = ExtractTriangleIndices(containingTriangles[i]); foreach (int index in triangleIndices) { VertexIndex vertexIndex = triangles[index]; if (!visited[vertexIndex] && IsOutlineEdge(currentIndex, vertexIndex)) { nextIndex = vertexIndex; return(true); } } } nextIndex = new VertexIndex(); return(false); }
public bool DoVerticesShareMultipleTriangles(VertexIndex indexA, VertexIndex indexB) { int a = numTrianglesByIndex[indexA]; int b = numTrianglesByIndex[indexB]; int sharedTriangleCount = 0; for (int x = 0; x < a; x++) { for (int y = 0; y < b; y++) { if (triangleLookup[indexA, x] == triangleLookup[indexB, y]) { sharedTriangleCount++; if (sharedTriangleCount > 1) { return(true); } } } } return(false); }
/// <summary> /// Sufficient (but not necessary) test for the vertex index to be on an outline. For each outline, at least one /// vertex will have an index that returns true according to this method. As such, indices failing this test /// can be ignored while still ensuring every outline is discovered. /// </summary> bool MustBeOutlineVertex(VertexIndex vertexIndex) { int numTrianglesContainingVertex = triangleLookup.CountTrianglesContainingVertex(vertexIndex); return(numTrianglesContainingVertex <= MAX_CONTAINING_TRIANGLES_ENSURING_OUTLINE_INDEX); }
/// <summary> /// Will these indices produce an Outline going in the right direction? The direction of the Outline will determine /// whether the walls are visible. /// </summary> /// <param name="startIndex">The starting index.</param> /// <param name="otherIndex">The discovered index in question.</param> /// <param name="triangle">A triangle containing both indices.</param> /// <returns>Returns whether going from the start index to the discovered index will result in a correctly /// oriented Outline.</returns> bool IsCorrectOrientation(VertexIndex startIndex, VertexIndex otherIndex, Triangle triangle) { VertexIndex outsideIndex = GetThirdPoint(startIndex, otherIndex, triangle); return(IsRightOf(vertices[startIndex], vertices[otherIndex], vertices[outsideIndex])); }
bool IsVertexContainedInTriangle(Triangle triangle, VertexIndex vertex) { return(triangles[triangle.a] == vertex || triangles[triangle.b] == vertex || triangles[triangle.c] == vertex); }
bool IsOutlineEdge(VertexIndex vertexA, VertexIndex vertexB) { return(vertexA != vertexB && !triangleLookup.DoVerticesShareMultipleTriangles(vertexA, vertexB)); }
/// <summary> /// How many triangles contain the given vertex? /// </summary> /// <param name="index"></param> /// <returns></returns> public int CountTrianglesContainingVertex(VertexIndex index) { return(numTrianglesByIndex[index]); }
void AddTriangle(VertexIndex a, VertexIndex b, VertexIndex c) { triangles.Add(a); triangles.Add(b); triangles.Add(c); }