Example #1
0
        private void HandleRemovalOfChunk(TerrainChunk chunk, float3 playerPosition)
        {
            if (chunk.hasBeenMarkedForRemoval)
            {
                return;
            }

            var isTooFarAway = math.distance(playerPosition, chunk.position) > chunkDrawDistance * 1.5 * TerrainChunk.CHUNK_SIZE;
            var isEmpty      = !chunk.hasSignChangeOnAnySide && !ShouldKeepEmptyChunks;

            if (!isTooFarAway && !isEmpty)
            {
                return;
            }

            // Tell the neighbours this chunk no longer exists
            foreach (var(sideIndex, side) in EnumUtil <CubeSide> .valuePairs)
            {
                if (chunk.hasNeighbourOnSide[sideIndex])
                {
                    var neighbourKey     = chunk.neighbourKeys[sideIndex];
                    var neighbour        = chunks[neighbourKey];
                    var flippedSideIndex = (int)side.Flip();

                    chunk.ClearNeighbour(sideIndex);
                    neighbour.ClearNeighbour(flippedSideIndex);
                }
            }

            if (chunk.hasSignChangeOnAnySide)
            {
                chunksWithSignChange--;
            }

            chunk.hasBeenMarkedForRemoval = true;
            chunk.CompleteJobs();
            chunk.meshObject.gameObject.SetActive(false);

            if (chunk.hasBeenDeformed)
            {
                var saveData = new ChunkSaveData {
                    fileKey  = "world",
                    chunkKey = chunk.key,
                };

                chunk.Save(saveData);
                ChunkSaveData.Save(saveData);
            }

            chunks.TryRemove(chunk.key, out _);
            chunkPool.AddItem(chunk);
        }
Example #2
0
        private TerrainChunk GetOrCreateChunkByKey(ChunkKey key)
        {
            if (chunks.TryGetValue(key, out var existingChunk))
            {
                return(existingChunk);
            }

            var chunk = chunkPool.GetItem(PoolCallbackCreateNewChunk, PoolCallbackResetChunk);

            chunk.position = (float3)key.origin * TerrainChunk.CHUNK_SIZE * voxelSize;
            chunk.key      = key;
            chunk.meshObject.gameObject.name    = $"Chunk {key.origin}";
            chunk.meshObject.transform.position = chunk.position;
            chunk.bounds = new Bounds {
                min = chunk.position,
                max = chunk.position + math.float3(chunk.size * chunk.voxelSize)
            };

            chunks.TryAdd(key, chunk);

            var loadedData            = ChunkSaveData.Load("world", key);
            var dataLoadedSuccesfully = false;

            if (loadedData != null)
            {
                dataLoadedSuccesfully = chunk.Load(loadedData);
            }

            if (!dataLoadedSuccesfully)
            {
                chunk.ScheduleGenerateDensitiesJob(noiseSettings);
            }

            // Fix neighbours
            foreach (var side in EnumUtil <CubeSide> .valuePairs)
            {
                var neighbourKey = new ChunkKey {
                    origin = GetNeighbourChunkOrigin(chunk, side.value)
                };
                if (!chunks.TryGetValue(neighbourKey, out var neighbour))
                {
                    continue;
                }

                chunk.SetNeighbour(neighbour, side);
            }

            return(chunk);
        }
Example #3
0
        public static void Save(ChunkSaveData data)
        {
            binaryFormatter ??= new BinaryFormatter();

            var filePath      = GetFilePath(data.fileKey, data.chunkKey);
            var directoryPath = Path.GetDirectoryName(filePath);

            if (directoryPath == null)
            {
                throw new Exception($"Unable to get directory path from '{filePath}'");
            }

            Directory.CreateDirectory(directoryPath);

            using var filestream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write);

            binaryFormatter.Serialize(filestream, data);
        }