Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections.Generic;
- [RequireComponent(typeof(MeshFilter))]
- public class MarchingCubes : MonoBehaviour
- {
- [Header("Main")]
- public Chunk ChunkRef;
- public TerrainManager TM;
- MeshFilter meshFilter;
- MeshCollider meshCollider;
- List<Vector3> Vertices = new List<Vector3>();
- List<int> Triangles = new List<int>();
- int c = -1;
- public void Create()
- {
- meshFilter = GetComponent<MeshFilter>();
- meshCollider = GetComponent<MeshCollider>();
- ChunkRef.TerrainMap = new float[TM.TD.ChunkSize + 1, TM.TD.ChunkHeight + 1, TM.TD.ChunkSize + 1];
- CreateTerrainMap();
- CreateMeshData();
- }
- void ClearMeshData()
- {
- Vertices.Clear();
- Triangles.Clear();
- }
- void BuildMesh()
- {
- Mesh mesh = new Mesh();
- mesh.vertices = Vertices.ToArray();
- mesh.triangles = Triangles.ToArray();
- mesh.RecalculateNormals();
- meshFilter.mesh = mesh;
- meshCollider.sharedMesh = mesh;
- }
- int GetCubeConfig(float[] cube)
- {
- int index = 0;
- for (int i = 0; i < 8; i++)
- {
- if (cube[i] > TM.TD.SurfaceLevel)
- index |= 1 << i;
- }
- return index;
- }
- void MarchCube(Vector3Int pos)
- {
- float[] cube = new float[8];
- for (int i = 0; i < 8; i++)
- {
- cube[i] = SampleTerrain(pos + TM.CornerTable[i]);
- }
- int index = GetCubeConfig(cube);
- if (index == 0 || index == 255)
- return;
- int e = 0;
- for (int i = 0; i < 5; i++)
- {
- for (int p = 0; p < 3; p++)
- {
- int indice = TM.TriangleTable[index, e];
- if (indice == -1)
- return;
- Vector3 vert1 = pos + TM.CornerTable[TM.EdgeIndexes[indice, 0]];
- Vector3 vert2 = pos + TM.CornerTable[TM.EdgeIndexes[indice, 1]];
- Vector3 vertPos;
- if (TM.TD.SmoothTerrain)
- {
- float vert1Sample = cube[TM.EdgeIndexes[indice, 0]];
- float vert2Sample = cube[TM.EdgeIndexes[indice, 1]];
- float dif = vert2Sample - vert1Sample;
- if (dif == 0)
- dif = TM.TD.SurfaceLevel;
- else
- dif = (TM.TD.SurfaceLevel - vert1Sample) / dif;
- vertPos = vert1 + ((vert2 - vert1) * dif);
- }
- else
- vertPos = (vert1 + vert2) / 2f;
- if (TM.TD.FlatShaded)
- {
- Vertices.Add(vertPos);
- Triangles.Add(Vertices.Count - 1);
- } else
- Triangles.Add(VertForIndice(vertPos));
- e++;
- }
- }
- }
- void CreateTerrainMap()
- {
- for (int x = 0; x < TM.TD.ChunkSize + 1; x++)
- {
- for (int y = 0; y < TM.TD.ChunkHeight + 1; y++)
- {
- for (int z = 0; z < TM.TD.ChunkSize + 1; z++)
- {
- float h = TM.PG.SampleTerrain(new Vector2(x + TM.TD.ChunkSize * ChunkRef.Pos.x, z + TM.TD.ChunkSize * ChunkRef.Pos.y));
- ChunkRef.TerrainMap[x, y, z] = y - h;
- }
- }
- }
- }
- void CreateMeshData()
- {
- ClearMeshData();
- for (int x = 0; x < TM.TD.ChunkSize; x++)
- {
- for (int y = 0; y < TM.TD.ChunkHeight; y++)
- {
- for (int z = 0; z < TM.TD.ChunkSize; z++)
- {
- MarchCube(new Vector3Int(x, y, z));
- }
- }
- }
- BuildMesh();
- }
- float SampleTerrain(Vector3Int point)
- {
- return ChunkRef.TerrainMap[point.x, point.y, point.z];
- }
- int VertForIndice(Vector3 vert)
- {
- for (int i = 0; i < Vertices.Count; i++)
- {
- if (Vertices[i] == vert)
- return i;
- }
- Vertices.Add(vert);
- return Vertices.Count - 1;
- }
- public void PlaceTerrain(Vector3 pos)
- {
- Vector3Int p = new Vector3Int(Mathf.CeilToInt(pos.x), Mathf.CeilToInt(pos.y), Mathf.CeilToInt(pos.z));
- ChunkRef.TerrainMap[p.x, p.y, p.z] = 0f;
- CreateMeshData();
- }
- public void RemoveTerrain(Vector3 pos)
- {
- Vector3Int p = new Vector3Int(Mathf.FloorToInt(pos.x), Mathf.FloorToInt(pos.y), Mathf.FloorToInt(pos.z));
- ChunkRef.TerrainMap[p.x, p.y, p.z] = 1f;
- CreateMeshData();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement