|
|
@@ -1,4 +1,7 @@
|
|
|
using UnityEngine;
|
|
|
+using System;
|
|
|
+using System.Threading;
|
|
|
+using System.Collections.Generic;
|
|
|
|
|
|
public class MapGenerator : MonoBehaviour
|
|
|
{
|
|
|
@@ -9,7 +12,7 @@ public class MapGenerator : MonoBehaviour
|
|
|
public const int mapChunkSize = 241;
|
|
|
|
|
|
[Range(0,6)]
|
|
|
- public int levelOfDetail;
|
|
|
+ public int editorPreviewLOD;
|
|
|
public float noiseScale;
|
|
|
|
|
|
public int octaves;
|
|
|
@@ -21,16 +24,97 @@ public class MapGenerator : MonoBehaviour
|
|
|
public int seed;
|
|
|
public Vector2 offset;
|
|
|
|
|
|
- public float MeshHeightMultiplier;
|
|
|
+ public float meshHeightMultiplier;
|
|
|
public AnimationCurve meshHeightCurve;
|
|
|
|
|
|
public bool autoUpdate;
|
|
|
|
|
|
public TerrainType[] regions;
|
|
|
|
|
|
- public void GenerateMap()
|
|
|
+ Queue<MapThreadInfo<MapData>> mapDataThreadInfoQueue = new Queue<MapThreadInfo<MapData>>();
|
|
|
+ Queue<MapThreadInfo<MeshData>> meshDataThreadInfoQueue = new Queue<MapThreadInfo<MeshData>>();
|
|
|
+
|
|
|
+ public void DrawMapInEditor()
|
|
|
+ {
|
|
|
+ MapData mapData = GenerateMapData(Vector2.zero);
|
|
|
+
|
|
|
+ MapDisplay display = FindFirstObjectByType<MapDisplay>();
|
|
|
+
|
|
|
+ if (drawMode == DrawMode.NoiseMap)
|
|
|
+ {
|
|
|
+ display.DrawTexture(TextureGenerator.TextureFromHeightMap(mapData.heightMap));
|
|
|
+ }
|
|
|
+ else if (drawMode == DrawMode.ColourMap)
|
|
|
+ {
|
|
|
+ display.DrawTexture(TextureGenerator.TextureFromColourMap(mapData.colourMap, mapChunkSize, mapChunkSize));
|
|
|
+ }
|
|
|
+ else if (drawMode == DrawMode.Mesh)
|
|
|
+ {
|
|
|
+ display.DrawMesh(MeshGenerator.GenerateTerrainMesh(mapData.heightMap, meshHeightMultiplier, meshHeightCurve, editorPreviewLOD), TextureGenerator.TextureFromColourMap(mapData.colourMap, mapChunkSize, mapChunkSize));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void RequestMapData(Vector2 centre, Action<MapData> callback)
|
|
|
+ {
|
|
|
+ ThreadStart threadStart = delegate
|
|
|
+ {
|
|
|
+ MapDataThread(centre, callback);
|
|
|
+ };
|
|
|
+
|
|
|
+ new Thread(threadStart).Start();
|
|
|
+ }
|
|
|
+
|
|
|
+ void MapDataThread(Vector2 centre, Action<MapData> callback)
|
|
|
+ {
|
|
|
+ MapData mapData = GenerateMapData(centre);
|
|
|
+ lock (mapDataThreadInfoQueue)
|
|
|
+ {
|
|
|
+ mapDataThreadInfoQueue.Enqueue(new MapThreadInfo<MapData>(callback, mapData));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void RequestMeshData(MapData mapData, int lod, Action<MeshData> callback)
|
|
|
+ {
|
|
|
+ ThreadStart threadStart = delegate
|
|
|
+ {
|
|
|
+ MeshDataThread(mapData, lod, callback);
|
|
|
+ };
|
|
|
+
|
|
|
+ new Thread(threadStart).Start();
|
|
|
+ }
|
|
|
+
|
|
|
+ void MeshDataThread(MapData mapData, int lod, Action<MeshData> callback)
|
|
|
+ {
|
|
|
+ MeshData meshData = MeshGenerator.GenerateTerrainMesh(mapData.heightMap, meshHeightMultiplier, meshHeightCurve, lod);
|
|
|
+ lock (meshDataThreadInfoQueue)
|
|
|
+ {
|
|
|
+ meshDataThreadInfoQueue.Enqueue(new MapThreadInfo<MeshData>(callback, meshData));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Update()
|
|
|
+ {
|
|
|
+ if (mapDataThreadInfoQueue.Count > 0)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < mapDataThreadInfoQueue.Count; i++)
|
|
|
+ {
|
|
|
+ MapThreadInfo<MapData> threadInfo = mapDataThreadInfoQueue.Dequeue();
|
|
|
+ threadInfo.callback(threadInfo.parameter);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (meshDataThreadInfoQueue.Count > 0)
|
|
|
+ {
|
|
|
+ for(int i = 0; i < meshDataThreadInfoQueue.Count; i++)
|
|
|
+ {
|
|
|
+ MapThreadInfo<MeshData> threadInfo = meshDataThreadInfoQueue.Dequeue();
|
|
|
+ threadInfo.callback(threadInfo.parameter);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ MapData GenerateMapData(Vector2 centre)
|
|
|
{
|
|
|
- float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, offset);
|
|
|
+ float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, centre + offset);
|
|
|
|
|
|
Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
|
|
|
|
|
|
@@ -49,18 +133,7 @@ public class MapGenerator : MonoBehaviour
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- MapDisplay display = FindFirstObjectByType<MapDisplay>();
|
|
|
- if(drawMode == DrawMode.NoiseMap)
|
|
|
- {
|
|
|
- display.DrawTexture(TextureGenerator.TextureFromHeightMap(noiseMap));
|
|
|
- } else if (drawMode == DrawMode.ColourMap)
|
|
|
- {
|
|
|
- display.DrawTexture(TextureGenerator.TextureFromColourMap(colourMap, mapChunkSize, mapChunkSize));
|
|
|
- }else if(drawMode == DrawMode.Mesh)
|
|
|
- {
|
|
|
- display.DrawMesh(MeshGenerator.GenerateTerrainMesh(noiseMap, MeshHeightMultiplier, meshHeightCurve, levelOfDetail), TextureGenerator.TextureFromColourMap(colourMap, mapChunkSize, mapChunkSize));
|
|
|
- }
|
|
|
+ return new MapData(noiseMap, colourMap);
|
|
|
}
|
|
|
|
|
|
private void OnValidate()
|
|
|
@@ -75,6 +148,18 @@ public class MapGenerator : MonoBehaviour
|
|
|
octaves = 0;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ struct MapThreadInfo<T>
|
|
|
+ {
|
|
|
+ public readonly Action<T> callback;
|
|
|
+ public readonly T parameter;
|
|
|
+
|
|
|
+ public MapThreadInfo(Action<T> callback, T parameter)
|
|
|
+ {
|
|
|
+ this.callback = callback;
|
|
|
+ this.parameter = parameter;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
[System.Serializable]
|
|
|
@@ -84,3 +169,15 @@ public struct TerrainType
|
|
|
public float height;
|
|
|
public Color colour;
|
|
|
}
|
|
|
+
|
|
|
+public struct MapData
|
|
|
+{
|
|
|
+ public readonly float[,] heightMap;
|
|
|
+ public readonly Color[] colourMap;
|
|
|
+
|
|
|
+ public MapData(float[,] heightMap, Color[] colourMap)
|
|
|
+ {
|
|
|
+ this.heightMap = heightMap;
|
|
|
+ this.colourMap = colourMap;
|
|
|
+ }
|
|
|
+}
|