Exemplo n.º 1
0
    /// <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);
    }