Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.49 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using UnityEngine;
  5. using Unity.Jobs;
  6. using Unity.Collections;
  7. using Unity.Mathematics;
  8. using Unity.Burst;
  9. using System.Collections;
  10. using System.Linq;
  11.  
  12. namespace VoxelMaster
  13. {
  14. public class VoxelGrid : MonoBehaviour
  15. {
  16. private ChunkDataStructure chunks = new ChunkDictionary();
  17. public Transform viewer;
  18. private Vector3Int viewerCoords = Vector3Int.zero;
  19. public int ChunkSize = 16;
  20. public int searchRadius = 6;
  21.  
  22. public TerrainGraph terrainGraph;
  23. private ChunkMeshGenerator meshGenerator = new MarchingCubesMeshGenerator();
  24.  
  25.  
  26. public Material material;
  27. public MeshFilter testMeshFilter;
  28.  
  29. public Dictionary<Chunk, Mesh> chunkMeshes = new Dictionary<Chunk, Mesh>();
  30.  
  31. void Start()
  32. {
  33. }
  34.  
  35. void Update()
  36. {
  37. CreateNearbyChunks();
  38.  
  39. RenderChunks();
  40. }
  41.  
  42. private void RenderChunks()
  43. {
  44. foreach (KeyValuePair<Chunk, Mesh> entry in chunkMeshes)
  45. {
  46. Graphics.DrawMesh(entry.Value, entry.Key.Coords * (entry.Key.Size), Quaternion.identity, material, 0);
  47. }
  48. }
  49.  
  50. int genThisFrame = 0;
  51. void CreateNearbyChunks()
  52. {
  53. viewerCoords = new Vector3Int(
  54. Mathf.FloorToInt(viewer.position.x / ChunkSize),
  55. Mathf.FloorToInt(viewer.position.y / ChunkSize),
  56. Mathf.FloorToInt(viewer.position.z / ChunkSize)
  57. );
  58.  
  59.  
  60. for (int y = -searchRadius; y < searchRadius; y++)
  61. {
  62. int x = 0;
  63. int z = 0;
  64. int dx = 0;
  65. int dy = -1;
  66. for (int i = 0; i < (searchRadius * 2) * (searchRadius * 2); i++)
  67. {
  68. if ((-searchRadius < x && x <= searchRadius) && ((-searchRadius < z && z <= searchRadius)))
  69. {
  70. var chunkCoords = viewerCoords + new Vector3Int(x, y, z);
  71. if (!chunks.ChunkExists(chunkCoords))
  72. {
  73. var chunk = new Chunk(chunkCoords, ChunkSize);
  74. chunks.AddChunk(chunkCoords, chunk);
  75. // Debug.Log($"added chunk at {x},{y},{z}");
  76. var job = new GenerateChunkDensityJob
  77. {
  78. chunkCoords = chunkCoords,
  79. chunkSize = chunk.Size,
  80. densities = chunk.Voxels,
  81. };
  82. var densityJob = job.Schedule(chunk.Voxels.Length, 64);
  83.  
  84. var triangles = new NativeArray<Triangle>(5 * ((chunk.Size - 1) * (chunk.Size - 1) * (chunk.Size - 1)), Allocator.TempJob);
  85. var meshJob = new GenerateChunkMeshJob
  86. {
  87. chunkSize = chunk.Size,
  88. densities = chunk.Voxels,
  89. isoLevel = .5f,
  90. triangles = triangles,
  91. triTable = NativeLookup.triTabl,
  92. cornerIndexAFromEdge = NativeLookup.cornerIndexAFromEdge,
  93. cornerIndexBFromEdge = NativeLookup.cornerIndexBFromEdge
  94. };
  95. var meshJobHandle = meshJob.Schedule((chunk.Size - 1) * (chunk.Size - 1) * (chunk.Size - 1), 32, densityJob);
  96. // densityJob.Complete();
  97. // meshJob.Run();
  98. meshJobHandle.Complete();
  99.  
  100.  
  101. var vertices = new List<Vector3>();
  102. var triangleIndices = new List<int>();
  103. int triIndex = 0;
  104. foreach (var triangle in triangles)
  105. {
  106. if (!triangle.isTriangle) continue;
  107. vertices.Add(triangle.a);
  108. vertices.Add(triangle.b);
  109. vertices.Add(triangle.c);
  110.  
  111. triangleIndices.Add(triIndex++);
  112. triangleIndices.Add(triIndex++);
  113. triangleIndices.Add(triIndex++);
  114. }
  115.  
  116. var mesh = new Mesh();
  117. mesh.SetVertices(vertices);
  118. mesh.SetTriangles(triangleIndices, 0);
  119. mesh.RecalculateNormals();
  120. chunkMeshes.Add(chunk, mesh);
  121.  
  122. triangles.Dispose();
  123.  
  124.  
  125. genThisFrame++;
  126. if (genThisFrame > 16)
  127. {
  128. genThisFrame = 0;
  129. return;
  130. }
  131. }
  132. }
  133. if (x == z || (x < 0 && x == -z) || (x > 0 && x == 1 - z))
  134. {
  135. var oldDx = dx;
  136. dx = -dy;
  137. dy = oldDx;
  138. }
  139. x += dx;
  140. z += dy;
  141. }
  142. }
  143.  
  144. }
  145.  
  146.  
  147. [BurstCompile]
  148. struct GenerateChunkDensityJob : IJobParallelFor
  149. {
  150. public NativeArray<float> densities;
  151. public int chunkSize;
  152. public Vector3Int chunkCoords;
  153.  
  154. public void Execute(int index)
  155. {
  156. var voxelCoord = (chunkCoords * (chunkSize)) + Util.Map1DTo3D(index, chunkSize);
  157.  
  158. var n = noise.cnoise(new float3(
  159. voxelCoord.x,
  160. voxelCoord.y,
  161. voxelCoord.z) / 50.00f
  162. );
  163.  
  164. densities[index] = n * 0.5f + 0.5f;
  165. // densities[index] = math.unlerp(-1, 1, n);
  166.  
  167. }
  168. }
  169.  
  170.  
  171. [BurstCompile]
  172. struct GenerateChunkMeshJob : IJobParallelFor
  173. {
  174. [ReadOnly] public NativeArray<float> densities;
  175. [ReadOnly] public int chunkSize;
  176. [ReadOnly] public float isoLevel;
  177. [NativeDisableParallelForRestriction] public NativeArray<Triangle> triangles;
  178. [ReadOnly] public NativeArray<int> triTable;
  179. [ReadOnly] public NativeArray<int> cornerIndexAFromEdge;
  180. [ReadOnly] public NativeArray<int> cornerIndexBFromEdge;
  181.  
  182.  
  183. int triangleIndex;
  184.  
  185. public void Execute(int index)
  186. {
  187. var coords = Util.Map1DTo3D(index, chunkSize);
  188. var x = coords.x; var y = coords.y; var z = coords.z;
  189.  
  190. var cubeDensity = new NativeArray<float>(8, Allocator.Temp);
  191. cubeDensity[0] = densities[Util.Map3DTo1D(x, y, z, chunkSize)];
  192. cubeDensity[1] = densities[Util.Map3DTo1D((x + 1), y, z, chunkSize)];
  193. cubeDensity[2] = densities[Util.Map3DTo1D((x + 1), y, (z + 1), chunkSize)];
  194. cubeDensity[3] = densities[Util.Map3DTo1D(x, y, (z + 1), chunkSize)];
  195. cubeDensity[4] = densities[Util.Map3DTo1D(x, (y + 1), z, chunkSize)];
  196. cubeDensity[5] = densities[Util.Map3DTo1D((x + 1), (y + 1), z, chunkSize)];
  197. cubeDensity[6] = densities[Util.Map3DTo1D((x + 1), (y + 1), (z + 1), chunkSize)];
  198. cubeDensity[7] = densities[Util.Map3DTo1D(x, (y + 1), (z + 1), chunkSize)];
  199.  
  200. var cubeVectors = new NativeArray<float3>(8, Allocator.Temp);
  201. cubeVectors[0] = new float3(x, y, z);
  202. cubeVectors[1] = new float3((x + 1), y, z);
  203. cubeVectors[2] = new float3((x + 1), y, (z + 1));
  204. cubeVectors[3] = new float3(x, y, (z + 1));
  205. cubeVectors[4] = new float3(x, (y + 1), z);
  206. cubeVectors[5] = new float3((x + 1), (y + 1), z);
  207. cubeVectors[6] = new float3((x + 1), (y + 1), (z + 1));
  208. cubeVectors[7] = new float3(x, (y + 1), (z + 1));
  209.  
  210. int cubeindex = 0;
  211.  
  212. if (cubeDensity[0] < isoLevel) cubeindex |= 1;
  213. if (cubeDensity[1] < isoLevel) cubeindex |= 2;
  214. if (cubeDensity[2] < isoLevel) cubeindex |= 4;
  215. if (cubeDensity[3] < isoLevel) cubeindex |= 8;
  216. if (cubeDensity[4] < isoLevel) cubeindex |= 16;
  217. if (cubeDensity[5] < isoLevel) cubeindex |= 32;
  218. if (cubeDensity[6] < isoLevel) cubeindex |= 64;
  219. if (cubeDensity[7] < isoLevel) cubeindex |= 128;
  220.  
  221.  
  222. var currentTriangulationIndex = cubeindex * 16;
  223. var triangleIndex = 0;
  224. for (int i = currentTriangulationIndex; triTable[i] != -1; i += 3)
  225. {
  226. var triVerts = new NativeArray<Vector3>(3, Allocator.Temp);
  227. for (int j = 0; j < 3; j++)
  228. {
  229. var a0 = cornerIndexAFromEdge[triTable[i + j]];
  230. var b0 = cornerIndexBFromEdge[triTable[i + j]];
  231. // vertices.Add(Vector3.Lerp(cubeVectors[a0], cubeVectors[b0], (isoLevel - cubeDensity[a0]) / (cubeDensity[b0] - cubeDensity[a0])));
  232. triVerts[j] = Vector3.Lerp(cubeVectors[a0], cubeVectors[b0], (isoLevel - cubeDensity[a0]) / (cubeDensity[b0] - cubeDensity[a0]));
  233. }
  234.  
  235. triangles[index * 5 + triangleIndex++] = new Triangle
  236. {
  237. isTriangle = true,
  238. a = triVerts[0],
  239. b = triVerts[1],
  240. c = triVerts[2],
  241. };
  242. triVerts.Dispose();
  243. }
  244. cubeDensity.Dispose();
  245. cubeVectors.Dispose();
  246.  
  247. }
  248.  
  249. }
  250.  
  251. public struct Triangle
  252. {
  253. public bool isTriangle;
  254. public Vector3 a;
  255. public Vector3 b;
  256. public Vector3 c;
  257. }
  258.  
  259.  
  260. void OnDestroy()
  261. {
  262. chunks.ForEach(c =>
  263. {
  264. c.Voxels.Dispose();
  265. });
  266. }
  267. }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement