예제 #1
0
        /// <summary>
        /// Not used, and not tested.
        /// Filters out colinear vertices. Which is a useful step in mesh simplification.
        /// The other steps aren't implemented yet. Mesh simplification would be neat,
        /// but the rendering performance gain in most situations would be tiny.
        /// </summary>
        static IEnumerable <Vertex> RemoveColinearVertices(IEnumerable <Vertex> originalVertices)
        {
            List <Vertex> cache = originalVertices.ToList();

            if (cache.Count == 0)
            {
                yield break;
            }

            // to save headaches about removal during enumeration, build a set of vertices to remove
            HashSet <Vertex> verticesToRemove = new HashSet <Vertex>();

            foreach (Vertex start in cache)
            {
                if (verticesToRemove.Contains(start))
                {
                    continue;
                }

                // build collection of unique directions from other vertices to start,
                // while building it also find any colinear vertices we can remove
                HashSet <DirectionToVertex> directionsFromStart = new HashSet <DirectionToVertex>();

                foreach (Vertex a in cache)
                {
                    if (verticesToRemove.Contains(a))
                    {
                        continue;
                    }
                    if (a.Equals(start))
                    {
                        continue;
                    }

                    DirectionToVertex startToA = new DirectionToVertex(start, a);
                    bool shouldAddDirection    = true;

                    foreach (var startToB in directionsFromStart.Where(direction => direction.RoughlyEqualDirection(startToA)))
                    {
                        // the following vertices are colinear: start, A, startToB.target,
                        // because direction to start is (roughly) the same for A and startToB.target, we know
                        // the middle of the 3 cannot be start. The middle is whichever of A and B is closest to start.
                        if (startToA.distancetoTarget <= startToB.distancetoTarget)
                        {
                            // A is the middle vertex
                            verticesToRemove.Add(a);

                            // no need to add this direction to the collection, as other colinears will be
                            // detected thanks to the startToB direction which detected this one
                            shouldAddDirection = false;

                            // no need to check any other parallel directions
                            // wouldn't expect there to be other parallels anyway (might want to check that!)
                            break;
                        }
                        else
                        {
                            // B is the middle vertex
                            verticesToRemove.Add(startToB.target);

                            // remove record of B's direction, replacing it with A's direction
                            directionsFromStart.Remove(startToB);
                            shouldAddDirection = true;
                        }
                    }

                    if (shouldAddDirection)
                    {
                        directionsFromStart.Add(startToA);
                    }
                }
            }

            foreach (Vertex item in cache)
            {
                if (!verticesToRemove.Contains(item))
                {
                    yield return(item);
                }
            }
        }
예제 #2
0
 public bool RoughlyEqualDirection(DirectionToVertex other, float fuzziness = 0.001f)
 {
     return(VectorRoughlyEqual(this.direction, other.direction, fuzziness));
 }