public void UpdateBiomeRepartitionPreview(BiomeData biomeData) { if (currentSampler == null || biomeRepartitionPreview == null) { return; } float min = currentSampler.min; float max = currentSampler.max; float range = max - min; //clear the current texture: for (int x = 0; x < previewTextureWidth; x++) { biomeRepartitionPreview.SetPixel(x, 0, Color.white); } localCoveragePercent = 0; int i = 0; foreach (var switchData in switchDatas) { float switchMin = Mathf.Max(switchData.min, min); float switchMax = Mathf.Min(switchData.max, max); float rMin = ((switchMin - min) / range) * previewTextureWidth; float rMax = ((switchMax - min) / range) * previewTextureWidth; localCoveragePercent += (rMax - rMin) / previewTextureWidth * 100; //Clamp values to image size: rMin = Mathf.Clamp(rMin, 0, biomeRepartitionPreview.width); rMax = Mathf.Clamp(rMax, 0, biomeRepartitionPreview.width); for (int x = (int)rMin; x < (int)rMax; x++) { biomeRepartitionPreview.SetPixel(x, 0, switchData.color); } i++; } //add water if there is and if switch mode is height: if (!biomeData.isWaterless && currentSamplerName == BiomeSamplerName.terrainHeight) { float rMax = (biomeData.waterLevel / range) * previewTextureWidth; rMax = Mathf.Clamp(rMax, 0, biomeRepartitionPreview.width); for (int x = 0; x < rMax; x++) { biomeRepartitionPreview.SetPixel(x, 0, Color.blue); } } biomeRepartitionPreview.Apply(); }
void FillParamRange(BiomeData biomeData) { builtSamplers.Clear(); for (int i = 0; i < biomeData.length; i++) { var dataSampler = biomeData.GetDataSampler(i); paramRanges.ranges[i] = new Vector2(dataSampler.dataRef.min, dataSampler.dataRef.max); builtSamplers.Add(dataSampler.dataRef); } }
public void UpdateIfNeeded(BiomeData biomeData) { if (blendEnabled != null && biomeData.length == blendEnabled.Length) { return; } blendEnabled = new bool[biomeData.length]; //set all blendEnabled value to true for (int i = 0; i < biomeData.length; i++) { blendEnabled[i] = true; } int waterIndex = biomeData.GetBiomeIndex(BiomeSamplerName.waterHeight); if (waterIndex != -1) { blendEnabled[waterIndex] = false; } }
public void OnGUI(BiomeData biomeData) { PWGUI.StartFrame(new Rect(0, 0, 0, 0)); if (biomeRepartitionPreview == null) { biomeRepartitionPreview = new Texture2D(previewTextureWidth, 1); UpdateBiomeRepartitionPreview(biomeData); } using (DefaultGUISkin.Get()) { reorderableSwitchDataList.DoLayoutList(); } EditorGUILayout.LabelField("repartition map: (" + localCoveragePercent.ToString("F1") + "%)"); Rect previewRect = EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true), GUILayout.Height(0)); previewRect.height = previewTextureHeight; GUILayout.Space(previewTextureHeight); PWGUI.TexturePreview(previewRect, biomeRepartitionPreview, false); PWGUI.SetScaleModeForField(-1, ScaleMode.StretchToFill); }
public static void DrawBiomeInfos(Rect view, BiomeData b) { if (b == null) { EditorGUILayout.LabelField("Null biome data"); return; } PWGUI.StartFrame(view); if (samplerFoldouts == null || samplerFoldouts.Length != b.length) { samplerFoldouts = new bool[b.length]; } // update = GUILayout.Button("Update maps"); //2D maps: int i = 0; foreach (var samplerDataKP in b.biomeSamplerNameMap) { if (!samplerDataKP.Value.is3D) { samplerFoldouts[i] = EditorGUILayout.Foldout(samplerFoldouts[i], samplerDataKP.Key); if (samplerFoldouts[i]) { PWGUI.Sampler2DPreview(samplerDataKP.Value.data2D); } } //TODO: 3D maps preview i++; } }
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; } } } } }
public bool BuildGraph(BiomeData biomeData) { ResetGraph(); PWNode rootNode = biomeData.biomeSwitchGraphStartPoint; Stack <PWNode> biomeNodes = new Stack <PWNode>(); biomeNodes.Push(rootNode); BiomeSwitchCell currentCell = null; //fill param range dictionary (used to compute weights) FillParamRange(biomeData); while (biomeNodes.Count > 0) { PWNode currentNode = biomeNodes.Pop(); Type nodeType = currentNode.GetType(); if (nodeType == typeof(PWNodeBiome)) { //get all precedent switch data in the order of the tree (start from rootNode) var precedentSwitchDatas = GetPrecedentSwitchDatas(currentNode, rootNode); var biomeNode = currentNode as PWNodeBiome; var lastSwitch = precedentSwitchDatas.Last(); currentCell = new BiomeSwitchCell(); //Set cell and partial biome remaining empty params currentCell.name = biomeNode.outputBiome.name = lastSwitch.name; currentCell.id = biomeNode.outputBiome.id = biomeIdCount++; currentCell.color = biomeNode.outputBiome.previewColor = 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(PWNodeBiomeBlender)) { if (currentCell == null) { throw new Exception("[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(); rootCell = cells.First(); if (!CheckValid()) { return(false); } isBuilt = true; return(true); }
public void FillBiomeMap(BiomeData biomeData, BiomeBlendList blendMatrix, float blendPercent = .15f) { Sampler terrain = biomeData.GetSampler(BiomeSamplerName.terrainHeight); var biomeSwitchValues = new BiomeSwitchValues(); //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++) { var val = biomeSwitchValues[i] = biomeData.biomeSamplers[i].data2D[x, y]; 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); 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(); }