Exemple #1
0
        /// <summary>
        /// The internal version of the building that functions while
        /// thread-safe.
        /// </summary>
        private void BuildConnectionsLocked()
        {
            // Don't bother if we have connections already
            if (builtConnections)
                return;

            // Sanity checking
            if (isBuildingConnections)
                throw new Exception("Building connections is not reentrant");

            isBuildingConnections = true;

            // Make sure our shapes are built to keep the order consistent
            BuildShapes();

            // Keep track of the overlap detection code
            LinkedList<IPoly> overlaps = new LinkedList<IPoly>();

            // Process the parent element
            if (ParentJunction != null)
            {
                // Find our input segment
                Segment ps = ParentJunction.GetSegment(this);

                if (ps == null)
                    throw new Exception("We got a null segment from parent");

                // Add the parent segment with swapped directions
                ps = ps.Swap();
                segments.Add(ps);

                // Add to the overlap, but don't bother checking (we
                // are guarenteed to the first).
                CheckOverlapIntersection(overlaps, ps);
            }

            // We want to create a random number of connections
            int connectionCount = Random.Next(
                Constants.BuildMinimumConnections,
                Constants.BuildMaximumConnections);

            // Go through each connection
            for (int i = 0; i < connectionCount; i++)
            {
                // Build up a connection in a random direction
                float angle = Random.NextSingle(0, 2 * (float) Math.PI);
                float length = Random.NextSingle(
                    Constants.MinimumConnectionDistance,
                    Constants.MaximumConnectionDistance);

                // Junction points are relative to the parent node
                PointF point = new PointF(
                    (float) Math.Cos(angle) * length,
                    (float) Math.Sin(angle) * length);

                // Create a new junction at this point
                Junction junction = new Junction(Random.Next());
                junction.ParentJunction = this;
                junction.BuildShapes();

                // Get the segment factory and create the segment
                ISegmentFactory isf =
                    FactoryManager.ChooseSegmentFactory(junction);
                Segment segment = isf.Create(junction, point, Distance);
                segment.ParentJunction = this;
                segment.ChildJunction = junction;
                segment.ChildJunctionPoint = point;

                // Set the junction's distance
                junction.Distance =
                    Distance + segment.CenterPoints.MaximumRelativeDistance;

                // Check and add the overlap
                if (CheckOverlapIntersection(overlaps, segment))
                {
                    // We intersect
                    Log.Debug("Rejection because segments overlap");
                    continue;
                }

                // Add some clutter
                IClutterFactory icf =
                    FactoryManager.ChooseClutterFactory(Random);
                icf.Create(segment);

                // Add it to the segments
                segments.Add(segment);
            }

            // Create the physics shapes
            if (GeneratePhysics)
            {
            #if DEBUG
                Stopwatch stopwatch = Stopwatch.StartNew();
            #endif
                BuildCombinedShape();
            #if DEBUG
                // Show timing information
                stopwatch.Stop();
                Log.Debug("   Physics Shape: {0}", stopwatch.Elapsed);
                stopwatch.Reset();
                stopwatch.Start();
            #endif
                CreateJunctionPhysics(0);

            #if DEBUG
                // Show timing information
                stopwatch.Stop();
                Log.Debug("Physics Creation: {0}", stopwatch.Elapsed);
            #endif
            }

            // We are done
            builtConnections = true;
            isBuildingConnections = false;
        }