public Chunk generateChunk(Chunk chunk, World world) { //samples heightnoise every SAMPLE_INTERVAL blocks and uses bilinear interpolation to fill in all the values Block[,,] blocks = chunk.blocks; float[,] heightSamples = new float[Chunk.CHUNK_SIZE / SAMPLE_INTERVAL + 1, Chunk.CHUNK_SIZE / SAMPLE_INTERVAL + 1]; //adding 1 to get one extra layer of samples right outside the chunk border for (int x = 0; x < heightSamples.GetLength(0); x++) { for (int y = 0; y < heightSamples.GetLength(1); y++) { //height function, multiplaying by sample interval so that changing that doens't change the overall shape of the terrain heightSamples[x, y] = heightOffset + heightNoise.sample(SAMPLE_INTERVAL * x + chunk.worldCoords.x, SAMPLE_INTERVAL * y + chunk.worldCoords.z, 0); } } for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { //get height for this block by interpolating int height = (int)WorldGenerator.bilinearInterpolate(new Vector2((float)(x % SAMPLE_INTERVAL) / SAMPLE_INTERVAL, (float)(z % SAMPLE_INTERVAL) / SAMPLE_INTERVAL), heightSamples[x / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL], heightSamples[x / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL + 1], heightSamples[x / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL + 1], heightSamples[x / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL]); //don't allocate the block array if no blocks will be generated if (blocks == null && (chunk.worldCoords.y <= height || chunk.worldCoords.y <= seaLevel)) { chunk.blocks = new Block[Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE]; blocks = chunk.blocks; } if (blocks != null) { for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { if (height <= seaLevel && y + chunk.worldCoords.y > height && y + chunk.worldCoords.y <= seaLevel) { blocks[x, y, z] = new Block(seaBlock); } else if (height <= seaLevel + beachDepth && y + chunk.worldCoords.y <= height && y + chunk.worldCoords.y <= seaLevel + beachDepth && y + chunk.worldCoords.y >= height - beachDepth) { blocks[x, y, z] = new Block(beachBlock); } else if (y + chunk.worldCoords.y == height) { blocks[x, y, z] = new Block(topBlock); } else if (y + chunk.worldCoords.y < height && y + chunk.worldCoords.y >= height - midDepth) { blocks[x, y, z] = new Block(midBlock); } else if (y + chunk.worldCoords.y < height) { blocks[x, y, z] = new Block(underGroundBlock); } else { blocks[x, y, z] = new Block(BlockType.empty); } } } } } return(chunk); }
public Biome selectBiome(float x, float y) { float luckyNumber = biomeSelectionNoise.sample(x, y, 0); for (int i = 0; i < selectionCount.Count; i++) { if (selectionCount[i] >= luckyNumber) { return(biomes[i]); } } return(biomes[biomes.Count - 1]); }
public Chunk generateChunk(Chunk chunk, World world) { if (chunk == null || chunk.blocks == null) { return(chunk); } float[,,] noiseSamples = new float[Chunk.CHUNK_SIZE / SAMPLE_INTERVAL + 1, Chunk.CHUNK_SIZE / SAMPLE_INTERVAL + 1, Chunk.CHUNK_SIZE / SAMPLE_INTERVAL + 1]; //adding 1 to get one extra layer of samples right outside the chunk border for (int x = 0; x < noiseSamples.GetLength(0); x++) { for (int y = 0; y < noiseSamples.GetLength(1); y++) { for (int z = 0; z < noiseSamples.GetLength(2); z++) { noiseSamples[x, y, z] = noise.sample(SAMPLE_INTERVAL * x + chunk.worldCoords.x, SAMPLE_INTERVAL * y + chunk.worldCoords.y, SAMPLE_INTERVAL * z + chunk.worldCoords.z); } } } float slope = 1.0f / (maxHeight - minHeight); for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { Vector3 blockCoords = new Vector3(chunk.worldCoords.x + x, chunk.worldCoords.y + y, chunk.worldCoords.z + z); float caveNoise = WorldGenerator.trilinearInterpolate( new Vector3((float)(x % SAMPLE_INTERVAL) / SAMPLE_INTERVAL, (float)(y % SAMPLE_INTERVAL) / SAMPLE_INTERVAL, (float)(z % SAMPLE_INTERVAL) / SAMPLE_INTERVAL), noiseSamples[x / SAMPLE_INTERVAL, y / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL], noiseSamples[x / SAMPLE_INTERVAL + 1, y / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL], noiseSamples[x / SAMPLE_INTERVAL, y / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL], noiseSamples[x / SAMPLE_INTERVAL, y / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL + 1], noiseSamples[x / SAMPLE_INTERVAL + 1, y / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL], noiseSamples[x / SAMPLE_INTERVAL, y / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL + 1], noiseSamples[x / SAMPLE_INTERVAL + 1, y / SAMPLE_INTERVAL, z / SAMPLE_INTERVAL + 1], noiseSamples[x / SAMPLE_INTERVAL + 1, y / SAMPLE_INTERVAL + 1, z / SAMPLE_INTERVAL + 1]); float scaledCaveNoise = (slope * (-blockCoords.y) + slope * maxHeight) * caveNoise; if (scaledCaveNoise > tolerance && chunk.blocks[x, y, z].type != dontReplace) { chunk.blocks[x, y, z].type = replaceWith; } } } } return(chunk); }
public Chunk generateChunk(Chunk chunk, World world) { Block[,,] blocks = chunk.blocks; for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { Vector3Int worldCoords = new Vector3Int(x + chunk.worldCoords.x, 0, z + chunk.worldCoords.z); int localSnowHeight = snowHeight + (int)snowLevelNoise.sample(worldCoords.x, worldCoords.z, 0); int snowDepth = 1 + (int)snowHeightNoise.sample(worldCoords.x, 0, worldCoords.z); int height = heightOffset + (int)heightNoise.sample(worldCoords.x, worldCoords.z, 0); if (height + snowDepth >= localSnowHeight) { height += snowDepth; } if (blocks == null && chunk.worldCoords.y <= height) { chunk.blocks = new Block[Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE]; blocks = chunk.blocks; } if (blocks != null) { for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { if (y + chunk.worldCoords.y > height) { blocks[x, y, z] = new Block(BlockType.empty); } else if (y + chunk.worldCoords.y + snowDepth >= localSnowHeight && y + chunk.worldCoords.y >= height - snowDepth) { blocks[x, y, z] = new Block(snowBlock); } else if (y + chunk.worldCoords.y < height && y + chunk.worldCoords.y >= height - surfaceDepth) { blocks[x, y, z] = new Block(surfaceBlock); } else if (y + chunk.worldCoords.y < height) { blocks[x, y, z] = new Block(underGroundBlock); } } } } } return(chunk); }