Ejemplo n.º 1
0
        private static bool IsEffectivelyRightOfSplitter(BspSegment splitter, BspSegment segment)
        {
            Rotation startSide = splitter.ToSide(segment.Start);

            if (startSide == Rotation.On)
            {
                Rotation endSide = splitter.ToSide(segment.End);
                Debug.Assert(endSide != Rotation.On, "Splitter and segment are too close to determine sides");

                return(endSide == Rotation.Right);
            }

            return(startSide == Rotation.Right);
        }
Ejemplo n.º 2
0
        protected void HandleEndpointIntersectionSplit(BspSegment splitter, BspSegment segmentToSplit, Endpoint endpoint)
        {
            // We know that the endpoint argument is the vertex that was
            // intersected by the splitter. This means the other endpoint is
            // on the left or the right side of the splitter, so we'll use
            // that 'opposite' endpoint to check the side we should place the
            // segment on.
            BspVertex oppositeVertex = segmentToSplit.Opposite(endpoint);
            Rotation  side           = splitter.ToSide(oppositeVertex);

            Debug.Assert(side != Rotation.On, "Ambiguous split, segment too small to determine splitter side");

            if (side == Rotation.Right)
            {
                States.RightSegments.Add(segmentToSplit);
            }
            else
            {
                States.LeftSegments.Add(segmentToSplit);
            }

            BspVertex vertex = segmentToSplit.VertexFrom(endpoint);

            States.CollinearVertices.Add(vertex);
        }
Ejemplo n.º 3
0
        protected void HandleNonEndpointIntersectionSplit(BspSegment splitter, BspSegment segmentToSplit, double segmentTime)
        {
            // Note for the future: If we ever change to using pointers or some
            // kind of reference that invalidates on a list resizing (like a
            // std::vector in C++), this will lead to undefined behavior since
            // it will add new segments and cause them to become dangling.
            (BspSegment segA, BspSegment segB) = SegmentAllocator.Split(segmentToSplit, segmentTime);

            // Since we split the segment such that the line is:
            //
            //    Seg A  |  Seg B
            // [A]=======o=========[B]
            //           |
            //           | <-- Splitter
            //           X
            //
            // We can find which side of the splitter the segments are on by
            // looking at where [A] or [B] ended up. Since the split causes us
            // to know that the middle index is at the first segment's endpoint
            // (and the second segment start point), either or of these would
            // tell us which side the segment is on... and when we know which
            // one is on which side of the splitter, we automatically know the
            // other segment from the split is on the other.
            Rotation side = splitter.ToSide(segA.Start);

            // It may be possible that a split occurs so close to the endpoint
            // (by some unfortunate map geometry) which screws up detecting
            // which side we are on for the splitting. In such a case, we'll
            // try checking both endpoints to see if this is the case and make
            // our decision accordingly.
            if (side == Rotation.On)
            {
                Log.Warn("Very tight endpoint split perform with segment {0}", segmentToSplit);

                Rotation otherSide = splitter.ToSide(segmentToSplit.End);
                Debug.Assert(otherSide != Rotation.On, "Segment being split is too small to detect which side of the splitter it's on");
                side = (otherSide == Rotation.Left ? Rotation.Right : Rotation.Left);
            }

            if (side == Rotation.Right)
            {
                States.RightSegments.Add(segA);
                States.LeftSegments.Add(segB);
            }
            else
            {
                States.LeftSegments.Add(segA);
                States.RightSegments.Add(segB);
            }

            // The reason we know it's the end index of segA is because the
            // splitter always has the first seg splitting based on the start.
            // A corollary is that this would be equal to segB.getStartIndex()
            // since they are equal.
            States.CollinearVertices.Add(segA.EndVertex);

            if (segmentToSplit.OneSided)
            {
                JunctionClassifier.AddSplitJunction(segA, segB);
            }
        }