Esempio n. 1
0
        public FileToVoxCore.Drawing.Color GetVegetation(BiomeSettings biome, float random)
        {
            float acumProb = 0;
            int   index    = 0;

            for (int t = 0; t < biome.Vegetation.Length; t++)
            {
                acumProb += biome.Vegetation[t].Probability;
                if (random < acumProb)
                {
                    index = t;
                    break;
                }
            }
            return(biome.Vegetation[index].Color);
        }
        public void PaintChunk(VoxelChunk chunk)
        {
            Vector3 position = chunk.Position;

            if (position.Y + TerrainEnvironment.CHUNK_HALF_SIZE < MinHeight)
            {
                return;
            }

            int bedrockRow = -1;

            if (position.Y < MinHeight + TerrainEnvironment.CHUNK_HALF_SIZE)
            {
                bedrockRow = (int)(MinHeight - (position.Y - TerrainEnvironment.CHUNK_HALF_SIZE) + 1) * ONE_Y_ROW - 1;
            }

            position.X -= TerrainEnvironment.CHUNK_HALF_SIZE;
            position.Y -= TerrainEnvironment.CHUNK_HALF_SIZE;
            position.Z -= TerrainEnvironment.CHUNK_HALF_SIZE;
            Vector3 pos        = new Vector3();
            int     waterLevel = WaterLevel > 0 ? WaterLevel : -1;

            Voxel[] voxels = chunk.Voxels;
            mGeneration++;
            TerrainEnvironment.Instance.GetHeightMapInfo(position.X, position.Z, mHeightChunkData);
            int shiftAmount = (int)MathF.Log(TerrainEnvironment.CHUNK_SIZE, 2);

            for (int arrayIndex = 0; arrayIndex < TerrainEnvironment.CHUNK_SIZE * TerrainEnvironment.CHUNK_SIZE; arrayIndex++)
            {
                float groundLevel  = mHeightChunkData[arrayIndex].GroundLevel;
                float surfaceLevel = waterLevel > groundLevel ? waterLevel : groundLevel;
                if (surfaceLevel < pos.Y)
                {
                    continue;
                }

                BiomeSettings biome = mHeightChunkData[arrayIndex].Biome;
                if (biome == null)
                {
                    biome = TerrainEnvironment.Instance.WorldTerrainData.DefaultBiome;
                    if (biome == null)
                    {
                        continue;
                    }
                }

                int y = (int)(surfaceLevel - position.Y);
                if (y >= TerrainEnvironment.CHUNK_SIZE)
                {
                    y = TerrainEnvironment.CHUNK_SIZE - 1;
                }

                pos.Y = position.Y + y;
                pos.X = position.X + (arrayIndex & (TerrainEnvironment.CHUNK_SIZE - 1));
                pos.Z = position.Z + (arrayIndex >> shiftAmount);

                int voxelIndex = y * ONE_Y_ROW + arrayIndex;
                if (voxelIndex < 0)
                {
                    continue;
                }
                if (pos.Y > groundLevel)
                {
                    while (pos.Y > groundLevel && voxelIndex >= 0)
                    {
                        voxels[voxelIndex].Color = WaterColor.ColorToUInt();
                        voxelIndex -= ONE_Y_ROW;
                        pos.Y--;
                    }
                }
                else if (pos.Y == groundLevel)
                {
                    voxels[voxelIndex].Color = 0;

                    if (voxels[voxelIndex].Color == 0)
                    {
                        if (pos.Y == waterLevel)
                        {
                            voxels[voxelIndex].Color = ShoreColor.ColorToUInt();
                        }
                        else
                        {
                            //float moisture = mHeightChunkData[arrayIndex].Moisture;
                            //Color colorTop = biome.VoxelTop;
                            //Color newColor = Color.FromArgb((int) (colorTop.R * moisture), (int)(colorTop.G * moisture), (int)(colorTop.B * moisture));
                            //voxels[voxelIndex].Color = newColor.ColorToUInt();

                            voxels[voxelIndex].Color = biome.VoxelTop.ColorToUInt();

                            if (pos.Y > waterLevel)
                            {
                                float rdn = WorldRandom.GetValue(pos);
                                if (biome.TreeDensity > 0 && rdn < biome.TreeDensity && biome.Trees.Length > 0)
                                {
                                    TerrainEnvironment.Instance.RequestTreeCreation(chunk, pos, TerrainEnvironment.Instance.GetTree(biome.Trees, rdn / biome.TreeDensity));
                                }
                                else if (biome.VegetationDensity > 0 && rdn < biome.VegetationDensity && biome.Vegetation.Length > 0)
                                {
                                    if (voxelIndex >= (TerrainEnvironment.CHUNK_SIZE - 1) * ONE_Y_ROW)
                                    {
                                        TerrainEnvironment.Instance.RequestVegetationCreation(chunk.Top, voxelIndex - ONE_Y_ROW * (TerrainEnvironment.CHUNK_SIZE - 1), TerrainEnvironment.Instance.GetVegetation(biome, rdn / biome.VegetationDensity));
                                    }
                                    else
                                    {
                                        voxels[voxelIndex + ONE_Y_ROW].Color = TerrainEnvironment.Instance.GetVegetation(biome, rdn / biome.VegetationDensity).ColorToUInt();
                                    }
                                }
                            }
                        }

                        voxelIndex -= ONE_Y_ROW;
                        pos.Y--;
                    }
                }

                biome.BiomeGeneration = mGeneration;

                while (voxelIndex >= 0 && voxels[voxelIndex].Color == 0 && pos.Y <= waterLevel)
                {
                    voxels[voxelIndex].Color = WaterColor.ColorToUInt();
                    voxelIndex -= ONE_Y_ROW;
                    pos.Y--;
                }

                for (; voxelIndex > bedrockRow; voxelIndex -= ONE_Y_ROW, pos.Y--)
                {
                    if (voxels[voxelIndex].Color == 0)
                    {
                        voxels[voxelIndex].Color = biome.VoxelDirt.ColorToUInt();
                    }
                    else if (voxels[voxelIndex].Color == 0 && pos.Y <= waterLevel)
                    {                     // hole under water level -> fill with water
                        voxels[voxelIndex].Color = WaterColor.ColorToUInt();
                    }
                }
                if (bedrockRow >= 0 && voxelIndex >= 0)
                {
                    voxels[voxelIndex].Color = BedrockColor.ColorToUInt();
                }
            }
        }