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); }
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); }
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)); }
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); } } } } } }
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); }