public void Start()
        {
            TaskUtils.SetGlobalMultithreading(false);
            //DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            //_currentHeightmap = creator.CreateDiamondSquareNoiseArray(_sizeOfTexture, 64);
            //MyArrayUtils.Multiply(_currentHeightmap.HeightmapAsArray, 0.1f);
            var heightTex = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240, 240,
                                                                     TextureFormat.RGBA32, true, true);

            _currentHeightmap = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTex);

            MyArrayUtils.Normalize(_currentHeightmap.HeightmapAsArray);
            MyArrayUtils.InvertNormalized(_currentHeightmap.HeightmapAsArray);

            CreateComparisionObject();
            //MyArrayUtils.Multiply(_currentHeightmap.HeightmapAsArray, 400);

            //float[,] newHeightArray = new float[256,256];
            //for (int x = 0; x < 256; x++)
            //{
            //    for (int y = 0; y < 256; y++)
            //    {
            //        var distance = (new Vector2(x,y) - new Vector2(128, 128)).magnitude;
            //        newHeightArray[x, y] = distance;
            //    }
            //}
            //MyArrayUtils.Normalize(newHeightArray);
            //_currentHeightmap = new HeightmapArray(newHeightArray);

            //Hydraulic_RenderComputeShader();

            Thermal_RenderComputeShader();
            //Hydraulic_RenderComputeShader();
        }
Esempio n. 2
0
        public void Start()
        {
            //var heightTexture = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
            //    240, TextureFormat.RGBA32, true, true);
            //_currentHeightmap = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture);

            DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));

            _currentHeightmap = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);
            MyArrayUtils.Multiply(_currentHeightmap.HeightmapAsArray, 0.1f);

            _go = GameObject.CreatePrimitive(PrimitiveType.Quad);
            var material = new Material(Shader.Find("Custom/Terrain/Terrain_Debug"));

            _go.GetComponent <MeshRenderer>().material = material;
            _go.name = "Terrain";
            _go.transform.localRotation          = Quaternion.Euler(0, 0, 0);
            _go.transform.localScale             = new Vector3(10, 10, 10);
            _go.transform.localPosition          = new Vector3(0, 0, 0);
            _go.GetComponent <MeshFilter>().mesh = PlaneGenerator.CreateFlatPlaneMesh(240, 240);

            var doneTexture =
                HeightmapUtils.CreateTextureFromHeightmap(_currentHeightmap);

            _go.GetComponent <MeshRenderer>().material.SetTexture("_HeightmapTex0", doneTexture);
            _go.GetComponent <MeshRenderer>().material.SetTexture("_HeightmapTex1", doneTexture);
            _oldDoneTexture = doneTexture;
        }
Esempio n. 3
0
        public void Start_Mai()
        {
            var heightTexture1 = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
                                                                          240, TextureFormat.RGBA32, true, true);
            var heightmap1 = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture1);

            //DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            //var heightmap2 = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);
            //MyArrayUtils.Multiply(heightmap2.HeightmapAsArray, 0.1f);
            HeightmapArray workingHeightmap = LoadHeightmapFromTextureFile(@"C:\inz\cont\temp3.png");

            MyArrayUtils.Normalize(workingHeightmap.HeightmapAsArray);
            MyArrayUtils.InvertNormalized(workingHeightmap.HeightmapAsArray);

            var generatedArrays = GenerateErodedArrays(workingHeightmap, new List <MeiHydraulicEroderConfiguration>()
            {
                new MeiHydraulicEroderConfiguration()
                {
                    StepCount           = 10,
                    A_PipeCrossSection  = 0.00005f,
                    ConstantWaterAdding = 1 / 16f,
                    GravityAcceleration = 9.81f,
                    DeltaT                   = 1 / 60f,
                    DepositionConstant       = 0.0001f * 12 * 10f,
                    DissolvingConstant       = 0.0001f * 12 * 10f,
                    EvaporationConstant      = 0.00011f * 0.5f * 10,
                    GridSize                 = new Vector2(1, 1),
                    L_PipeLength             = 1,
                    SedimentCapacityConstant = 25000
                },
            });

            CreateTestObject(workingHeightmap, generatedArrays);
        }
Esempio n. 4
0
        public void Start_Hydraulic()
        {
            var heightTexture1 =
                SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\temp3.png", 240, 240, TextureFormat.RGBA32, true,
                                                         true);
            var heightmap1 = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture1);

            //DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            //var heightmap2 = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);
            //MyArrayUtils.Multiply(heightmap2.HeightmapAsArray, 0.1f);

            var tParam = EroderDebugObject.CalculateFromHillFactor(1, new ArrayExtremes(0, 5000), 24);

            var extents = MyArrayUtils.CalculateExtremes(heightmap1.HeightmapAsArray);

            MyArrayUtils.Normalize(heightmap1.HeightmapAsArray);

            var erodedArrays = GenerateHydraulicErodedArrays(heightmap1, new List <HydraulicEroderConfiguration>()
            {
                new HydraulicEroderConfiguration()
                {
                    StepCount                  = 40,
                    NeighbourFinder            = NeighbourFinders.Big9Finder,
                    kr_ConstantWaterAddition   = 0.001f,
                    ks_GroundToSedimentFactor  = 1f,
                    ke_WaterEvaporationFactor  = 0.05f,
                    kc_MaxSedimentationFactor  = 0.8f,
                    FinalSedimentationToGround = true,
                    WaterGenerator             = HydraulicEroderWaterGenerator.AllFrames,
                    DestinationFinder          = HydraulicEroderWaterDestinationFinder.OnlyBest
                },
            });

            CreateTestObject(heightmap1, erodedArrays);
        }
