public override void GenerateDataForChunkUnchecked(int3 chunkCoordinate, VoxelDataVolume <byte> existingData)
        {
            int3 chunkWorldOrigin = chunkCoordinate * VoxelWorld.WorldSettings.ChunkSize;
            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = VoxelWorld.VoxelDataGenerator.GenerateVoxelData(chunkWorldOrigin, existingData);

            _generationJobHandles.Add(chunkCoordinate, jobHandleWithData);
        }
예제 #2
0
 /// <summary>
 /// Sets the job handle for a chunk coordinate
 /// </summary>
 /// <param name="generationJobHandle">The job handle with data</param>
 /// <param name="chunkCoordinate">The coordinate of the chunk to set the job handle for</param>
 public void SetVoxelDataJobHandle(JobHandleWithData <IVoxelDataGenerationJob> generationJobHandle, int3 chunkCoordinate)
 {
     if (!_generationJobHandles.ContainsKey(chunkCoordinate))
     {
         _generationJobHandles.Add(chunkCoordinate, generationJobHandle);
     }
 }
        /// <summary>
        /// Starts a mesh generation job
        /// </summary>
        /// <param name="voxelDataStore">The store where to retrieve the voxel data from</param>
        /// <param name="chunkCoordinate">The coordinate of the chunk that will be generated</param>
        /// <returns>The job handle and the actual mesh generation job</returns>
        public override JobHandleWithData <IMesherJob> CreateMesh(VoxelDataStore voxelDataStore, int3 chunkCoordinate)
        {
            if (!voxelDataStore.TryGetVoxelDataChunk(chunkCoordinate, out VoxelDataVolume boundsVoxelData))
            {
                return(null);
            }

            NativeCounter vertexCountCounter = new NativeCounter(Allocator.TempJob);

            int voxelCount = (boundsVoxelData.Width - 1) * (boundsVoxelData.Height - 1) * (boundsVoxelData.Depth - 1);
            int maxLength  = 15 * voxelCount;

            NativeArray <MeshingVertexData> outputVertices  = new NativeArray <MeshingVertexData>(maxLength, Allocator.TempJob);
            NativeArray <ushort>            outputTriangles = new NativeArray <ushort>(maxLength, Allocator.TempJob);

            MarchingCubesJob marchingCubesJob = new MarchingCubesJob
            {
                VoxelData          = boundsVoxelData,
                Isolevel           = Isolevel,
                VertexCountCounter = vertexCountCounter,

                OutputVertices  = outputVertices,
                OutputTriangles = outputTriangles
            };

            JobHandle jobHandle = marchingCubesJob.Schedule(voxelCount, 128);

            JobHandleWithData <IMesherJob> jobHandleWithData = new JobHandleWithData <IMesherJob>();

            jobHandleWithData.JobHandle = jobHandle;
            jobHandleWithData.JobData   = marchingCubesJob;

            return(jobHandleWithData);
        }
        /// <summary>
        /// Moves a chunk to a different coordinate if a chunk doesn't already exist there
        /// </summary>
        /// <param name="fromCoordinate">The coordinate of the chunk to move</param>
        /// <param name="toCoordinate">The coordinate where the chunk should be moved</param>
        private void MoveChunk(int3 fromCoordinate, int3 toCoordinate)
        {
            if (!VoxelWorld.ChunkStore.TryGetChunkAtCoordinate(fromCoordinate, out Chunk chunk))
            {
                Debug.LogWarning($"No chunk at {fromCoordinate.ToString()}, exiting the function");
                return;
            }

            if (VoxelWorld.ChunkStore.DoesChunkExistAtCoordinate(toCoordinate))
            {
                Debug.LogWarning($"A chunk already exists at {toCoordinate.ToString()}, exiting the function");
                return;
            }

            Bounds generationBounds = BoundsUtilities.GetChunkBounds(toCoordinate, VoxelWorld.WorldSettings.ChunkSize);
            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = VoxelWorld.VoxelDataGenerator.GenerateVoxelData(generationBounds);

            jobHandleWithData.JobHandle.Complete();
            VoxelWorld.VoxelDataStore.SetVoxelDataChunk(jobHandleWithData.JobData.OutputVoxelData, toCoordinate);

            VoxelWorld.ChunkStore.RemoveChunk(fromCoordinate);

            chunk.Initialize(toCoordinate, VoxelWorld);
            VoxelWorld.ChunkStore.AddChunk(chunk);
        }
