//Create a switchGraph that always return this biome Id public void BuildTestGraph(short biomeId) { BiomeSwitchCell bsc = new BiomeSwitchCell(); bsc.id = biomeId; rootCell = bsc; cells.Add(bsc); }
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); }
void ResetGraph() { isBuilt = false; biomeIdCount = 0; rootCell = null; lastCell = null; cells.Clear(); partialBiomePerId.Clear(); partialBiomePerName.Clear(); paramRanges.Clear(); for (int i = 0; i < BiomeData.maxBiomeSamplers; i++) { biomeCoverage[i] = 0; } }
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 bool BuildGraph(BiomeData biomeData) { ResetGraph(); BaseNode rootNode = biomeData.biomeSwitchGraphStartPoint; Stack <BaseNode> biomeNodes = new Stack <BaseNode>(); biomeNodes.Push(rootNode); BiomeSwitchCell currentCell = null; //fill param range dictionary (used to compute weights) FillParamRange(biomeData); while (biomeNodes.Count > 0) { BaseNode currentNode = biomeNodes.Pop(); Type nodeType = currentNode.GetType(); if (nodeType == typeof(NodeBiome)) { //get all precedent switch data in the order of the tree (start from rootNode) var precedentSwitchDatas = GetPrecedentSwitchDatas(currentNode, rootNode); var biomeNode = currentNode as NodeBiome; var lastSwitch = precedentSwitchDatas.Last(); currentCell = new BiomeSwitchCell(); //Set cell and partial biome remaining empty params currentCell.name = lastSwitch.name; biomeNode.outputBiome.name = lastSwitch.name; biomeNode.outputBiome.id = biomeIdCount++; currentCell.id = biomeNode.outputBiome.id; biomeNode.outputBiome.previewColor = lastSwitch.color; currentCell.color = lastSwitch.color; currentCell.weight = currentCell.GetWeight(paramRanges); //add the partial biome to utility dictionary accessors: partialBiomePerName[currentCell.name] = biomeNode.outputBiome; partialBiomePerId[currentCell.id] = biomeNode.outputBiome; //load all access condition for this biome switch foreach (var sd in precedentSwitchDatas) { int index = biomeData.GetBiomeIndex(sd.samplerName); var param = currentCell.switchParams.switchParams[index]; param.enabled = true; param.min = sd.min; param.max = sd.max; biomeCoverage[index] += (sd.max - sd.min) / (sd.absoluteMax - sd.absoluteMin); } } else if (nodeType == typeof(NodeBiomeBlender)) { if (currentCell == null) { throw new InvalidOperationException("[PWBiomeSwitchGraph] idk what happened but this is really bad"); } //if the flow reaches the biomeblender everything is OK and add the current cell to the graph cells.Add(currentCell); continue; } foreach (var outputNode in currentNode.GetOutputNodes()) { biomeNodes.Push(outputNode); } } //Generate links between all linkable nodes BuildLinks(); if (cells.Count != 0) { rootCell = cells.First(); } if (!CheckValid()) { return(false); } isBuilt = true; return(true); }