/// <summary> /// Creates a new voxel chunk mesher. /// </summary> /// <param name="chunkProperties">The chunk properties to handle.</param> /// <param name="greedyMesher">The greedy mesher to use.</param> internal VoxelChunkMesher(ChunkGroup chunkProperties, GreedyMesher greedyMesher) { m_ChunkProperties = chunkProperties; m_GreedyMesher = greedyMesher; m_Mesh = new ProcMesh(); m_Task = Task.Run(Remesh); }
/// <summary> /// Iterates over all blocks in the chunk, creating visual tasks as needed. /// </summary> /// <param name="properties">The chunk properties.</param> /// <param name="tasks">The task list to add to.</param> private void VisualBlockIterator(ChunkGroup properties, RemeshTaskStack taskStack) { var volume = m_ChunkSize.Volume; var blocks = properties.Blocks; for (int i = 0; i < volume; i++) { var type = m_BlockList.GetBlockType(blocks[i]); if (!type.Visible) { continue; } // TODO Make sure block type is a cube for (int j = 0; j < type.FaceCount; j++) { var material = type.Face(j).MaterialID; if (m_MaterialBuffer[material]) { continue; } m_MaterialBuffer[material] = true; taskStack.AddTask(new VisualRemeshTask(properties, material, PullMesher())); } } }
/// <summary> /// Analyses the given chunk and starts a set of remesh tasks for handling that chunk. /// This method blocks until all remesh tasks have been completed. /// </summary> /// <param name="worldContainer">The world to operate on.</param> /// <param name="chunkPos">The chunk target position.</param> internal RemeshTaskStack RemeshChunk(WorldContainer worldContainer, ChunkPosition chunkPos) { var taskStack = new RemeshTaskStack(chunkPos); var chunkGroup = new ChunkGroup(worldContainer, chunkPos); foreach (var dis in m_Distributors) { dis.CreateTasks(chunkGroup, taskStack); } return(taskStack); }
/// <summary> /// Generates the collision remesh task, as needed. /// </summary> /// <param name="properties">The chunk properties.</param> /// <param name="tasks">The task list to add to.</param> private void GenerateCollision(ChunkGroup properties, RemeshTaskStack taskStack) { int volume = m_ChunkSize.Volume; var blocks = properties.Blocks; for (int i = 0; i < volume; i++) { var type = m_BlockList.GetBlockType(blocks[i]); if (type.Solid) { taskStack.AddTask(new CollisionRemeshTask(properties, PullMesher())); return; } } }
/// <summary> /// Generates the visual remeshing tasks, as needed. /// </summary> /// <param name="properties">The chunk properties.</param> /// <param name="tasks">The task list to add to.</param> private void GenerateVisuals(ChunkGroup properties, RemeshTaskStack taskStack) { PrepareMaterialBuffer(); VisualBlockIterator(properties, taskStack); ResetMaterialBuffer(); }
/// <inheritdoc cref="IRemeshTask"/> public void CreateTasks(ChunkGroup properties, RemeshTaskStack taskStack) { GenerateVisuals(properties, taskStack); GenerateCollision(properties, taskStack); }
/// <summary> /// Checks whether or not the given quad within the check should be added to the mesh. /// </summary> /// <param name="chunkProperties">The chunk properties to read from.</param> /// <param name="pos">The block position.</param> /// <param name="side">The side of the block being checked.</param> /// <returns>True if the quad should be placed. False otherwise.</returns> protected abstract bool CanPlaceQuad(ChunkGroup chunkProperties, BlockPosition pos, int side);