diff --git a/Documentation/Pictures/funnyresult.png b/Documentation/Pictures/funnyresult.png
new file mode 100644
index 0000000..5863030
Binary files /dev/null and b/Documentation/Pictures/funnyresult.png differ
diff --git a/Game/Assembly-CSharp-vs.csproj b/Game/Assembly-CSharp-vs.csproj
index b0fee09..168fb4b 100644
--- a/Game/Assembly-CSharp-vs.csproj
+++ b/Game/Assembly-CSharp-vs.csproj
@@ -54,11 +54,15 @@
+
+
+
+
@@ -67,6 +71,7 @@
+
@@ -75,6 +80,7 @@
+
diff --git a/Game/Assembly-CSharp.csproj b/Game/Assembly-CSharp.csproj
index 0973862..a868770 100644
--- a/Game/Assembly-CSharp.csproj
+++ b/Game/Assembly-CSharp.csproj
@@ -54,11 +54,15 @@
+
+
+
+
@@ -67,6 +71,7 @@
+
@@ -75,6 +80,7 @@
+
diff --git a/Game/Assets/Data/Config/tergen.xml b/Game/Assets/Data/Config/tergen.xml
index 06d1924..0e46a7e 100644
--- a/Game/Assets/Data/Config/tergen.xml
+++ b/Game/Assets/Data/Config/tergen.xml
@@ -3,7 +3,7 @@
9
2.4
1.9
- 0.001
+ 0.00075
100
60
0.1
diff --git a/Game/Assets/Data/Materials/building.mat b/Game/Assets/Data/Materials/building.mat
new file mode 100644
index 0000000..b0f3969
Binary files /dev/null and b/Game/Assets/Data/Materials/building.mat differ
diff --git a/Game/Assets/Data/Materials/building.mat.meta b/Game/Assets/Data/Materials/building.mat.meta
new file mode 100644
index 0000000..84831ff
--- /dev/null
+++ b/Game/Assets/Data/Materials/building.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 269eb1f1b18ec284784864c4015500d7
+timeCreated: 1433922839
+licenseType: Free
+NativeFormatImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Data/Textures/grass.png.meta b/Game/Assets/Data/Textures/grass.png.meta
index c3e89be..4bf853f 100644
--- a/Game/Assets/Data/Textures/grass.png.meta
+++ b/Game/Assets/Data/Textures/grass.png.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/mountain.jpg.meta b/Game/Assets/Data/Textures/mountain.jpg.meta
index f446700..e3c669e 100644
--- a/Game/Assets/Data/Textures/mountain.jpg.meta
+++ b/Game/Assets/Data/Textures/mountain.jpg.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/mountain2.jpg.meta b/Game/Assets/Data/Textures/mountain2.jpg.meta
index 581db96..ff4b9c3 100644
--- a/Game/Assets/Data/Textures/mountain2.jpg.meta
+++ b/Game/Assets/Data/Textures/mountain2.jpg.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/red.png.meta b/Game/Assets/Data/Textures/red.png.meta
index 2a937d8..8c91b8c 100644
--- a/Game/Assets/Data/Textures/red.png.meta
+++ b/Game/Assets/Data/Textures/red.png.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/sand.jpg.meta b/Game/Assets/Data/Textures/sand.jpg.meta
index 60549d2..24a0da8 100644
--- a/Game/Assets/Data/Textures/sand.jpg.meta
+++ b/Game/Assets/Data/Textures/sand.jpg.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/sidewalk.jpg.meta b/Game/Assets/Data/Textures/sidewalk.jpg.meta
index ecdc552..3fd637b 100644
--- a/Game/Assets/Data/Textures/sidewalk.jpg.meta
+++ b/Game/Assets/Data/Textures/sidewalk.jpg.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/snow.jpg.meta b/Game/Assets/Data/Textures/snow.jpg.meta
index de60de4..2d6be17 100644
--- a/Game/Assets/Data/Textures/snow.jpg.meta
+++ b/Game/Assets/Data/Textures/snow.jpg.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Data/Textures/street.gif.meta b/Game/Assets/Data/Textures/street.gif.meta
index 86c4a09..fe48c9a 100644
--- a/Game/Assets/Data/Textures/street.gif.meta
+++ b/Game/Assets/Data/Textures/street.gif.meta
@@ -19,7 +19,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
@@ -45,7 +45,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 0
- textureType: -1
+ textureType: 5
buildTargetSettings: []
spriteSheet:
sprites: []
diff --git a/Game/Assets/Main.unity b/Game/Assets/Main.unity
index f104383..5483a99 100644
Binary files a/Game/Assets/Main.unity and b/Game/Assets/Main.unity differ
diff --git a/Game/Assets/Scripts/Generator/BuildingGenerator.cs b/Game/Assets/Scripts/Generator/BuildingGenerator.cs
index 8a9a012..e6a2569 100644
--- a/Game/Assets/Scripts/Generator/BuildingGenerator.cs
+++ b/Game/Assets/Scripts/Generator/BuildingGenerator.cs
@@ -11,8 +11,11 @@ namespace TransportGame.Generator
{
public class BuildingGenerator
{
- private const float LotSquareSize = 1f;
- private const float LotSpacing = 0.1f;
+ Random random = new Random();
+
+ private float LotSquareMinSize { get { return ConfigManager.Buildgen.LotSquareMinSize; } }
+ private float LotSquareMaxSize { get { return ConfigManager.Buildgen.LotSquareMaxSize; } }
+ private float LotSpacing { get { return ConfigManager.Buildgen.LotSpacing; } }
private Map map;
QuadTree nodeTree;
@@ -20,43 +23,75 @@ namespace TransportGame.Generator
private void AllocateLots()
{
- float advance = LotSquareSize + LotSpacing;
-
// Generate lots for every segment
foreach (var pair in map.RoadNetwork.ArticulationSegments)
{
- var seg = pair.Value;
- var dir = seg.Direction;
+ bool didSomething;
+ var segment = pair.Value;
+ var dir = segment.Direction;
var perp = dir.RotateDeg(90);
- float width0 = ConfigManager.Roadgen.SidewalkWidth + ConfigManager.Roadgen.LaneWidth * seg.LanesTo1;
- float width1 = ConfigManager.Roadgen.SidewalkWidth + ConfigManager.Roadgen.LaneWidth * seg.LanesTo2;
+ float width0 = ConfigManager.Roadgen.SidewalkWidth + ConfigManager.Roadgen.LaneWidth * segment.LanesTo1;
+ float width1 = ConfigManager.Roadgen.SidewalkWidth + ConfigManager.Roadgen.LaneWidth * segment.LanesTo2;
- for (Vector2 pos = seg.Terminal1.Position; (pos - seg.Terminal2.Position).LengthSq > advance * advance; pos += dir * advance)
+ Vector2 start = segment.Terminal1.Position;
+ Vector2 end = segment.Terminal2.Position;
+ Vector2 posL = start, posR = start, nposL, nposR;
+ int attempts = 0;
+
+ do
{
- // Build lot squares
- Vector2[] left = new Vector2[4];
- left[0] = pos + perp * (width0 + LotSpacing + LotSquareSize);
- left[1] = pos + perp * (width0 + LotSpacing);
- left[2] = pos + dir * LotSquareSize + perp * (width0 + LotSpacing);
- left[3] = pos + dir * LotSquareSize + perp * (width0 + LotSpacing + LotSquareSize);
+ didSomething = false;
+ float sizeL = random.NextSingle(LotSquareMinSize, LotSquareMaxSize), sizeR = random.NextSingle(LotSquareMinSize, LotSquareMaxSize);
+ nposL = posL + dir * sizeL;
+ nposR = posR + dir * sizeR;
- Vector2[] right = new Vector2[4];
- right[0] = pos - perp * (width0 + LotSpacing + LotSquareSize);
- right[1] = pos - perp * (width0 + LotSpacing);
- right[2] = pos + dir * LotSquareSize - perp * (width0 + LotSpacing);
- right[3] = pos + dir * LotSquareSize - perp * (width0 + LotSpacing + LotSquareSize);
+ // Left side
+ if ((posL - end).LengthSq >= sizeL * sizeL)
+ {
+ didSomething = true;
- BuildingLot lot0 = new BuildingLot(left);
- BuildingLot lot1 = new BuildingLot(right);
+ // Build lot squares
+ Vector2[] left = new Vector2[4];
+ left[0] = posL + perp * (width0 + LotSpacing + sizeL);
+ left[1] = posL + perp * (width0 + LotSpacing);
+ left[2] = nposL + perp * (width0 + LotSpacing);
+ left[3] = nposL + perp * (width0 + LotSpacing + sizeL);
- // Test for intersections
- if (CanAllocate(pos, lot0))
- lotTree.Add(lot0);
+ BuildingLot lot = new BuildingLot(sizeL, left);
- if (CanAllocate(pos, lot1))
- lotTree.Add(lot1);
- }
+ if (CanAllocate(posL, lot))
+ lotTree.Add(lot);
+
+ // Advance
+ posL = nposL;
+ }
+
+ // Right side
+ if ((posR - end).LengthSq >= sizeR * sizeR)
+ {
+ didSomething = true;
+
+ // Build lot squares
+ Vector2[] right = new Vector2[4];
+ right[0] = posR - perp * (width1 + LotSpacing + sizeR);
+ right[1] = posR - perp * (width1 + LotSpacing);
+ right[2] = nposR - perp * (width1 + LotSpacing);
+ right[3] = nposR - perp * (width1 + LotSpacing + sizeR);
+
+ BuildingLot lot = new BuildingLot(sizeR, right);
+
+ if (CanAllocate(posL, lot))
+ lotTree.Add(lot);
+
+ // Advance
+ posR = nposR;
+ }
+
+ if (!didSomething)
+ attempts++;
+
+ } while (attempts < ConfigManager.Buildgen.MaxLotAttempts);
}
// Done
@@ -65,26 +100,34 @@ namespace TransportGame.Generator
private bool CanAllocate(Vector2 pos, BuildingLot lot0)
{
+ if (!lotTree.Boundary.Contains(pos))
+ return false;
+
// Test other lots
- Rectangle lotArea = new Rectangle(pos.X - 2 * LotSquareSize, pos.Y - 2 * LotSquareSize, pos.X + 2 * LotSquareSize, pos.Y + 2 * LotSquareSize);
+ Rectangle lotArea = new Rectangle(
+ pos.X - 2f * LotSquareMaxSize,
+ pos.Y - 2f * LotSquareMaxSize,
+ pos.X + 2f * LotSquareMaxSize,
+ pos.Y + 2f * LotSquareMaxSize);
+
foreach (var lot in lotTree.Query(lotArea))
{
- if (BuildingLot.Intersect(lot0, lot))
+ if (BuildingLot.DoesIntersect(lot0, lot))
return false;
}
// Test nearby roads
Rectangle roadArea = new Rectangle(
- pos.X - 2 * ConfigManager.Roadgen.HighwaySegmentLength,
- pos.Y - 2 * ConfigManager.Roadgen.HighwaySegmentLength,
- pos.X + 2 * ConfigManager.Roadgen.HighwaySegmentLength,
- pos.Y + 2 * ConfigManager.Roadgen.HighwaySegmentLength);
+ pos.X - 1.1f * ConfigManager.Roadgen.HighwaySegmentLength,
+ pos.Y - 1.1f * ConfigManager.Roadgen.HighwaySegmentLength,
+ pos.X + 1.1f * ConfigManager.Roadgen.HighwaySegmentLength,
+ pos.Y + 1.1f * ConfigManager.Roadgen.HighwaySegmentLength);
foreach (var node in nodeTree.Query(roadArea))
{
foreach (var segment in node.ArticulationSegments)
{
- if (BuildingLot.Intersect(lot0, segment.AsLineSegment()))
+ if (BuildingLot.DoesIntersect(lot0, segment.AsLineSegment()))
return false;
}
@@ -95,12 +138,69 @@ namespace TransportGame.Generator
private void GenerateBuildings()
{
+ foreach (var lot in map.BuildingLots)
+ map.Buildings.Add(GenerateBuilding(lot));
+ }
+ Polygon GeneratePrimitivePolygon(BuildingLot lot)
+ {
+ int sides = random.Next(3, 8); // Number of sides
+ float angle = 2 * (float)Math.PI / sides; // Angle between sides
+
+ float radius = random.NextSingle(lot.Size * 0.25f, lot.Size * 0.75f) / 2; // Length of a side
+ Vector2 current = lot.Position + new Vector2(random.NextSingle(-lot.Size / 4, lot.Size / 4), random.NextSingle(-lot.Size / 4, lot.Size / 4));
+ Vector2 dir = new Vector2(random.NextSingle(), random.NextSingle()).Normalized * radius;
+
+ List points = new List();
+
+ for (int i = 0; i < sides; i++)
+ {
+ points.Add(current);
+ current = current + dir;
+ dir = dir.Rotate(angle);
+ }
+
+ return new Polygon(points);
+ }
+
+ private Building GenerateBuilding(BuildingLot lot)
+ {
+ Building b = new Building();
+
+ int levelCount = random.Next(1, ConfigManager.Buildgen.MaxBuildingLevels);
+ b.LevelHeights = new float[levelCount];
+ b.Polygons = new Polygon[levelCount][];
+
+ for (int i = levelCount - 1; i >= 0; --i)
+ {
+ List polys = new List();
+
+ for (int j = 0; j < 1 + random.Next(ConfigManager.Buildgen.MaxPolygonsPerLevel); j++)
+ polys.Add(GeneratePrimitivePolygon(lot));
+
+ if (i + 1 < levelCount)
+ {
+ polys.AddRange(b.Polygons[i + 1]);
+ b.LevelHeights[i] = random.NextSingle(0, b.LevelHeights[i + 1]);
+ }
+ else
+ {
+ b.LevelHeights[i] = random.NextSingle(0, ConfigManager.Buildgen.MaxBuildingHeight);
+ }
+
+ for (int j = 0; j < random.Next(ConfigManager.Buildgen.MaxPolygonsPerLevel); j++)
+ polys.Add(GeneratePrimitivePolygon(lot));
+
+ b.Polygons[i] = polys.ToArray();
+ }
+
+ return b;
}
public void Generate(Map map)
{
this.map = map;
+ map.Buildings = new List();
// Construct node tree
nodeTree = new QuadTree(0, 0, map.Width, map.Height);
diff --git a/Game/Assets/Scripts/Generator/CityGenerator.cs b/Game/Assets/Scripts/Generator/CityGenerator.cs
index 0f208db..a4a4952 100644
--- a/Game/Assets/Scripts/Generator/CityGenerator.cs
+++ b/Game/Assets/Scripts/Generator/CityGenerator.cs
@@ -35,6 +35,10 @@ namespace TransportGame.Generator
RoadGenerator roadGenerator = new RoadGenerator();
roadGenerator.Generate(map);
+ // Generate buildings
+ BuildingGenerator buildingGenerator = new BuildingGenerator();
+ buildingGenerator.Generate(map);
+
// Done
return map;
}
diff --git a/Game/Assets/Scripts/Model/Building.cs b/Game/Assets/Scripts/Model/Building.cs
new file mode 100644
index 0000000..3295b13
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Building.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace TransportGame.Model
+{
+ public class Building
+ {
+ ///
+ /// From lowest to highest level
+ ///
+ public Polygon[][] Polygons { get; set; }
+
+ ///
+ /// From lowest to highest level
+ ///
+ public float[] LevelHeights { get; set; }
+ }
+}
diff --git a/Game/Assets/Scripts/Model/Building.cs.meta b/Game/Assets/Scripts/Model/Building.cs.meta
new file mode 100644
index 0000000..a67955b
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Building.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 4ef412bd6ccb705428e5569cf84b018f
+timeCreated: 1433489978
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Model/BuildingLot.cs b/Game/Assets/Scripts/Model/BuildingLot.cs
index 57dd375..462c05a 100644
--- a/Game/Assets/Scripts/Model/BuildingLot.cs
+++ b/Game/Assets/Scripts/Model/BuildingLot.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransportGame.Business;
+using TransportGame.Utils;
namespace TransportGame.Model
{
@@ -13,21 +14,54 @@ namespace TransportGame.Model
///
public Vector2[] Points { get; set; }
+ ///
+ /// Gets or sets the size of the lot
+ ///
+ public float Size { get; set; }
+
+ ///
+ /// Initializes the building lot
+ ///
public BuildingLot()
{
Points = new Vector2[4];
}
- public BuildingLot(params Vector2[] points)
+ ///
+ /// Initializes lot with given size
+ ///
+ /// size
+ public BuildingLot(float size)
+ {
+ Points = new Vector2[4];
+ Size = size;
+ }
+
+ ///
+ /// Initializes lot with given points and size
+ ///
+ /// Size
+ /// Points
+ public BuildingLot(float size, params Vector2[] points)
{
Points = points;
+ Size = size;
}
- public BuildingLot(IEnumerable points)
+ ///
+ /// Initializes lot with given points and size
+ ///
+ /// Size
+ /// Points
+ public BuildingLot(float size, IEnumerable points)
{
Points = points.ToArray();
+ Size = size;
}
+ ///
+ /// Gets the lot position
+ ///
public Vector2 Position
{
get { return Points.Aggregate((x, y) => x + y) / Points.Length; }
@@ -39,9 +73,9 @@ namespace TransportGame.Model
/// First lot
/// Second lot
///
- public static bool Intersect(BuildingLot a, BuildingLot b)
+ public static bool DoesIntersect(BuildingLot a, BuildingLot b)
{
- return (a.Position - b.Position).LengthSq <= ConfigManager.Buildgen.LotSquareSize + ConfigManager.Buildgen.LotSpacing;
+ return Algorithmss.DoPolygonsIntersect(a.Points, b.Points);
}
///
@@ -50,7 +84,7 @@ namespace TransportGame.Model
///
///
///
- public static bool Intersect(BuildingLot a, LineSegment b)
+ public static bool DoesIntersect(BuildingLot a, LineSegment b)
{
for (int i = 0; i < a.Points.Length; i++)
{
diff --git a/Game/Assets/Scripts/Model/BuildingLot.cs.meta b/Game/Assets/Scripts/Model/BuildingLot.cs.meta
new file mode 100644
index 0000000..f5fc672
--- /dev/null
+++ b/Game/Assets/Scripts/Model/BuildingLot.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8d4e9031660798e43954c6c698daf966
+timeCreated: 1433365105
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs b/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs
index eeb000d..c695dbb 100644
--- a/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs
+++ b/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs
@@ -8,19 +8,49 @@ namespace TransportGame.Model.Config
public class BuildingGeneratorConfig
{
///
- /// Lot size
+ /// Minimum lot size
///
- public float LotSquareSize { get; set; }
+ public float LotSquareMinSize { get; set; }
+
+ ///
+ /// Maximum lot size
+ ///
+ public float LotSquareMaxSize { get; set; }
///
/// Space between lots
///
public float LotSpacing { get; set; }
+ ///
+ /// Maximum number of attempts to generate a lot in a specific area
+ ///
+ public int MaxLotAttempts { get; set; }
+
+ ///
+ /// Maximum number of levels on a building
+ ///
+ public int MaxBuildingLevels { get; set; }
+
+ ///
+ /// Maximum height for a building
+ ///
+ public float MaxBuildingHeight { get; set; }
+
+ ///
+ /// Maximum number of primitive polygons to be generated per level
+ ///
+ public int MaxPolygonsPerLevel { get; set; }
+
public BuildingGeneratorConfig()
{
- LotSquareSize = 1f;
+ LotSquareMinSize = 5f;
+ LotSquareMaxSize = 20f;
LotSpacing = 0.1f;
+ MaxLotAttempts = 3;
+ MaxBuildingHeight = 20f;
+ MaxBuildingLevels = 5;
+ MaxPolygonsPerLevel = 3;
}
}
}
diff --git a/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs.meta b/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs.meta
new file mode 100644
index 0000000..736c0e1
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Config/BuildingGeneratorConfig.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 67b392479c775904c970253005f9c856
+timeCreated: 1433365105
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Model/Map.cs b/Game/Assets/Scripts/Model/Map.cs
index aab7643..513f682 100644
--- a/Game/Assets/Scripts/Model/Map.cs
+++ b/Game/Assets/Scripts/Model/Map.cs
@@ -75,6 +75,9 @@ namespace TransportGame.Model
[XmlArrayItem("center")]
public List PopulationCenters { get; set; }
+ ///
+ /// Gets or sets the range of one population center (distance how far it influences)
+ ///
public float PopulationCenterRange { get; set; }
///
@@ -89,6 +92,12 @@ namespace TransportGame.Model
[XmlElement("lots")]
public List BuildingLots { get; set; }
+ ///
+ /// Gets or sets the buildings
+ ///
+ [XmlElement("buildings")]
+ public List Buildings { get; set; }
+
#endregion
#region Constructors
diff --git a/Game/Assets/Scripts/Model/Polygon.cs b/Game/Assets/Scripts/Model/Polygon.cs
new file mode 100644
index 0000000..74a5796
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Polygon.cs
@@ -0,0 +1,247 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TransportGame.Utils;
+
+namespace TransportGame.Model
+{
+ ///
+ /// Represents a polygon
+ ///
+ public class Polygon : IPositionable
+ {
+ #region Private types
+
+ private struct Edge
+ {
+ public int U, V;
+
+ public Edge(int U, int V)
+ {
+ this.U = U;
+ this.V = V;
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Gets or sets the points that define the polygon
+ ///
+ public Vector2[] Points { get; set; }
+
+ ///
+ /// Gets the gravitational center
+ ///
+ public Vector2 Position
+ {
+ get { return Points.Aggregate((x, y) => x + y) / Points.Length; }
+ }
+
+ ///
+ /// Initializes polygon
+ ///
+ public Polygon()
+ {
+ Points = new Vector2[0];
+ }
+
+ ///
+ /// Initializes polygon using given points
+ ///
+ /// Points
+ public Polygon(IEnumerable points)
+ {
+ Points = points.ToArray();
+ }
+
+ ///
+ /// Initializes polygon using given points
+ ///
+ /// Points
+ public Polygon(params Vector2[] points)
+ {
+ Points = points;
+ }
+
+ ///
+ /// Compares angle between two NORMALIZED vectors.
+ ///
+ ///
+ ///
+ ///
+ private static float CompareAngle(Vector2 a, Vector2 b)
+ {
+ float sin = Vector2.Cross(a, b);
+ float cos = Vector2.Dot(a, b);
+
+ if (sin >= 0 && cos >= 0)
+ return sin;
+
+ else if (sin >= 0 && cos <= 0)
+ return 1 + Math.Abs(cos);
+
+ else if (sin <= 0 && cos <= 0)
+ return 2 + Math.Abs(sin);
+
+ else return 3 + cos;
+ }
+
+ ///
+ /// Returns the union between given polygons
+ ///
+ /// Polygons
+ /// Polygon representing union
+ public static Polygon Union(params Polygon[] polys)
+ {
+ return Union(polys);
+ }
+
+ ///
+ /// Returns the union between given polygons
+ ///
+ /// Polygons
+ /// Polygon representing union
+ public static Polygon Union(IEnumerable polys)
+ {
+ List vertices = new List();
+ List edges = new List();
+ List union = new List();
+
+ foreach (var poly in polys)
+ {
+ // Add all points
+ for (int i = 0; i < poly.Points.Length; i++)
+ {
+ int j = (i + 1) % poly.Points.Length;
+
+ // Get/add first point
+ int indexi = vertices.IndexOf(poly.Points[i]);
+ if (indexi == -1)
+ {
+ vertices.Add(poly.Points[i]);
+ indexi = vertices.Count - 1;
+ }
+
+ // Get/add second point
+ int indexj = vertices.IndexOf(poly.Points[j]);
+ if (indexj == -1)
+ {
+ vertices.Add(poly.Points[j]);
+ indexj = vertices.Count - 1;
+ }
+
+ // Add edge
+ edges.Add(new Edge(indexi, indexj));
+ }
+ }
+
+ // Intersect edges
+ for (int i = 0; i < edges.Count; i++)
+ for (int j = i + 1; j < edges.Count; j++)
+ {
+ LineSegment a = new LineSegment(vertices[edges[i].U], vertices[edges[i].V]);
+ LineSegment b = new LineSegment(vertices[edges[j].U], vertices[edges[j].V]);
+
+ var inters = LineSegment.Intersect(a, b);
+ if (inters.HasValue && inters.Value != a.P0 && inters.Value != a.P1 && inters.Value != b.P0 && inters.Value != b.P1)
+ {
+ vertices.Add(inters.Value);
+ int index = vertices.Count - 1;
+
+ edges.Add(new Edge(index, edges[i].V));
+ edges[i] = new Edge(edges[i].U, index);
+ edges.Add(new Edge(index, edges[j].V));
+ edges[j] = new Edge(edges[j].U, index);
+ }
+ }
+
+ // Compute union
+ int start = 0;
+
+ // Find starting point
+ for (int i = 0; i < vertices.Count; i++)
+ if (vertices[i].X + vertices[i].Y < vertices[start].X + vertices[start].Y)
+ start = i;
+
+ int v = start, vold = -1;
+ Vector2 prev = vertices[v].Normalized;
+
+ do
+ {
+ union.Add(vertices[v]);
+
+ int newV = -1;
+ float smallestAngle = -1;
+ Vector2 smallestDir = Vector2.Zero;
+
+ foreach (var edge in edges)
+ {
+ if ((edge.U == v || edge.V == v) && edge.V != vold && edge.U != vold)
+ {
+ int otherv = (edge.U == v) ? edge.V : edge.U;
+ Vector2 dir = (vertices[otherv] - vertices[v]).Normalized;
+
+ // Find smallest angle
+ float cmpAngle = CompareAngle(-prev, dir);
+ if (cmpAngle < smallestAngle || smallestAngle < 0)
+ {
+ newV = otherv;
+ smallestAngle = cmpAngle;
+ smallestDir = dir;
+ }
+ }
+ }
+
+ // Advance
+ prev = smallestDir;
+ vold = v;
+ v = newV;
+
+ } while (v != start);
+
+ return new Polygon(union);
+ }
+
+ public static bool DoPolygonsIntersect(Polygon a, Polygon b)
+ {
+ foreach (var poly in new[] { a, b })
+ {
+ for (int i = 0; i < poly.Points.Length; i++)
+ {
+ int j = (i + 1) % poly.Points.Length;
+
+ var normal = new Vector2(poly.Points[j].Y - poly.Points[i].Y, poly.Points[i].X - poly.Points[j].X);
+
+ double? minA = null, maxA = null;
+ foreach (var p in a.Points)
+ {
+ var projected = Vector2.Dot(normal, p);
+ if (minA == null || projected < minA)
+ minA = projected;
+ if (maxA == null || projected > maxA)
+ maxA = projected;
+ }
+
+ double? minB = null, maxB = null;
+ foreach (var p in b.Points)
+ {
+ var projected = Vector2.Dot(normal, p);
+ if (minB == null || projected < minB)
+ minB = projected;
+ if (maxB == null || projected > maxB)
+ maxB = projected;
+ }
+
+ if (maxA <= minB || maxB <= minA)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ }
+}
diff --git a/Game/Assets/Scripts/Model/Polygon.cs.meta b/Game/Assets/Scripts/Model/Polygon.cs.meta
new file mode 100644
index 0000000..52cc98b
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Polygon.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ee96020375a8f3d4bb7a04e9f7a6b05e
+timeCreated: 1433489979
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs b/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs
new file mode 100644
index 0000000..56f341d
--- /dev/null
+++ b/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TransportGame.Model;
+using UnityEngine;
+
+namespace TransportGame.Unity
+{
+ public class BuildingMeshGenerator
+ {
+ public Material BuildingMaterial { get; set; }
+
+ private GameObject parent = new GameObject("buildings");
+ private Map map;
+
+ public IEnumerable Generate(Map map)
+ {
+ this.map = map;
+
+ foreach (var building in map.Buildings)
+ {
+ GenerateBuilding(building);
+ yield return null;
+ }
+ }
+
+ private void GenerateBuilding(Building building)
+ {
+ List vertices = new List();
+ List uv = new List();
+ List triangles = new List();
+ int vIndex = 0;
+
+ if (building.Polygons.Length == 0)
+ return;
+
+ float terrainHeight = building.Polygons[0].SelectMany(poly => poly.Points).Min(pt => map.GetHeight((int)pt.X, (int)pt.Y));
+ float minY, maxY = terrainHeight;
+
+ for (int i = 0; i < building.Polygons.Length; i++)
+ {
+ // Update minY and maxY
+ minY = maxY;
+ maxY += building.LevelHeights[i];
+
+ for (int p = 0; p < building.Polygons[i].Length; p++)
+ {
+ // Build mesh
+ var center = building.Polygons[i][p].Position;
+ var pts = building.Polygons[i][p].Points;
+
+ for (int j = 0; j < pts.Length; j++)
+ {
+ int k = (j + 1) % pts.Length;
+
+ vertices.Add(new Vector3(pts[j].Y, minY, pts[j].X));
+ vertices.Add(new Vector3(pts[k].Y, minY, pts[k].X));
+ vertices.Add(new Vector3(pts[k].Y, maxY, pts[k].X));
+ vertices.Add(new Vector3(pts[j].Y, maxY, pts[j].X));
+ vertices.Add(new Vector3(center.Y, maxY, center.X));
+
+ uv.Add(new UnityEngine.Vector2(0, 0));
+ uv.Add(new UnityEngine.Vector2(0, 1));
+ uv.Add(new UnityEngine.Vector2(1, 1));
+ uv.Add(new UnityEngine.Vector2(1, 0));
+ uv.Add(new UnityEngine.Vector2(0.5f, 0.5f));
+
+ triangles.AddRange(new[] { vIndex, vIndex + 1, vIndex + 2 });
+ triangles.AddRange(new[] { vIndex, vIndex + 2, vIndex + 3 });
+ triangles.AddRange(new[] { vIndex + 4, vIndex + 3, vIndex + 2 }); // top side
+
+ vIndex = vertices.Count;
+ }
+ }
+ }
+
+ // Construct mesh
+ Mesh mesh = new Mesh();
+ mesh.vertices = vertices.ToArray();
+ mesh.triangles = triangles.ToArray();
+ mesh.uv = uv.ToArray();
+ mesh.RecalculateNormals();
+
+ // Construct game object
+ GameObject inters = new GameObject("building");
+ inters.transform.parent = parent.transform;
+
+ MeshFilter meshFilter = inters.AddComponent();
+ meshFilter.mesh = mesh;
+
+ MeshRenderer meshRenderer = inters.AddComponent();
+ meshRenderer.materials = new[] { BuildingMaterial };
+ }
+ }
+}
diff --git a/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs.meta b/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs.meta
new file mode 100644
index 0000000..8fdf6af
--- /dev/null
+++ b/Game/Assets/Scripts/Unity/BuildingMeshGenerator.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 285289bd35a5aac429d15f8fdf99512f
+timeCreated: 1433859861
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs b/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs
index 3ce771d..d3201de 100644
--- a/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs
+++ b/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs
@@ -16,6 +16,7 @@ public class TerrainGeneratorScript : MonoBehaviour
public GameObject WaterObject;
public Texture2D[] Textures;
public Material RoadMaterial;
+ public Material BuildingMaterial;
// Use this for initialization
void Start()
@@ -54,7 +55,7 @@ public class TerrainGeneratorScript : MonoBehaviour
private IEnumerator GenerateMap()
{
// Generate terrain
- foreach (var i in Task.RunAsync(GenerateTerrainThread))
+ foreach (var i in Task.Await(GenerateTerrainThread))
yield return i;
// Generate terrain data
@@ -105,20 +106,62 @@ public class TerrainGeneratorScript : MonoBehaviour
// Set up textures
Logger.Info("Setting up textures...");
- foreach (var i in SetupSplatmaps(terrainData))
+ BeginSetupSplatmaps(terrainData);
+
+ foreach (var lot in map.BuildingLots)
+ {
+ for (int i = 0; i < lot.Points.Length; i++)
+ {
+ int j = (i + 1) % lot.Points.Length;
+
+ if (!map.IsInside(lot.Points[i]))
+ {
+ Logger.Warning("Generated point not inside: {0}", lot.Points[i]);
+ continue;
+ }
+ if (!map.IsInside(lot.Points[j]))
+ {
+ Logger.Warning("Generated point not inside: {0}", lot.Points[j]);
+ continue;
+ }
+
+ Debug.DrawLine(
+ new Vector3(lot.Points[i].Y, map.GetHeight((int)lot.Points[i].X, (int)lot.Points[i].Y) + 0.5f, lot.Points[i].X),
+ new Vector3(lot.Points[j].Y, map.GetHeight((int)lot.Points[j].X, (int)lot.Points[j].Y) + 0.5f, lot.Points[j].X),
+ Color.yellow, 10000);
+ }
+ }
+
+ // Generate road & building mesh (we run the loops in parallel)
+ Logger.Info("Generating buildings and roads...");
+
+ BuildingMeshGenerator buildingMeshGenerator = new BuildingMeshGenerator();
+ buildingMeshGenerator.BuildingMaterial = BuildingMaterial;
+ var it1 = buildingMeshGenerator.Generate(map).GetEnumerator();
+
+ RoadMeshGenerator roadMeshGenerator = new RoadMeshGenerator();
+ roadMeshGenerator.RoadMaterial = RoadMaterial;
+ var it2 = roadMeshGenerator.Generate(map).GetEnumerator();
+
+ bool stop;
+ do
+ {
+ stop = true;
+ if (it1.MoveNext())
+ {
+ yield return it1.Current;
+ stop = false;
+ }
+ if (it2.MoveNext())
+ {
+ yield return it2.Current;
+ stop = false;
+ }
+ } while (!stop);
+
+ // Finish setting up textures
+ foreach (var i in EndSetupSplatmaps(terrainData))
yield return i;
-
- // Generate road mesh
- Logger.Info("Generating roads...");
- RoadMeshGenerator meshGenerator = new RoadMeshGenerator();
- meshGenerator.RoadMaterial = RoadMaterial;
- foreach (object i in meshGenerator.Generate(map))
- yield return i;
-
- // -- DEBUG --
-
- foreach (var center in map.PopulationCenters)
- Debug.DrawLine(new Vector3(center.Y, 0, center.X), new Vector3(center.Y, map.Biome.Height, center.X), Color.yellow, 100000);
}
private float[,,] GenerateSplatData(int alphaWidth, int alphaHeight, int alphaLayers)
@@ -174,14 +217,21 @@ public class TerrainGeneratorScript : MonoBehaviour
return splatData;
}
- private IEnumerable SetupSplatmaps(TerrainData terrainData)
+ float[, ,] splatData = null;
+ private Task splatmapsTask = null;
+
+ private void BeginSetupSplatmaps(TerrainData terrainData)
{
- float[, ,] splatData = null;
int alphaW = terrainData.alphamapWidth;
int alphaH = terrainData.alphamapHeight;
int alphaL = terrainData.alphamapLayers;
- foreach (var i in Task.RunAsync(() => splatData = GenerateSplatData(alphaW, alphaH, alphaL)))
+ splatmapsTask = Task.RunAsync(() => splatData = GenerateSplatData(alphaW, alphaH, alphaL));
+ }
+
+ private IEnumerable EndSetupSplatmaps(TerrainData terrainData)
+ {
+ foreach (var i in splatmapsTask.Await())
yield return i;
terrainData.SetAlphamaps(0, 0, splatData);
diff --git a/Game/Assets/Scripts/Utils/Algorithms.cs b/Game/Assets/Scripts/Utils/Algorithms.cs
index f8a3556..012ce7e 100644
--- a/Game/Assets/Scripts/Utils/Algorithms.cs
+++ b/Game/Assets/Scripts/Utils/Algorithms.cs
@@ -2,11 +2,48 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using TransportGame.Model;
namespace TransportGame.Utils
{
public static class Algorithmss
{
-
+ public static bool DoPolygonsIntersect(Vector2[] a, Vector2[] b)
+ {
+ foreach (var poly in new[] {a, b})
+ {
+ for (int i = 0; i < poly.Length; i++)
+ {
+ int j = (i + 1) % poly.Length;
+
+ var normal = new Vector2(poly[j].Y - poly[i].Y, poly[i].X - poly[j].X);
+
+ double? minA = null, maxA = null;
+ foreach (var p in a)
+ {
+ var projected = Vector2.Dot(normal, p);
+ if (minA == null || projected < minA)
+ minA = projected;
+ if (maxA == null || projected > maxA)
+ maxA = projected;
+ }
+
+ double? minB = null, maxB = null;
+ foreach (var p in b)
+ {
+ var projected = Vector2.Dot(normal, p);
+ if (minB == null || projected < minB)
+ minB = projected;
+ if (maxB == null || projected > maxB)
+ maxB = projected;
+ }
+
+ if (maxA <= minB || maxB <= minA)
+ return false;
+ }
+ }
+
+ return true;
+ }
}
}
diff --git a/Game/Assets/Scripts/Utils/Task.cs b/Game/Assets/Scripts/Utils/Task.cs
index 7e7274e..88a8616 100644
--- a/Game/Assets/Scripts/Utils/Task.cs
+++ b/Game/Assets/Scripts/Utils/Task.cs
@@ -7,41 +7,55 @@ using System.Threading;
namespace TransportGame.Utils
{
- public static class Task
+ public class Task
{
- private class TaskInfo
+ public bool? Success { get; private set; }
+
+ private Exception thrownException;
+ private Action action;
+ private Thread thread;
+
+ private Task()
{
- public Action Action { get; set; }
- public bool? Success { get; set; }
- public Exception ThrownException { get; set; }
}
private static void RunAsync_ActionThread(object info)
{
- TaskInfo taskInfo = (TaskInfo)info;
+ Task taskInfo = (Task)info;
try
{
- taskInfo.Action();
+ taskInfo.action();
taskInfo.Success = true;
}
catch (Exception ex)
{
- taskInfo.ThrownException = ex;
+ taskInfo.thrownException = ex;
taskInfo.Success = false;
}
}
- public static IEnumerable RunAsync(Action action)
+ public static Task RunAsync(Action action)
{
// Set up task info object
- TaskInfo taskInfo = new TaskInfo();
- taskInfo.Action = action;
+ Task taskInfo = new Task();
+ taskInfo.action = action;
+ taskInfo.thread = new Thread(RunAsync_ActionThread);
- // Start thread and wait
- var thread = new Thread(RunAsync_ActionThread);
- thread.Start(taskInfo);
+ // Start thread
+ taskInfo.thread.Start(taskInfo);
+ // Return task info
+ return taskInfo;
+ }
+
+ public static IEnumerable Await(Action action)
+ {
+ return Task.RunAsync(action).Await();
+ }
+
+ public IEnumerable Await()
+ {
// Wait for thread to finish
while (thread.ThreadState == ThreadState.Running)
yield return null;
@@ -49,8 +63,8 @@ namespace TransportGame.Utils
thread.Join();
// Rethrow exception
- if (taskInfo.Success.HasValue && !taskInfo.Success.Value)
- throw new Exception("Task failed", taskInfo.ThrownException);
+ if (Success.HasValue && !Success.Value)
+ throw new Exception("Task failed", thrownException);
}
}
}
diff --git a/Game/Game-csharp.sln b/Game/Game-csharp.sln
index afec93c..39b9df1 100644
--- a/Game/Game-csharp.sln
+++ b/Game/Game-csharp.sln
@@ -23,7 +23,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
+ GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
Policies = $0
$0.TextStylePolicy = $1
diff --git a/Game/Game.sln b/Game/Game.sln
index d1d583c..a0df216 100644
--- a/Game/Game.sln
+++ b/Game/Game.sln
@@ -29,7 +29,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
+ GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
Policies = $0
$0.TextStylePolicy = $1
diff --git a/Game/ProjectSettings/GraphicsSettings.asset b/Game/ProjectSettings/GraphicsSettings.asset
index d75e792..53f83ae 100644
Binary files a/Game/ProjectSettings/GraphicsSettings.asset and b/Game/ProjectSettings/GraphicsSettings.asset differ
diff --git a/Game/ProjectSettings/ProjectSettings.asset b/Game/ProjectSettings/ProjectSettings.asset
index 753fee5..105ccf7 100644
Binary files a/Game/ProjectSettings/ProjectSettings.asset and b/Game/ProjectSettings/ProjectSettings.asset differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll b/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll
index d8cdc26..76f8855 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll and b/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll.mdb b/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll.mdb
index 9fb796e..8225ee4 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll.mdb and b/Game/TransportGame_Data/Managed/Assembly-CSharp-firstpass.dll.mdb differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-CSharp.dll b/Game/TransportGame_Data/Managed/Assembly-CSharp.dll
index 1744c53..f29ed8e 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-CSharp.dll and b/Game/TransportGame_Data/Managed/Assembly-CSharp.dll differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-CSharp.dll.mdb b/Game/TransportGame_Data/Managed/Assembly-CSharp.dll.mdb
index 1f9bdae..8ac6e0f 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-CSharp.dll.mdb and b/Game/TransportGame_Data/Managed/Assembly-CSharp.dll.mdb differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll b/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll
index cef2822..7201e88 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll and b/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll differ
diff --git a/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll.mdb b/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll.mdb
index bf58181..6be4cf3 100644
Binary files a/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll.mdb and b/Game/TransportGame_Data/Managed/Assembly-UnityScript-firstpass.dll.mdb differ
diff --git a/Game/TransportGame_Data/PlayerConnectionConfigFile b/Game/TransportGame_Data/PlayerConnectionConfigFile
index e37a14e..9d7503d 100644
--- a/Game/TransportGame_Data/PlayerConnectionConfigFile
+++ b/Game/TransportGame_Data/PlayerConnectionConfigFile
@@ -1 +1 @@
-listen 267420748 1 1
\ No newline at end of file
+listen 3921045144 1 1
\ No newline at end of file
diff --git a/Game/TransportGame_Data/Resources/unity_builtin_extra b/Game/TransportGame_Data/Resources/unity_builtin_extra
index b0276a3..a53a3aa 100644
Binary files a/Game/TransportGame_Data/Resources/unity_builtin_extra and b/Game/TransportGame_Data/Resources/unity_builtin_extra differ
diff --git a/Game/TransportGame_Data/mainData b/Game/TransportGame_Data/mainData
index 5944cda..f04e8e5 100644
Binary files a/Game/TransportGame_Data/mainData and b/Game/TransportGame_Data/mainData differ
diff --git a/Game/TransportGame_Data/output_log.txt b/Game/TransportGame_Data/output_log.txt
index e4d86dc..72dbd25 100644
--- a/Game/TransportGame_Data/output_log.txt
+++ b/Game/TransportGame_Data/output_log.txt
@@ -4,7 +4,7 @@ Direct3D:
Version: Direct3D 11.0 [level 11.0]
Renderer: NVIDIA GeForce GTX 750 (ID=0x1381)
Vendor: NVIDIA
- VRAM: 968 MB
+ VRAM: 967 MB
Begin MonoManager ReloadAssembly
Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.dll (this message is harmless)
Loading C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.dll into Unity Child Domain
@@ -16,25 +16,82 @@ Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Transpo
Loading C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\Assembly-UnityScript-firstpass.dll into Unity Child Domain
Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.UI.dll (this message is harmless)
Loading C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.UI.dll into Unity Child Domain
-Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.UI.dll (this message is harmless)
-Loading C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\UnityEngine.UI.dll into Unity Child Domain
-- Completed reload, in 0.094 seconds
+- Completed reload, in 0.045 seconds
desktop: 1920x1080 60Hz; virtual: 1920x1080 at 0,0
Initializing input.
Input initialized.
Initialized touch support.
Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\System.Core.dll (this message is harmless)
+Loading configuration...
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+InitializeScript:Start() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\InitializeScript.cs:14)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\System.Xml.dll (this message is harmless)
Platform assembly: C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\TransportGame_Data\Managed\System.dll (this message is harmless)
-Unable to find shaders used for the terrain engine. Please include Nature/Terrain/Diffuse shader in Graphics settings.
-UnityEngine.Terrain:CreateTerrainGameObject(TerrainData)
-c__Iterator0:MoveNext() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\TerrainGeneratorScript.cs:67)
-
-[C:/buildslave/unity/build/Runtime/Terrain/SplatMaterials.cpp line 383]
-(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs Line: 67)
-
-Unable to find shaders used for the terrain engine. Please include Nature/Terrain/Diffuse shader in Graphics settings.
+Loading biomes...
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+InitializeScript:Start() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\InitializeScript.cs:18)
-(Filename: C:/buildslave/unity/build/Runtime/Terrain/DetailRenderer.cpp Line: 65)
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
+Loaded biome 'Grassland' from file 'Assets\Data\Biomes\Grassland.xml'.
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+TransportGame.Business.BiomeManager:LoadBiomes() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Business\BiomeManager.cs:42)
+InitializeScript:Start() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\InitializeScript.cs:19)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
+Loaded biome 'Mountain' from file 'Assets\Data\Biomes\Mountain.xml'.
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+TransportGame.Business.BiomeManager:LoadBiomes() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Business\BiomeManager.cs:42)
+InitializeScript:Start() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\InitializeScript.cs:19)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
+Picked biome: Grassland
+
+(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebug.gen.cpp Line: 56)
+
+Setting up textures...
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+c__Iterator3:MoveNext() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\TerrainGeneratorScript.cs:108)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
+Generating buildings and roads...
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+c__Iterator3:MoveNext() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\TerrainGeneratorScript.cs:136)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
+
+Finished generating road mesh.
+UnityEngine.Debug:Internal_Log(Int32, String, Object)
+UnityEngine.Debug:Log(Object)
+TransportGame.Utils.Logger:Log(Level, String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:66)
+TransportGame.Utils.Logger:Info(String, Object[]) (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Utils\Logger.cs:74)
+TransportGame.Unity.c__Iterator2:MoveNext() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\RoadMeshGenerator.cs:95)
+c__Iterator3:MoveNext() (at C:\Users\Tibi\Google Drive\FacultateCY\$ Licenta\Game\Assets\Scripts\Unity\TerrainGeneratorScript.cs:155)
+
+(Filename: C:/Users/Tibi/Google Drive/FacultateCY/$ Licenta/Game/Assets/Scripts/Utils/Logger.cs Line: 66)
Waiting for finish
diff --git a/Game/TransportGame_Data/sharedassets0.assets b/Game/TransportGame_Data/sharedassets0.assets
index 6185e5d..8bd8099 100644
Binary files a/Game/TransportGame_Data/sharedassets0.assets and b/Game/TransportGame_Data/sharedassets0.assets differ
diff --git a/Game/UnityVS.Game.CSharp.csproj b/Game/UnityVS.Game.CSharp.csproj
index 0ca21dc..32295e4 100644
--- a/Game/UnityVS.Game.CSharp.csproj
+++ b/Game/UnityVS.Game.CSharp.csproj
@@ -78,6 +78,7 @@
+
@@ -85,6 +86,7 @@
+
@@ -93,6 +95,7 @@
+