public void FillBiomeMap(int biomeBlendCount, BiomeData biomeData) { bool is3DBiomes = false; bool is3DTerrain = biomeData.terrain3D != null; Biome[] nearestBiomes = new Biome[biomeBlendCount]; //TODO: biome blend count > 1 management //TODO: biomeData.datas3D null check if (biomeData.air3D != null || biomeData.wind3D != null || biomeData.wetness3D != null || biomeData.temperature3D != null) { is3DBiomes = true; } if (biomeData.terrainRef == null) { return; } int terrainSize = (is3DTerrain) ? biomeData.terrain3D.size : biomeData.terrain.size; float terrainStep = (is3DTerrain) ? biomeData.terrain3D.step : biomeData.terrain.step; if (is3DBiomes) { biomeData.biomeIds3D = new BiomeMap3D(terrainSize, terrainStep); } else { biomeData.biomeIds = new BiomeMap2D(terrainSize, terrainStep); } if (is3DBiomes) { //TODO } else { for (int x = 0; x < terrainSize; x++) { for (int y = 0; y < terrainSize; y++) { bool water = (biomeData.isWaterless) ? false : biomeData.waterHeight[x, y] > 0; float temp = (biomeData.temperature != null) ? biomeData.temperature[x, y] : 0; float wet = (biomeData.wetness != null) ? biomeData.wetness[x, y] : 0; // Debug.Log("map [" + x + "/" + y + "] = " + biomeData.terrain[x, y]); //TODO: 3D terrain management float height = (is3DTerrain) ? 0 : biomeData.terrain[x, y]; BiomeSwitchNode current = root; while (true) { nextChild: if (current.biome != null) { break; } int childCount = current.GetChildCount(); for (int i = 0; i < childCount; i++) { var child = current.GetChildAt(i); switch (child.biomeSwitchMode) { case BiomeSwitchMode.Water: if (child.value == water) { current = child; goto nextChild; } break; case BiomeSwitchMode.Height: if (height > child.min && height <= child.max) { current = child; goto nextChild; } break; case BiomeSwitchMode.Temperature: if (temp > child.min && temp <= child.max) { current = child; goto nextChild; } break; case BiomeSwitchMode.Wetness: if (wet > child.min && wet <= child.max) { current = child; goto nextChild; } break; } } //if flow reach this part, values are missing in the biome graph so biome can't be chosen. break; } //TODO: blending with second biome if (current.biome != null) { biomeData.biomeIds.SetFirstBiomeId(x, y, current.biome.id); } else { //FIXME!!!! biomeData.biomeIds.SetFirstBiomeId(x, y, -1); // PWUtils.LogWarningMax("Can't choose biome with water:" + water + ", temp: " + temp + ", wet: " + wet + ", height: " + height, 200); PWUtils.LogWarningMax("Can't choose biome with water:" + water + ", temp: " + temp + ", wet: " + wet + ", height: " + height, 300); continue; } } } } }
void BuildTreeInternal(PWNode node, BiomeSwitchNode currentNode, int depth, BiomeSwitchNode parent = null) { if (node == null) { return; } //TODO: anchor to multiple PWNodeBiomeSwitch management if (node.GetType() == typeof(PWNodeBiomeSwitch)) { PWNodeBiomeSwitch bSwitch = node as PWNodeBiomeSwitch; int outputLinksCount = bSwitch.GetLinks().Count; int childIndex = 0; List <PWNode> outputNodeList = new List <PWNode>(); Debug.Log("encountered switch: " + bSwitch.switchMode); currentNode.SetChildCount(outputLinksCount); switch (bSwitch.switchMode) { case BiomeSwitchMode.Water: int?terrestrialAnchorId = node.GetAnchorId(PWAnchorType.Output, 0); int?aquaticAnchorId = node.GetAnchorId(PWAnchorType.Output, 1); if (terrestrialAnchorId != null) { var nodes = node.GetNodesAttachedToAnchor(terrestrialAnchorId.Value); outputNodeList.AddRange(nodes); // Debug.Log("terrestrialNodes: " + nodes[0].nodeId); for (int i = 0; i < nodes.Count; i++) { currentNode.GetChildAt(childIndex++).SetSwitchValue(false, bSwitch.switchMode, "terrestrial", Color.black); } biomeCoverage[BiomeSwitchMode.Water] += 0.5f; } //get all nodes on the first anchor: if (aquaticAnchorId != null) { var nodes = node.GetNodesAttachedToAnchor(aquaticAnchorId.Value); // Debug.Log("aquaticNodes: " + nodes[0].nodeId); outputNodeList.AddRange(nodes); for (int i = 0; i < nodes.Count; i++) { currentNode.GetChildAt(childIndex++).SetSwitchValue(true, bSwitch.switchMode, "aquatic", Color.blue); } biomeCoverage[BiomeSwitchMode.Water] += 0.5f; } break; default: // Debug.Log("swicth data count for node " + node.nodeId + ": " + bSwitch.switchDatas.Count); for (int anchorIndex = 0; anchorIndex < bSwitch.switchDatas.Count; anchorIndex++) { int?anchorId = node.GetAnchorId(PWAnchorType.Output, anchorIndex); var sData = bSwitch.switchDatas[anchorIndex]; if (anchorId == null) { continue; } var attachedNodesToAnchor = node.GetNodesAttachedToAnchor(anchorId.Value); outputNodeList.AddRange(attachedNodesToAnchor); // if (attachedNodesToAnchor.Count == 0) // Debug.LogWarning("nothing attached to the biome switch output " + anchorIndex); foreach (var attachedNode in attachedNodesToAnchor) { var child = currentNode.GetChildAt(childIndex++); child.SetSwitchValue(sData.min, sData.max, bSwitch.switchMode, sData.name, sData.color); } biomeCoverage[bSwitch.switchMode] += (sData.max - sData.min) / (sData.absoluteMax - sData.absoluteMin); } break; } childIndex = 0; foreach (var outNode in outputNodeList) { if (bSwitch.switchMode == BiomeSwitchMode.Water) { Debug.Log("water switch mode output type: " + currentNode.GetChildAt(childIndex) + " [" + childIndex + "] -> " + outNode); } BuildTreeInternal(outNode, currentNode.GetChildAt(childIndex, true), depth + 1, currentNode); Type outNodeType = outNode.GetType(); if (outNodeType == typeof(PWNodeBiomeSwitch) || outNodeType == typeof(PWNodeBiomeBinder)) { childIndex++; } } } else if (node.GetType() == typeof(PWNodeBiomeBinder)) { PWNodeBiomeBinder binder = node as PWNodeBiomeBinder; string biomeName = currentNode.biomeName; if (String.IsNullOrEmpty(biomeName)) { Debug.LogWarning("Biome name null or empty for biomeBinder: " + binder); return; } //Biome binder detected, assign the biome to the current Node: currentNode.biome = binder.outputBiome; // Debug.Log("current node: " + currentNode + ", preview color: " + currentNode.previewColor); //set the color of the biome in the binder binder.outputBiome.previewColor = currentNode.previewColor; Debug.Log("set biome " + currentNode.biome + " in node " + currentNode); //set the biome ID and name: currentNode.biome.name = biomeName; currentNode.biome.id = biomeIdCount++; //store the biome in dictionaries for fast access biomePerId[currentNode.biome.id] = currentNode.biome; biomePerName[biomeName] = currentNode.biome; } else { foreach (var outNode in node.GetOutputNodes()) { BuildTreeInternal(outNode, currentNode, depth++, parent); } } return; }