Esempio n. 5
0
        public void Start()
        {
            TaskUtils.SetGlobalMultithreading(false);
            var heightTex = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240, 240,
                                                                     TextureFormat.RGBA32, true, true);

            _currentHeightmap = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTex);

            MyArrayUtils.Normalize(_currentHeightmap.HeightmapAsArray);
            MyArrayUtils.InvertNormalized(_currentHeightmap.HeightmapAsArray);

            //for (int x = 0; x < 40; x++)
            //{
            //    for (int y = 0; y < 40; y++)
            //    {
            //        _currentHeightmap.HeightmapAsArray[90+x, 90+y] = 0;
            //    }
            //}

            CreateComparisionObject();
            MyArrayUtils.Multiply(_currentHeightmap.HeightmapAsArray, 400);


            Mei_RenderComputeShader();
        }
 public Ring1VisibilityTextureChangeGrabber(int sidePixelsCount = 16)
 {
     _sidePixelsCount        = sidePixelsCount;
     _lastFrameVisibility    = new bool[_sidePixelsCount, _sidePixelsCount];
     _currentFrameVisibility = new bool[_sidePixelsCount, _sidePixelsCount];
     MyArrayUtils.PopulateArray(_lastFrameVisibility, false);
     MyArrayUtils.PopulateArray(_currentFrameVisibility, false);
 }
Esempio n. 7
0
        private TextureWithSize CreateBaseTexture(float height, DebugTerrainCharacter character)
        {
            if (character == DebugTerrainCharacter.Noise)
            {
                var texture = new RenderTexture(241, 241, 0, RenderTextureFormat.RFloat);
                texture.wrapMode   = TextureWrapMode.Clamp;
                texture.filterMode = FilterMode.Point;

                var material = new Material(Shader.Find("Custom/Tool/FillHeightTextureWithRandomValues"));
                material.SetTexture("_HeightTexture", texture);
                Graphics.Blit(texture, (RenderTexture)texture, material);
                return(new TextureWithSize()
                {
                    Texture = texture,
                    Size = new IntVector2(241, 241)
                });
            }
            else
            {
                float[,] heightArray;

                if (character == DebugTerrainCharacter.Flat)
                {
                    heightArray = MyArrayUtils.CreateFilled(241, 241, height);
                }
                else //if (character == DebugTerrainCharacter.Volcano)
                {
                    heightArray = new float[241, 241];
                    float minHeight = height * 0.2f;
                    float maxHeight = height;
                    for (int x = 0; x < 241; x++)
                    {
                        for (int y = 0; y < 241; y++)
                        {
                            heightArray[x, y] = Mathf.Lerp(minHeight, maxHeight,
                                                           1 - Vector2.Distance(new Vector2(x, y), new Vector2(120, 120)) / 200f);
                        }
                    }
                }
                var heightTex = HeightmapUtils.CreateTextureFromHeightmap(new HeightmapArray(heightArray));

                var transformator      = new TerrainTextureFormatTransformator(new CommonExecutorUTProxy());
                var plainHeightTexture = transformator.EncodedHeightTextureToPlain(new TextureWithSize()
                {
                    Size    = new IntVector2(241, 241),
                    Texture = heightTex
                });
                plainHeightTexture.wrapMode = TextureWrapMode.Clamp;
                return(new TextureWithSize()
                {
                    Size = new IntVector2(241, 241),
                    Texture = plainHeightTexture
                });
            }
        }
Esempio n. 8
0
        public void StartY()
        {
            var heightTexture = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
                                                                         240, TextureFormat.RGBA32, true, true);

            _currentHeightmap = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture);
            var array = _currentHeightmap.HeightmapAsArray;

            MyArrayUtils.Multiply(array, 65000);
            var extremes = MyArrayUtils.CalculateExtremes(array);

            Debug.Log("Max: " + extremes.Max + " min: " + extremes.Min);
        }
Esempio n. 9
0
        public void Start_Thermal()
        {
            var heightTexture1 = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
                                                                          240, TextureFormat.RGBA32, true, true);
            var heightmap1 = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture1);

            DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            var heightmap2 = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);

            MyArrayUtils.Multiply(heightmap2.HeightmapAsArray, 0.1f);

            var tParam       = EroderDebugObject.CalculateFromHillFactor(1, new ArrayExtremes(0, 5000), 24);
            var erodedArrays = GenerateErodedArrays(heightmap1, new List <ThermalErosionConfiguration>()
            {
                new ThermalErosionConfiguration()
                {
                    CParam          = 0.5f,
                    StepCount       = 10,
                    TParam          = tParam * 0.6f,
                    NeighbourFinder = NeighbourFinders.Big9Finder,
                    GroundMover     = ThermalErosionGroundMovers.OnlyBestMover
                },
                new ThermalErosionConfiguration()
                {
                    CParam          = 0.5f,
                    StepCount       = 10,
                    TParam          = tParam * 0.6f,
                    NeighbourFinder = NeighbourFinders.Big9Finder,
                    GroundMover     = ThermalErosionGroundMovers.AllNeighboursMover
                },
                new ThermalErosionConfiguration()
                {
                    CParam            = 0.5f,
                    StepCount         = 10,
                    TParam            = tParam * 0.6f,
                    NeighbourFinder   = NeighbourFinders.Big9Finder,
                    GroundMover       = ThermalErosionGroundMovers.OnlyBestMoverTweaked,
                    NeighboursChooser = ThermalEroderNeighboursChoosers.LesserEqualThanTChooser
                },
            });

            CreateTestObject(heightmap1, erodedArrays);
        }