예제 #5
0
        /// <summary>
        /// Loads a chunk to a specific coordinate
        /// </summary>
        /// <param name="chunkCoordinate">The coordinate of the chunk to load</param>
        /// <returns>The newly loaded chunk</returns>
        public Chunk LoadChunkToCoordinate(int3 chunkCoordinate)
        {
            int3  worldPosition = chunkCoordinate * VoxelWorld.WorldSettings.ChunkSize;
            Chunk chunk         = Instantiate(VoxelWorld.WorldSettings.ChunkPrefab, worldPosition.ToVectorInt(), Quaternion.identity);

            Bounds chunkBounds = BoundsUtilities.GetChunkBounds(chunkCoordinate, VoxelWorld.WorldSettings.ChunkSize);
            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = VoxelWorld.VoxelDataGenerator.GenerateVoxelData(chunkBounds);

            VoxelWorld.VoxelDataStore.SetVoxelDataJobHandle(jobHandleWithData, chunkCoordinate);

            chunk.Initialize(chunkCoordinate, VoxelWorld);

            VoxelWorld.ChunkStore.AddChunk(chunk);

            return(chunk);
        }
예제 #6
0
        /// <summary>
        /// Forces the regeneration of the mesh
        /// </summary>
        public void GenerateMeshImmediate(ChunkProperties chunkProperties)
        {
            JobHandleWithData <IMesherJob> jobHandleWithData = VoxelWorld.VoxelMesher.CreateMesh(VoxelWorld.VoxelDataStore, VoxelWorld.VoxelColorStore, chunkProperties.ChunkCoordinate);

            if (jobHandleWithData == null)
            {
                return;
            }

            IMesherJob job = jobHandleWithData.JobData;

            Mesh mesh = new Mesh();
            SubMeshDescriptor subMesh = new SubMeshDescriptor(0, 0);

            jobHandleWithData.JobHandle.Complete();

            int vertexCount = job.VertexCountCounter.Count * 3;

            job.VertexCountCounter.Dispose();

            mesh.SetVertexBufferParams(vertexCount, MeshingVertexData.VertexBufferMemoryLayout);
            mesh.SetIndexBufferParams(vertexCount, IndexFormat.UInt16);

            mesh.SetVertexBufferData(job.OutputVertices, 0, 0, vertexCount, 0, MeshUpdateFlags.DontValidateIndices);
            mesh.SetIndexBufferData(job.OutputTriangles, 0, 0, vertexCount, MeshUpdateFlags.DontValidateIndices);

            job.OutputVertices.Dispose();
            job.OutputTriangles.Dispose();

            mesh.subMeshCount  = 1;
            subMesh.indexCount = vertexCount;
            mesh.SetSubMesh(0, subMesh);

            mesh.RecalculateBounds();

            chunkProperties.MeshFilter.sharedMesh   = mesh;
            chunkProperties.MeshCollider.sharedMesh = mesh;

            chunkProperties.MeshCollider.enabled = true;
            chunkProperties.MeshRenderer.enabled = true;

            chunkProperties.HasChanges = false;

            chunkProperties.IsMeshGenerated = true;
        }
예제 #7
0
        /// <summary>
        /// Starts generating the voxel data for a specified volume
        /// </summary>
        /// <param name="bounds">The volume to generate the voxel data for</param>
        /// <param name="allocator">The allocator for the new <see cref="VoxelDataVolume"/></param>
        /// <returns>The job handle and the voxel data generation job</returns>
        public override JobHandleWithData <IVoxelDataGenerationJob> GenerateVoxelData(Bounds bounds, Allocator allocator)
        {
            VoxelDataVolume voxelData = new VoxelDataVolume(bounds.size.ToInt3(), allocator);
            ProceduralTerrainVoxelDataCalculationJob job = new ProceduralTerrainVoxelDataCalculationJob
            {
                WorldPositionOffset       = bounds.min.ToInt3(),
                OutputVoxelData           = voxelData,
                ProceduralTerrainSettings = proceduralTerrainSettings
            };

            JobHandle jobHandle = job.Schedule(voxelData.Length, 256);

            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = new JobHandleWithData <IVoxelDataGenerationJob>();

            jobHandleWithData.JobHandle = jobHandle;
            jobHandleWithData.JobData   = job;

            return(jobHandleWithData);
        }
        /// <inheritdoc/>
        public override JobHandleWithData <IVoxelDataGenerationJob> GenerateVoxelData(int3 worldSpaceOrigin, VoxelDataVolume <byte> outputVoxelDataArray)
        {
            ProceduralTerrainVoxelDataCalculationJob job = new ProceduralTerrainVoxelDataCalculationJob
            {
                WorldPositionOffset       = worldSpaceOrigin,
                OutputVoxelData           = outputVoxelDataArray,
                ProceduralTerrainSettings = proceduralTerrainSettings
            };

            JobHandle jobHandle = job.Schedule();

            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = new JobHandleWithData <IVoxelDataGenerationJob>
            {
                JobHandle = jobHandle,
                JobData   = job
            };

            return(jobHandleWithData);
        }
