/// <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(ChunkProperties 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(ChunkProperties properties, RemeshTaskStack taskStack) { var volume = m_BlockWorld.ChunkSize.Volume; var blocks = properties.Blocks; for (int i = 0; i < volume; i++) { var type = blocks[i]; if (!type.IsVisible) { continue; } var faces = type.Faces; for (int j = 0; j < 6; j++) { var material = faces[j].MaterialID; if (m_MaterialBuffer[material]) { continue; } m_MaterialBuffer[material] = true; taskStack.AddTask(new VisualRemeshTask(properties, material, PullMesher())); } } }
/// <summary> /// Returns a chunk properties object back to the pool after it is finished being used. /// </summary> /// <param name="props">The properties object to return.</param> internal void Return(ChunkProperties props) { if (m_Pool.Count >= MAX_OBJECTs) { return; } m_Pool.Add(props); }
/// <summary> /// Waits for all tasks to finish before returning. /// </summary> internal ChunkProperties Finish() { foreach (var task in m_Tasks) { task.Finish(); } var props = m_ChunkProperties; m_ChunkProperties = null; // Clear memory reference return(props); }
/// <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(ChunkProperties properties, RemeshTaskStack taskStack) { int volume = m_BlockWorld.ChunkSize.Volume; for (int i = 0; i < volume; i++) { var type = properties.Blocks[i]; if (type.IsSolid) { taskStack.AddTask(new CollisionRemeshTask(properties, PullMesher())); return; } } }
/// <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(ChunkProperties chunkProperties, BlockPosition pos, int side);
/// <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(ChunkProperties properties, RemeshTaskStack taskStack) { PrepareMaterialBuffer(); VisualBlockIterator(properties, taskStack); ResetMaterialBuffer(); }
/// <inheritdoc cref="IRemeshTask"/> public void CreateTasks(ChunkProperties properties, RemeshTaskStack taskStack) { GenerateVisuals(properties, taskStack); GenerateCollision(properties, taskStack); }
/// <summary> /// Creates a new remesh task stack. /// </summary> /// <param name="chunkProperties">The chunk properties remeshed.</param> internal RemeshTaskStack(ChunkProperties chunkProperties) { m_ChunkProperties = chunkProperties; ChunkPosition = chunkProperties.ChunkPosition; }