/// <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));
 }
Пример #15
0
 /// <summary>
 /// How many triangles contain the given vertex?
 /// </summary>
 /// <param name="index"></param>
 /// <returns></returns>
 public int CountTrianglesContainingVertex(VertexIndex index)
 {
     return(numTrianglesByIndex[index]);
 }
Пример #16
0
 void AddTriangle(VertexIndex a, VertexIndex b, VertexIndex c)
 {
     triangles.Add(a);
     triangles.Add(b);
     triangles.Add(c);
 }