static bool IsChunkOnDisk(ChunkIndex index) { return File.Exists(GetChunkFilename(index)); }
static Chunk ObtainChunk(ChunkIndex index, bool setup = false) { ChunkIndex? actualIndex = GetArrayIndex(index); Chunk chunk; if (actualIndex.HasValue && !setup) { chunk = Chunks[actualIndex.Value.X, actualIndex.Value.Y, actualIndex.Value.Z]; } else { chunk = new Chunk(index); if (IsChunkOnDisk(index)) { Setup.AddToLoad(chunk); } else { TerrainGenerator.SetChunkTerrain(chunk); Console.Write("Chunk terrain generated!"); } } return chunk; }
private static ChunkIndex? GetArrayIndex(ChunkIndex index, ChunkIndex center) { if (index.X >= center.X - Constants.World.WorldSize / 2 && index.X <= center.X + Constants.World.WorldSize / 2 && index.Y >= center.Y - Constants.World.WorldSize / 2 && index.Y <= center.Y + Constants.World.WorldSize / 2 && index.Z >= center.Z - Constants.World.WorldSize / 2 && index.Z <= center.Z + Constants.World.WorldSize / 2) { return new ChunkIndex(EuclideanModulo(index.X, Constants.World.WorldSize), EuclideanModulo(index.Y, Constants.World.WorldSize), EuclideanModulo(index.Z, Constants.World.WorldSize)); } return null; }
static string GetChunkFilename(ChunkIndex index) { return Constants.Content.Data.ChunkFilePath + index.ToString() + Constants.Content.Data.ChunkFileExtension; }
public static void UpdateCenter(ChunkIndex centerIndex) { for (int x = -Constants.World.WorldSize / 2; x <= Constants.World.WorldSize / 2; x++) { for (int y = -Constants.World.WorldSize / 2; y <= Constants.World.WorldSize / 2; y++) { for (int z = -Constants.World.WorldSize / 2; z <= Constants.World.WorldSize / 2; z++) { Chunk chunk = ObtainChunk(centerIndex + new ChunkIndex(x, y, z), true); ChunkIndex? index = GetArrayIndex(centerIndex + new ChunkIndex(x, y, z), centerIndex); Chunks[index.Value.X, index.Value.Y, index.Value.Z] = chunk; ChangeChunk(chunk); } } } CenterIndex = centerIndex; }
private static ChunkIndex? GetArrayIndex(ChunkIndex index) { return GetArrayIndex(index, CenterIndex); }
public static Chunk LoadChunk(ChunkIndex index) { Chunk returnChunk = new Chunk(index); return returnChunk; }
public static void Initialize() { InitializeThreads(); Chunks = new Chunk[Constants.World.WorldSize, Constants.World.WorldSize, Constants.World.WorldSize]; CenterIndex = new ChunkIndex(Constants.Engines.Physics.Player.Position); RenderHelp.CreateBlockData3DArray(out DataID); for (int x = -Constants.World.WorldSize / 2; x <= Constants.World.WorldSize / 2; x++) { for (int y = -Constants.World.WorldSize / 2; y <= Constants.World.WorldSize / 2; y++) { for (int z = -Constants.World.WorldSize / 2; z <= Constants.World.WorldSize / 2; z++) { Chunk chunk = ObtainChunk(CenterIndex + new ChunkIndex(x, y, z), true); ChunkIndex? index = GetArrayIndex(CenterIndex + new ChunkIndex(x, y, z)); Chunks[index.Value.X, index.Value.Y, index.Value.Z] = chunk; TerrainGenerator.SetChunkTerrain(chunk); ChangeChunk(chunk); } } } //SetupThread.Start(); }
public static Chunk GetChunk(ChunkIndex index) { ChunkIndex? arrayIndex = GetArrayIndex(index); if (!arrayIndex.HasValue) { return null; } return Chunks[arrayIndex.Value.X, arrayIndex.Value.Y, arrayIndex.Value.Z]; }
Block[, ,] Data; // Must be in the format Z Y X, or else copying to memory will be in the wrong order #endregion Fields #region Constructors public Chunk(ChunkIndex index) { Index = index; Data = new Block[Constants.World.ChunkSize, Constants.World.ChunkSize, Constants.World.ChunkSize]; }
private static int[,] GetHeightMap(ChunkIndex index) { int squareSize = (int)Math.Pow(2, Constants.Landscape.TerrainStretch); int x = (int)index.Position.X; int y = (int)index.Position.Z; int xInSquare = Mathematics.AbsModulo(x, squareSize); int yInSquare = Mathematics.AbsModulo(y, squareSize); float[,] dataPoints = new float[4, 4]; dataPoints[0, 0] = NoiseMaps.GetPerlin(x - xInSquare - squareSize, y - yInSquare - squareSize, Seed); dataPoints[0, 1] = NoiseMaps.GetPerlin(x - xInSquare - squareSize, y - yInSquare, Seed); dataPoints[0, 2] = NoiseMaps.GetPerlin(x - xInSquare - squareSize, y - yInSquare + squareSize, Seed); dataPoints[0, 3] = NoiseMaps.GetPerlin(x - xInSquare - squareSize, y - yInSquare + squareSize * 2, Seed); dataPoints[1, 0] = NoiseMaps.GetPerlin(x - xInSquare, y - yInSquare - squareSize, Seed); dataPoints[1, 1] = NoiseMaps.GetPerlin(x - xInSquare, y - yInSquare, Seed); dataPoints[1, 2] = NoiseMaps.GetPerlin(x - xInSquare, y - yInSquare + squareSize, Seed); dataPoints[1, 3] = NoiseMaps.GetPerlin(x - xInSquare, y + y - yInSquare + squareSize * 2, Seed); dataPoints[2, 0] = NoiseMaps.GetPerlin(x - xInSquare + squareSize, y - yInSquare - squareSize, Seed); dataPoints[2, 1] = NoiseMaps.GetPerlin(x - xInSquare + squareSize, y - yInSquare, Seed); dataPoints[2, 2] = NoiseMaps.GetPerlin(x - xInSquare + squareSize, y - yInSquare + squareSize, Seed); dataPoints[2, 3] = NoiseMaps.GetPerlin(x - xInSquare + squareSize, y - yInSquare + squareSize * 2, Seed); dataPoints[3, 0] = NoiseMaps.GetPerlin(x - xInSquare + squareSize * 2, y - yInSquare - squareSize, Seed); dataPoints[3, 1] = NoiseMaps.GetPerlin(x - xInSquare + squareSize * 2, y - yInSquare, Seed); dataPoints[3, 2] = NoiseMaps.GetPerlin(x - xInSquare + squareSize * 2, y - yInSquare + squareSize, Seed); dataPoints[3, 3] = NoiseMaps.GetPerlin(x - xInSquare + squareSize * 2, y - yInSquare + squareSize * 2, Seed); Interpolation.UpdateBicubicCoefficients(dataPoints); int[,] data = new int[Constants.World.ChunkSize, Constants.World.ChunkSize]; int xBlockInSquare = 0; int yBlockInSquare = 0; for (int blockX = 0; blockX < Constants.World.ChunkSize; blockX++) { for (int blockY = 0; blockY < Constants.World.ChunkSize; blockY++) { xBlockInSquare = blockX + xInSquare; yBlockInSquare = blockY + yInSquare; data[blockX, blockY] = (int)(Interpolation.Linear( NoiseMaps.GetPerlin(x + blockX, y + blockY, Seed), Interpolation.Bicubic((float)xBlockInSquare / (float)squareSize, (float)yBlockInSquare / (float)squareSize), Constants.Landscape.PerlinBicubicWeight ) * Constants.Landscape.WorldHeightAmplitude) + Constants.Landscape.WorldHeightOffset; } } return data; }