Esempio n. 10
0
        public void AddArray(string name, HeightmapArray array, int stepNo)
        {
            if (!_arraysDict.ContainsKey(name))
            {
                _arraysDict[name] = new List <HeightmapArray>();
            }
            var clone = MyArrayUtils.DeepClone(array.HeightmapAsArray);
            //for (int x = 10; x < 10 + stepNo * 5; x++)
            //{
            //    for (int y = 10; y < 10 + stepNo * 5; y++)
            //    {
            //        clone[x, y] = array.HeightmapAsArray[10, 10];
            //    }
            //}

            var copyArray = new HeightmapArray(clone);

            _arraysDict[name].Add(copyArray);
        }
        public Ring1VisibilityTextureDelta RetriveVisibilityChanges()
        {
            var changes = new Dictionary <IntVector2, bool>();

            for (int x = 0; x < _lastFrameVisibility.GetLength(0); x++)
            {
                for (int y = 0; y < _lastFrameVisibility.GetLength(1); y++)
                {
                    var last    = _lastFrameVisibility[x, y];
                    var current = _currentFrameVisibility[x, y];
                    if (last != current)
                    {
                        changes[new IntVector2(x, y)] = current;
                    }
                }
            }

            _lastFrameVisibility    = _currentFrameVisibility;
            _currentFrameVisibility = MyArrayUtils.DeepClone(_lastFrameVisibility);
            changes = new Dictionary <IntVector2, bool>();
            return(new Ring1VisibilityTextureDelta(changes));
        }
Esempio n. 12
0
        public List <HeightmapArray> GenerateErodedArrays(HeightmapArray baseArray,
                                                          List <MeiHydraulicEroderConfiguration> configurations)
        {
            var msw = new MyStopWatch();
            List <HeightmapArray> outArray = new List <HeightmapArray>();
            int i = 0;

            foreach (var aConfiguration in configurations)
            {
                var copyArray          = MyArrayUtils.DeepClone(baseArray.HeightmapAsArray);
                var currentHeightArray = new SimpleHeightArray(copyArray);
                msw.StartSegment("eroding-" + i);
                var eroder = new MeiHydraulicEroder();
                eroder.Erode(currentHeightArray, aConfiguration);
                msw.StopSegment();

                outArray.Add(SimpleHeightArray.ToHeightmap(currentHeightArray));
                i++;
            }
            Debug.Log("T22: " + msw.CollectResults());
            return(outArray);
        }
Esempio n. 13
0
 public void NormalizeInGroups()
 {
     foreach (var list in _arraysDict.Values)
     {
         var extremes = list.Select(c => MyArrayUtils.CalculateExtremes(c.HeightmapAsArray)).ToList();
         var extent   = new ArrayExtremes(
             extremes.Min(c => c.Min),
             extremes.Max(c => c.Max)
             );
         list.ForEach(c => MyArrayUtils.Normalize(c.HeightmapAsArray, extent));
         //foreach (var arr in list)
         //{
         //    //Debug.Log("T67: "+arr.HeightmapAsArray[10, 10]);
         //    //var ext = MyArrayUtils.CalculateExtremes(arr.HeightmapAsArray);
         //    //Debug.Log("T88: min "+ext.Min+" max"+ext.Max);
         //    MyArrayUtils.Normalize(arr.HeightmapAsArray);
         //    //Debug.Log("T000_67: "+arr.HeightmapAsArray[10, 10]);
         //    //var ext2 = MyArrayUtils.CalculateExtremes(arr.HeightmapAsArray);
         //    //Debug.Log("T000_88: min "+ext2.Min+" max"+ext2.Max);
         //    //Debug.Log("___________________________");
         //}
         //list.ForEach(c => MyArrayUtils.Normalize(c.HeightmapAsArray));
     }
 }
