private void CellNoiseCalculation(object sender, DoWorkEventArgs e) { float[] helper = new float[TerrainPoints.Length]; for (int octave = 1; octave <= Octaves; octave++) { float height = Height * (1 / (float)octave); int quantity = Quantity * octave + 1; cellNoiseAlgorithm.PrepareValues(Seed, TerrainSize, quantity, Distance, octave); // Calculate Heights depending on Distance to the next FeaturePoint for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { float value = cellNoiseAlgorithm.Evaluate(x, z); value *= height; helper[z + x * TerrainSize] = TerrainUtilities.Apply(helper[z + x * TerrainSize], value, ApplicationMode.Add); } } int progressPercentage = (int)(((float)octave / (float)Octaves) * 100); (sender as BackgroundWorker).ReportProgress(progressPercentage); } for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { TerrainPoints[z + x * TerrainSize] = TerrainUtilities.Apply(TerrainPoints[z + x * TerrainSize], helper[z + x * TerrainSize], CurrentApplicationMode); } } }
public void calculateOffset(int x, int z) { float currentPoint = heights[(z + x * terrainSize)]; offset = 0; int[] neighbours = TerrainUtilities.GetNeighbours(x, z, terrainSize); float weightedNeighbours = 0.0f; for (int i = 0; i < neighbours.Length; i++) { weightedNeighbours += heights[neighbours[i]]; } weightedNeighbours /= (float)neighbours.Length; if (invert) { offset = (((weightedNeighbours - currentPoint) - min) / range) + shift; } else { offset = (((currentPoint - weightedNeighbours) - min) / range) + shift; } }
public static void GenerateCave(int x, WorldData worldData) { int depth = 0; Vector2i surface = TerrainUtilities.FindUpperMostTile(x, worldData, type => type != TileType.Empty); int y = Random.Range(surface.Y, worldData.Height); do { if (!(Random.value < caveContinuationChance)) { continue; } depth++; TerrainUtilities.GenerateFuzzyCircle(minimumCaveSize, maximumCaveSize, worldData, new Vector2i(x, y), TileType.Empty); //Logger.Log("TerrainCaveProcessor", string.Format("Generated cave at ({0}, {1}). Current depth: {2}", x * Chunk.Size, y * Chunk.Size, depth)); float angle = Random.value * MathHelper.Tau; Vector2 direction = new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)); int step = Random.Range(minimumCaveSize, maximumCaveSize); x += (int)Math.Floor(direction.x * step); y += (int)Math.Floor(direction.y * step); }while (depth < maximumCaveDepth); }
public void GeneratePrairie(int startX, WorldData worldData) { int size = Random.Range(minimumSize, maximumSize); int endX = startX + size; Vector2i spotPosition = TerrainUtilities.FindUpperMostTile(startX, worldData, type => type != TileType.Empty); for (int x = 0; x < size; x++) { int nx = x + endX; TileType tileAt = worldData.GetTileTypeAt(nx, spotPosition.Y); if (tileAt == TileType.Empty) { continue; } endX = nx; break; } if (worldData.GetTileTypeAt(endX, spotPosition.Y) == TileType.Empty) { return; } int offset = 0; int offsetSwitch = 0; int offsetRate = 0; for (int x = startX; x < endX; x++) { for (int y = spotPosition.Y; y < worldData.Height; y++) { TileType tileAt = worldData.GetTileTypeAt(x, y + offset); if (tileAt == TileType.Empty) { worldData.SetTileTypeAt(x, y + offset, TileType.NonEmpty); } else { break; } } if (offsetSwitch >= offsetRate) { offsetSwitch = 0; offsetRate = Random.Range(minimumOffsetSwitchRate, maximumOffsetSwitchRate); offset = Random.Range(minimumOffset, maximumOffset); } else { offsetSwitch++; } } }
public void StampHole() { if (inputField == null || string.IsNullOrEmpty(inputField.text)) { return; } string[] coords = inputField.text.Split(','); int x = int.Parse(coords[0]); int y = int.Parse(coords[1]); TerrainUtilities.GenerateCircle(10, World.Current.WorldData, new Vector2i(x, y), TileType.Empty); }
private void HeightCalculation(object sender, DoWorkEventArgs e) { for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { TerrainPoints[z + x * TerrainSize] = TerrainUtilities.Apply(TerrainPoints[z + x * TerrainSize], Height, CurrentApplicationMode); } int progressPercentage = (int)(((float)x / (float)TerrainSize) * 100); (sender as BackgroundWorker).ReportProgress(progressPercentage); } }
private void Update() { Vector2 movePosition = Vector2.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime); transform.position = new Vector3(movePosition.x, movePosition.y, -1); TerrainUtilities.GenerateCircle(1, World.Current.WorldData, WorldController.Instance.WorldCoordiantesToGridSpace(transform.position), TileType.Empty); if (transform.position != targetPosition) { return; } Impact(); }
private void CheckSetup() { if (_setupCompleted) { return; } child = new GameObject("Colliders").transform; child.parent = transform; terrainController = GetComponent <TerrainController>(); _loadingCircle = TerrainUtilities.GenerateLoadingCircle(preloadRadius); _collisionUsers = new List <TerrainCollisionUser>(); _collisionTileBuffer = new Dictionary <IntegerCoordinate2D, TerrainCollisionTile>(); _currentCenterLoadingStates = new Dictionary <IntegerCoordinate2D, LoadingState>(); _currentLoadingCenters = new HashSet <IntegerCoordinate2D>(); _setupCompleted = true; }
private void OpenSimplexNoiseCalculation(object sender, DoWorkEventArgs e) { float octaveWeight = 1; float octaveMultiplier = 1; int sizeCompensator = TerrainUtilities.GetReversedSizeCompensator(TerrainSize); float[] helper = new float[TerrainPoints.Length]; for (int octaves = 0; octaves < OSNOctaves; octaves++) { for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { float value = 0; float xValue = (float)((((0.00025f / OSNScale) / OSNScaleX) * (x * sizeCompensator) + OSNSeed) * octaveMultiplier); float zValue = (float)((((0.00025f / OSNScale) / OSNScaleZ) * (z * sizeCompensator) + OSNSeed) * octaveMultiplier); if (octaves == 0) { value = (float)(((_openSimplexNoise.Evaluate(xValue, zValue) * octaveWeight) + 1) / 2); } else { value = (float)((_openSimplexNoise.Evaluate(xValue, zValue) * octaveWeight) / 2); } helper[z + x * TerrainSize] += value * OSNStrength; } } octaveWeight /= 2.0f - (OSNOctaveWeight - 0.5f); octaveMultiplier = octaves * 2.0f; int progressPercentage = (int)(((float)octaves / (float)OSNOctaves) * 100); (sender as BackgroundWorker).ReportProgress(progressPercentage); } for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { TerrainPoints[z + x * TerrainSize] = TerrainUtilities.Apply(TerrainPoints[z + x * TerrainSize], helper[z + x * TerrainSize], CurrentApplicationMode); } } }
private static void GenerateCanyon(int startX, WorldData worldData) { int steps = Random.Range(minimumCanyonSteps, maximumCanyonSteps); int currentX = startX; for (int i = 0; i < steps; i++) { int radius = Random.Range(minimumCanyonSize, maximumCanyonSize); int pivot = Random.Range(-radius, radius); int x = currentX + pivot; Vector2i spot = TerrainUtilities.FindUpperMostTile(x, worldData, type => type != TileType.Empty); TerrainUtilities.GenerateFuzzyCircle(minimumCanyonSize, maximumCanyonSize, worldData, spot, TileType.Empty); currentX = x; } }
public static IEnumerator GetChunkData(CollisionBaseData[] inputData, TerrainCollisionController controller, TerrainCollisionTile tile) { var settings = controller.terrainController.terrainGeneratorSettings; var shader = controller.terrainCollisionComputeShader; var kernel = shader.FindKernel("ComputeOffsets"); var dataBuffer = new ComputeBuffer(inputData.Length, 40); //See CollisionBaseData summary dataBuffer.SetData(inputData); var outputData = new float[inputData.Length]; for(var i = 0; i < inputData.Length; i++) { outputData[i] = 10; } var outputBuffer = new ComputeBuffer(outputData.Length, 4); //Float = 4 Bytes outputBuffer.SetData(outputData); TerrainUtilities.TransferTerrainGeneratorSettingsToComputeShader(shader, settings); shader.SetBuffer(kernel, "_BaseData", dataBuffer); shader.SetBuffer(kernel, "_FullData", outputBuffer); shader.SetInt("_size", inputData.Length); //Obtain base shader data. controller.terrainController.SetMainComputeShaderData(shader, kernel); //Dispatch the main Kernel shader.Dispatch(kernel, Mathf.CeilToInt(inputData.Length / 8.0f), 1, 1); //Wait for the requests to finish asynchronously var request = AsyncGPUReadback.Request(outputBuffer); yield return new WaitUntil(() => request.done); //Write results back to tile tile.displacements = request.GetData<float>().ToArray(); //Clean up GPU buffers dataBuffer.Release(); dataBuffer.Dispose(); outputBuffer.Release(); outputBuffer.Dispose(); yield return null; }
private void Impact() { float size = impactRadius / 2f; Vector2i impactPosition = WorldController.Instance.WorldCoordiantesToGridSpace(transform.position + new Vector3(0, size)); TerrainUtilities.GenerateFuzzyCircle(impactRadius, impactRadius + 2, World.Current.WorldData, impactPosition, TileType.Empty); GameObject impactGameObject = Instantiate(impactPrefab, transform.position + new Vector3(0, 0, -1), Quaternion.identity); impactGameObject.transform.localScale = new Vector3(size, size, size); if (Vector3.Distance(transform.position, Player.Current.transform.position) <= impactRadius) { Player.Current.Shock(0.5f); } Destroy(impactGameObject, impactGameObject.GetComponent <ParticleSystem>().main.duration); Destroy(gameObject); }
private static void GenerateValley(int startX, WorldData worldData) { int steps = Random.Range(minimumValleySteps, maximumValleySteps); int currentX = startX; for (int i = 0; i < steps; i++) { int radius = Random.Range(minimumValleySize, maximumValleySize); int pivot = Random.Range(-radius, radius); int x = currentX + pivot; Vector2i spot = TerrainUtilities.FindUpperMostTile(x, worldData, type => type != TileType.Empty); TileType spotType = Random.value < valleyExtrusionChance ? TileType.NonEmpty : TileType.Empty; TerrainUtilities.GenerateFuzzyCircle(minimumValleySize, maximumValleySize, worldData, spot, spotType); currentX = x; } }
public void calculateMinMax() { min = -0.01f; max = 0.01f; float currentPoint; float check; for (int x = 0; x < terrainSize; x++) { for (int z = 0; z < terrainSize; z++) { currentPoint = heights[(z + x * terrainSize)]; int[] neighbours = TerrainUtilities.GetNeighbours(x, z, terrainSize); float weightedNeighbours = 0.0f; for (int i = 0; i < neighbours.Length; i++) { weightedNeighbours += heights[neighbours[i]]; } weightedNeighbours /= (float)neighbours.Length; check = currentPoint - weightedNeighbours; if (check < min) { min = check; } else if (check > max) { max = check; } } } range = -min + max * colorRange; }
private void SlopeCalculation(object sender, DoWorkEventArgs e) { float value = 0; float heightRange = StartHeight - EndHeight; float startPosition = (float)StartPosition / 100.0f * TerrainSize; float endPosition = (float)EndPosition / 100.0f * TerrainSize; float positionRange = endPosition - startPosition; if (positionRange < 0) { positionRange = -positionRange; } if (heightRange < 0) { heightRange = -heightRange; } for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { switch (CurrentDirection) { case Direction.X_Axis: switch (CurrentInterpolationMode) { case InterpolationMode.Linear: if (x < startPosition) { value = StartHeight; } else if (x > endPosition) { value = EndHeight; } else { if (StartHeight < EndHeight) { value = StartHeight + ((((float)x - startPosition) / positionRange) * heightRange); } else { value = StartHeight - ((((float)x - startPosition) / positionRange) * heightRange); } } break; case InterpolationMode.Smooth: if (x < startPosition) { value = StartHeight; } else if (x > endPosition) { value = EndHeight; } else { if (StartHeight < EndHeight) { value = StartHeight + (float)(Math.Cos(Math.PI - ((x - startPosition) / positionRange) * Math.PI) / 2.0f + 0.5f) * heightRange; } else { value = StartHeight - (float)(Math.Cos(Math.PI - ((x - startPosition) / positionRange) * Math.PI) / 2.0f + 0.5f) * heightRange; } } break; } break; case Direction.Z_Axis: switch (CurrentInterpolationMode) { case InterpolationMode.Linear: if (z < startPosition) { value = StartHeight; } else if (z > endPosition) { value = EndHeight; } else { if (StartHeight < EndHeight) { value = StartHeight + ((((float)z - startPosition) / positionRange) * heightRange); } else { value = StartHeight - ((((float)z - startPosition) / positionRange) * heightRange); } } break; case InterpolationMode.Smooth: if (z < startPosition) { value = StartHeight; } else if (z > endPosition) { value = EndHeight; } else { if (StartHeight < EndHeight) { value = StartHeight + (float)(Math.Cos(Math.PI - ((z - startPosition) / positionRange) * Math.PI) / 2.0f + 0.5f) * heightRange; } else { value = StartHeight - (float)(Math.Cos(Math.PI - ((z - startPosition) / positionRange) * Math.PI) / 2.0f + 0.5f) * heightRange; } } break; } break; } TerrainPoints[z + x * TerrainSize] = TerrainUtilities.Apply(TerrainPoints[z + x * TerrainSize], value, CurrentApplicationMode); } int progressPercentage = (int)(((float)x / (float)TerrainSize) * 100); (sender as BackgroundWorker).ReportProgress(progressPercentage); } }
private void IslandCalculation(object sender, DoWorkEventArgs e) { float value = 0; float heightRange = InnerHeight - OutterHeight; float highestValue = 1; float lowestValue = 0; float distance = 0; float midPosition = TerrainSize / 2; float maxDistance = midPosition * (Size + 0.5f); if (InnerHeight < OutterHeight) { highestValue = OutterHeight; lowestValue = InnerHeight; } else { highestValue = InnerHeight; lowestValue = OutterHeight; } for (int x = 0; x < TerrainSize; x++) { for (int z = 0; z < TerrainSize; z++) { float currentPositionX = x - midPosition; float currentPositionZ = z - midPosition; distance = (float)Math.Sqrt((double)(currentPositionX * currentPositionX + currentPositionZ * currentPositionZ)); switch (CurrentInterpolationMode) { case InterpolationMode.Linear: if (OutterHeight >= InnerHeight) { value = lowestValue - ((distance / maxDistance) * heightRange); } else { value = highestValue - ((distance / maxDistance) * heightRange); } if (value < lowestValue) { value = lowestValue; } else if (value > highestValue) { value = highestValue; } break; case InterpolationMode.Smooth: if (heightRange < 0) { value = highestValue - (float)((Math.Cos(Math.PI - (1 - ((distance / maxDistance))) * Math.PI)) / 2.0f + 0.5f) * -heightRange; } else { value = lowestValue + (float)((Math.Cos(Math.PI - (1 - ((distance / maxDistance))) * Math.PI)) / 2.0f + 0.5f) * heightRange; } if (distance >= maxDistance) { value = OutterHeight; } break; } TerrainPoints[z + x * TerrainSize] = TerrainUtilities.Apply(TerrainPoints[z + x * TerrainSize], value, CurrentApplicationMode); } int progressPercentage = (int)(((float)x / (float)TerrainSize) * 100); (sender as BackgroundWorker).ReportProgress(progressPercentage); } }