Example #1
0
    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;
        }
Example #3
0
        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();
        }
    }