Esempio n. 14
0
        public void Start_Mai_Debug()
        {
            var heightTexture1 = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
                                                                          240, TextureFormat.RGBA32, true, true);
            var heightmap1 = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture1);

            //DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            //var heightmap2 = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);
            //MyArrayUtils.Multiply(heightmap2.HeightmapAsArray, 0.1f);
            //HeightmapArray workingHeightmap = LoadHeightmapFromTextureFile(@"C:\inz\cont\temp3.png");
            HeightmapArray workingHeightmap = heightmap1;

            MyArrayUtils.Normalize(workingHeightmap.HeightmapAsArray);
            MyArrayUtils.InvertNormalized(workingHeightmap.HeightmapAsArray);
            HeightmapArray originalMap = new HeightmapArray(MyArrayUtils.DeepClone(workingHeightmap.HeightmapAsArray));

            MyArrayUtils.Multiply(workingHeightmap.HeightmapAsArray, 400);

            var configuration = new MeiHydraulicEroderConfiguration()
            {
                StepCount           = 50,
                A_PipeCrossSection  = 0.05f,
                ConstantWaterAdding = 1 / 64f,
                GravityAcceleration = 9.81f,
                DeltaT                   = 1f,
                DepositionConstant       = 0.0001f * 12 * 2f,
                DissolvingConstant       = 0.0001f * 12 * 2f,
                EvaporationConstant      = 0.05f * 10,
                GridSize                 = new Vector2(1, 1),
                L_PipeLength             = 1,
                SedimentCapacityConstant = 250
            };

            var eroder    = new MeiHydraulicEroder();
            var debOutput = eroder.ErodeWithDebug(SimpleHeightArray.FromHeightmap(workingHeightmap), configuration);

            MyArrayUtils.Multiply(workingHeightmap.HeightmapAsArray, 1f / 400);
            debOutput.NormalizeInGroups();


            _go = GameObject.CreatePrimitive(PrimitiveType.Quad);
            var material = new Material(Shader.Find("Custom/Terrain/Terrain_Mei_Debug_Comparision_StepByStep"));

            _go.GetComponent <MeshRenderer>().material = material;
            _go.name = "Terrain";
            _go.transform.localRotation          = Quaternion.Euler(0, 0, 0);
            _go.transform.localScale             = new Vector3(10, 1, 10);
            _go.transform.localPosition          = new Vector3(0, 0, 0);
            _go.GetComponent <MeshFilter>().mesh = PlaneGenerator.CreateFlatPlaneMesh(240, 240);

            MyHeightTextureArray heightTextureArray =
                new MyHeightTextureArray(240, 240, 2, TextureFormat.ARGB32, false, true);

            heightTextureArray.AddElementArray(originalMap, 0);
            heightTextureArray.AddElementArray(workingHeightmap, 1);
            _go.GetComponent <MeshRenderer>().material
            .SetTexture("_HeightmapTexArray", heightTextureArray.ApplyAndRetrive());


            var arrayListsCount  = debOutput.OneArrayListCount;
            var arrayListsLength = debOutput.OneArrayListLength;
            MyHeightTextureArray detailHeightTexturesArray =
                new MyHeightTextureArray(240, 240, arrayListsCount * arrayListsLength, TextureFormat.ARGB32, false,
                                         true);

            foreach (var snapshot in debOutput.ArraysDict.Values.SelectMany(c => c))
            {
                detailHeightTexturesArray.AddElementArray(snapshot);
            }
            _go.GetComponent <MeshRenderer>().material
            .SetTexture("_DetailTexArray", detailHeightTexturesArray.ApplyAndRetrive());
            _go.GetComponent <MeshRenderer>().material.SetFloat("_DetailTexLength", arrayListsLength);
        }
Esempio n. 15
0
 public float GetValueWithIndexClamped(Vector2 uv)
 {
     return(MyArrayUtils.GetValueWithIndexClamped(Array, uv));
 }
