/// <summary> /// Creates a pre loaded chunk from chunk data. /// This entire function is run in a thread /// </summary> /// <param name="cData"></param> /// <returns></returns> private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk, int lod = 1) { //We create a thread safe mesh for the terrain // PreMesh terrainMesh = GenerateMarchingCubesTerrain(chunk); ChunkData[] neighbors = ChunkRegionManager.GetNeighbors(new Vec2i(chunk.X, chunk.Z)); PreMesh terrainMesh = GenerateSmoothTerrain(chunk, neighbors, lod); terrainMesh.RecalculateNormals(); Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies", Debug.CHUNK_LOADING); //Create the base pre-loaded chunk PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk); //if we have no voxel data, return just the terrain map if (chunk.VoxelData == null) { return(preChunk); } int maxHeight = 0; if (neighbors != null) { foreach (ChunkData cd in neighbors) { if (cd != null && cd.VoxelData != null) { if (maxHeight < cd.VoxelData.TotalHeight()) { maxHeight = cd.VoxelData.TotalHeight(); } } } } //If the chunk hasn't had its boundry points defined, we do it now if (!chunk.VoxelData.HasBoundryVoxels) { for (int y = 0; y < maxHeight; y++) { for (int i = 0; i < World.ChunkSize; i++) { if (neighbors[0] != null && neighbors[0].VoxelData != null) { VoxelNode node = neighbors[0].VoxelData.GetVoxelNode(i, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(i, y, World.ChunkSize, node); } } if (neighbors[2] != null && neighbors[2].VoxelData != null) { VoxelNode node = neighbors[2].VoxelData.GetVoxelNode(0, y, i); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, i, node); } } } if (neighbors[1] != null && neighbors[1].VoxelData != null) { VoxelNode node = neighbors[1].VoxelData.GetVoxelNode(0, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, World.ChunkSize, node); } } } chunk.VoxelData.HasBoundryVoxels = true; } //Next we generate all relevent voxel meshes foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } //If the chunk has this type of voxel in it if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb)) { //Clear all lists to prepair CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); CurrentUVs.Clear(); //Generate the voxel mesh //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); PreMesh voxelMesh = new PreMesh(); voxelMesh.Verticies = CurrentVerticies.ToArray(); voxelMesh.Triangles = CurrentTriangles.ToArray(); voxelMesh.UV = CreateUV(voxelMesh); voxelMesh.RecalculateNormals(); //Add it the the pre loaded chunk preChunk.VoxelMesh.Add(v, voxelMesh); } } /* * if(chunk.WorldObjects != null) * { * * lock (ObjectsToLoadLock) * { * Debug.Log("[ChunkLoader] Chunk " + chunk.X + "," + chunk.Z + " has " + chunk.WorldObjects.Count + " objects to load", Debug.CHUNK_LOADING); * ObjectsToLoad.AddRange(chunk.WorldObjects); * } * * }*/ return(preChunk); }