コード例 #1
0
        private void addRoadForward(PriorityQueue <RoadSegment> queue, RoadSegment prev)
        {
            RoadSegment newRoad = new RoadSegment();

            newRoad.prev       = prev;
            newRoad.start      = prev.end;
            newRoad.roadType   = prev.roadType;
            newRoad.roadLength = prev.roadLength + 1;

            newRoad.end = newRoad.start;             //for GetRefSegments

            float stepLength      = prev.roadType == RoadType.MainRoad ? MainRoadStepLength : SubRoadStepLength;
            int   changeIntensity = prev.roadType == RoadType.MainRoad ? MainChangeIntensity : SubChangeIntensity;


            newRoad.rotation = getBestRotation(changeIntensity,
                                               prev.rotation, newRoad.start, stepLength, MainSegments, mainRoadDetrimentRange, mainRoadDetrimentImpact);

            newRoad.end = newRoad.start + RoadSegment.RotateVector(newRoad.rotation, stepLength);

            float val = getValueOfRotation(newRoad.end, MainSegments, mainRoadDetrimentRange, mainRoadDetrimentImpact);

            newRoad.priority = -val + ((newRoad.roadType == RoadType.MainRoad) ? mainRoadAdvantage : 0) +
                               Mathf.Abs(0.1f * prev.priority);         // + baseLibraryStream.FRand() * 0.1;

            if (checkVaild(newRoad))
            {
                queue.Push(newRoad);
                Debug.Log($"addRoadForward {newRoad.start} -> {newRoad.end}");
            }
        }
コード例 #2
0
        private void addRoadSide(PriorityQueue <RoadSegment> queue, RoadSegment prev, bool left, RoadType roadType)
        {
            RoadSegment newRoad = new RoadSegment();

            newRoad.prev     = prev;
            newRoad.roadType = roadType;

            float newRotation = left ? 90 : -90;

            newRoad.rotation = prev.rotation + newRotation;

            newRoad.start = prev.start;
            newRoad.end   = newRoad.start;           //for GetRefSegments

            float stepLength = prev.roadType == RoadType.MainRoad ? MainRoadStepLength : SubRoadStepLength;

            newRoad.rotation = getBestRotation(SubChangeIntensity,
                                               newRoad.rotation, newRoad.start, stepLength, MainSegments, mainRoadDetrimentRange, mainRoadDetrimentImpact);

            newRoad.end = newRoad.start + RoadSegment.RotateVector(newRoad.rotation, stepLength);

            float val = getValueOfRotation(newRoad.end, MainSegments, mainRoadDetrimentRange, mainRoadDetrimentImpact);

            newRoad.priority = -val + ((newRoad.roadType == RoadType.MainRoad) ? mainRoadAdvantage : 0) +
                               Mathf.Abs(0.1f * prev.priority);         // + baseLibraryStream.FRand() * 0.1;

            newRoad.roadLength = (prev.roadType == RoadType.MainRoad && roadType != RoadType.MainRoad) ? 1 : prev.roadLength + 1;

            if (checkVaild(newRoad))
            {
                queue.Push(newRoad);
                Debug.Log($"addRoadSide {newRoad.start} -> {newRoad.end}");
            }
        }
コード例 #3
0
        HashSet <RoadSegment> GetRefSegments(RoadSegment current)
        {
            HashSet <RoadSegment> retval = new HashSet <RoadSegment>();

            GetRefPoint(current.start, retval);
            GetRefPoint(current.start, retval);
            return(retval);
        }
コード例 #4
0
 private bool checkVaild(RoadSegment road)
 {
     if (road.start.x < 0 || road.start.x > MapSize || road.end.x < 0 || road.end.x > MapSize)
     {
         return(false);
     }
     if (road.start.y < 0 || road.start.y > MapSize || road.end.y < 0 || road.end.y > MapSize)
     {
         return(false);
     }
     return(true);
 }
