public void SimpleSwitchGraphBuild() { PWMainGraph graph = TestUtils.GenerateTestMainGraphBiomeSwitch(); BiomeData bd = new BiomeData(); var wlevel = graph.FindNodeByName("wlevel"); var bswitch = graph.FindNodeByName <PWNodeBiomeSwitch>("bswitch"); var b1 = graph.FindNodeByName <PWNodeBiome>("b1"); var b2 = graph.FindNodeByName <PWNodeBiome>("b2"); bd.biomeSwitchGraphStartPoint = wlevel; PartialBiome p1 = new PartialBiome(); PartialBiome p2 = new PartialBiome(); b1.outputBiome = p1; b2.outputBiome = p2; //setup the switch values var sd = bswitch.switchList.switchDatas; sd[0].min = 0; sd[0].max = 5; sd[0].name = "1"; sd[0].samplerName = BiomeSamplerName.terrainHeight; sd[1].min = 5; sd[1].max = 10; sd[1].name = "2"; sd[1].samplerName = BiomeSamplerName.terrainHeight; Sampler2D terrainHeight = new Sampler2D(32, 1); terrainHeight.min = 0; terrainHeight.max = 10; bd.UpdateSamplerValue(BiomeSamplerName.terrainHeight, terrainHeight); BiomeSwitchGraph switchGraph = new BiomeSwitchGraph(); switchGraph.BuildGraph(bd); Assert.That(switchGraph.isBuilt == true); var values = new BiomeSwitchValues(); values[0] = 4.0f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 0f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 5f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 6.0f; Assert.That(switchGraph.FindBiome(values).id == p2.id); values[0] = 10f; Assert.That(switchGraph.FindBiome(values).id == p2.id); }
public BiomeSwitchCell FindBiome(BiomeSwitchValues values) { BiomeSwitchCell currentCell = (lastCell == null) ? rootCell : lastCell; if (!isBuilt || currentCell == null) { return(null); } //since there is no default state, we can do this: if (currentCell.Matches(values)) { return(currentCell); } int maxSearchDepth = 100; int i = 0; while (true) { if (i > maxSearchDepth) { Debug.LogError("[BiomeSurfaceGraph] Infinite loop detected, exiting ..."); return(null); } i++; if (currentCell.Matches(values)) { //try to find a better link var betterCell = CheckForBetterCell(currentCell, values); //if there is nothing better, we've the solution if (betterCell == null) { lastCell = currentCell; return(currentCell); } else { currentCell = betterCell; } continue; } else { //find the best link to take to get near from the node we look for currentCell = FindBestCell(currentCell, values); if (currentCell == null) { return(null); } } } }
BiomeSwitchCell CheckForBetterCell(BiomeSwitchCell cell, BiomeSwitchValues values) { //check the current node links and find if there is a better solution than the current foreach (var link in cell.links) { if (link.Matches(values)) { if (link.weight < cell.weight) { return(link); } } } return(null); }
BiomeSwitchCell FindBestCell(BiomeSwitchCell cell, BiomeSwitchValues values) { BiomeSwitchCell bestCell = null; float minGap = 1e20f; //return the best node to get close to the final one foreach (var link in cell.links) { if (link.Matches(values)) { return(link); } float gap = link.GapWidth(cell); if (gap > 0 && gap < minGap) { minGap = gap; bestCell = link; } } return(bestCell); }
public void FillBiomeMap(BiomeData biomeData, BiomeBlendList blendMatrix, float blendPercent = .15f) { Sampler terrain = biomeData.GetSampler(BiomeSamplerName.terrainHeight); var biomeSwitchValues = new BiomeSwitchValues(); if (!isBuilt) { Debug.LogError("Biome switch graph is not built, you can't fill the biome map !"); return; } //TODO: 3D Biome fill map if (biomeData.biomeMap == null || biomeData.biomeMap.NeedResize(terrain.size, terrain.step)) { biomeData.biomeMap = new BiomeMap2D(terrain.size, terrain.step); } Profiler.BeginSample("FillBiomeMap"); var blendParams = new BiomeSwitchCellParams(); //getter for range (faster than dictionary) float[] ranges = new float[biomeData.length]; for (int i = 0; i < biomeData.length; i++) { ranges[i] = paramRanges.ranges[i].y - paramRanges.ranges[i].x; } for (int x = 0; x < terrain.size; x++) { for (int y = 0; y < terrain.size; y++) { //fill biomeSwitchValue and blendParams with the current biomeData sampler values for (int i = 0; i < biomeData.length; i++) { biomeSwitchValues[i] = biomeData.biomeSamplers[i].data2D[x, y]; var val = biomeSwitchValues[i]; var r = ranges[i]; var spc = blendParams.switchParams[i]; spc.min = val - (r * blendPercent); spc.max = val + (r * blendPercent); spc.enabled = true; } var biomeSwitchCell = FindBiome(biomeSwitchValues); if (biomeSwitchCell == null) { Debug.LogError("Biome can't be found for values: " + biomeSwitchValues); foreach (var c in cells) { Debug.Log("c: " + c.name + " -> " + c.switchParams); } return; } short biomeId = biomeSwitchCell.id; biomeData.ids.Add(biomeId); biomeData.biomeMap.SetPrimaryBiomeId(x, y, biomeId); //add biome that can be blended with the primary biome, if (blendPercent > 0) { foreach (var link in biomeSwitchCell.links) { if (link.Overlaps(blendParams)) { float blend = link.ComputeBlend(blendMatrix, paramRanges, biomeSwitchValues, blendPercent); if (blend > 0.001f) { biomeData.biomeMap.AddBiome(x, y, link.id, blend); } } } } } } Profiler.EndSample(); }