310 lines
12 KiB
C#
310 lines
12 KiB
C#
using Assets.Scripts;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System.Linq;
|
|
|
|
public class NoiseGenerator
|
|
{
|
|
System.Random rand = new System.Random();
|
|
public void applyNoise(GameObject tile, Dictionary<Vector3, GameObject> map, Vector3 index)
|
|
{
|
|
//resetMesh(tile);
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples;
|
|
Color32[] colors;
|
|
Color32 low;
|
|
Color32 high;
|
|
List<TileType> availableTypes = checkAvailability(map, index);
|
|
TileType tiletype = TileType.NULL;
|
|
if (index == new Vector3(0, 0, 0))
|
|
{ //IS SPAWN
|
|
tiletype = (TileType)rand.Next(0, TileTypeMethods.getHighest() + 1);
|
|
}
|
|
else
|
|
{
|
|
if (availableTypes.Count == 0)
|
|
{
|
|
Debug.Log("NO MATCH FOUND");
|
|
}
|
|
else
|
|
{
|
|
if (availableTypes.Contains(TileType.CITY))
|
|
{
|
|
if (rand.Next(0, 101) < 10)
|
|
{
|
|
tiletype = TileType.CITY;
|
|
SteamWorksHandler.getStandardAchievement("CityAchievement");
|
|
}
|
|
else
|
|
{
|
|
availableTypes.Remove(TileType.CITY);
|
|
tiletype = availableTypes[rand.Next(0, availableTypes.Count)];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tiletype = availableTypes[rand.Next(0, availableTypes.Count)];
|
|
}
|
|
}
|
|
}
|
|
tile.name = tiletype.ToString() + "_" + map.Count;
|
|
|
|
low = TileTypeMethods.getLowestColor(tiletype);
|
|
high = TileTypeMethods.getHighestColor(tiletype);
|
|
samples = TileTypeMethods.generateSamples(tiletype, vertices, rand);
|
|
|
|
float lowestValue = 10;
|
|
float highestValue = 0;
|
|
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
if (lowestValue > samples[i])
|
|
{
|
|
lowestValue = samples[i];
|
|
}
|
|
if (highestValue < samples[i])
|
|
{
|
|
highestValue = samples[i];
|
|
}
|
|
}
|
|
|
|
float modifier = highestValue - lowestValue;
|
|
|
|
colors = new Color32[samples.Length];
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
colors[i] = Color32.Lerp(low, high, (1 / modifier) * (samples[i] - lowestValue));
|
|
}
|
|
|
|
//Connect samples to neighbours
|
|
samples = connectNeighbourSamples(samples, map, index);
|
|
colors = connectNeighbourColors(colors, map, index);
|
|
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
vertices[i].y = samples[i];
|
|
}
|
|
|
|
applyMesh(tile, mesh, vertices, colors);
|
|
}
|
|
|
|
private List<TileType> checkAvailability(Dictionary<Vector3, GameObject> tiles, Vector3 index)
|
|
{
|
|
List<List<TileType>> toCheck = new List<List<TileType>>();
|
|
List<TileType> result = new List<TileType>();
|
|
for (int i = 0; i < TileTypeMethods.getHighest() + 1; i++)
|
|
{
|
|
result.Add((TileType)i);
|
|
}
|
|
|
|
if (tiles.ContainsKey(index - new Vector3(1, 0, 0)))
|
|
{
|
|
toCheck.Add(tiles[index - new Vector3(1, 0, 0)].GetComponent<Tile>().getPossibleNeighbours());
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(-1, 0, 0)))
|
|
{
|
|
toCheck.Add(tiles[index - new Vector3(-1, 0, 0)].GetComponent<Tile>().getPossibleNeighbours());
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, 1)))
|
|
{
|
|
toCheck.Add(tiles[index - new Vector3(0, 0, 1)].GetComponent<Tile>().getPossibleNeighbours());
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, -1)))
|
|
{
|
|
toCheck.Add(tiles[index - new Vector3(0, 0, -1)].GetComponent<Tile>().getPossibleNeighbours());
|
|
}
|
|
|
|
for (int i = 0; i < toCheck.Count; i++)
|
|
{
|
|
result = result.Intersect(toCheck[i]).ToList();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private float[] connectNeighbourSamples(float[] basis, Dictionary<Vector3, GameObject> tiles, Vector3 index)
|
|
{
|
|
float[] result = basis;
|
|
Mesh mesh;
|
|
Vector3[] vertices;
|
|
int sidelength = (int)Mathf.Sqrt(result.Length);
|
|
|
|
if (tiles.ContainsKey(index - new Vector3(1, 0, 0))) //Links
|
|
{
|
|
mesh = tiles[index - new Vector3(1, 0, 0)].GetComponent<MeshFilter>().mesh;
|
|
vertices = mesh.vertices;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[sidelength - 1 + i * sidelength] = vertices[0 + i * sidelength].y;
|
|
result[sidelength - 2 + i * sidelength] = (result[sidelength - 1 + i * sidelength] + result[sidelength - 3 + i * sidelength]) / 2;
|
|
}
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(-1, 0, 0))) //Rechts
|
|
{
|
|
mesh = tiles[index - new Vector3(-1, 0, 0)].GetComponent<MeshFilter>().mesh;
|
|
vertices = mesh.vertices;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[0 + i * sidelength] = vertices[sidelength - 1 + i * sidelength].y;
|
|
result[1 + i * sidelength] = (result[0 + i * sidelength] + result[2 + i * sidelength]) / 2;
|
|
}
|
|
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, 1))) //Unten
|
|
{
|
|
mesh = tiles[index - new Vector3(0, 0, 1)].GetComponent<MeshFilter>().mesh;
|
|
vertices = mesh.vertices;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[sidelength * sidelength - (sidelength - i)] = vertices[i].y;
|
|
result[sidelength * (sidelength - 1) - (sidelength - i)] = (result[sidelength * sidelength - (sidelength - i)] + result[sidelength * (sidelength - 2) - (sidelength - i)]) / 2;
|
|
}
|
|
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, -1))) //Oben
|
|
{
|
|
mesh = tiles[index - new Vector3(0, 0, -1)].GetComponent<MeshFilter>().mesh;
|
|
vertices = mesh.vertices;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[i] = vertices[sidelength * sidelength - (sidelength - i)].y;
|
|
result[i + sidelength] = (result[i] + result[i + sidelength * 2]) / 2;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private Color32[] connectNeighbourColors(Color32[] basis, Dictionary<Vector3, GameObject> tiles, Vector3 index)
|
|
{
|
|
Color32[] result = basis;
|
|
Mesh mesh;
|
|
Color32[] colors;
|
|
int sidelength = (int)Mathf.Sqrt(result.Length);
|
|
|
|
if (tiles.ContainsKey(index - new Vector3(1, 0, 0))) //Links
|
|
{
|
|
mesh = tiles[index - new Vector3(1, 0, 0)].GetComponent<MeshFilter>().mesh;
|
|
colors = mesh.colors32;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[sidelength - 1 + i * sidelength] = colors[0 + i * sidelength];
|
|
result[sidelength - 2 + i * sidelength] = Color32.Lerp(result[sidelength - 1 + i * sidelength], result[sidelength - 3 + i * sidelength], 0.5f);
|
|
}
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(-1, 0, 0))) //Rechts
|
|
{
|
|
mesh = tiles[index - new Vector3(-1, 0, 0)].GetComponent<MeshFilter>().mesh;
|
|
colors = mesh.colors32;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[0 + i * sidelength] = colors[sidelength - 1 + i * sidelength];
|
|
result[1 + i * sidelength] = Color32.Lerp(result[0 + i * sidelength], result[2 + i * sidelength], 0.5f);
|
|
}
|
|
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, 1))) //Unten
|
|
{
|
|
mesh = tiles[index - new Vector3(0, 0, 1)].GetComponent<MeshFilter>().mesh;
|
|
colors = mesh.colors32;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[sidelength * sidelength - (sidelength - i)] = colors[i];
|
|
result[sidelength * (sidelength - 1) - (sidelength - i)] = Color32.Lerp(result[sidelength * sidelength - (sidelength - i)], result[sidelength * (sidelength - 2) - (sidelength - i)], 0.5f);
|
|
}
|
|
}
|
|
if (tiles.ContainsKey(index - new Vector3(0, 0, -1))) //Oben
|
|
{
|
|
mesh = tiles[index - new Vector3(0, 0, -1)].GetComponent<MeshFilter>().mesh;
|
|
colors = mesh.colors32;
|
|
for (int i = 0; i < sidelength; i++)
|
|
{
|
|
result[i] = colors[sidelength * sidelength - (sidelength - i)];
|
|
result[i + sidelength] = Color32.Lerp(result[i], result[i + sidelength * 2], 0.5f);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
private void resetMesh(GameObject tile)
|
|
{
|
|
Mesh mesh = tile.GetComponent<MeshCollider>().sharedMesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
vertices[i].y = 0;
|
|
}
|
|
mesh.vertices = vertices;
|
|
mesh.RecalculateBounds();
|
|
mesh.RecalculateNormals();
|
|
tile.GetComponent<MeshCollider>().sharedMesh = mesh;
|
|
}
|
|
|
|
|
|
public void applyMesh(GameObject tile, Mesh mesh, Vector3[] vertices, Color32[] colors)
|
|
{
|
|
mesh.vertices = vertices;
|
|
mesh.colors32 = colors;
|
|
mesh.RecalculateBounds();
|
|
mesh.RecalculateNormals();
|
|
tile.GetComponent<MeshCollider>().sharedMesh = mesh;
|
|
tile.GetComponent<MeshFilter>().sharedMesh = mesh;
|
|
}
|
|
|
|
public void saveTile(GameObject tile, string path)
|
|
{
|
|
string result = "";
|
|
Vector3[] vertices = tile.GetComponent<MeshFilter>().mesh.vertices;
|
|
Color32[] colors = tile.GetComponent<MeshFilter>().mesh.colors32;
|
|
result = result + "\"vertices\": {\r\n";
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
result = result + FileHandler.generateJSON("vertice" + i, "\"" + vertices[i].x + "/" + vertices[i].y + "/" + vertices[i].z + "\"");
|
|
if (i < vertices.Length - 1)
|
|
{
|
|
result = result + ",\r\n";
|
|
}
|
|
}
|
|
result = result + "\r\n},\"colors\": {\r\n";
|
|
for (int i = 0; i < colors.Length; i++)
|
|
{
|
|
result = result + FileHandler.generateJSON("color" + i, "\"" + colors[i].r + "/" + colors[i].g + "/" + colors[i].b + "/" + colors[i].a + "\"");
|
|
if (i < colors.Length - 1)
|
|
{
|
|
result = result + ",\r\n";
|
|
}
|
|
}
|
|
result = result + "\r\n}\r\n}";
|
|
FileHandler.saveNoise(result, path);
|
|
}
|
|
|
|
public void loadTile(GameObject tile, JToken jsonVertices, JToken jsonColors)
|
|
{
|
|
var jsonData = JObject.Parse(jsonColors.ToString()).Children();
|
|
List<JToken> colorTokens = jsonData.Children().ToList();
|
|
jsonData = JObject.Parse(jsonVertices.ToString()).Children();
|
|
List<JToken> verticeTokens = jsonData.Children().ToList();
|
|
Color32[] colors = new Color32[colorTokens.Count];
|
|
Vector3[] vertices = new Vector3[verticeTokens.Count];
|
|
JToken current;
|
|
string[] parts;
|
|
for (int i = 0; i < colorTokens.Count; i++)
|
|
{
|
|
current = colorTokens[i];
|
|
parts = current.Value<string>().Split('/');
|
|
colors[i] = new Color32(byte.Parse(parts[0]), byte.Parse(parts[1]), byte.Parse(parts[2]), byte.Parse(parts[3]));
|
|
}
|
|
for (int i = 0; i < verticeTokens.Count; i++)
|
|
{
|
|
current = verticeTokens[i];
|
|
parts = current.Value<string>().Split('/');
|
|
vertices[i] = new Vector3(float.Parse(parts[0]), float.Parse(parts[1]), float.Parse(parts[2]));
|
|
}
|
|
applyMesh(tile, tile.GetComponent<MeshFilter>().mesh, vertices, colors);
|
|
}
|
|
}
|