Compare commits
2 Commits
master
...
city_gener
Author | SHA1 | Date | |
---|---|---|---|
|
476411f6e7 | ||
|
4facf6c3ba |
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Assets.Cities;
|
||||
using Assets.Common;
|
||||
using System;
|
||||
using Assets.Voronoi;
|
||||
using UnityEngine;
|
||||
using Random = System.Random;
|
||||
|
||||
namespace Assets.AnnotationPass
|
||||
{
|
||||
@ -18,6 +21,7 @@ namespace Assets.AnnotationPass
|
||||
public double MinNudgeDistance { get; set; } = .75;
|
||||
|
||||
public double MinimumRoadLength { get; set; } = 2;
|
||||
public double BusinessCityFields { get; set; } = 0.3;
|
||||
|
||||
public CityFieldsPass(Random random)
|
||||
{
|
||||
@ -120,6 +124,8 @@ namespace Assets.AnnotationPass
|
||||
(current, next) = (next, GetNext(next, current));
|
||||
} while (current != start && watchdog-- > 0);
|
||||
|
||||
field.Center = PointUtils.Mean(field.Boundary);
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
@ -133,6 +139,26 @@ namespace Assets.AnnotationPass
|
||||
|
||||
// remove outside field
|
||||
city.Fields.RemoveAll(field => !PointUtils.IsClockwise(field.Boundary));
|
||||
|
||||
// add field types
|
||||
var orderedFields = city.Fields.OrderBy(cf => Point.Dist(cf.Center, city.Center)).ToList();
|
||||
|
||||
orderedFields.First().Type = FieldType.MainSquare;
|
||||
|
||||
|
||||
int businessCityFields = (int)Math.Ceiling((BusinessCityFields*orderedFields.Count()));
|
||||
|
||||
foreach (var cityField in orderedFields.Skip(1).Take(businessCityFields))
|
||||
{
|
||||
cityField.Type = FieldType.Business;
|
||||
}
|
||||
|
||||
|
||||
foreach (var cityField in orderedFields.Skip(1+businessCityFields))
|
||||
{
|
||||
cityField.Type = FieldType.Living;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Annotate(Map map)
|
||||
|
@ -10,6 +10,11 @@ namespace Assets.AnnotationPass
|
||||
{
|
||||
public const string CitiesProperty = "Cities";
|
||||
public const string CityProperty = "City";
|
||||
public int MaxCitiesCount { get; set; } = 20;
|
||||
public int MaxPlacementTries { get; set; } = 30;
|
||||
public float RangeOfInfluence { get; set; } = .5f;
|
||||
public float CitiesSize { get; set; } = .5f;
|
||||
|
||||
|
||||
private Graph<Location> _locationGraph;
|
||||
private Graph<MapSite> _basicGraph;
|
||||
@ -20,16 +25,14 @@ namespace Assets.AnnotationPass
|
||||
_random = random ?? new Random();
|
||||
}
|
||||
|
||||
IEnumerable<int> LocateCities()
|
||||
{
|
||||
return ChoosePoints(5);
|
||||
}
|
||||
|
||||
City CreateCity(int vertex, int size)
|
||||
{
|
||||
City newCity = new City();
|
||||
|
||||
var site = _basicGraph.Vertices[vertex];
|
||||
newCity.Center = site.Center.Clone() as Point;
|
||||
site.Tags.Add("City.Center");
|
||||
|
||||
var sites = new List<MapSite> { site };
|
||||
var location = site.Metadata.GetProperty<Location>(LandmassPass.SiteLocationProperty);
|
||||
|
||||
@ -46,22 +49,38 @@ namespace Assets.AnnotationPass
|
||||
s.Metadata.SetProperty(CityProperty, newCity);
|
||||
}
|
||||
|
||||
newCity.RangeOfInfluence = GetCityRangeOfInfluence(newCity);
|
||||
return newCity;
|
||||
}
|
||||
|
||||
IEnumerable<int> ChoosePoints(int number)
|
||||
List<City> CreateCities()
|
||||
{
|
||||
List<City> cities = new List<City>();
|
||||
var vertices = new List<int>();
|
||||
|
||||
for (int i = 0; i < number; i++)
|
||||
int guard = MaxPlacementTries;
|
||||
int createdCitiesCount = 0;
|
||||
|
||||
while (createdCitiesCount < MaxCitiesCount && guard-- > 0)
|
||||
{
|
||||
var randomLocation = _locationGraph.Vertices[_random.Next(1, _locationGraph.Vertices.Count())];
|
||||
var count = randomLocation.Sites.Count();
|
||||
var randomPoint = randomLocation.Sites[_random.Next(0, count)];
|
||||
vertices.Add(randomPoint.Index);
|
||||
var randomLocation = _locationGraph.Vertices.Skip(1).RandomElement(_random);
|
||||
var randomSite = randomLocation.Sites.RandomElement(_random);
|
||||
|
||||
if (cities.Any(c => Point.Dist(PointUtils.Mean(c.Sites.Select(s => s.Center)), randomSite.Center) < c.RangeOfInfluence))
|
||||
continue;
|
||||
|
||||
cities.Add(CreateCity(randomSite.Index, (int)Math.Ceiling(CitiesSize * _random.Next(0, 30))));
|
||||
guard = MaxPlacementTries;
|
||||
createdCitiesCount++;
|
||||
}
|
||||
|
||||
return vertices;
|
||||
return cities;
|
||||
|
||||
}
|
||||
|
||||
public float GetCityRangeOfInfluence(City city)
|
||||
{
|
||||
return RangeOfInfluence*city.Sites.Count;
|
||||
}
|
||||
|
||||
public void Annotate(Map map)
|
||||
@ -69,11 +88,7 @@ namespace Assets.AnnotationPass
|
||||
_basicGraph = map.Sites.Clone() as Graph<MapSite>;
|
||||
_locationGraph = map.Metadata.GetProperty<Graph<Location>>(LandmassPass.MapLocationsProperty);
|
||||
|
||||
var cities = new List<City>();
|
||||
var locations = LocateCities();
|
||||
|
||||
foreach (var index in locations)
|
||||
cities.Add(CreateCity(index, _random.Next(0, 10)));
|
||||
var cities = CreateCities();
|
||||
|
||||
map.Metadata.SetProperty(CitiesProperty, cities);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using Assets.Voronoi;
|
||||
|
||||
namespace Assets.Cities
|
||||
{
|
||||
public class City
|
||||
public class City : IHasMetadata
|
||||
{
|
||||
public List<MapSite> Sites { get; set; } = new List<MapSite>();
|
||||
|
||||
@ -15,6 +15,8 @@ namespace Assets.Cities
|
||||
public List<CityField> Fields { get; set; } = new List<CityField>();
|
||||
|
||||
public List<(int, int)> Edges = new List<(int, int)>();
|
||||
public Point Center { get; set; }
|
||||
public float RangeOfInfluence { get; set; } = 0;
|
||||
|
||||
public City()
|
||||
{
|
||||
@ -25,6 +27,7 @@ namespace Assets.Cities
|
||||
Sites = sites;
|
||||
}
|
||||
|
||||
|
||||
public void AddSite(MapSite site)
|
||||
{
|
||||
Sites.Add(site);
|
||||
@ -38,5 +41,7 @@ namespace Assets.Cities
|
||||
|
||||
Edges = a.Union(b).Except(a.Intersect(b)).ToList();
|
||||
}
|
||||
|
||||
public Metadata Metadata { get; } = new Metadata();
|
||||
}
|
||||
}
|
@ -3,8 +3,17 @@ using Assets.Common;
|
||||
|
||||
namespace Assets.Cities
|
||||
{
|
||||
public enum FieldType
|
||||
{
|
||||
MainSquare,
|
||||
Business,
|
||||
Living
|
||||
}
|
||||
|
||||
public class CityField
|
||||
{
|
||||
public IList<Point> Boundary { get; set; } = new List<Point>();
|
||||
public FieldType Type { get; set; }
|
||||
public Point Center { get; set; }
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ namespace Assets
|
||||
public bool displayCityFields = true;
|
||||
|
||||
[NonSerialized] public float generationTime = 0.0f;
|
||||
public bool displayRangeOfInfluence = false;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@ -60,13 +61,21 @@ namespace Assets
|
||||
|
||||
[Range(0f, 360f)]
|
||||
public float minimumRoadAngle = 30f;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
public float businessCityFields = 0.3f;
|
||||
[Range(0f, 4f)]
|
||||
public float minimumNudgeDistance = 0.5f;
|
||||
[Range(0f, 4f)]
|
||||
public float maximumNudgeDistance = 1f;
|
||||
[Range(0f, 4f)]
|
||||
public float minimumRoadLength = 1f;
|
||||
public float rangeOfInfluence = .5f;
|
||||
[Range(0f, 1f)]
|
||||
public float citiesSize = .5f;
|
||||
|
||||
|
||||
[Range(0, 50)]
|
||||
public int citiesCount = 20;
|
||||
|
||||
[Range(2.0f, 64.0f)]
|
||||
public float radius = 8;
|
||||
@ -109,13 +118,19 @@ namespace Assets
|
||||
var generator = new MapGenerator(new VoronoiGridGenerator(seed, new PoissonDiskSampler(radius) { Generator = new Random(seed) }));
|
||||
|
||||
generator.AddAnnotationPass(new LandmassPass(types.Prepend(new LocationType { name = "Ocean", height = -1 }).Select(t => new Location { Type = t }), new Random(seed)));
|
||||
generator.AddAnnotationPass(new LocateCitiesPass(new Random(seed)));
|
||||
generator.AddAnnotationPass(new LocateCitiesPass(new Random(seed))
|
||||
{
|
||||
MaxCitiesCount = citiesCount,
|
||||
RangeOfInfluence = rangeOfInfluence,
|
||||
CitiesSize = citiesSize
|
||||
});
|
||||
generator.AddAnnotationPass(new CityFieldsPass(new Random(seed))
|
||||
{
|
||||
MinimumAngle = Mathf.Deg2Rad * minimumRoadAngle,
|
||||
MaxNudgeDistance = maximumNudgeDistance,
|
||||
MinNudgeDistance = minimumNudgeDistance,
|
||||
MinimumRoadLength = minimumRoadLength
|
||||
MinimumRoadLength = minimumRoadLength,
|
||||
BusinessCityFields = businessCityFields
|
||||
});
|
||||
|
||||
return generator;
|
||||
@ -261,14 +276,39 @@ namespace Assets
|
||||
}
|
||||
}
|
||||
|
||||
if (debug.displayRangeOfInfluence)
|
||||
{
|
||||
foreach (var city in cities)
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(PointUtils.Mean(city.Sites.Select(s => s.Center)).ToVector3(), city.RangeOfInfluence);
|
||||
Gizmos.DrawSphere(PointUtils.Mean(city.Sites.Select(s => s.Center)).ToVector3(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug.displayCityFields)
|
||||
{
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.color = Color.blue;
|
||||
|
||||
foreach (var city in cities)
|
||||
{
|
||||
foreach (var field in city.Fields)
|
||||
{
|
||||
switch (field.Type)
|
||||
{
|
||||
case FieldType.Business:
|
||||
Gizmos.color = Color.green;
|
||||
break;
|
||||
case FieldType.Living:
|
||||
Gizmos.color = Color.yellow;
|
||||
break;
|
||||
case FieldType.MainSquare:
|
||||
Gizmos.color = Color.red;
|
||||
break;
|
||||
default:
|
||||
Gizmos.color = Color.blue;
|
||||
break;
|
||||
}
|
||||
foreach (var (a, b) in field.Boundary.RotateRight().Zip(field.Boundary, (a, b) => (a, b)))
|
||||
Gizmos.DrawLine(a.ToVector3(), b.ToVector3());
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--- !u!129 &1
|
||||
PlayerSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 17
|
||||
serializedVersion: 18
|
||||
productGUID: 59b609f943ea458cd81d6a9bda1ea716
|
||||
AndroidProfiler: 0
|
||||
AndroidFilterTouchesWhenObscured: 0
|
||||
@ -52,8 +52,8 @@ PlayerSettings:
|
||||
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
|
||||
iosShowActivityIndicatorOnLoading: -1
|
||||
androidShowActivityIndicatorOnLoading: -1
|
||||
iosAppInBackgroundBehavior: 0
|
||||
displayResolutionDialog: 0
|
||||
iosUseCustomAppBackgroundBehavior: 0
|
||||
iosAllowHTTPDownload: 1
|
||||
allowedAutorotateToPortrait: 1
|
||||
allowedAutorotateToPortraitUpsideDown: 1
|
||||
@ -156,7 +156,6 @@ PlayerSettings:
|
||||
protectGraphicsMemory: 0
|
||||
enableFrameTimingStats: 0
|
||||
useHDRDisplay: 0
|
||||
D3DHDRBitDepth: 0
|
||||
m_ColorGamuts: 00000000
|
||||
targetPixelDensity: 30
|
||||
resolutionScalingMode: 0
|
||||
@ -597,6 +596,7 @@ PlayerSettings:
|
||||
XboxOneAllowedProductIds: []
|
||||
XboxOnePersistentLocalStorageSize: 0
|
||||
XboxOneXTitleMemory: 8
|
||||
xboxOneScriptCompiler: 1
|
||||
XboxOneOverrideIdentityName:
|
||||
vrEditorSettings:
|
||||
daydream:
|
||||
|
@ -1,2 +1,2 @@
|
||||
m_EditorVersion: 2019.2.0f1
|
||||
m_EditorVersionWithRevision: 2019.2.0f1 (20c1667945cf)
|
||||
m_EditorVersion: 2019.3.0a8
|
||||
m_EditorVersionWithRevision: 2019.3.0a8 (8ea4afdbfa47)
|
||||
|
Loading…
Reference in New Issue
Block a user