public void GetChunkData(Chunk chunk) { // Chunk global position. var Offset = chunk.Offset; // Settings ! float temperature = TemperatureManager.GetTemperature(0 + (int)(Offset.x * ChunkSize.x), 0 + (int)(Offset.y * ChunkSize.z)); float humidity = TemperatureManager.GetHumidity(0 + (int)(Offset.x * ChunkSize.x), 0 + (int)(Offset.y * ChunkSize.z)); BiomeSettings CurrentSettings = BiomeManager.BestMatch(temperature, humidity); bool placedTree = false; for (int z = 0; z < ChunkSize.z; z += 1) { for (int x = 0; x < ChunkSize.x; x += 1) { temperature = TemperatureManager.GetTemperature(x + (int)(chunk.Offset.x * ChunkSize.x), z + (int)(chunk.Offset.y * ChunkSize.z)); humidity = TemperatureManager.GetHumidity(x + (int)(chunk.Offset.x * ChunkSize.x), z + (int)(chunk.Offset.y * ChunkSize.z)); CurrentSettings = BiomeManager.BestMatch(temperature, humidity); // Global position of the cube. int gX = ((int)Offset.x * (int)Chunk.ChunkSize.x) + x; int gZ = ((int)Offset.y * (int)Chunk.ChunkSize.z) + z; float noiseResult = ((Noise.GetNoise2d(gX, gZ) * CurrentSettings.TerrainAmplitude) + 1f) * (ChunkSize.y / 2); float height = Mathf.Clamp(Mathf.Stepify(noiseResult, 1), 0, 254); // Default type BlockType type = CurrentSettings.DefaultBlocktype; // Filling under the chunk too. for (int i = 0; i <= height; i++) { chunk.Voxels[x, i, z].Active = true; chunk.Voxels[x, i, z].Type = type; } // Big mountains? if (CurrentSettings.Mountains) { GenerateMountains(chunk, x, z, (int)Mathf.Clamp(height, 0f, 254f)); } // Add X layers of block on top of the generated rock. var pos = chunk.HighestAt(x, z); for (int i = 0; i < CurrentSettings.TopLayerThickness; i++) { // Adding some dirt under top layer. var newType = CurrentSettings.UnderLayerType; // if highest block, its grass! if (i == 0) { newType = CurrentSettings.TopLayerType; } // Placing block. Making sure its under 255 height. chunk.Voxels[x, Mathf.Clamp(pos - i, 0, 254), z].Type = newType; } // Placing decoration int decorationChance = rng.RandiRange(1, 100); if (decorationChance < CurrentSettings.DecorationRate) { // Placing point int dy = chunk.HighestAt(x, z) + 1; var mesh = (ArrayMesh)ResourceLoader.Load(CurrentSettings.DecorationModel); chunk.AddVoxelSprite(new VoxelSprite(mesh, new Vector3(x, dy, z))); } // Placing trees float treeChance = rng.RandfRange(1f, 100f); //GD.Print(treeChance + " <= " + CurrentSettings.TreeRate); if (treeChance < CurrentSettings.TreeRate) { //GD.Print("Placed tree"); var file = (ArrayMesh)ResourceLoader.Load(CurrentSettings.TreeModel); int ty = chunk.HighestAt(x, z) + 1; //Placing point. // Creating and setting the mesh. var meshInstance = new MeshInstance(); meshInstance.Mesh = file; meshInstance.Name = CurrentSettings.TreeModel; // Adding it next frame.(safe with mutex lock) CallDeferred("add_child", meshInstance); // Moving it next frame(not in the tree yet :)) meshInstance.SetDeferred("translation", new Vector3(x + (Offset.x * ChunkSize.x) - 10, ty, z + (Offset.y * ChunkSize.z + 10))); //meshInstance.SetDeferred("rotation_degrees", new Vector3(0, rng.RandfRange(0, 360), 0)); } } } }