public override Volumetric3 Generate(Volumetric3 startData)
        {
            float[,] terrainheights = new float[startData.Width, startData.Width];

            Vector3 point00 = new Vector3(-0.5f, -0.5f);
            Vector3 point10 = new Vector3(0.5f, -0.5f);
            Vector3 point01 = new Vector3(-0.5f, 0.5f);
            Vector3 point11 = new Vector3(0.5f, 0.5f);

            NoiseMethod method   = Noise.noiseMethods[(int)NoiseMethodType.Perlin][2];
            float       stepSize = 1f / startData.Width;

            for (int y = 0; y < startData.Width; y++)
            {
                Vector3 point0 = Vector3.Lerp(point00, point01, (y + 0.5f) * stepSize);
                Vector3 point1 = Vector3.Lerp(point10, point11, (y + 0.5f) * stepSize);

                for (int x = 0; x < startData.Width; x++)
                {
                    Vector3 point  = Vector3.Lerp(point0, point1, (x + 0.5f) * stepSize);
                    float   sample = Noise.Sum(method, point, Frequency, Octaves, Lacunarity, Persistence);

                    sample = sample * 0.5f + 0.5f;
                    terrainheights[y, x] = sample * Scale;
                }
            }

            for (int x = 0; x < startData.Width; x++)
            {
                for (int z = 0; z < startData.Length; z++)
                {
                    float endPoint    = 0;
                    float heightExtra = 0;
                    if (Additive)
                    {
                        //We are in additive mode, we add our data only on top of the highest data points instead.
                        float highestPoint = GetHighestYPoint(startData, x, z);
                        endPoint    = highestPoint;
                        heightExtra = highestPoint;
                    }
                    for (int y = 0; y < startData.Height; y++)
                    {
                        float heightValue = terrainheights[x, z] * (startData.Height - 1) + heightExtra;

                        //Only set the value as 1 within the range we wish to modify.
                        if (y < heightValue && y >= endPoint)
                        {
                            startData.SetData(x, y, z, 1);
                        }
                    }
                }
            }

            return(startData);
        }
        private int GetHighestYPoint(Volumetric3 data, int x, int z)
        {
            int y;

            for (y = data.Height - 1; z >= 0; y--)
            {
                if (data.GetData(x, y, z) == 1)
                {
                    return(y);
                }
            }
            return(y);
        }
Esempio n. 3
0
 public override Volumetric3 Generate(Volumetric3 startData)
 {
     for (int x = 0; x < startData.Length; x++)
     {
         for (int z = 0; z < startData.Width; z++)
         {
             for (int y = 0; y < Height; y++)
             {
                 startData.SetData(x, y, z, 1);
             }
         }
     }
     return(startData);
 }
Esempio n. 4
0
        private Vector3Int GetStartPosition(Volumetric3 startData)
        {
            int x = 0;
            int y = 0;
            int z = 0;

            x = Mathf.CeilToInt(startData.Width * BeginXRatio);
            z = Mathf.CeilToInt(startData.Length * BeginZRatio);
            for (int potentialY = startData.Height - 1; potentialY >= 0; potentialY--)
            {
                y = potentialY;
                if (startData.GetData(x, y, z) == 1)
                {
                    break;
                }
            }
            return(new Vector3Int(x, y, z));
        }
Esempio n. 5
0
 private void RemoveFromArea(Vector3Int position, ref Volumetric3 data)
 {
     for (int x = position.x - Radius; x < position.x + Radius; x++)
     {
         for (int y = position.y - Radius; y < position.y + Radius; y++)
         {
             for (int z = position.z - Radius; z < position.z + Radius; z++)
             {
                 if (Mathf.FloorToInt(Vector3Int.Distance(new Vector3Int(x, y, z), position)) <= Radius)
                 {
                     //We are in the sphere range, check if we are in bounds as well.
                     if (data.InBounds(new Vector3Int(x, y, z)))
                     {
                         data.SetData(x, y, z, 0);
                     }
                 }
             }
         }
     }
 }
Esempio n. 6
0
        public override Volumetric3 Generate(Volumetric3 startData)
        {
            //Clamp values to ratio ranges.
            if (RandomStartPos)
            {
                BeginXRatio = (float)_random.NextDouble();
                BeginXRatio = (float)_random.NextDouble();
            }
            else
            {
                BeginXRatio = Mathf.Clamp01(BeginXRatio);
                BeginZRatio = Mathf.Clamp01(BeginZRatio);
            }
            DepthRatio = Mathf.Clamp01(DepthRatio);

            //Our current position for the meta ball.
            Vector3Int currentPos = GetStartPosition(startData);

            int caveY = Mathf.CeilToInt(currentPos.y * DepthRatio);

            if (DepthAboveBase && caveY <= Radius * 2)
            {
                caveY = (Radius * 2) + 1;
            }

            //Create entrance, choose random vear direction to use.
            //We will extract data in a sphere untill we hit the y target.

            //Create diverge values:
            float xDiverge = 0;
            float zDiverge = 0;
            float xAmount  = RandomDiverge ? (float)_random.NextDouble() * 2 - 1 * RandomConvergeMax : DivergeX;
            float zAmount  = RandomDiverge ? (float)_random.NextDouble() * 2 - 1 * RandomConvergeMax : DivergeX;

            while (currentPos.y >= caveY)
            {
                RemoveFromArea(currentPos, ref startData);
                currentPos.y--;
                //Increase diverge amounts.
                xDiverge += xAmount;
                zDiverge += zAmount;
                if (xDiverge >= 1)
                {
                    currentPos.x -= 1;
                    xDiverge     -= 1;
                }
                if (zDiverge >= 1)
                {
                    currentPos.z -= 1;
                    zDiverge     -= 1;
                }
            }

            //Create a path that goes in a random direction and curves

            //Setup Y divergence.
            //float yDiverge = 0;
            //float yAmount = RandomDiverge ? (float)_random.NextDouble() * 2 - 1 * RandomConvergeMax : DivergeY;
            zDiverge = 0;
            xDiverge = 0;
            Vector3Int tunnelStart = currentPos;

            //Create a random normalized direction.
            Vector3 direction = new Vector3((float)_random.NextDouble() * 2 - 1, 0, (float)_random.NextDouble() * 2 - 1).normalized;

            float x = 0;
            float z = 0;

            while (Vector3Int.Distance(currentPos, tunnelStart) < Length && startData.InBounds(currentPos))
            {
                //While we are below the length and are in bounds, make a tunnel.
                RemoveFromArea(currentPos, ref startData);
                x += direction.x;
                z += direction.z;
                //Positive values
                if (x > 1)
                {
                    x            -= 1;
                    currentPos.x += 1;
                }
                if (z > 1)
                {
                    z            -= 1;
                    currentPos.z += 1;
                }

                //Negative values
                if (x < -1)
                {
                    x            += 1;
                    currentPos.x -= 1;
                }
                if (z < -1)
                {
                    z            += 1;
                    currentPos.z -= 1;
                }
            }

            return(startData);
        }