/// <summary> /// Try to assign a chunk to an unused controller. /// </summary> /// <param name="chunkLocation"></param> /// <returns>A bool for being used in Removeall, if the chunk should be removed from the wait queue.</returns> bool tryToAssignNewlyMeshedChunkToController(VoxelMeshData meshData) { if (!meshData.isEmpty) { // try to find an unused chunk controller and add it to the queue if it's valid if (getUnusedChunkController(meshData.chunkID.Coordinate, out ChunkController unusedChunkController)) { unusedChunkController.setChunkToRender(meshData); chunksToMesh.Enqueue(getDistanceToClosestFocus(meshData.chunkID), unusedChunkController); return(true); // don't drop it yet, we didn't find a chunk controller. } else { return(false); } // if the chunk isn't meshable, just drop it from the queue } else { return(true); } }
private static VoxelMeshData GetVoxelMeshFromFaces(List <VoxelFace> faces) { if (faces.Count < 1) { return(null); } List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); List <Vector2> uvs = new List <Vector2>(); List <Vector3> normals = new List <Vector3>(); int faceCount = 0; foreach (VoxelFace face in faces) { // copy the Vertex information for (int i = 0; i < 4; i++) { vertices.Add(face.vertices[i]); uvs.Add(face.uvs[i]); normals.Add(face.normals[i]); } for (int i = 0; i < 6; i++) { triangles.Add(face.triangles[i] + faceCount * 4); } faceCount++; } VoxelMeshData voxelMeshData = new VoxelMeshData(vertices, triangles, uvs, normals); return(voxelMeshData); }
void setUpTestChunk() { // Set up one chunk to load and mesh Level storage = new Level((1, 1, 1), null); Chunk.ID chunkID = new Chunk.ID(0, 0, 0); World.setActiveLevel(storage); levelManager.initializeFor(World.Current.activeLevel); World.EventSystem.subscribe( levelManager, WorldEventSystem.Channels.ChunkActivationUpdates ); // run the load job syncly BiomeMap.GenerateChunkDataFromSourceJob terrainGenJob = BiomeMap.GetTerrainGenerationJob(chunkID, storage); terrainGenJob.Execute(); // get the data from the load job Chunk newlyLoadedChunk = new Chunk(); if (terrainGenJob.solidVoxelCount[0] > 0) { newlyLoadedChunk.setVoxels( terrainGenJob.outVoxels, terrainGenJob.solidVoxelCount[0] ); } terrainGenJob.outVoxels.Dispose(); // add the loaded chunk to storage storage.chunks.Add(chunkID, newlyLoadedChunk); newlyLoadedChunk.isLoaded = true; // get the mesh gen job and run it syncly MarchingTetsMeshGenerator.MarchingTetsMeshGenJob meshGenJob = MarchingTetsMeshGenerator.GetJob(MarchingTetsMeshGenerator.GetVoxelsToMarchOver(chunkID, storage)); meshGenJob.Execute(); // set up the mesh data bool meshIsEmpty = meshGenJob.outVerticies.Length <= 0; VoxelMeshData chunkMeshData = new VoxelMeshData( chunkID, meshIsEmpty, meshGenJob.outVerticies, meshGenJob.outTriangles, meshGenJob.outColors ); // dispose of the allocated resources meshGenJob.outVerticies.Dispose(); meshGenJob.outTriangles.Dispose(); meshGenJob.outColors.Dispose(); // update the chunk data to say if it's meshed if (storage.chunks.TryGetValue(chunkID, out Chunk updatedChunk)) { updatedChunk.meshIsGenerated = true; updatedChunk.meshIsEmpty = meshIsEmpty; } /// notify the chunk manager World.EventSystem.notifyChannelOf( new MeshGenerationAperture.ChunkMeshLoadingFinishedEvent(chunkMeshData), WorldEventSystem.Channels.ChunkActivationUpdates ); // set the chunk active ActiveChunkObjectAperture.ActivateChunkObjectJob activateChunkJob = new ActiveChunkObjectAperture.ActivateChunkObjectJob(chunkID); activateChunkJob.Execute(); }
///// PUBLIC FUNCTIONS /// <summary> /// Set the chunk to render. Returns true if the data was set up /// </summary> /// <param name="chunkMeshData"></param> /// <param name="chunkLevelLocation"></param> public void setChunkToRender(VoxelMeshData chunkMeshData) { currentChunkMeshData = chunkMeshData; chunkLocation = chunkMeshData.chunkID.Coordinate; isMeshed = false; }