public static string ProjectFileBrowser(string title, string description, string file, string extention) { string path = file; EGL.BeginHorizontal(); { EGL.PrefixLabel(title); GUILayout.Label(file, Skin.textField); string newPath = file; if (GUILayout.Button("Browse", GUILayout.Width(64f))) { newPath = EditorUtility.OpenFilePanel(description, Path.GetFullPath(UPath.GetAbsolutePath(file)), extention); if (newPath != string.Empty) { newPath = UPath.GetProjectPath(newPath); } else { newPath = file; } } path = newPath; } EGL.EndHorizontal(); return(path); }
public void SaveSettings() { // Parse prototypes to a format that can be serialized ImportCfg.SplatPrototypes.Clear(); foreach (SplatPrototype prototype in SplatPrototypes) { ImportCfg.SplatPrototypes.Add(SplatPrototypeConfiguration.Serialize(prototype)); } ImportCfg.DetailPrototypes.Clear(); foreach (DetailPrototype prototype in DetailPrototypes) { ImportCfg.DetailPrototypes.Add(DetailPrototypeConfiguration.Serialize(prototype)); } ImportCfg.TreePrototypes.Clear(); foreach (TreePrototype prototype in TreePrototypes) { ImportCfg.TreePrototypes.Add(TreePrototypeConfiguration.Serialize(prototype)); } // Serialize string filePath = UPath.GetAbsolutePath(ImportCfgPath); XmlSerializer serializer = new XmlSerializer(typeof(ImporterConfiguration)); TextWriter writer = new StreamWriter(filePath); serializer.Serialize(writer, ImportCfg); writer.Close(); ImportCfg.IsDirty = false; }
private void OpenTerrainDataFileStream() { string terrainDataPath = ""; #if UNITY_EDITOR terrainDataPath = UPath.GetAbsolutePath("Assets/Terrains/SwissAlps/swissalps.land"); #else terrainDataPath = Application.dataPath + "/swissalps.land"; #endif Debug.Log("Loading terrain file: " + terrainDataPath); _terrainReader = new BinaryReader(File.Open(terrainDataPath, FileMode.Open, FileAccess.Read)); }
public static void SetupMaterials() { if (!Directory.Exists(UPath.GetAbsolutePath(MaterialPath))) { Directory.CreateDirectory(MaterialPath); } var tiles = LandmasImporter.FindTerrainTilesInScene(); foreach (var lodLevel in tiles) { SetupLandmassUnityTerrain(lodLevel.Value, Instance.ImportCfg.LodLevels[lodLevel.Key], CustomShaderId, MaterialPath); } }
public void LoadSettings() { // Deserialize string filePath = UPath.GetAbsolutePath(ImportCfgPath); if (File.Exists(filePath)) { try { TextReader textReader = new StreamReader(filePath); XmlSerializer serializer = new XmlSerializer(typeof(ImporterConfiguration)); ImportCfg = serializer.Deserialize(textReader) as ImporterConfiguration; textReader.Close(); } catch (Exception e) { Debug.LogWarning("Import configuration could not be loaded, loading defaults.\n" + e.Message); ImportCfg = new ImporterConfiguration(); } } else { Debug.LogWarning("No configuration found, loading defaults"); ImportCfg = new ImporterConfiguration(); } // Parse splatPrototypeSettings to actual splatPrototype objects SplatPrototypes.Clear(); foreach (SplatPrototypeConfiguration settings in ImportCfg.SplatPrototypes) { var prototype = SplatPrototypeConfiguration.Deserialize(settings); SplatPrototypes.Add(prototype); } DetailPrototypes.Clear(); foreach (DetailPrototypeConfiguration settings in ImportCfg.DetailPrototypes) { var prototype = DetailPrototypeConfiguration.Deserialize(settings); DetailPrototypes.Add(prototype); } TreePrototypes.Clear(); foreach (TreePrototypeConfiguration settings in ImportCfg.TreePrototypes) { var prototype = TreePrototypeConfiguration.Deserialize(settings); TreePrototypes.Add(prototype); } ImportCfg.IsDirty = false; }
public List <string> FilterFolder(string path, string typeTag, string extention) { string absPath = UPath.GetAbsolutePath(path); if (!Directory.Exists(absPath)) { throw new DirectoryNotFoundException("Directory does not exist: " + path); } string pattern = "*" + typeTag + "*" + extention; string[] files = Directory.GetFiles(absPath, pattern, SearchOption.TopDirectoryOnly); List <string> assets = new List <string>(); for (int i = 0; i < files.Length; i++) { string fileName = UPath.GetProjectPath(files[i]); assets.Add(fileName); } return(assets); }
public IList <TerrainData> CreateTerrainDatas(string sourceFolder, IList <string> names, LodLevel lod) { string destinationPath = UPath.Combine(sourceFolder, "TerrainData"); string absPath = UPath.GetAbsolutePath(destinationPath); if (!Directory.Exists(absPath)) { Directory.CreateDirectory(absPath); } IList <TerrainData> terrainDatas = new List <TerrainData>(); for (int i = 0; i < names.Count; i++) { // Create structure var terrainData = new TerrainData { heightmapResolution = lod.HeightmapResolution + 1, alphamapResolution = lod.SplatmapResolution, size = new Vector3(lod.TerrainWidth, lod.TerrainHeight, lod.TerrainWidth) }; if (lod.HasDetailMap) { terrainData.SetDetailResolution(lod.DetailmapResolution, lod.DetailResolutionPerPatch); } terrainDatas.Add(terrainData); // Serialize it string terrainName = GetTerrainNameFromAsset(names[i]); string terrainDataPath = UPath.Combine(destinationPath, terrainName + "." + ImportCfg.TerrainDataExtention); AssetDatabase.CreateAsset(terrainData, terrainDataPath); } return(terrainDatas); }
public static void ExportTerrain() { var cfg = new TiledTerrainConfig(8, 1024, 32, 513, 512, 4000f); // Todo: get from global instead of hardcoding int totalPatches = cfg.NumTiles * cfg.PatchesPerTile; var lodTiles = LandmasImporter.FindTerrainTilesInScene(); var path = UPath.GetAbsolutePath("Assets/Terrains/SwissAlps/swissalps.land"); Debug.Log("Exporting terrain to: " + path); using (var writer = new BinaryWriter(File.Open(path, FileMode.Create))) { try { for (int x = 0; x < totalPatches; x++) { for (int z = 0; z < totalPatches; z++) { // Find tile this patch is from var tileIndex = new IntVector3(x / cfg.PatchesPerTile, 0, z / cfg.PatchesPerTile); var tile = lodTiles[0][tileIndex]; // Find out which pixels we need to read for this patch var startPatchIndex = new IntVector2(tileIndex.X * cfg.PatchesPerTile, tileIndex.Z * cfg.PatchesPerTile); var localPatchIndex = new IntVector2(x, z) - startPatchIndex; var heightPixIndex = new IntVector2(localPatchIndex.X * (cfg.PatchHeightRes - 1), localPatchIndex.Y * (cfg.PatchHeightRes - 1)); var splatPixIndex = new IntVector2(localPatchIndex.X * cfg.PatchSplatRes, localPatchIndex.Y * cfg.PatchSplatRes); // Sample PoT+1 blocks, so that each patch's edge overlaps the first edge of its neighbour float[,] heights = GetHeights(tile.Terrain.terrainData, heightPixIndex, cfg.PatchHeightRes); Vector3[,] normals = GetNormals(tile.Terrain.terrainData, heightPixIndex, cfg.PatchHeightRes); float[,,] splats = GetSplats(tile.Terrain.terrainData, splatPixIndex, cfg.PatchSplatRes); // Write heights for (int xPixel = 0; xPixel < cfg.PatchHeightRes; xPixel++) { for (int zPixel = 0; zPixel < cfg.PatchHeightRes; zPixel++) { ushort val = (ushort)(heights[xPixel, zPixel] * 65000f); writer.Write(val); } } // Write normals // Todo: calculate normals from loaded height values instead of caching them on disk // Todo: single byte per axis, implicit 3rd axis for (int xPixel = 0; xPixel < cfg.PatchHeightRes; xPixel++) { for (int zPixel = 0; zPixel < cfg.PatchHeightRes; zPixel++) { Vector3 normal = normals[xPixel, zPixel]; byte valX = (byte)((normal.x * 0.5f + 0.5f) * 250f); byte valY = (byte)((normal.y * 0.5f + 0.5f) * 250f); byte valZ = (byte)((normal.z * 0.5f + 0.5f) * 250f); writer.Write(valX); writer.Write(valY); writer.Write(valZ); } } // Write splats (todo: byte) for (int xPixel = 0; xPixel < cfg.PatchSplatRes; xPixel++) { for (int zPixel = 0; zPixel < cfg.PatchSplatRes; zPixel++) { // Swizzled writes because Unity's terrain data is store wrong byte valR = (byte)(splats[zPixel, xPixel, 0] * 250f); // Grass byte valA = (byte)(splats[zPixel, xPixel, 3] * 250f); // Snow writer.Write(valR); writer.Write(valA); } } } } } catch (Exception e) { Debug.LogException(e); } writer.Close(); } }