void OnWizardCreate() { FoliageLog.d("On wizard create!"); List <int> hashes = new List <int>(); for (int i = 0; i < m_Types.Count; i++) { int hash = m_Types[i].m_Hash; if (m_Extracting[i] && m_Painter.HasFoliageType(hash) && hashes.Contains(hash) == false) { hashes.Add(hash); } } if (hashes.Count > 0) { m_Callback(hashes.ToArray()); } else { FoliageLog.w("Could not extract anything from the list!"); } }
private static void ExtractDetailsFromTerrain(FoliagePainter painter, Terrain terrain, List <FoliageDetailExtracterMapping> mappings, bool disable, bool delete) { string label = FoliageGlobals.LABEL_TERRAIN_DETAILS_EXTRACTED + terrain.name; FoliagePainterEditTime edit = painter.GetEditTime; int detailMapSizeW = terrain.terrainData.detailWidth; int detailMapSizeH = terrain.terrainData.detailHeight; float patchSizeW = terrain.terrainData.size.x / detailMapSizeW; float patchSizeH = terrain.terrainData.size.z / detailMapSizeH; int extracted = 0; // Extract the types for all the mapping for (int m = 0; m < mappings.Count; m++) { int layer = mappings[m].m_DetailLayer; int mapping = mappings[m].m_FoliageTypeHash; float density = mappings[m].m_ExtractedDensity; FoliageLog.Assert(painter.HasFoliageType(mapping), "Must have foliage hash!!"); // Get the foliage type FoliageType type = painter.GetFoliageTypeByHash(mapping); DetailPrototype proto = terrain.terrainData.detailPrototypes[layer]; // If we should align to the surface bool followTerrainNormal = type.m_PaintInfo.m_SurfaceAlign; Vector2 alignPercentage = type.m_PaintInfo.m_SurfaceAlignInfluence; // Get the terrain data int[,] data = terrain.terrainData.GetDetailLayer(0, 0, detailMapSizeW, detailMapSizeH, layer); // Iterate data for (int i = 0; i < detailMapSizeH; i++) { for (int j = 0; j < detailMapSizeW; j++) { // j,i not i,j int count = data[j, i]; if (count > 0) { // Minimum 1 never 0 count = Mathf.Clamp(Mathf.CeilToInt(count * density), 1, count + 1); // Map from local space cell space to local terrain space Vector2 cellMin = new Vector2(patchSizeW * i, patchSizeH * j); Vector2 cellMax = cellMin + new Vector2(patchSizeW, patchSizeH); for (int d = 0; d < count; d++) { Vector3 randomInCell; randomInCell.x = Random.Range(cellMin.x, cellMax.x); randomInCell.z = Random.Range(cellMin.y, cellMax.y); randomInCell.y = 0; randomInCell = FoliageTerrainUtilities.TerrainLocalToTerrainNormalizedPos(randomInCell, terrain); float y = FoliageTerrainUtilities.TerrainHeight(randomInCell, terrain); // Build the rotation Quaternion rotation = Quaternion.identity; if (followTerrainNormal) { Quaternion slopeOrientation = Quaternion.LookRotation(FoliageTerrainUtilities.TerrainNormal(randomInCell, terrain)) * Quaternion.Euler(90, 0, 0); // How much we orient towards the slope rotation = Quaternion.Slerp(rotation, slopeOrientation, Random.Range(alignPercentage.x, alignPercentage.y)); } // Rotate around the Y axis rotation *= Quaternion.Euler(0, Random.Range(0, 360), 0); // Random in cell in world position randomInCell = FoliageTerrainUtilities.TerrainNormalizedToWorldPos(randomInCell, terrain); randomInCell.y = y; Vector3 scale; float x = Random.Range(proto.minWidth, proto.maxWidth); scale.x = x; scale.z = x; scale.y = Random.Range(proto.minHeight, proto.maxHeight); // Construct a foliage instance based on the foliage type data FoliageInstance instance = new FoliageInstance(); // Build the foliage data based on the type instance.m_Position = randomInCell; instance.m_Rotation = rotation; instance.m_Scale = scale; // Instantiate at a random pos in that cell edit.AddFoliageInstance(mapping, instance, label); extracted++; } } // If we should delete if (delete) { data[j, i] = 0; } } } // End detail array iteration // If we deleted set the new detail layer data if (delete) { terrain.terrainData.SetDetailLayer(0, 0, layer, data); } } // End types iteration // If we should disable the trees and foliage draw if (disable) { terrain.drawTreesAndFoliage = false; } // If we deleted anything we need to save if (delete) { UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(terrain.gameObject.scene); } FoliageLog.i("Extracted details: " + extracted + " from: " + terrain.name); }
void OnWizardCreate() { if (m_TerrainsExtract.Count > 0) { if (m_TerrainsExtract.Count > 1) { for (int i = 1; i < m_TerrainsExtract.Count; i++) { if (HasSameDetails(m_TerrainsExtract[0].GetComponent <Terrain>(), m_TerrainsExtract[i].GetComponent <Terrain>()) == false) { FoliageLog.e("Missing type when verified! Don't modify the types/details while extracting details!"); return; } } } Terrain terrain = m_TerrainsExtract[0].GetComponent <Terrain>(); DetailPrototype[] proto = terrain.terrainData.detailPrototypes; List <FoliageDetailExtracterMapping> mappings = new List <FoliageDetailExtracterMapping>(); // Build all the extracting data for (int i = 0; i < m_PrototypesData.Length; i++) { var data = m_PrototypesData[i]; if (data.m_ShouldExtract == true && data.m_NoneMapping == false) { FoliageDetailExtracterMapping mapping = new FoliageDetailExtracterMapping(); mapping.m_DetailLayer = data.m_DetailLayer; mapping.m_FoliageTypeHash = data.m_FoliageHashMapping; mapping.m_ExtractedDensity = data.m_ExtractedDensity; mappings.Add(mapping); } } if (mappings.Count > 0) { // Check that we have all the types and nothing has been tampered between the create for (int i = 0; i < mappings.Count; i++) { if (m_Painter.HasFoliageType(mappings[i].m_FoliageTypeHash) == false) { FoliageLog.e("Missing type when created! Don't modify the types while extracting details!"); return; } if (mappings[i].m_DetailLayer < 0 || mappings[i].m_DetailLayer >= proto.Length) { FoliageLog.e("Missing type when created! Don't modify the types while extracting details!"); return; } } // Proceed with the extraction m_Callback(mappings, m_TerrainsExtract, m_DisableAfterExtraction, m_DeleteAfterExtraction); } else { FoliageLog.i("Nothing to extract!"); } } else { FoliageLog.i("Nothing to extract!"); } }