Esempio n. 16
0
        public void Start_Hydraulic_Debuggable()
        {
            var heightTexture1 = SavingFileManager.LoadPngTextureFromFile(@"C:\inz\cont\smallCut.png", 240,
                                                                          240, TextureFormat.RGBA32, true, true);
            var heightmap1 = HeightmapUtils.CreateHeightmapArrayFromTexture(heightTexture1);

            //DiamondSquareCreator creator = new DiamondSquareCreator(new RandomProvider(22));
            //var heightmap2 = creator.CreateDiamondSquareNoiseArray(new IntVector2(240, 240), 64);
            //MyArrayUtils.Multiply(heightmap2.HeightmapAsArray, 0.1f);

            var tParam = EroderDebugObject.CalculateFromHillFactor(1, new ArrayExtremes(0, 5000), 24);

            var extents = MyArrayUtils.CalculateExtremes(heightmap1.HeightmapAsArray);

            MyArrayUtils.Normalize(heightmap1.HeightmapAsArray);

            var configuration =
                new HydraulicEroderConfiguration()
            {
                StepCount                  = 20,
                NeighbourFinder            = NeighbourFinders.Big9Finder,
                kr_ConstantWaterAddition   = 0.001f,
                ks_GroundToSedimentFactor  = 1f,
                ke_WaterEvaporationFactor  = 0.05f,
                kc_MaxSedimentationFactor  = 0.8f,
                FinalSedimentationToGround = false,
                WaterGenerator             = HydraulicEroderWaterGenerator.FirstFrame,
                DestinationFinder          = HydraulicEroderWaterDestinationFinder.OnlyBest
            };

            var copyArray          = MyArrayUtils.DeepClone(heightmap1.HeightmapAsArray);
            var currentHeightArray = new SimpleHeightArray(copyArray);
            var eroder             = new DebuggableHydraulicEroder();
            var debuggingOutput    = eroder.Erode(currentHeightArray, configuration, 1);

            var sedimentExtentsArr = debuggingOutput.SedimentSnapshots
                                     .Select(c => MyArrayUtils.CalculateExtremes(c.Array)).ToList();
            var sedimentExtents = new ArrayExtremes(sedimentExtentsArr.Min(c => c.Min),
                                                    sedimentExtentsArr.Max(c => c.Max));

            debuggingOutput.SedimentSnapshots.ForEach(c => MyArrayUtils.Normalize(c.Array, sedimentExtents));

            var waterExtentsArr = debuggingOutput.WaterSnapshots.Select(c => MyArrayUtils.CalculateExtremes(c.Array))
                                  .ToList();
            var waterExtents = new ArrayExtremes(waterExtentsArr.Min(c => c.Min), waterExtentsArr.Max(c => c.Max));

            debuggingOutput.WaterSnapshots.ForEach(c => MyArrayUtils.Normalize(c.Array, waterExtents));


            _go = GameObject.CreatePrimitive(PrimitiveType.Quad);
            var material = new Material(Shader.Find("Custom/Terrain/Terrain_Debug_Comparision_StepByStep"));

            _go.GetComponent <MeshRenderer>().material = material;
            _go.name = "Terrain";
            _go.transform.localRotation          = Quaternion.Euler(0, 0, 0);
            _go.transform.localScale             = new Vector3(10, 1, 10);
            _go.transform.localPosition          = new Vector3(0, 0, 0);
            _go.GetComponent <MeshFilter>().mesh = PlaneGenerator.CreateFlatPlaneMesh(240, 240);

            MyHeightTextureArray heightTextureArray =
                new MyHeightTextureArray(240, 240, 2, TextureFormat.ARGB32, false, true);

            heightTextureArray.AddElementArray(heightmap1, 0);
            heightTextureArray.AddElementArray(new HeightmapArray(currentHeightArray.Array), 1);
            _go.GetComponent <MeshRenderer>().material
            .SetTexture("_HeightmapTexArray", heightTextureArray.ApplyAndRetrive());


            MyHeightTextureArray waterArray = new MyHeightTextureArray(240, 240, debuggingOutput.WaterSnapshots.Count,
                                                                       TextureFormat.ARGB32, false, true);
            int i = 0;

            foreach (var waterSnapshot in debuggingOutput.WaterSnapshots)
            {
                waterArray.AddElementArray(new HeightmapArray(waterSnapshot.Array), i);
                i++;
            }
            _go.GetComponent <MeshRenderer>().material.SetTexture("_WaterArray", waterArray.ApplyAndRetrive());


            MyHeightTextureArray sedimentArray = new MyHeightTextureArray(240, 240,
                                                                          debuggingOutput.SedimentSnapshots.Count, TextureFormat.ARGB32, false, true);
            int j = 0;

            foreach (var sedimentSnapshot in debuggingOutput.SedimentSnapshots)
            {
                sedimentArray.AddElementArray(new HeightmapArray(sedimentSnapshot.Array), j);
                j++;
            }
            _go.GetComponent <MeshRenderer>().material.SetTexture("_SedimentArray", sedimentArray.ApplyAndRetrive());
        }