コード例 #5
0
        public void InitRoadSegments()
        {
            RoadSegment startRoad = new RoadSegment {
                start      = new Vector2(MapSize / 2, MapSize / 2),
                roadType   = RoadType.MainRoad,
                roadLength = 1,
            };

            startRoad.prev = startRoad;

            float bestval = float.MinValue;

            for (int i = 0; i < 360; i++)
            {
                Vector2 end = startRoad.start + RoadSegment.RotateVector(i, MainRoadStepLength);

                float tmp = noise.GetNoise(end.x, end.y, MapSize);
                if (bestval < tmp)
                {
                    bestval            = tmp;
                    startRoad.rotation = i;
                    startRoad.end      = end;
                }
            }

            PriorityQueue <RoadSegment> queue = new PriorityQueue <RoadSegment>(4096);

            queue.Push(startRoad);

            while (queue.Count > 0 && determinedSegments.Count < MaxSegments)
            {
                var current = queue.Pop();
                if (localConstraints(current))
                {
                    determinedSegments.Add(current);
                    RefSegmentsAdd(current);
                    if (current.roadType == RoadType.MainRoad)
                    {
                        MainSegments.Add(current);
                    }

                    addExtensions(queue, current);
                }
            }

            Debug.Log("Done");
        }
コード例 #6
0
        void RefSegmentsRemove(RoadSegment current)
        {
            int x1 = (int)current.end.x / maxMainRoadLength;
            int y1 = (int)current.end.y / maxMainRoadLength;

            int x2 = (int)current.start.x / maxMainRoadLength;
            int y2 = (int)current.start.y / maxMainRoadLength;

            if (SegmentMap[x1][y1].Contains(current))
            {
                SegmentMap[x1][y1].Remove(current);
            }
            if (SegmentMap[x2][y2].Contains(current))
            {
                SegmentMap[x2][y2].Remove(current);
            }
        }
コード例 #7
0
        private float getBestRotation(int maxDiffAllowed, float original, Vector2 originalPoint, float step,
                                      List <RoadSegment> others, float maxDist, float detriment)
        {
            Vector2 testPoint   = originalPoint + RoadSegment.RotateVector(original, step);
            float   bestVal     = float.MinValue;
            float   bestRotator = original;

            for (int i = 0; i < 7; i++)
            {
                float curr = original + random.Next(-maxDiffAllowed, maxDiffAllowed);
                testPoint = originalPoint + RoadSegment.RotateVector(curr, step);
                float val = getValueOfRotation(testPoint, others, maxDist, detriment);
                if (val > bestVal)
                {
                    bestRotator = curr;
                    bestVal     = noise.GetNoise(testPoint.x, testPoint.y, MapSize);
                }
            }

            return(bestRotator);
        }
コード例 #8
0
        void addExtensions(PriorityQueue <RoadSegment> queue, RoadSegment current)
        {
            if (current.roadType == RoadType.MainRoad)
            {
                if (current.roadLength < maxMainRoadLength)
                {
                    addRoadForward(queue, current);
                }

                if (random.Next(0, 100) < mainRoadBranchChance)
                {
                    addRoadSide(queue, current, true, RoadType.MainRoad);
                }
                else
                {
                    addRoadSide(queue, current, true, RoadType.SubRoad);
                }

                if (random.Next(0, 100) < mainRoadBranchChance)
                {
                    addRoadSide(queue, current, false, RoadType.MainRoad);
                }
                else
                {
                    addRoadSide(queue, current, false, RoadType.SubRoad);
                }
            }
            else if (current.roadType == RoadType.SubRoad)
            {
                if (current.roadLength < maxSecondaryRoadLength)
                {
                    addRoadForward(queue, current);

                    addRoadSide(queue, current, true, RoadType.SubRoad);
                    addRoadSide(queue, current, false, RoadType.SubRoad);
                }
            }
        }
コード例 #9
0
        bool localConstraints(RoadSegment current)
        {
            foreach (var seg in GetRefSegments(current))
            {
                if (seg.prev == current)
                {
                    continue;
                }

                if (Vector2.Distance(current.getMiddle(), seg.getMiddle()) < closeMiddle)
                {
                    return(false);
                }

                Vector2 intersection;
                if (Intersection.Get(current.start, current.end, seg.start, seg.end, out intersection))
                {
                    current.priority = float.MaxValue;
                    collideInto(current, seg, intersection);
                }
            }

            return(true);
        }
コード例 #10
0
 void RefSegmentsAdd(RoadSegment current)
 {
     SegmentMap[(int)current.start.x / maxMainRoadLength][(int)current.start.y / maxMainRoadLength].Add(current);
     SegmentMap[(int)current.end.x / maxMainRoadLength][(int)current.end.y / maxMainRoadLength].Add(current);
 }
コード例 #11
0
 void collideInto(RoadSegment current, RoadSegment seg, Vector2 intersection)
 {
     current.end = intersection;
 }