|
@@ -30,6 +30,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
int height = 8;
|
|
|
|
|
|
float[,,] terrainMap;
|
|
|
+ uint[,,] terrainCodes;
|
|
|
|
|
|
List<Vector3> vertices = new List<Vector3>();
|
|
|
List<int> triangles = new List<int>();
|
|
@@ -39,8 +40,23 @@ namespace KairoEngine.TerrainEngine
|
|
|
private List<MarchingCubesJob> jobs = new List<MarchingCubesJob>();
|
|
|
|
|
|
private void Update()
|
|
|
+ {
|
|
|
+ UpdateFinishedJobs();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnDestroy()
|
|
|
+ {
|
|
|
+ // Make sure we run our jobs to completion before exiting.
|
|
|
+ for (int i = 0; i < jobHandles.Count; i++)
|
|
|
+ {
|
|
|
+ jobHandles[i].Complete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UpdateFinishedJobs()
|
|
|
{
|
|
|
//jobHandle.Complete();
|
|
|
+ Debug.Log("Updating finished jobs - " + jobHandles.Count);
|
|
|
for (int i = 0; i < jobHandles.Count; i++)
|
|
|
{
|
|
|
|
|
@@ -58,9 +74,11 @@ namespace KairoEngine.TerrainEngine
|
|
|
Debug.Log($"Completed job has {jobs[i].vertices.Count()}/{verticeCount} vertices and {jobs[i].triangles.Count()}/{trianglesCount} triangles");
|
|
|
Vector3[] vertices = jobs[i].vertices.Take(verticeCount).ToArray();
|
|
|
int[] triangles = jobs[i].triangles.Take(trianglesCount).ToArray();
|
|
|
- BuildMesh(target, vertices, triangles);
|
|
|
+ Color[] vertexColors = jobs[i].vertexColors.Take(verticeCount).ToArray();
|
|
|
+ BuildMesh(target, vertices, triangles, vertexColors);
|
|
|
// Remove this
|
|
|
jobs[i].blocks.Dispose();
|
|
|
+ jobs[i].codes.Dispose();
|
|
|
jobs[i].vertices.Dispose();
|
|
|
jobs[i].triangles.Dispose();
|
|
|
jobs[i].arrayIndexes.Dispose();
|
|
@@ -70,47 +88,44 @@ namespace KairoEngine.TerrainEngine
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void OnDestroy()
|
|
|
- {
|
|
|
- // Make sure we run our jobs to completion before exiting.
|
|
|
- for (int i = 0; i < jobHandles.Count; i++)
|
|
|
- {
|
|
|
- jobHandles[i].Complete();
|
|
|
- }
|
|
|
- }
|
|
|
+ public bool IsGeneratorDone() => jobHandles.Count == 0 ? true : false;
|
|
|
|
|
|
public void Generate(ChunkSystem<BlockBase> chunkSystem, Vector3Int initialPosition = new Vector3Int())
|
|
|
{
|
|
|
+ Debug.Log("Generating chunk " + initialPosition);
|
|
|
this.chunkSystem = chunkSystem;
|
|
|
width = chunkSystem.chunkSize.x;
|
|
|
length = chunkSystem.chunkSize.z;
|
|
|
height = chunkSystem.chunkSize.y;
|
|
|
//transform.tag = "Terrain";
|
|
|
terrainMap = new float[width + 1, height + 1, length + 1];
|
|
|
+ terrainCodes = new uint[width + 1, height + 1, length + 1];
|
|
|
PopulateTerrainMap(chunkSystem, initialPosition);
|
|
|
ScheduleJob(initialPosition);
|
|
|
//CreateMeshData();
|
|
|
|
|
|
}
|
|
|
|
|
|
- void PopulateTerrainMap (ChunkSystem<BlockBase> chunkSystem, Vector3Int initialPosition = new Vector3Int()) {
|
|
|
-
|
|
|
+ void PopulateTerrainMap (ChunkSystem<BlockBase> chunkSystem, Vector3Int initialPosition = new Vector3Int())
|
|
|
+ {
|
|
|
// The data points for terrain are stored at the corners of our "cubes", so the terrainMap needs to be 1 larger
|
|
|
// than the width/height of our mesh.
|
|
|
for (int x = 0; x < width + 1; x++) {
|
|
|
for (int z = 0; z < length + 1; z++) {
|
|
|
for (int y = 0; y < height + 1; y++) {
|
|
|
- BlockBase block = chunkSystem.GetBlock(initialPosition + new Vector3Int(x, y, z));
|
|
|
+ Vector3Int pos = initialPosition + new Vector3Int(x, y, z);
|
|
|
+ BlockBase block = chunkSystem.GetBlock(pos);
|
|
|
// Set the value of this point in the terrainMap.
|
|
|
- terrainMap[x, y, z] = (float)y - (float)block.value/1000;
|
|
|
+ terrainMap[x, y, z] = (float)pos.y - (float)block.value;
|
|
|
+ terrainCodes[x, y, z] = block.code;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- void BuildMesh (GameObject target, Vector3[] vertices, int[] triangles)
|
|
|
+ void BuildMesh (GameObject target, Vector3[] vertices, int[] triangles, Color[] vertexColors)
|
|
|
{
|
|
|
- Debug.Log($"Building mesh with {vertices.Length} vertices and {triangles.Length} triangles");
|
|
|
+ //Debug.Log($"Building mesh with {vertices.Length} vertices and {triangles.Length} triangles");
|
|
|
MeshRenderer meshRederer = target.GetComponent<MeshRenderer>();
|
|
|
if(meshRederer == null) meshRederer = target.AddComponent<MeshRenderer>();
|
|
|
meshRederer.sharedMaterial = material;
|
|
@@ -121,6 +136,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
Mesh mesh = new Mesh();
|
|
|
mesh.vertices = vertices;
|
|
|
mesh.triangles = triangles;
|
|
|
+ mesh.colors = vertexColors;
|
|
|
mesh.RecalculateNormals();
|
|
|
meshFilter.mesh = mesh;
|
|
|
meshCollider.sharedMesh = mesh;
|
|
@@ -136,8 +152,10 @@ namespace KairoEngine.TerrainEngine
|
|
|
smoothTerrain = smoothTerrain,
|
|
|
flatShaded = flatShaded,
|
|
|
blocks = new NativeArray<float>(terrainMap.Length, Allocator.TempJob),
|
|
|
+ codes = new NativeArray<uint>(terrainMap.Length, Allocator.TempJob),
|
|
|
vertices = new NativeArray<Vector3>(15000, Allocator.TempJob),
|
|
|
triangles = new NativeArray<int>(25000, Allocator.TempJob),
|
|
|
+ vertexColors = new NativeArray<Color>(15000, Allocator.TempJob),
|
|
|
arrayIndexes = new NativeArray<int>(2, Allocator.TempJob),
|
|
|
initialPosition = initialPosition
|
|
|
};
|
|
@@ -146,6 +164,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
for (int y = 0; y < height + 1; y++) {
|
|
|
for (int z = 0; z < length + 1; z++) {
|
|
|
marchingCubesJob.blocks[blockIndex] = terrainMap[x, y, z];
|
|
|
+ marchingCubesJob.codes[blockIndex] = terrainCodes[x, y, z];
|
|
|
blockIndex += 1;
|
|
|
}
|
|
|
}
|
|
@@ -156,6 +175,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ [ExecuteInEditMode]
|
|
|
struct MarchingCubesJob : IJob
|
|
|
{
|
|
|
public Vector3Int chunkSize;
|
|
@@ -163,8 +183,10 @@ namespace KairoEngine.TerrainEngine
|
|
|
public bool smoothTerrain;
|
|
|
public bool flatShaded;
|
|
|
public NativeArray<float> blocks;
|
|
|
+ public NativeArray<uint> codes;
|
|
|
public NativeArray<Vector3> vertices;
|
|
|
public NativeArray<int> triangles;
|
|
|
+ public NativeArray<Color> vertexColors;
|
|
|
public Vector3Int initialPosition;
|
|
|
public NativeArray<int> arrayIndexes;
|
|
|
|
|
@@ -235,12 +257,13 @@ namespace KairoEngine.TerrainEngine
|
|
|
{
|
|
|
vertices[verticesArrayIndex] = vertPosition;
|
|
|
triangles[trianglesArrayIndex] = verticesArrayIndex;
|
|
|
+ vertexColors[verticesArrayIndex] = SampleTerrainColor(position);
|
|
|
verticesArrayIndex += 1;
|
|
|
trianglesArrayIndex += 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- triangles[trianglesArrayIndex] = VertForIndice(vertPosition);
|
|
|
+ triangles[trianglesArrayIndex] = VertForIndice(vertPosition, position);
|
|
|
trianglesArrayIndex += 1;
|
|
|
}
|
|
|
edgeIndex++;
|
|
@@ -255,6 +278,22 @@ namespace KairoEngine.TerrainEngine
|
|
|
return blocks[index];
|
|
|
}
|
|
|
|
|
|
+ Color SampleTerrainColor (Vector3Int point)
|
|
|
+ {
|
|
|
+ int index = (((chunkSize.y + 1) * (chunkSize.z + 1)) * point.x) + ((chunkSize.z + 1) * point.y) + point.z;
|
|
|
+ uint code = codes[index];
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ default:
|
|
|
+ case 0:
|
|
|
+ return Color.red;
|
|
|
+ case 1:
|
|
|
+ return Color.green;
|
|
|
+ case 2:
|
|
|
+ return Color.blue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
int GetCubeConfiguration (float[] cube)
|
|
|
{
|
|
|
// Starting with a configuration of zero, loop through each point in the cube and check if it is below the terrain surface.
|
|
@@ -268,7 +307,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
return configurationIndex;
|
|
|
}
|
|
|
|
|
|
- int VertForIndice (Vector3 vert)
|
|
|
+ int VertForIndice (Vector3 vert, Vector3Int point)
|
|
|
{
|
|
|
// Loop through all the vertices currently in the vertices list.
|
|
|
for (int i = 0; i < verticesArrayIndex; i++)
|
|
@@ -278,6 +317,7 @@ namespace KairoEngine.TerrainEngine
|
|
|
}
|
|
|
// If we didn't find a match, add this vert to the list and return last index.
|
|
|
vertices[verticesArrayIndex] = vert;
|
|
|
+ vertexColors[verticesArrayIndex] = SampleTerrainColor(point);
|
|
|
verticesArrayIndex += 1;
|
|
|
return verticesArrayIndex - 1;
|
|
|
}
|