Esempio n. 17
0
        public TerrainErosionDebugOutput ErodeWithDebug(SimpleHeightArray heightMap,
                                                        MeiHydraulicEroderConfiguration configuration)
        {
            var debugOutput = new TerrainErosionDebugOutput();
            var sb          = new StringBuilder();

            int     stepCount                   = configuration.StepCount;
            float   deltaT                      = configuration.DeltaT;
            float   constantWaterAdding         = configuration.ConstantWaterAdding;
            float   A_pipeCrossSection          = configuration.A_PipeCrossSection;
            float   l_pipeLength                = configuration.L_PipeLength;
            float   g_GravityAcceleration       = configuration.GravityAcceleration;
            float   ks_DissolvingConstant       = configuration.DissolvingConstant;
            float   kd_DepositionConstant       = configuration.DepositionConstant;
            float   ke_EvaporationConstant      = configuration.EvaporationConstant;
            float   kc_SedimentCapacityConstant = configuration.SedimentCapacityConstant;
            Vector2 gridSize                    = configuration.GridSize;

            float lX = gridSize.x;
            float lY = gridSize.y;

            var waterMap   = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var waterMap_1 = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var waterMap_2 = new SimpleHeightArray(heightMap.Width, heightMap.Height);

            var fluxMap       = new Vector4ArrayTODO(heightMap.Width, heightMap.Height);
            var velocityMap   = new VectorArrayTODO(heightMap.Width, heightMap.Height);
            var sedimentMap   = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var sedimentMap_1 = new SimpleHeightArray(heightMap.Width, heightMap.Height);

            for (int i = 0; i < stepCount; i++)
            {
                if (i >= 0)
                {
                    // water increment
                    for (int y = 0; y < heightMap.Height; y++)
                    {
                        for (int x = 0; x < heightMap.Width; x++)
                        {
                            var aPoint    = new IntVector2(x, y);
                            var oldValue  = waterMap.GetValue(aPoint);
                            var newAmount = oldValue + deltaT * constantWaterAdding;
                            waterMap_1.SetValue(aPoint, newAmount);
                            if (x == 10 && y == 10)
                            {
                                var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                                 velocityMap, sedimentMap, sedimentMap_1);
                                int yyy = 2;
                            }
                        }
                    }
                }
                else
                {
                    MyArrayUtils.Copy(waterMap.Array, waterMap_1.Array);
                }

                debugOutput.AddArray("waterMap", SimpleHeightArray.ToHeightmap(waterMap_1), i);
                debugOutput.AddArray("heightMap", SimpleHeightArray.ToHeightmap(heightMap), i);
                debugOutput.AddArray("sedimentMap", SimpleHeightArray.ToHeightmap(sedimentMap), i);

                var speedMap = new float[sedimentMap.Width, sedimentMap.Height];
                for (int x = 0; x < sedimentMap.Width; x++)
                {
                    for (int y = 0; y < sedimentMap.Height; y++)
                    {
                        speedMap[x, y] = velocityMap.GetValue(x, y).magnitude;
                    }
                }
                debugOutput.AddArray("speedMap", new HeightmapArray(speedMap), i);

                // flow simulation
                int onesCount = 0;
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var aPoint = new IntVector2(x, y);
                        if (x == 10 && y == 10)
                        {
                            var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                             velocityMap, sedimentMap, sedimentMap_1);
                            Debug.Log("T44. W0: " + waterMap.GetValue(aPoint) + " w1: " + waterMap_1.GetValue(aPoint));
                            int yyy = 2;
                        }

                        Vector4 newFlux    = Vector4.zero;
                        var     neighbours = GetNeighbours(heightMap, aPoint);
                        foreach (var neighbour in neighbours)
                        {
                            var d_difference = (heightMap.GetValue(aPoint) + waterMap_1.GetValue(aPoint)) -
                                               (heightMap.GetValue(neighbour.Position) +
                                                waterMap_1.GetValue(neighbour.Position));

                            var d_flux     = fluxMap.GetValue(aPoint)[(int)neighbour.DirectionIndex];
                            var d_new_flux = Mathf.Max(0,
                                                       d_flux + deltaT * A_pipeCrossSection * (g_GravityAcceleration * d_difference) /
                                                       l_pipeLength);
                            Preconditions.Assert(!float.IsNaN(d_new_flux), "");
                            newFlux[(int)neighbour.DirectionIndex] = d_new_flux;
                        }

                        var   aD1      = waterMap_1.GetValue(aPoint);
                        var   fluxSum  = VectorUtils.SumMembers(newFlux);
                        float K_factor = 0;
                        if (fluxSum != 0)
                        {
                            K_factor = Mathf.Min(1,
                                                 aD1 * (lX * lY) / (fluxSum * deltaT));
                        }
                        if (K_factor > 0.99999)
                        {
                            onesCount++;
                        }
                        fluxMap.SetValue(aPoint, K_factor * newFlux);
                    }
                }
                Debug.Log("t66: onesCount is " + onesCount);

                // velocity calculation
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var aPoint = new IntVector2(x, y);
                        if (x == 10 && y == 10)
                        {
                            var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                             velocityMap, sedimentMap, sedimentMap_1);
                            int yyy = 2;
                        }

                        var neighbours = GetNeighbours(heightMap, aPoint);

                        var outFlow = VectorUtils.SumMembers(fluxMap.GetValue(aPoint));
                        var inFlow  =
                            neighbours.Select(c => fluxMap.GetValue(c.Position)[(int)c.DirectionIndex.GetOpposite()])
                            .Sum();

                        var aChangeOfWater = deltaT * (inFlow - outFlow);
                        waterMap_2.SetValue(aPoint,
                                            Mathf.Max(0, waterMap_1.GetValue(aPoint) + aChangeOfWater / (lX * lY)));

                        var horizontalFlux =
                            GetFlux(fluxMap, neighbours, MaiNeighbourDirection.LEFT, MaiNeighbourDirection.RIGHT) -
                            fluxMap.GetValue(aPoint)[(int)MaiNeighbourDirection.LEFT] +
                            fluxMap.GetValue(aPoint)[(int)MaiNeighbourDirection.RIGHT] -
                            GetFlux(fluxMap, neighbours, MaiNeighbourDirection.RIGHT, MaiNeighbourDirection.LEFT);

                        var deltaWx = horizontalFlux / 2;

                        var verticalFlux =
                            GetFlux(fluxMap, neighbours, MaiNeighbourDirection.DOWN, MaiNeighbourDirection.UP) -
                            fluxMap.GetValue(aPoint)[(int)MaiNeighbourDirection.DOWN] +
                            fluxMap.GetValue(aPoint)[(int)MaiNeighbourDirection.UP] -
                            GetFlux(fluxMap, neighbours, MaiNeighbourDirection.UP, MaiNeighbourDirection.DOWN);

                        var deltaWy = verticalFlux / 2;

                        var avgHeight = (waterMap_1.GetValue(aPoint) + waterMap_2.GetValue(aPoint)) / 2;

                        var newVelocity = new Vector2(
                            (deltaWx / (lX * avgHeight)),
                            (deltaWy / (lY * avgHeight))
                            );
                        if (float.IsNaN(newVelocity.magnitude))
                        {
                            newVelocity = Vector2.zero;
                        }
                        velocityMap.SetValue(aPoint, newVelocity); //todo ograniczenie CFL
                    }
                }

                var erodedAmountMap     = new float[sedimentMap.Width, sedimentMap.Height];
                var depositionAmountMap = new float[sedimentMap.Width, sedimentMap.Height];

                // sediment calc
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var aPoint = new IntVector2(x, y);
                        if (x == 10 && y == 10)
                        {
                            var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                             velocityMap, sedimentMap, sedimentMap_1);
                            int yyy = 2;
                        }
                        var aHeight = heightMap.GetValue(aPoint);

                        Vector3 upDir = new Vector3(0, 0, lY);
                        if (y != heightMap.Height - 1)
                        {
                            var upHeight = heightMap.GetValue(aPoint + new IntVector2(0, 1));
                            upDir[1] = upHeight - aHeight;
                        }

                        Vector3 rightDir = new Vector3(lX, 0, 0);
                        if (x != heightMap.Width - 1)
                        {
                            var rightHeight = heightMap.GetValue(aPoint + new IntVector2(1, 0));
                            rightDir[1] = rightHeight - aHeight;
                        }

                        var aNormal = Vector3.Cross(upDir, rightDir);

                        var baseNormal = new Vector3(0, 1, 0);

                        var cosAlpha = Vector3.Dot(baseNormal, aNormal) / (baseNormal.magnitude * aNormal.magnitude);
                        var sinAlpha = Math.Sqrt(1 - cosAlpha * cosAlpha);

                        //////// OTHER CALCULATING

                        var _o_notmal =
                            new Vector3(
                                heightMap.GetValueWithZeroInMissing(y, x + 1) -
                                heightMap.GetValueWithZeroInMissing(y, x - 1),
                                heightMap.GetValueWithZeroInMissing(y + 1, x) -
                                heightMap.GetValueWithZeroInMissing(y - 1, x), 2);
                        var o_normal2 = _o_notmal.normalized;

                        Vector3 up         = new Vector3(0, 1, 0);
                        float   cosa       = Vector3.Dot(o_normal2, up);
                        float   o_sinAlpha = Mathf.Sin(Mathf.Acos(cosa));


                        // todo kontrolne zwiększenie wody
                        var capacity = kc_SedimentCapacityConstant * Mathf.Max(o_sinAlpha, 0.1f) *
                                       velocityMap.GetValue(aPoint).magnitude; //todo set minimum alpha

                        var suspendedSediment = sedimentMap.GetValue(aPoint);

                        erodedAmountMap[x, y]     = 0;
                        depositionAmountMap[x, y] = 0;
                        if (capacity > suspendedSediment)
                        {
                            var sedimentChangeAmount = (float)(ks_DissolvingConstant * (capacity - suspendedSediment));
                            erodedAmountMap[x, y] = sedimentChangeAmount;
                            heightMap.AddValue(aPoint, -sedimentChangeAmount);
                            sedimentMap_1.AddValue(aPoint, sedimentChangeAmount);
                        }
                        else
                        {
                            var sedimentChangeAmount = (float)(kd_DepositionConstant * (suspendedSediment - capacity));
                            depositionAmountMap[x, y] = sedimentChangeAmount;
                            heightMap.AddValue(aPoint,
                                               sedimentChangeAmount); // sedimentChangeAmount jest ujemna, więc dodajemy teren
                            sedimentMap_1.AddValue(aPoint, -sedimentChangeAmount);
                        }
                    }
                }

                debugOutput.AddArray("erodedAmount", new HeightmapArray(erodedAmountMap), i);
                debugOutput.AddArray("depositedAmount", new HeightmapArray(depositionAmountMap), i);

                // sediment transportation
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var aPoint = new IntVector2(x, y);
                        if (x == 10 && y == 10)
                        {
                            var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                             velocityMap, sedimentMap, sedimentMap_1);
                            int yyy = 2;
                        }
                        var velocity = velocityMap.GetValue(aPoint);
                        sedimentMap.SetValue(aPoint,
                                             sedimentMap_1.GetValueWithIndexClamped(aPoint.ToFloatVec() - velocity * deltaT));
                    }
                }

                //evaporation
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var aPoint = new IntVector2(x, y);
                        if (x == 10 && y == 10)
                        {
                            var settings = DebugGetMapValues(x, y, waterMap, waterMap_1, waterMap_2, fluxMap,
                                                             velocityMap, sedimentMap, sedimentMap_1);
                            int yyy = 2;
                        }
                        waterMap.SetValue(aPoint, waterMap_2.GetValue(aPoint) * (1 - ke_EvaporationConstant * deltaT));
                    }
                }
            }

            //for (int y = 0; y < heightMap.Height; y++)
            //{
            //    for (int x = 0; x < heightMap.Width; x++)
            //    {
            //        var aPoint = new IntVector2(x,y);
            //        heightMap.AddValue(aPoint, sedimentMap.GetValue(aPoint));
            //    }
            //}
            //Debug.Log("t23: " + sb.ToString());
            return(debugOutput);
        }
