public static void GenerateMeshForChunks(List <Chunk> chunksToProcess) { List <JobData <MarchingCubeJob> > jobDataList = new List <JobData <MarchingCubeJob> >(); foreach (Chunk chunk in chunksToProcess) { MarchingCubeJob job = new MarchingCubeJob() { counter = new NativeCounter(Allocator.TempJob), voxelData = new NativeArray <VoxelData>(voxelData[chunk.id], Allocator.TempJob), vertexData = new NativeArray <VertexData>(voxelData[chunk.id].Length * 15, Allocator.TempJob), triangles = new NativeArray <ushort>(voxelData[chunk.id].Length * 15, Allocator.TempJob) }; jobDataList.Add(new JobData <MarchingCubeJob>(job, job.Schedule())); } for (int i = 0; i < chunksToProcess.Count; i++) { Chunk chunk = chunksToProcess[i]; JobData <MarchingCubeJob> jobData = jobDataList[i]; jobData.handle.Complete(); chunk.SetMeshData(jobData.job.counter.Count * 3, jobData.job.vertexData, jobData.job.triangles); jobData.job.Dispose(); chunk.workState.Next(); chunk.workState.Next(); } }
private void CreateOctree() { int maxSize = Mathf.RoundToInt(Mathf.Pow(2, maxHierarchyIndex)) + 3; //Make native containers NativeList <Octree> octrees = new NativeList <Octree>(Allocator.TempJob); NativeList <Octree> totalOctrees = new NativeList <Octree>(Allocator.TempJob); NativeArray <float> densities = new NativeArray <float>(maxSize * maxSize * maxSize, Allocator.TempJob); //Mesh native containers NativeList <Vector3> vertices = new NativeList <Vector3>(Allocator.TempJob); NativeList <int> triangles = new NativeList <int>(Allocator.TempJob); NativeList <Color> vertexColors = new NativeList <Color>(Allocator.TempJob); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); //Create the jobs and execute them DensityJob densityJob = new DensityJob { densities = densities, maxSize = maxSize, data = data }; densityJob.Run(maxSize * maxSize * maxSize); OctreeJob octreeJob = new OctreeJob { maxHierarchyIndex = maxHierarchyIndex, isoThreshold = isoThreshold, isoObstacleThreshold = isoObstacleThreshold, voxels = densities, finalOctrees = octrees, totalOctrees = totalOctrees }; octreeJob.Run(); MarchingCubeJob mcJob = new MarchingCubeJob { octrees = octrees, vertices = vertices, vertexColors = vertexColors, triangles = triangles, densities = densities, isoThreshold = isoThreshold, gridSize = new int3(maxSize, maxSize, maxSize) }; mcJob.Run(); //Gizmo draw if (drawGizmos) { foreach (var octree in totalOctrees) { Gizmos.color = Color.Lerp(Color.black, Color.white, (float)octree.hierarchyIndex / (float)maxHierarchyIndex); Gizmos.DrawWireCube(math.float3(new float3(octree.position) + ((float)octree.size / 2f)), new Vector3(octree.size, octree.size, octree.size)); } Octree currentOctree = totalOctrees[octreeIndexTest]; List <int> neighbours = FindNeighbours(totalOctrees, octreeIndexTest); foreach (var item in neighbours) { Octree octreeNeighbour = totalOctrees[item]; Gizmos.color = Color.red; Gizmos.DrawWireCube(octreeNeighbour.center, new Vector3(octreeNeighbour.size, octreeNeighbour.size, octreeNeighbour.size)); } Gizmos.color = Color.blue; Gizmos.DrawWireCube(currentOctree.center, new Vector3(currentOctree.size, currentOctree.size, currentOctree.size)); } Mesh mesh = new Mesh() { vertices = vertices.ToArray(), colors = vertexColors.ToArray(), triangles = triangles.ToArray() }; mesh.Optimize(); mesh.RecalculateNormals(); GetComponent <MeshFilter>().mesh = mesh; GetComponent <MeshCollider>().sharedMesh = mesh; //Release the native containers from the memory vertices.Dispose(); triangles.Dispose(); octrees.Dispose(); densities.Dispose(); UnityEngine.Debug.Log("Final: " + stopwatch.ElapsedMilliseconds); stopwatch.Stop(); }
//Generates the MarchingCube mesh public void GenerateMesh(TerrainGenerationData _terrainGenerationData, TerrainColorData _terrainColorData, Vector3Int chunkPos, TerrainGenerator _terrain, int[] _triTable, float3[] _edgeTable, float3[] _edgeTable2, int LOD = 0, bool resetMesh = true, bool immediate = false) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); if (resetMesh) { GetComponent <MeshFilter>().sharedMesh = new Mesh(); } completed = false; terrainGenerationData = _terrainGenerationData; terrainColorData = _terrainColorData; terrain = _terrain; chunkPosition = chunkPos; int resolution = terrainGenerationData.resolution - LOD; voxels = new NativeArray <float>((resolution + 2) * (resolution + 2) * (resolution + 2), Allocator.Persistent); vertices = new NativeArray <float3>(12 * resolution * resolution * resolution, Allocator.Persistent); finalVertices = new NativeList <Vector3>(Allocator.Persistent); triangles = new NativeArray <int>(16 * resolution * resolution * resolution, Allocator.Persistent); finalTriangles = new NativeList <int>(Allocator.Persistent); colors = new NativeArray <Color>(12 * resolution * resolution * resolution, Allocator.Persistent); finalColors = new NativeList <Color>(Allocator.Persistent); triTable = new NativeArray <int>(_triTable.Length, Allocator.Persistent); edgeTable = new NativeArray <float3>(12, Allocator.Persistent); edgeTable2 = new NativeArray <float3>(12, Allocator.Persistent); edgeTable.CopyFrom(_edgeTable); edgeTable2.CopyFrom(_edgeTable2); triTable.CopyFrom(_triTable); if (_terrainGenerationData.usePregeneratedVoxelData) { MarchingCubeVoxelJob voxelJob = new MarchingCubeVoxelJob() { voxels = voxels, chunkPosition = new float3(chunkPosition.x * 10, chunkPosition.y * 10, chunkPosition.z * 10), scale = (float)10 / (float)resolution, resolution = resolution + 2, terrainGenerationData = _terrainGenerationData }; voxelHandle = voxelJob.Schedule((resolution + 2) * (resolution + 2) * (resolution + 2), 64); } MarchingCubeJob job = new MarchingCubeJob() { edgeTable = edgeTable, edgeTable2 = edgeTable2, scale = (float)10 / (float)resolution, LOD = LOD, voxels = voxels, resolution = resolution, triangulationTable = triTable, chunkPosition = new float3(chunkPosition.x * 10, chunkPosition.y * 10, chunkPosition.z * 10), vertices = vertices, triangles = triangles, colors = colors, terrainGenerationData = _terrainGenerationData, terrainColorData = _terrainColorData }; if (_terrainGenerationData.usePregeneratedVoxelData) { jobHandle = job.Schedule(resolution * resolution * resolution, 64, voxelHandle); } else { jobHandle = job.Schedule(resolution * resolution * resolution, 64); } MarchingCubeOptimizeJob optimize = new MarchingCubeOptimizeJob() { vertices = vertices, finalVertices = finalVertices, triangles = triangles, finalTriangles = finalTriangles, colors = colors, finalColors = finalColors }; optimizeHandle = optimize.Schedule(jobHandle); if (immediate) { CompleteChunkJob(); stopwatch.Stop(); UnityEngine.Debug.Log(stopwatch.ElapsedMilliseconds); } }