private void SetBiome() { switch (ConfigurationData.biome) { case WorldBiome.DEFAULT: biome = biomes[0]; break; case WorldBiome.FOREST: biome = biomes[1]; break; case WorldBiome.MOUNTAINS: biome = biomes[2]; break; case WorldBiome.DESERT: biome = biomes[3]; break; case WorldBiome.TAIGA: biome = biomes[4]; break; default: biome = biomes[0]; break; } }
private int GetTerrainHeight(Vector2Int pos) { BiomeAttributes biome = world.WorldAttributes.BiomeAttributes[world.Bioms[pos.x, pos.y]]; int terrainHeight = biome.SolidGroundHeight; for (int i = 0; i < biome.OctavesNumber; ++i) { terrainHeight += Mathf.FloorToInt((1 / Mathf.Pow(2, i)) * biome.BiomeHeight * PerlinNoise.Get2DPerlin(world, pos, i, biome.BiomeScale * Mathf.Pow(2, i))); } return(terrainHeight); }
public void AddBiome(BiomeAttributes biome) { if (m_biomes.TryGetValue(biome, out BiomePresence presence)) { presence.Count++; } else { m_biomes.Add(biome, new BiomePresence()); } recalculatePresence(); }
private void AddTree(Vector2Int pos) { BiomeAttributes biome = world.WorldAttributes.BiomeAttributes[world.Bioms[pos.x, pos.y]]; int height = Random.Range(biome.TreeMinHeight, biome.TreeMaxHeight); Vector2Int ChunkCoord = world.GetChunkCoord(pos); Vector2Int InChunkCoord = world.GetInChunkCoord(pos); for (int y = heightMap[pos.x, pos.y] + 1; y <= heightMap[pos.x, pos.y] + height; ++y) { world.Chunks[ChunkCoord.x, ChunkCoord.y].Voxels[InChunkCoord.x, y, InChunkCoord.y] = 7; } AddComa(new Vector3Int(pos.x, heightMap[pos.x, pos.y] + height, pos.y), Mathf.RoundToInt(biome.ComaRadius * ((float)height / biome.TreeMaxHeight))); }
public void MakeBiome() { BiomeAttributes biome = new BiomeAttributes(); if (!(scale.text == "" || scale.text == null)) { biome.terrainScale = float.Parse(scale.text) / 100; } if (!(height.text == "" || height.text == null)) { biome.solidGroundHeight = int.Parse(height.text); } if (!(height.text == "" || height.text == null)) { biome.terrainHeight = int.Parse(height.text); } biome.placeMajorFlora = false; biome.offset = Random.Range(0, 10000); biome.surfaceBlock = (byte)((byte)surfaceBlock.value + 1); biome.subSurfaceBlock = 5; Lode lode = new Lode(); lode.blockID = 5; lode.minHeight = 0; lode.maxHeight = 0; lode.scale = 0; lode.threshold = 0; lode.noiseOffset = 0; lode.nodeName = ""; biome.lodes = new Lode[1]; biome.lodes[0] = lode; for (int i = 0; i < world.biomes.Length; i++) { world.biomes[i] = biome; } mainMenu._GenerateWorld(); Back(); }
public void BuildHeight(INoise noise) { //Build the chunk blocks for (int x = 0; x < ChunkSizeX; x++) { for (int z = 0; z < ChunkSizeZ; z++) { BiomeAttributes biome = m_owner.GetBiome(x, z); for (int y = 0; y < ChunkSizeY; y++) { //Vector3 pos = ; int worldX = (int)(x + m_gameObject.transform.position.x); int worldY = (int)(y + m_gameObject.transform.position.y); int worldZ = (int)(z + m_gameObject.transform.position.z); float value = noise.Compute(worldX, worldY, worldZ); //TODO: Apply the noise and the biome if (y < value) { Blocks[x, y, z] = new Block( biome.Block, new Vector3(x, y, z), m_owner, this); } else { Blocks[x, y, z] = Block.Empty( new Vector3(x, y, z), m_owner, this); } } } } State = ChunkState.Draw; }
private void AddSoilInColumn(Vector2Int pos, BiomeAttributes biome) { Vector2Int ChunkCoord = world.GetChunkCoord(pos); Vector2Int InChunkCoord = world.GetInChunkCoord(pos); int y; int terrainHeight = heightMap[pos.x, pos.y]; if (terrainHeight >= world.WorldAttributes.ChunkHeight || terrainHeight < 0) { Debug.Log(pos.x + " " + pos.y + " " + heightMap[pos.x, pos.y]); } world.Chunks[ChunkCoord.x, ChunkCoord.y].Voxels[InChunkCoord.x, terrainHeight, InChunkCoord.y] = biome.MainVoxel; int groundDepth = UnityEngine.Random.Range(biome.GroundDepthMin, biome.GroundDepthMax + 1); for (y = heightMap[pos.x, pos.y] - 1; y > heightMap[pos.x, pos.y] - groundDepth && y > 0; --y) { world.Chunks[ChunkCoord.x, ChunkCoord.y].Voxels[InChunkCoord.x, y, InChunkCoord.y] = biome.SecondVoxel; } }
// 用實際座標取得生態圈的方塊 public BlockType GetInitialVoxel(Vector3s pos) { int yPos = Mathf.FloorToInt(pos.y); /* 不變規則 */ // 超出世界回傳空氣 if (!IsVoxelInWorld(pos)) { return(BlockType.Air); } // 達到世界底部回傳基岩 if (yPos == 0) { return(BlockType.Bedrock); } /* 生態圈選擇規則 */ int solidGroundHeight = 42; float sumOfHeights = 0f; int count = 0; float strongestWeight = 0f; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); // 檢查哪個生態圈的加權值 (Perlin雜訊值) 較高 if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; } // 計算生態圈的高度 (雜訊值 * 設定高度) float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biomes[i].terrainScale) * weight; // 如果高度有效那麼加進平均 if (height > 0) { sumOfHeights += height; count++; } } // 設定最高加權值的生態圈 BiomeAttributes biome = biomes[strongestBiomeIndex]; // 生態圈平均高度 sumOfHeights /= count; int terrainHeight = Mathf.FloorToInt(sumOfHeights + solidGroundHeight); /* 生態圈地表規則 */ BlockType voxelValue = 0; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return(BlockType.Air); } else { voxelValue = BlockType.Stone; } /* 生態圈內部礦物規則 */ if (voxelValue == BlockType.Stone) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(sv(pos), lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } /* 生態圈表面植被規則 */ if (yPos == terrainHeight && biome.placeMajorFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraZoneScale) > biome.majorFloraZoneThreshold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraPlacementScale) > biome.majorFloraPlacementThreshold) { modifications.Enqueue(Structure.GenerateMajorFlora(biome.majorFloraIndex, sv(pos), biome.minHeight, biome.maxHeight)); } } } return(voxelValue); }
//World Algorithm public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); //IMMUTABLE PASS //If outside world, return air if (!IsVoxelInWorld(pos)) //Making Chunk empty { return(0); } //If bottom block of chunk, return bedrock if (yPos == 0) { return(1); } //BIOME SELECTION PASS int solidGroundHeight = 42; float sumOfHeight = 0f; int count = 0; float strongestWeight = 0f; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); //Keep track of which weight is strongest if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; } //Get the height of the terrain (for the current biome) and multiply it by its weight float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biomes[i].terrainScale) * weight; //If the height value if greater 0 add it to the sum of heights if (height > 0) { sumOfHeight += height; count++; } } //Set biome to the one with the strongest weight BiomeAttributes biome = biomes[strongestBiomeIndex]; //Get the average of the heights sumOfHeight /= count; int terrainHeight = Mathf.FloorToInt(sumOfHeight + solidGroundHeight); //BASIC TERRAIN PASS byte voxelValue = 6; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return(0); } else { voxelValue = 2; } //SECOND PASS if (voxelValue == 2) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } //TREE PASS if (yPos == terrainHeight && biome.placeMajorFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraZoneScale) > biome.majorFloraZoneThreshold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraPlacementScale) > biome.majorFloraPlacementThreshold) { modifications.Enqueue(Structure.GenerateMajorFlora(biome.majorFloraIndex, pos, biome.minHeight, biome.maxHeight)); } } } return(voxelValue); }
public byte GenerateVoxel(int x, int y, int z) { /* IMMUTABLE PASS */ //if(y==0) return 1; //return 0; // If outside world, return air. //IsVoxelInWorld(pos) if (y < 0 || y >= VoxelData.ChunkHeight) { return(0); } // If bottom block of chunk, return bedrock. if (y == 0) { return(1); } /* BIOME SELECTION PASS*/ int solidGroundHeight = 42; float sumOfHeights = 0f; int count = 0; float strongestHeight = 0f; float strongestWeight = 0f; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(x, z, biomes[i].offset, biomes[i].scale); // Get the height of the terrain (for the current biome) and multiply it by its weight. float height = biomes[i].terrainHeight * Noise.Get2DPerlin(x, z, 0, biomes[i].terrainScale) * weight; // Keep track of which weight is strongest. if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; strongestHeight = height; } // If the height value is greater 0 add it to the sum of heights. if (height > 0) { sumOfHeights += height; count++; } } // Set biome to the one with the strongest weight. BiomeAttributes biome = biomes[strongestBiomeIndex]; // Get the average of the heights. sumOfHeights /= count; sumOfHeights = sumOfHeights * 3 / 4 + strongestHeight * 1 / 4; int terrainHeight = (int)(sumOfHeights + solidGroundHeight); //terrainHeight = (int)(sumOfHeights/4 + solidGroundHeight); //BiomeAttributes biome = biomes[index]; /* BASIC TERRAIN PASS */ byte voxelValue = 0; if (y == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (y < terrainHeight && y > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (y > terrainHeight) { return(0); } else { voxelValue = 2; } /* SECOND PASS */ if (voxelValue == 2) { foreach (Lode lode in biome.lodes) { if (y > lode.minHeight && y < lode.maxHeight) { if (Noise.Get3DPerlin(x, y, z, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } /* TREE PASS */ //if(false) if (y == terrainHeight && biome.placeMajorFlora) { if (Noise.Get2DPerlin(x, z, 0, biome.majorFloraZoneScale) > biome.majorFloraZoneThreshold) { //voxelValue = 6; if (Noise.Get2DPerlin(x, z, 0, biome.majorFloraPlacementScale) > biome.majorFloraPlacementThreshold) { //voxelValue = 12; lock (modifications) { //Structure.GenerateMajorFlora(this, biome.majorFloraIndex, x, y, z, biome.minHeight, biome.maxHeight); switch (biome.majorFloraIndex) { //default: case 0: { voxelValue = 10; int height = (int)(biome.maxHeight * Noise.Get2DPerlin(x, z, 250f, 3f)); if (height < biome.minHeight) { height = biome.minHeight; } //height = 50; int baseY = y + height - 2; new BoxPainter(this, x - 2, baseY, z - 2, 4, 0, 4, 11); new BoxPainter(this, x - 2, baseY + 1, z - 2, 4, 0, 4, 11); new BoxPainter(this, x - 1, baseY + 2, z - 1, 2, 0, 2, 11); new BoxPainter(this, x - 1, baseY + 3, z - 1, 2, 0, 2, 11, 1); BoxPainter trunk = new BoxPainter(this, x, y + 1, z, 0, height - 1, 0, 6); //BoxPainter MainLeaves = new BoxPainter(this, x-1, y+height, z-1, 3, 4, 3, 11); } break; case 1: { int height = (int)(biome.maxHeight * Noise.Get2DPerlin(x, z, 23456f, 2f)); if (height < biome.minHeight) { height = biome.minHeight; } BoxPainter trunk = new BoxPainter(this, x, y, z, 0, height, 0, 12); } break; } } } } } return(voxelValue); }
public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); if (!IsVoxelInWorld(pos)) {//if outside world return air return((byte)BlockTypeEnum.Air); } if (yPos == 0) {//if bottom return bedrock return((byte)BlockTypeEnum.Bedrock); } //biome selection pass float sumOfHeights = 0f; int count = 0; float strongestWeight = 0; int strongestWeightIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); //get srotger biome if (weight > strongestWeight) { strongestWeight = weight; strongestWeightIndex = i; } //get terrain height float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.y), 0, biomes[i].terrainScale) * weight; if (height > 0) { sumOfHeights += height; count++; } } //set biome BiomeAttributes biome = biomes[strongestWeightIndex]; //get avrage sumOfHeights /= count; int terrainHeight = Mathf.FloorToInt(sumOfHeights + solideGroundHeight); //basic terrain BlockTypeEnum voxelValue = BlockTypeEnum.Stone; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return((byte)BlockTypeEnum.Air); } //second pass if (voxelValue == BlockTypeEnum.Stone) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.BlockType; } } } } //trees if (yPos == terrainHeight && biome.placeMajorFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraZoneScale) > biome.majorFloraZoneThreshold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraPlacementScale) > biome.majorFloraPlacementThreshold) { modifications.Enqueue(Structure.GenerateMajorFlora(biome.floraType, pos, biome.minHeight, biome.maxHeight)); } } } return((byte)voxelValue); }
// Generate main terrain public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); // IMMUTABLE PASS if (!IsVoxelInWorld(pos)) { return(0); } // If bottom, return bedrock if (yPos == 0) { return(1); } // BIOME SELECTION PASS int index = 0; float value = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 142124, 0.05f); float prob_off = 0; float hold_terrainHeight = 0; float hold_terrainScale = 0; float hold_solidGroundHeight = 0; for (int i = 0; i < biomes.Length; i++) { prob_off += biomes[i].biomeProbability; if (Math.Abs(value - prob_off) < 0.05 && Math.Abs(prob_off - 1.0f) > 0.05) { if (value < prob_off && index + 1 != biomes.Length) { float distance = (prob_off - value) / 0.05f; float distance2 = 1.0f - distance; hold_terrainHeight = (biomes[i].terrainHeight * distance + biomes[i + 1].terrainHeight * distance2); hold_solidGroundHeight = (biomes[i].solidGroundHeight * distance + biomes[i + 1].solidGroundHeight * distance2); hold_terrainScale = (biomes[i].terrainScale * distance + biomes[i + 1].terrainScale * distance2); index = i; break; } else { float distance = (value - prob_off) / 0.05f; float distance2 = 1.0f - distance; hold_terrainHeight = (biomes[i + 1].terrainHeight * distance + biomes[i].terrainHeight * distance2); hold_solidGroundHeight = (biomes[i + 1].solidGroundHeight * distance + biomes[i].solidGroundHeight * distance2); hold_terrainScale = (biomes[i + 1].terrainScale * distance + biomes[i].terrainScale * distance2); index = i + 1; break; } } if (value <= prob_off) { hold_terrainHeight = biomes[i].terrainHeight; hold_solidGroundHeight = biomes[i].solidGroundHeight; hold_terrainScale = biomes[i].terrainScale; index = i; break; } } BiomeAttributes biome = biomes[index]; // BASIC TERRAIN PASS int terrainHeight = Mathf.FloorToInt(Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.terrainScale) * biome.terrainHeight) + (int)hold_solidGroundHeight; byte voxelValue = 0; if (yPos == terrainHeight) { if (yPos >= (87 + rnd.Next(-1, 1))) { // So high up we get snow voxelValue = biome.highLevelBlock; } else { voxelValue = biome.normalLevelBlock; } } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.littleBelowNormalBlock; } else if (yPos > terrainHeight) { // I don't wanna use this anymore because i want sky-islands } else { float perlin3dvalue = PerlinNoise3D(pos.x, pos.y, pos.z); if (perlin3dvalue > 0.6f) { voxelValue = 0; } else { voxelValue = 2; } } // SECOND PASS if (voxelValue == 2) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } // Make biome specific structures. // TREE PASS if (yPos == terrainHeight && biome.biomeName == "Plain") { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treeZoneScale) > biome.treeZoneThreshold) { Queue <VoxelMod> hold_queue = new Queue <VoxelMod>(); // Set voxelValuie = 1, so see what the area will be for the trees //voxelValue = 1; if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treePlacementScale) > biome.treePlacementThreshold) { //voxelValue = 5; int height = rnd.Next(biome.minTreeHeight, biome.maxTreeHeight); for (int i = 1; i <= height; i++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x, pos.y + i, pos.z), 6)); } for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { for (int z = -1; z <= 2; z++) { if (i == 0 && j == 0 && z <= 0) { continue; } hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + height + z, pos.z + j), 7)); } } } modifications.Enqueue(hold_queue); } } } // Make cactus if (yPos == terrainHeight && biome.biomeName == "Desert") { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, 0.99f) > 0.5f) { Queue <VoxelMod> hold_queue = new Queue <VoxelMod>(); // Set voxelValuie = 1, so see what the area will be for the trees if (rnd.Next(1, 80) == 1) { //voxelValue = 5; int height = rnd.Next(3, 4); for (int i = 1; i <= height; i++) { if (i == height) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x, pos.y + i, pos.z), 15)); } else { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x, pos.y + i, pos.z), 14)); } } modifications.Enqueue(hold_queue); } } } // Make pyramid in desert if (yPos == terrainHeight && biome.biomeName == "Desert") { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 570, biome.treeZoneScale) > 0.7) { Queue <VoxelMod> hold_queue = new Queue <VoxelMod>(); // Set voxelValuie = 1, so see what the area will be for the houses //voxelValue = 1; if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treePlacementScale) > 0.95) { //voxelValue = 5; int size = 2 * rnd.Next(5, 10); for (int i = 1; i <= size; i++) { for (int j = 1; j <= size; j++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y, pos.z + j), 5)); } } for (int z = 1; z <= size / 2; z++) { for (int j = 1 + (z - 1); j <= (size - (z - 1)); j++) { for (int i = 1 + (z - 1); i <= (size - (z - 1)); i++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + z, pos.z + j), 16)); } } } modifications.Enqueue(hold_queue); } } } // Make houses if (yPos == terrainHeight && biome.biomeName == "Plain") { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 570, biome.treeZoneScale) > 0.7) { Queue <VoxelMod> hold_queue = new Queue <VoxelMod>(); // Set voxelValuie = 1, so see what the area will be for the houses //voxelValue = 1; if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treePlacementScale) > 0.92) { //voxelValue = 5; // Clear everything inside the house so there isnt any dirt and shit // Doesn't actually work, first generate the map then do the addianl additions for (int i = 2; i <= 4; i++) { for (int j = 2; j <= 4; j++) { for (int z = 2; z <= 4; z++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + z, pos.z + j), 0)); } } } // Make floor for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y, pos.z + j), 13)); } } // Make the dirt underneath so its even for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { for (int z = -1; z >= -3; z--) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + z, pos.z + j), 4)); } } } // Make around the house for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { int counter = 0; if (i != 1 && i != 5) { counter += 1; } if (j != 1 && j != 5) { counter += 1; } if (counter == 2) { continue; } for (int z = 1; z <= 4; z++) { if (i == 3 && j == 1 && z <= 2) { continue; } hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + z, pos.z + j), 13)); } } } // Make the roof for (int i = 2; i <= 4; i++) { for (int j = 2; j <= 4; j++) { hold_queue.Enqueue(new VoxelMod(new Vector3(pos.x + i, pos.y + 4, pos.z + j), 13)); } } modifications.Enqueue(hold_queue); } } } // Island Generation if (Math.Abs(yPos - (120 + rnd.Next(-1, 1))) <= 1) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.skyIslandZoneScale) > biome.skyIslandZoneThreshold) { voxelValue = 8; } } // Make Lakes return(voxelValue); }
/// <summary> /// Algarithim that helps to decide where the gereration is allowed to put textures on voxels, caves, biomes and ect /// </summary> public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); /* MUST CALL */ // If outside world bounds, return air voxel ID if (!IsVoxelInWorld(pos)) { return(0); } // If bottom block of chunk, return bedrock voxel ID if (yPos == 0) { return(6); } /* BIOME SELECTION */ /// <summary> /// Below <see cref="solidGroundHeight"/> is always solid ground. /// </summary> int solidGroundHeight = 20; float sumOfHeights = 0; int count = 0; float strongestWeight = 0; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = VoxelData.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); // Is the weight the strongest of all the biomes if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; } // Get the height of the current terrain and multiply by the weight to apply smoothing between biomes float height = biomes[i].terrainHeight * VoxelData.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biomes[i].terrainScale) * weight; if (height > 0) { sumOfHeights += height; count++; } } // Set Biome BiomeAttributes biome = biomes[strongestBiomeIndex]; // Get average heights sumOfHeights /= count; // Converts a 0 to 1 value into a percentage that gets multiplied by the heignt to create terrain int terrainHeight = Mathf.FloorToInt(sumOfHeights + solidGroundHeight); /* BASIC TERRAIN */ byte voxelValue = 0; // If top block of chunk, return stone voxel ID. Else if heigher then top block return air voxel ID if (yPos == terrainHeight) { voxelValue = biome.surfaceBlockID; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlockID; } else if (yPos > terrainHeight) { return(0); } else { voxelValue = 5; } if ((voxelValue == biome.surfaceBlockID || voxelValue == biome.surfaceBlockID || voxelValue == 5) && biome.lodes.Length > 0) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (VoxelData.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } return(voxelValue); }
public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); /* IMMUTABLE PASS */ // If outside world, return air. if (!IsVoxelInWorld(pos)) { return(0); } // If bottom block of chunk, return bedrock. if (yPos == 0) { return(1); } /* BIOME SELECTION PASS */ int solidGroundHeight = 42; float sumOfHiehgts = 0; int count = 0; float strongestWeight = 0; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; } float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biomes[i].terrainScale) * weight; if (height > 0) { sumOfHiehgts += height; count++; } } //Set Biome BiomeAttributes biome = biomes[strongestBiomeIndex]; sumOfHiehgts /= count; int terrainHeight = Mathf.FloorToInt(sumOfHiehgts + solidGroundHeight); /* BASIC TERRAIN PASS */ byte voxelValue = 0; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - biome.subsurfaceBlockHeight) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return(0); } else { voxelValue = 2; } /* SECOND PASS */ if (voxelValue == 2) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } /* TREE PASS */ if (yPos == terrainHeight && biome.placeMajorFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraZoneScale) > biome.majorFloraZoneThreshold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.majorFloraPlacementScale) > biome.majorFloraPlacementThreshold) { System.Random random = new System.Random(); modifications.Enqueue(Structure.GenerateMajorFlora(biome.majorFloraIndex[(int)random.Next(0, biome.majorFloraIndex.Length)], pos, biome.minHeight, biome.maxHeight)); } } } return(voxelValue); }
public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); /* Boundary conditions*/ //if outside world if (!IsVoxelInWorld(pos)) { return(0); } //if bottom block then return bedrock if (yPos == 0) { return(1); } //BIOME SELECTION PASS int groundHeight = 42; float sumOfHeights = 0f; int count = 0; float strongestWeight = 0f; int strongestBiomeIndex = 0; for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); if (weight > strongestWeight) { strongestWeight = weight; strongestBiomeIndex = i; } //getting the height of the terrain float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 2.5f, biomes[i].terrainScale) * weight; if (height > 0) { sumOfHeights += height; count++; } } //Set biome to one with strongest weight BiomeAttributes biome = biomes[strongestBiomeIndex]; //Getting AVG of heights and the final terrain height sumOfHeights /= count; int terrainHeight = Mathf.FloorToInt(sumOfHeights + groundHeight); /*Basic terrain conditions*/ byte voxelValue = 0; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return(0); } else { voxelValue = 2; } /* Second Pass for dirt and ores */ if (voxelValue == 2) { foreach (Lode lode in biome.lodes) { if (yPos > lode.minHeight && yPos < lode.maxHeight) { if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold)) { voxelValue = lode.blockID; } } } } /* Third pass for trees */ if (yPos == terrainHeight && biome.placeFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 2.5f, biome.floraZoneScale) > biome.floraThreshhold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 2.5f, biome.floraPlacementScale) > biome.floraPlacementThreshold) { mods.Enqueue(Structure.GenerateFlora(biome.floraIndex, pos, biome.HeightMin, biome.HeightMax)); } } } return(voxelValue); }
public byte GetVoxel(Vector3 pos) { int yPos = Mathf.FloorToInt(pos.y); // -- IMMUTABLES -- // Outside the world => air if (!IsVoxelInWorld(pos)) { return(0); } // Bottom of chunk => bedrock if (yPos == 0) { return(1); } // -- BIOME SELECT -- int solidGroundHeight = 42; // always solid below this level float sumOfHeights = 0f; int counter = 0; (float weight, int biome_index)strongestWeight = (0, 0); for (int i = 0; i < biomes.Length; i++) { float weight = Noise.Get2DPerlin(new Vector2(pos.x, pos.z), biomes[i].offset, biomes[i].scale); // Assign a "strongest" weight. if (weight > strongestWeight.weight) { strongestWeight.weight = weight; strongestWeight.biome_index = i; } // Get biome's terrain height and mult. by weigth. float height = biomes[i].terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biomes[i].terrainScale) * weight; if (height > 0) { sumOfHeights += height; counter++; } } BiomeAttributes biome = biomes[strongestWeight.biome_index]; sumOfHeights /= counter; int terrainHeight = Mathf.FloorToInt(sumOfHeights + solidGroundHeight); // -- TERRAIN PASS -- byte voxelValue = 0; if (yPos == terrainHeight) { voxelValue = biome.surfaceBlock; } else if (yPos < terrainHeight && yPos > terrainHeight - 4) { voxelValue = biome.subSurfaceBlock; } else if (yPos > terrainHeight) { return(0); } else { voxelValue = 2; } // -- SECOND PASS -- if (voxelValue == 2) { foreach (Lode l in biome.lodes) { if (yPos > l.minHeight && yPos < l.maxHeight) { if (Noise.Get3DPerlin(pos, l.noiseOffset, l.scale, l.threshold)) { voxelValue = l.blockID; } } } } // -- FLORA PASS -- if (yPos == terrainHeight && biome.placeBigFlora) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.bigFloraZoneScale) > biome.bigFloraZoneTreshold) { if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.bigFloraPlacementScale) > biome.bigFloraPlacementThreshold) { var test = Structure.GenerateBigFlora(biome.majorFloraIndex, pos, biome.minHeight, biome.maxHeight); modifications.Enqueue(test); } } } return(voxelValue); }