예제 #9
0
        /// <inheritdoc/>
        public override JobHandleWithData <IMesherJob> CreateMesh(VoxelDataStore voxelDataStore, VoxelColorStore voxelColorStore, int3 chunkCoordinate)
        {
            if (!voxelDataStore.TryGetDataChunk(chunkCoordinate, out VoxelDataVolume <byte> boundsVoxelData))
            {
                return(null);
            }

            if (!voxelColorStore.TryGetDataChunk(chunkCoordinate, out VoxelDataVolume <Color32> boundsVoxelColors))
            {
                return(null);
            }

            NativeCounter vertexCountCounter = new NativeCounter(Allocator.TempJob);

            int voxelCount = VoxelWorld.WorldSettings.ChunkSize.x * VoxelWorld.WorldSettings.ChunkSize.y * VoxelWorld.WorldSettings.ChunkSize.z;
            int maxLength  = 15 * voxelCount;

            NativeArray <MeshingVertexData> outputVertices  = new NativeArray <MeshingVertexData>(maxLength, Allocator.TempJob);
            NativeArray <ushort>            outputTriangles = new NativeArray <ushort>(maxLength, Allocator.TempJob);

            MarchingCubesJob marchingCubesJob = new MarchingCubesJob
            {
                VoxelData          = boundsVoxelData,
                VoxelColors        = boundsVoxelColors,
                Isolevel           = Isolevel,
                VertexCountCounter = vertexCountCounter,

                OutputVertices  = outputVertices,
                OutputTriangles = outputTriangles
            };

            JobHandle jobHandle = marchingCubesJob.Schedule();

            JobHandleWithData <IMesherJob> jobHandleWithData = new JobHandleWithData <IMesherJob>
            {
                JobHandle = jobHandle,
                JobData   = marchingCubesJob
            };

            return(jobHandleWithData);
        }
예제 #10
0
        /// <inheritdoc/>
        public override JobHandleWithData <IVoxelDataGenerationJob> GenerateVoxelData(int3 worldSpaceOrigin, VoxelDataVolume <byte> outputVoxelDataArray)
        {
            HeightmapTerrainVoxelDataCalculationJob job = new HeightmapTerrainVoxelDataCalculationJob
            {
                WorldPositionOffset = worldSpaceOrigin,
                OutputVoxelData     = outputVoxelDataArray,
                HeightmapData       = heightmapWorldGenerator.HeightmapTerrainSettings.HeightmapData,
                HeightmapWidth      = heightmapWorldGenerator.HeightmapTerrainSettings.Width,
                HeightmapHeight     = heightmapWorldGenerator.HeightmapTerrainSettings.Height,
                Amplitude           = heightmapWorldGenerator.HeightmapTerrainSettings.Amplitude,
                HeightOffset        = heightmapWorldGenerator.HeightmapTerrainSettings.HeightOffset
            };

            JobHandle jobHandle = job.Schedule();

            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = new JobHandleWithData <IVoxelDataGenerationJob>
            {
                JobHandle = jobHandle,
                JobData   = job
            };

            return(jobHandleWithData);
        }
예제 #11
0
        /// <summary>
        /// Starts generating the voxel data for a specified volume
        /// </summary>
        /// <param name="bounds">The volume to generate the voxel data for</param>
        /// <param name="allocator">The allocator for the new <see cref="VoxelDataVolume"/></param>
        /// <returns>The job handle and the voxel data generation job</returns>
        public override JobHandleWithData <IVoxelDataGenerationJob> GenerateVoxelData(Bounds bounds, Allocator allocator)
        {
            VoxelDataVolume voxelData = new VoxelDataVolume(bounds.size.ToInt3(), allocator);

            HeightmapTerrainVoxelDataCalculationJob job = new HeightmapTerrainVoxelDataCalculationJob
            {
                WorldPositionOffset = bounds.min.ToInt3(),
                OutputVoxelData     = voxelData,
                HeightmapData       = heightmapWorldGenerator.HeightmapTerrainSettings.HeightmapData,
                HeightmapWidth      = heightmapWorldGenerator.HeightmapTerrainSettings.Width,
                HeightmapHeight     = heightmapWorldGenerator.HeightmapTerrainSettings.Height,
                Amplitude           = heightmapWorldGenerator.HeightmapTerrainSettings.Amplitude,
                HeightOffset        = heightmapWorldGenerator.HeightmapTerrainSettings.HeightOffset
            };

            JobHandle jobHandle = job.Schedule(voxelData.Length, 256);

            JobHandleWithData <IVoxelDataGenerationJob> jobHandleWithData = new JobHandleWithData <IVoxelDataGenerationJob>();

            jobHandleWithData.JobHandle = jobHandle;
            jobHandleWithData.JobData   = job;

            return(jobHandleWithData);
        }