Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
        }
        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));
        }
Ejemplo n.º 4
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
            });
        }
Ejemplo n.º 5
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());
        }
Ejemplo n.º 6
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);
        }