Esempio n. 18
0
        public DebuggableHydraulicEroderOutput Erode(SimpleHeightArray heightMap,
                                                     HydraulicEroderConfiguration configuration, int snapshotFrequencies)
        {
            List <SimpleHeightArray> WaterSnapshots    = new List <SimpleHeightArray>();
            List <SimpleHeightArray> SedimentSnapshots = new List <SimpleHeightArray>();


            float krParam = configuration.kr_ConstantWaterAddition;
            float ksParam = configuration.ks_GroundToSedimentFactor;
            float keParam = configuration.ke_WaterEvaporationFactor;
            float kcParam = configuration.kc_MaxSedimentationFactor;
            bool  finalSedimentationToGround = configuration.FinalSedimentationToGround;
            int   stepCount = configuration.StepCount;
            ErodedNeighbourFinder neighbourFinder = configuration.NeighbourFinder;

            var waterMap            = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var sedimentMap         = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var sedimentAdditionMap = new SimpleHeightArray(heightMap.Width, heightMap.Height);
            var waterAdditionMap    = new SimpleHeightArray(heightMap.Width, heightMap.Height);

            for (int i = 0; i < stepCount; i++)
            {
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var point = new IntVector2(x, y);
                        if (configuration.WaterGenerator == HydraulicEroderWaterGenerator.FirstFrame)
                        {
                            if (i == 0)
                            {
                                waterMap.AddValue(point, krParam);
                            }
                        }
                        else
                        {
                            waterMap.AddValue(point, krParam);
                        }

                        float amountChangedToSediment = ksParam * waterMap.GetValue(point);
                        heightMap.AddValue(point, -amountChangedToSediment);
                        sedimentMap.AddValue(point, amountChangedToSediment);
                    }
                }

                if (i == 0)
                {
                    WaterSnapshots.Add(new SimpleHeightArray(MyArrayUtils.DeepClone <float>(waterMap.Array)));
                    SedimentSnapshots.Add(new SimpleHeightArray(MyArrayUtils.DeepClone <float>(sedimentMap.Array)));
                }


                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var point = new IntVector2(x, y);

                        var neighbourPoints = neighbourFinder.Find(heightMap, point);

                        var pTotalHeight = heightMap.GetValue(point) + waterMap.GetValue(point);

                        var neighbours = neighbourPoints.Select(nPoint => new
                        {
                            Point                 = nPoint,
                            TotalHeight           = heightMap.GetValue(nPoint) + waterMap.GetValue(nPoint),
                            TotalHeightDifference = pTotalHeight - (heightMap.GetValue(nPoint) +
                                                                    waterMap.GetValue(nPoint)),
                        }).Where(c => c.TotalHeightDifference > 0).ToList();
                        if (!neighbours.Any())
                        {
                            continue;
                        }

                        var dTotalHeightDiffSum = neighbours.Sum(c => c.TotalHeightDifference);
                        var avgTotalHeight      = (neighbours.Sum(c => c.TotalHeight) + pTotalHeight) /
                                                  (neighbours.Count + 1);

                        var pSediment = sedimentMap.GetValue(point);
                        var pWater    = waterMap.GetValue(point);
                        if (pWater < 0.00000001f)
                        {
                            continue;
                        }
                        var pDeltaA = pTotalHeight - avgTotalHeight;
                        var pMin    = Mathf.Min(pDeltaA, pWater);

                        if (configuration.DestinationFinder == HydraulicEroderWaterDestinationFinder.OnlyBest)
                        {
                            var bestNeighbour = neighbours.OrderByDescending(c => c.TotalHeightDifference).First();
                            var nMovedWater   = pMin;
                            var addedSediment = pSediment * (nMovedWater / pWater);
                            waterAdditionMap.AddValue(bestNeighbour.Point, nMovedWater);
                            sedimentAdditionMap.AddValue(bestNeighbour.Point, addedSediment);

                            sedimentAdditionMap.AddValue(point, -addedSediment);
                            waterAdditionMap.AddValue(point, -pMin);
                        }
                        else
                        {
                            var movedSedimentSum = 0f;
                            foreach (var aNeighbour in neighbours)
                            {
                                var nMovedWater   = pMin * (aNeighbour.TotalHeightDifference / dTotalHeightDiffSum);
                                var addedSediment = pSediment * (nMovedWater / pWater);
                                movedSedimentSum += addedSediment;
                                waterAdditionMap.AddValue(aNeighbour.Point, nMovedWater);
                                sedimentAdditionMap.AddValue(aNeighbour.Point, addedSediment);
                            }
                            sedimentAdditionMap.AddValue(point, -movedSedimentSum);
                            waterAdditionMap.AddValue(point, -pMin);
                        }
                    }
                }

                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var point = new IntVector2(x, y);
                        waterMap.AddValue(point, waterAdditionMap.GetValue(point));
                        waterAdditionMap.SetValue(point, 0);

                        sedimentMap.AddValue(point, sedimentAdditionMap.GetValue(point));
                        sedimentAdditionMap.SetValue(point, 0);
                    }
                }

                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var point  = new IntVector2(x, y);
                        var pWater = waterMap.GetValue(point);
                        var waterAfterEvaporation = pWater * (1 - keParam);
                        waterMap.SetValue(point, waterAfterEvaporation);

                        var pSedimentMax  = kcParam * waterAfterEvaporation;
                        var pSediment     = sedimentMap.GetValue(point);
                        var deltaSediment = Mathf.Max(0, pSediment - pSedimentMax);
                        sedimentMap.AddValue(point, -deltaSediment);
                        heightMap.AddValue(point, deltaSediment);
                    }
                }

                if (i % snapshotFrequencies == 0)
                {
                    WaterSnapshots.Add(new SimpleHeightArray(MyArrayUtils.DeepClone <float>(waterMap.Array)));
                    SedimentSnapshots.Add(new SimpleHeightArray(MyArrayUtils.DeepClone <float>(sedimentMap.Array)));
                }
            }

            if (finalSedimentationToGround)
            {
                for (int y = 0; y < heightMap.Height; y++)
                {
                    for (int x = 0; x < heightMap.Width; x++)
                    {
                        var point = new IntVector2(x, y);
                        heightMap.AddValue(point, sedimentMap.GetValue(point));
                    }
                }
            }
            return(new DebuggableHydraulicEroderOutput()
            {
                SedimentSnapshots = SedimentSnapshots,
                WaterSnapshots = WaterSnapshots
            });
        }