336 lines
11 KiB
C#
336 lines
11 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, string name, Dictionary<Vector3, GameObject> map)
|
|
{
|
|
/*if(name.Length > 0){
|
|
applyCityNoise(tile);
|
|
}
|
|
else{
|
|
applyNormalNoise(tile, map);
|
|
}*/
|
|
applyNormalNoise(tile, map);
|
|
|
|
}
|
|
|
|
private void applyCityNoise(GameObject tile)
|
|
{
|
|
//resetMesh(tile);
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples;
|
|
Color32[] colors;
|
|
int chance = rand.Next(1, 101);
|
|
samples = calculateSamplesCity(tile);
|
|
string tiletype = "City";
|
|
|
|
colors = new Color32[samples.Length];
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
colors[i] = new Color32(0, 185, 0, 255);
|
|
}
|
|
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
vertices[i].y = samples[i] * 3;
|
|
}
|
|
applyMesh(tile, vertices, mesh, colors);
|
|
tile.GetComponent<Tile>().setType(tiletype);
|
|
}
|
|
|
|
private void applyNormalNoise(GameObject tile, Dictionary<Vector3, GameObject> map)
|
|
{
|
|
//resetMesh(tile);
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples;
|
|
Color32[] colors;
|
|
Color32 low;
|
|
Color32 high;
|
|
int chance = rand.Next(1, 101);
|
|
string tiletype = "";
|
|
if (chance > 85 && chance <= 100)
|
|
{
|
|
samples = calculateSamplesForest(tile);
|
|
low = new Color32(0, 150, 0, 255);
|
|
high = new Color32(0, 110, 20, 255);
|
|
tiletype = "Forest";
|
|
}
|
|
else if (chance > 70 && chance <= 85)
|
|
{
|
|
samples = calculateSamplesMountain(tile);
|
|
low = new Color32(0, 150, 0, 255);
|
|
high = new Color32(140, 140, 140, 255);
|
|
tiletype = "Mountain";
|
|
}
|
|
else if (chance > 55 && chance <= 70)
|
|
{
|
|
samples = calculateSamplesLake(tile);
|
|
low = new Color32(30, 110, 190, 255);
|
|
high = new Color32(0, 150, 0, 255);
|
|
tiletype = "Lake";
|
|
}
|
|
else if (chance > 40 && chance <= 55)
|
|
{
|
|
samples = calculateSamplesRiver(tile);
|
|
low = new Color32(30, 160, 190, 255);
|
|
high = new Color32(0, 150, 0, 255);
|
|
tiletype = "River";
|
|
}
|
|
else
|
|
{
|
|
samples = calculateSamplesPlane(tile);
|
|
low = new Color32(0, 150, 0, 255);
|
|
high = new Color32(0, 185, 0, 255);
|
|
tiletype = "Plane";
|
|
}
|
|
|
|
|
|
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));
|
|
}
|
|
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
vertices[i].y = samples[i] * 3;
|
|
}
|
|
applyMesh(tile, vertices, mesh, colors);
|
|
tile.GetComponent<Tile>().setType(tiletype);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
private float[] calculateBasicSamples(GameObject tile)
|
|
{
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples = new float[vertices.Length];
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
if (vertices[i].x != 5 && vertices[i].z != 5 && vertices[i].x != -5 && vertices[i].z != -5)
|
|
{
|
|
float xCord = tile.GetComponent<Tile>().getPosition().x + vertices[i].x / (vertices.Length - 1) * 10;
|
|
float yCord = tile.GetComponent<Tile>().getPosition().z + vertices[i].z / (vertices.Length - 1) * 10;
|
|
float sample = Mathf.PerlinNoise(xCord, yCord) - 0.1f * rand.Next(0, 6);
|
|
samples[i] = sample;
|
|
}
|
|
}
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesCity(GameObject tile){
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples = new float[vertices.Length];
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
samples[i] = 0;
|
|
}
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesPlane(GameObject tile)
|
|
{
|
|
float[] samples = calculateBasicSamples(tile);
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesForest(GameObject tile)
|
|
{
|
|
float[] samples = calculateBasicSamples(tile);
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesMountain(GameObject tile)
|
|
{
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples = calculateBasicSamples(tile);
|
|
|
|
int amount = rand.Next(1, 5);
|
|
int index = 0;
|
|
for (int i = 0; i < amount; i++)
|
|
{
|
|
do
|
|
{
|
|
index = rand.Next(0, samples.Length);
|
|
if (vertices[index].x != 5 && vertices[index].z != 5 && vertices[index].x != -5 && vertices[index].z != -5)
|
|
{
|
|
samples[index] = 3;
|
|
break;
|
|
}
|
|
} while (true);
|
|
}
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesRiver(GameObject tile)
|
|
{
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples = calculateBasicSamples(tile);
|
|
|
|
bool isVertical = (rand.Next(0,2) == 0 ? true : false);
|
|
int startX = 0;
|
|
int startZ = 0;
|
|
|
|
if (isVertical)
|
|
{
|
|
startZ = (rand.Next(0, 2) == 0 ? 4 : -4);
|
|
startX = rand.Next(-4, 5);
|
|
}
|
|
else
|
|
{
|
|
startZ = rand.Next(-4, 5);
|
|
startX = (rand.Next(0, 2) == 0 ? 4 : -4);
|
|
}
|
|
|
|
for (int k = 0; k < vertices.Length; k++)
|
|
{
|
|
if (isVertical)
|
|
{
|
|
if (Mathf.Round(vertices[k].x) == startX && Mathf.Round(vertices[k].z) != 5 && Mathf.Round(vertices[k].z) != -5)
|
|
{
|
|
samples[k] = samples[k] - rand.Next(2, 4) + 0.5f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Mathf.Round(vertices[k].x) != 5 && Mathf.Round(vertices[k].x) != -5 && Mathf.Round(vertices[k].z) == startZ)
|
|
{
|
|
samples[k] = samples[k] - rand.Next(2, 4) + 0.5f;
|
|
}
|
|
}
|
|
}
|
|
|
|
return samples;
|
|
}
|
|
|
|
private float[] calculateSamplesLake(GameObject tile)
|
|
{
|
|
Mesh mesh = tile.GetComponent<MeshFilter>().mesh;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float[] samples = calculateBasicSamples(tile);
|
|
|
|
int randX = rand.Next(-3, 4);
|
|
int randZ = rand.Next(-3, 4);
|
|
|
|
for (int i = -1; i < 2; i++)
|
|
{
|
|
for (int j = -1; j < 2; j++)
|
|
{
|
|
for (int k = 0; k < vertices.Length; k++)
|
|
{
|
|
if (Mathf.Round(vertices[k].x) == randX+i && Mathf.Round(vertices[k].z) == randZ+j)
|
|
{
|
|
samples[k] = samples[k] - rand.Next(1,3) - 0.25f * rand.Next(0,4);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return samples;
|
|
}
|
|
|
|
|
|
private void applyMesh(GameObject tile, Vector3[] vertices, Mesh mesh, Color32[] colors)
|
|
{
|
|
mesh.vertices = vertices;
|
|
mesh.RecalculateBounds();
|
|
mesh.RecalculateNormals();
|
|
mesh.colors32 = colors;
|
|
tile.GetComponent<MeshCollider>().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, vertices, tile.GetComponent<MeshFilter>().mesh, colors);
|
|
}
|
|
}
|