#if GRIFFIN using UnityEngine; using System.Collections.Generic; using System.IO; #if UNITY_EDITOR using UnityEditor; #endif namespace Pinwheel.Griffin.DataTool { public class GUnityTerrainDataExporter { public GTerrainData SrcData { get; set; } public TerrainData DesData { get; set; } public bool CreateNewAsset { get; set; } public bool ExportGeometry { get; set; } public bool ExportTerrainSize { get; set; } public bool ExportSplats { get; set; } public bool OverwriteSplatLayers { get; set; } public bool ExportTrees { get; set; } public bool ExportGrasses { get; set; } public string DataDirectory { get; set; } public void Export() { try { #if UNITY_EDITOR GCommonGUI.ProgressBar("Working", "Saving unsaved assets...", 1f); //SaveAssets(); GCommonGUI.ProgressBar("Working", "Exporting", 1f); #endif InitializeAssets(); if (ExportGeometry) DoExportGeometry(); if (ExportSplats) DoExportSplats(); if (ExportTrees) DoExportTrees(); if (ExportGrasses) DoExportGrasses(); #if UNITY_EDITOR GCommonGUI.ProgressBar("Working", "Saving unsaved assets...", 1f); //SaveAssets(); #endif } catch (System.Exception e) { Debug.LogError(e.ToString()); } finally { #if UNITY_EDITOR GCommonGUI.ClearProgressBar(); #endif } } private void SaveAssets() { #if UNITY_EDITOR AssetDatabase.SaveAssets(); #endif } private void InitializeAssets() { if (CreateNewAsset) { DesData = new TerrainData(); DesData.SetDetailResolution(512, 32); #if UNITY_EDITOR GUtilities.EnsureDirectoryExists(DataDirectory); string fileName = string.Format("TerrainData_{0}.asset", SrcData.Id); string filePath = Path.Combine(DataDirectory, fileName); AssetDatabase.CreateAsset(DesData, filePath); #endif } if (ExportSplats) { #if !UNITY_2018_1 && !UNITY_2018_2 TerrainLayer[] layers = DesData.terrainLayers; DesData.terrainLayers = null; GSplatPrototypeGroup group = SrcData.Shading.Splats; if (group != null) { List prototypes = group.Prototypes; List newLayers = new List(); List layerToSave = new List(); for (int i = 0; i < prototypes.Count; ++i) { if (i < layers.Length && layers[i] != null && OverwriteSplatLayers) { prototypes[i].CopyTo(layers[i]); newLayers.Add(layers[i]); } else { TerrainLayer l = (TerrainLayer)prototypes[i]; layerToSave.Add(l); newLayers.Add(l); } } DesData.terrainLayers = newLayers.ToArray(); #if UNITY_EDITOR if (layerToSave.Count > 0) { GUtilities.EnsureDirectoryExists(DataDirectory); for (int i = 0; i < layerToSave.Count; ++i) { string fileName = string.Format("TerrainLayer_{0}_{1}.asset", layerToSave[i].diffuseTexture != null ? layerToSave[i].diffuseTexture.name : i.ToString(), System.DateTime.Now.Ticks); string filePath = Path.Combine(DataDirectory, fileName); AssetDatabase.CreateAsset(layerToSave[i], filePath); } } #endif } #else DesData.splatPrototypes = null; GSplatPrototypeGroup group = SrcData.Shading.Splats; if (group != null) { SplatPrototype[] layers = new SplatPrototype[group.Prototypes.Count]; for (int i = 0; i < layers.Length; ++i) { layers[i] = (SplatPrototype)group.Prototypes[i]; } DesData.splatPrototypes = layers; } #endif } } private void DoExportGeometry() { DesData.heightmapResolution = SrcData.Geometry.HeightMapResolution + 1; int resolution = DesData.heightmapResolution; float[,] heightSample = new float[resolution, resolution]; Vector2 uv = Vector2.zero; Vector2 enc = Vector2.zero; float h = 0; for (int z = 0; z < resolution; ++z) { for (int x = 0; x < resolution; ++x) { uv.Set( Mathf.InverseLerp(0, resolution - 1, x), Mathf.InverseLerp(0, resolution - 1, z)); enc = (Vector4)SrcData.Geometry.HeightMap.GetPixelBilinear(uv.x, uv.y); h = GCommon.DecodeTerrainHeight(enc); heightSample[z, x] = h; } } DesData.SetHeights(0, 0, heightSample); if (ExportTerrainSize) { DesData.size = new Vector3(SrcData.Geometry.Width, SrcData.Geometry.Height, SrcData.Geometry.Length); } } private void DoExportSplats() { DesData.alphamapResolution = SrcData.Shading.SplatControlResolution; Texture2D[] alphaMaps = DesData.alphamapTextures; for (int i = 0; i < alphaMaps.Length; ++i) { Texture2D controlMap = SrcData.Shading.GetSplatControlOrDefault(i); GCommon.CopyTexture(controlMap, alphaMaps[i]); } } private void DoExportTrees() { DesData.treeInstances = new TreeInstance[0]; DesData.treePrototypes = new TreePrototype[0]; if (SrcData.Foliage.Trees == null) return; TreePrototype[] treePrototypes = new TreePrototype[SrcData.Foliage.Trees.Prototypes.Count]; for (int i = 0; i < treePrototypes.Length; ++i) { treePrototypes[i] = (TreePrototype)SrcData.Foliage.Trees.Prototypes[i]; } DesData.treePrototypes = treePrototypes; TreeInstance[] treeInstances = new TreeInstance[SrcData.Foliage.TreeInstances.Count]; for (int i = 0; i < treeInstances.Length; ++i) { treeInstances[i] = (TreeInstance)SrcData.Foliage.TreeInstances[i]; } DesData.treeInstances = treeInstances; } private void DoExportGrasses() { DesData.detailPrototypes = new DetailPrototype[0]; if (SrcData.Foliage.Grasses == null) return; DetailPrototype[] detailPrototypes = new DetailPrototype[SrcData.Foliage.Grasses.Prototypes.Count]; for (int i = 0; i < detailPrototypes.Length; ++i) { detailPrototypes[i] = (DetailPrototype)SrcData.Foliage.Grasses.Prototypes[i]; } DesData.detailPrototypes = detailPrototypes; DesData.RefreshPrototypes(); List instances = SrcData.Foliage.GetGrassInstances(); if (DesData.detailResolution <= 0) { DesData.SetDetailResolution(512, 32); Debug.Log("Detail Resolution is invalid, set to default value (512/32)"); } int resolution = DesData.detailResolution; for (int layer = 0; layer < detailPrototypes.Length; ++layer) { int x = 0; int z = 0; int[,] density = new int[resolution, resolution]; for (int i = 0; i < instances.Count; ++i) { if (instances[i].PrototypeIndex != layer) continue; GGrassInstance g = instances[i]; x = Mathf.FloorToInt(Mathf.Lerp(0, resolution - 1, g.Position.x)); z = Mathf.FloorToInt(Mathf.Lerp(0, resolution - 1, g.Position.z)); density[z, x] += 1; } DesData.SetDetailLayer(0, 0, layer, density); } } } } #endif