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