Exemple #1
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);
        }
Exemple #2
0
 /// <summary>
 /// Checks if the indices from the values provided cross the void or
 /// not, where the void is the space outside the map.
 /// </summary>
 /// <param name="first">The index of the first segment.</param>
 /// <param name="second">The actual vertex coordinate of the
 /// second segment.</param>
 /// <returns>True if the two vertices are crossing the void, false if
 /// it is inside the map.</returns>
 public bool CheckCrossingVoid(BspVertex first, BspVertex second)
 {
     if (vertexToJunction.TryGetValue(first, out Junction junction))
     {
         return(!junction.BetweenWedge(second.Struct()));
     }
     return(false);
 }
Exemple #3
0
        /// <summary>
        /// Tells the junction classifier that we will not be adding anymore
        /// junctions from `Add()` anymore. It will then compile all the
        /// junctions.
        /// </summary>
        /// <remarks>
        /// The only way to add new junctions after calling this should be
        /// through <see cref="AddSplitJunction"/>. This is unfortunately
        /// needed since creating the junctions on the fly while adding new
        /// segments would be extra work and extra code. It might be worth
        /// doing one day however since it is a code smell due to requiring
        /// users to know about this function.
        /// </remarks>
        private void NotifyDoneAdding()
        {
            foreach (var vertexJunctionPair in vertexToJunction)
            {
                BspVertex vertex   = vertexJunctionPair.Key;
                Junction  junction = vertexJunctionPair.Value;

                if (junction.HasUnexpectedSegCount())
                {
                    Log.Warn($"BSP junction at ({vertex}) has wrong amount of one-sided lines, BSP tree likely to be malformed");
                }

                junction.GenerateWedges();
            }
        }
Exemple #4
0
        private List <BspSegment> ReadLinesFrom(MapData map)
        {
            List <BspSegment> segments = new List <BspSegment>();

            foreach (MapLinedef line in map.Linedefs)
            {
                MapVertex startMapVertex = map.Vertices[line.StartVertex];
                MapVertex endMapVertex   = map.Vertices[line.EndVertex];

                BspVertex start = VertexAllocator[startMapVertex.Struct()];
                BspVertex end   = VertexAllocator[endMapVertex.Struct()];

                BspSegment segment = SegmentAllocator.GetOrCreate(start, end, line);
                segments.Add(segment);
            }

            return(segments);
        }
Exemple #5
0
        /// <summary>
        /// A function called during BSP partitioning where we create a new
        /// junction when we split a one sided line in two.
        /// </summary>
        /// <param name="inboundSegment">The inbound segment.</param>
        /// <param name="outboundSegment">The outbound segment.</param>
        public void AddSplitJunction(BspSegment inboundSegment, BspSegment outboundSegment)
        {
            Debug.Assert(!ReferenceEquals(inboundSegment, outboundSegment), "Trying to add the same segment as an inbound/outbound junction");
            BspVertex middleVertex = inboundSegment.EndVertex;

            Debug.Assert(outboundSegment.StartVertex == middleVertex, "Adding split junction where inbound/outbound segs are not connected");
            Debug.Assert(!vertexToJunction.ContainsKey(middleVertex), "When creating a split, the middle vertex shouldn't already exist as a junction");

            // We create new junctions because this function is called from a
            // newly created split. This means the middle vertex is new and the
            // junction cannot exist by virtue of the pivot point never having
            // existed.
            Junction junction = new Junction();

            vertexToJunction[middleVertex] = junction;

            junction.InboundSegments.Add(inboundSegment);
            junction.OutboundSegments.Add(outboundSegment);
            junction.AddWedge(inboundSegment, outboundSegment);
        }
Exemple #6
0
        protected void HandleMinisegGeneration(BspVertex first, BspVertex second)
        {
            States.VoidStatus = VoidStatus.NotInVoid;

            // If a segment exists for the vertices then we're walking along a
            // segment that was collinear with the splitter, so we don't need a
            // miniseg.
            if (SegmentAllocator.ContainsSegment(first, second))
            {
                return;
            }

            if (JunctionClassifier.CheckCrossingVoid(first, second))
            {
                States.VoidStatus = VoidStatus.InVoid;
            }
            else
            {
                BspSegment miniseg = SegmentAllocator.GetOrCreate(first, second);
                States.Minisegs.Add(miniseg);
            }
        }
Exemple #7
0
 /// <summary>
 /// Creates an index/time pair.
 /// </summary>
 /// <param name="vertex">The vertex.</param>
 /// <param name="splitterTime">The time this is relative to the
 /// splitter.</param>
 public VertexSplitterTime(BspVertex vertex, double splitterTime)
 {
     Vertex       = vertex;
     SplitterTime = splitterTime;
 }