BITFALL/Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain .../Runtime/Scripts/DataTool/GUnityTerrainDataExporter.cs

249 lines
8.8 KiB
C#

#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<GSplatPrototype> prototypes = group.Prototypes;
List<TerrainLayer> newLayers = new List<TerrainLayer>();
List<TerrainLayer> layerToSave = new List<TerrainLayer>();
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<GGrassInstance> 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