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);
                }
            }
        }
Example #2
0
        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;
            }
        }
Example #3
0
    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);
    }
Example #4
0
    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);
    }
Example #6
0
        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);
                }
            }
        }
Example #10
0
    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;
        }
    }
Example #11
0
        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);
    }
Example #13
0
    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;
        }
    }
Example #14
0
        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;
        }
Example #15
0
        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);
            }
        }