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}"); } }
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}"); } }
HashSet <RoadSegment> GetRefSegments(RoadSegment current) { HashSet <RoadSegment> retval = new HashSet <RoadSegment>(); GetRefPoint(current.start, retval); GetRefPoint(current.start, retval); return(retval); }
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); }
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"); }
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); } }
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); }
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); } } }
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); }
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); }
void collideInto(RoadSegment current, RoadSegment seg, Vector2 intersection) { current.end = intersection; }