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(); }
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; }
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); }
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); }
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); }
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 }); } }
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); }
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); }
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)); }
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 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)); } }
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); }
public float GetValueWithIndexClamped(Vector2 uv) { return(MyArrayUtils.GetValueWithIndexClamped(Array, uv)); }
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 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); }
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 }); }