portals and dash. Also a bit of terrain building and level design

This commit is contained in:
2022-03-13 00:26:35 +02:00
parent 813cd0c451
commit e82799c36a
6242 changed files with 2160679 additions and 188245 deletions

View File

@@ -0,0 +1,9 @@
#if GRIFFIN
namespace Pinwheel.Griffin.DataTool
{
public enum GBitDepth
{
Bit8, Bit16
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 97f8aa96543decd419fc44e24ad0b5b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
#if GRIFFIN
using UnityEngine;
using System.IO;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Griffin.DataTool
{
public class GRawExporter
{
public GTerrainData SrcData { get; set; }
public GBitDepth BitDepth { get; set; }
public string DataDirectory { get; set; }
public void Export()
{
try
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Working", "Exporting RAW file...", 1f);
#endif
if (BitDepth == GBitDepth.Bit8)
{
DoExportRaw8();
}
else if (BitDepth == GBitDepth.Bit16)
{
DoExportRaw16();
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
private void DoExportRaw8()
{
int rawResolution = SrcData.Geometry.HeightMapResolution + 1;
byte[] data = new byte[rawResolution * rawResolution];
Vector2 uv = Vector2.zero;
Color c = Color.white;
Vector2 enc = Vector2.zero;
byte h = 0;
for (int z = 0; z < rawResolution; ++z)
{
for (int x = 0; x < rawResolution; ++x)
{
uv.Set(
Mathf.InverseLerp(0, rawResolution - 1, x),
1 - Mathf.InverseLerp(0, rawResolution - 1, z));
c = SrcData.Geometry.HeightMap.GetPixelBilinear(uv.x, uv.y);
enc.Set(c.r, c.g);
h = (byte)(GCommon.DecodeTerrainHeight(enc) * byte.MaxValue);
data[GUtilities.To1DIndex(x, z, rawResolution)] = h;
}
}
GUtilities.EnsureDirectoryExists(DataDirectory);
string fileName = string.Format("RAW8_{0}x{0}_{1}.raw", rawResolution, SrcData.Id);
string path = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(path, data);
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
private void DoExportRaw16()
{
int rawResolution = SrcData.Geometry.HeightMapResolution + 1;
byte[] data = new byte[rawResolution * rawResolution * sizeof(UInt16)];
Vector2 uv = Vector2.zero;
Color c = Color.white;
Vector2 enc = Vector2.zero;
UInt16 h = 0;
int startIndex = 0;
for (int z = 0; z < rawResolution; ++z)
{
for (int x = 0; x < rawResolution; ++x)
{
uv.Set(
Mathf.InverseLerp(0, rawResolution - 1, x),
1 - Mathf.InverseLerp(0, rawResolution - 1, z));
c = SrcData.Geometry.HeightMap.GetPixelBilinear(uv.x, uv.y);
enc.Set(c.r, c.g);
h = (UInt16)(GCommon.DecodeTerrainHeight(enc) * UInt16.MaxValue);
startIndex = 2 * GUtilities.To1DIndex(x, z, rawResolution);
Array.Copy(BitConverter.GetBytes(h), 0, data, startIndex, sizeof(UInt16));
}
}
GUtilities.EnsureDirectoryExists(DataDirectory);
string fileName = string.Format("RAW16_{0}x{0}_{1}.r16", rawResolution, SrcData.Id);
string path = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(path, data);
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6cc359d9748e6d64db0e4c855b8fa160
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,154 @@
#if GRIFFIN
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace Pinwheel.Griffin.DataTool
{
public class GRawImporter
{
public GStylizedTerrain Terrain { get; set; }
public GTerrainData DesData { get; set; }
public GBitDepth BitDepth { get; set; }
public bool UseRawResolution { get; set; }
public string FilePath { get; set; }
public void Import()
{
try
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Working", "Importing RAW...", 1f);
#endif
if (BitDepth == GBitDepth.Bit8)
{
ImportRaw8();
}
else if (BitDepth == GBitDepth.Bit16)
{
ImportRaw16();
}
if (Terrain != null)
{
DesData.Foliage.SetTreeRegionDirty(GCommon.UnitRect);
DesData.Foliage.SetGrassRegionDirty(GCommon.UnitRect);
Terrain.UpdateTreesPosition();
Terrain.UpdateGrassPatches();
DesData.Foliage.ClearTreeDirtyRegions();
DesData.Foliage.ClearGrassDirtyRegions();
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
private void ImportRaw8()
{
byte[] data = File.ReadAllBytes(FilePath);
int rawResolution = Mathf.FloorToInt(Mathf.Sqrt(data.Length));
if (rawResolution * rawResolution != data.Length)
throw new Exception("Error on populate data, RAW file doesn't have squared size or bit depth has been mis-configured!");
if (UseRawResolution)
DesData.Geometry.HeightMapResolution = rawResolution;
float[] heightData = new float[rawResolution * rawResolution];
for (int i = 0; i < heightData.Length; ++i)
{
heightData[i] = data[i] * 1.0f / byte.MaxValue;
}
Vector2 uv = Vector2.zero;
Vector2 enc = Vector2.zero;
float h = 0;
Color[] heightMapColors = DesData.Geometry.HeightMap.GetPixels();
Color[] oldHeightMapColors = new Color[heightMapColors.Length];
Array.Copy(heightMapColors, oldHeightMapColors, heightMapColors.Length);
int heightMapResolution = DesData.Geometry.HeightMapResolution;
for (int z = 0; z < heightMapResolution; ++z)
{
for (int x = 0; x < heightMapResolution; ++x)
{
uv.Set(
Mathf.InverseLerp(0, heightMapResolution - 1, x),
1 - Mathf.InverseLerp(0, heightMapResolution - 1, z));
Color c = heightMapColors[GUtilities.To1DIndex(x, z, heightMapResolution)];
h = GUtilities.GetValueBilinear(heightData, rawResolution, rawResolution, uv);
enc = GCommon.EncodeTerrainHeight(h);
c.r = enc.x;
c.g = enc.y;
heightMapColors[GUtilities.To1DIndex(x, z, heightMapResolution)] = c;
}
}
DesData.Geometry.HeightMap.SetPixels(heightMapColors);
DesData.Geometry.HeightMap.Apply();
IEnumerable<Rect> dirtyRects = GCommon.CompareTerrainTexture(DesData.Geometry.ChunkGridSize, oldHeightMapColors, heightMapColors);
DesData.Geometry.SetRegionDirty(dirtyRects);
DesData.SetDirty(GTerrainData.DirtyFlags.Geometry);
}
private void ImportRaw16()
{
byte[] data = File.ReadAllBytes(FilePath);
int rawResolution = Mathf.FloorToInt(Mathf.Sqrt(data.Length / sizeof(UInt16)));
if (rawResolution * rawResolution != data.Length / sizeof(UInt16))
throw new Exception("Error on populate data, RAW file doesn't have squared size or bit depth has been mis-configured!");
if (UseRawResolution)
DesData.Geometry.HeightMapResolution = rawResolution;
float[] heightData = new float[rawResolution * rawResolution];
for (int i = 0; i < heightData.Length; ++i)
{
UInt16 pixelValue = BitConverter.ToUInt16(data, i * 2);
heightData[i] = pixelValue * 1.0f / UInt16.MaxValue;
}
Vector2 uv = Vector2.zero;
Vector2 enc = Vector2.zero;
float h = 0;
Color[] heightMapColors = DesData.Geometry.HeightMap.GetPixels();
Color[] oldHeightMapColors = new Color[heightMapColors.Length];
Array.Copy(heightMapColors, oldHeightMapColors, heightMapColors.Length);
int heightMapResolution = DesData.Geometry.HeightMapResolution;
for (int z = 0; z < heightMapResolution; ++z)
{
for (int x = 0; x < heightMapResolution; ++x)
{
uv.Set(
Mathf.InverseLerp(0, heightMapResolution - 1, x),
1 - Mathf.InverseLerp(0, heightMapResolution - 1, z));
Color c = heightMapColors[GUtilities.To1DIndex(x, z, heightMapResolution)];
h = GUtilities.GetValueBilinear(heightData, rawResolution, rawResolution, uv);
enc = GCommon.EncodeTerrainHeight(h);
c.r = enc.x;
c.g = enc.y;
heightMapColors[GUtilities.To1DIndex(x, z, heightMapResolution)] = c;
}
}
DesData.Geometry.HeightMap.SetPixels(heightMapColors);
DesData.Geometry.HeightMap.Apply();
IEnumerable<Rect> dirtyRects = GCommon.CompareTerrainTexture(DesData.Geometry.ChunkGridSize, oldHeightMapColors, heightMapColors);
DesData.Geometry.SetRegionDirty(dirtyRects);
DesData.SetDirty(GTerrainData.DirtyFlags.Geometry);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b73933ddf39291b48a8409cc82f827ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,169 @@
#if GRIFFIN
using UnityEngine;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Griffin.DataTool
{
public class GTextureExporter
{
public GTerrainData SrcData { get; set; }
public bool ExportHeightMap { get; set; }
public bool ExportVisibilityMap { get; set; }
public bool ExportAlbedoMap { get; set; }
public bool ExportMetallicMap { get; set; }
public bool ExportGradientLookupMaps { get; set; }
public bool ExportSplatControlMaps { get; set; }
public string DataDirectory { get; set; }
public void Export()
{
try
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Working", "Exporting terrain textures...", 1f);
#endif
if (ExportHeightMap)
{
DoExportHeightMap();
}
if (ExportVisibilityMap)
{
DoExportVisibilityMap();
}
if (ExportAlbedoMap)
{
DoExportAlbedoMap();
}
if (ExportMetallicMap)
{
DoExportMetallicMap();
}
if (ExportGradientLookupMaps)
{
DoExportGradientLookupMaps();
}
if (ExportSplatControlMaps)
{
DoExportSplatControlMaps();
}
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
catch (System.Exception e)
{
Debug.LogError(e);
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
private void DoExportHeightMap()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
Color[] colors = SrcData.Geometry.HeightMap.GetPixels();
Vector2 enc = Vector2.zero;
float h = 0;
for (int i = 0; i < colors.Length; ++i)
{
enc.Set(colors[i].r, colors[i].g);
h = GCommon.DecodeTerrainHeight(enc);
colors[i] = new Color(h, 0, 0, 0);
}
Texture2D tex = new Texture2D(SrcData.Geometry.HeightMapResolution, SrcData.Geometry.HeightMapResolution, TextureFormat.RGBAFloat, false);
tex.SetPixels(colors);
tex.Apply();
byte[] data = tex.EncodeToPNG();
GUtilities.DestroyObject(tex);
string fileName = string.Format("HeightMap_{0}x{0}_{1}.png", SrcData.Geometry.HeightMapResolution, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
}
private void DoExportVisibilityMap()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
Color[] colors = SrcData.Geometry.HeightMap.GetPixels();
for (int i = 0; i < colors.Length; ++i)
{
colors[i] = new Color(1 - colors[i].a, 0, 0, 0);
}
Texture2D tex = new Texture2D(SrcData.Geometry.HeightMapResolution, SrcData.Geometry.HeightMapResolution);
tex.SetPixels(colors);
tex.Apply();
byte[] data = tex.EncodeToPNG();
GUtilities.DestroyObject(tex);
string fileName = string.Format("VisibilityMap_{0}x{0}_{1}.png", SrcData.Geometry.HeightMapResolution, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
}
private void DoExportAlbedoMap()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
Texture2D albedo = GCommon.CloneAndResizeTexture(SrcData.Shading.AlbedoMapOrDefault, SrcData.Shading.AlbedoMapResolution, SrcData.Shading.AlbedoMapResolution);
byte[] data = albedo.EncodeToPNG();
string fileName = string.Format("AlbedoMap_{0}x{0}_{1}.png", SrcData.Shading.AlbedoMapResolution, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
GUtilities.DestroyObject(albedo);
}
private void DoExportMetallicMap()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
Texture2D metallic = GCommon.CloneAndResizeTexture(SrcData.Shading.MetallicMapOrDefault, SrcData.Shading.MetallicMapResolution, SrcData.Shading.MetallicMapResolution);
byte[] data = metallic.EncodeToPNG();
string fileName = string.Format("MetallicMap_{0}x{0}_{1}.png", SrcData.Shading.MetallicMapResolution, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
GUtilities.DestroyObject(metallic);
}
private void DoExportGradientLookupMaps()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
SrcData.Shading.UpdateLookupTextures();
SrcData.Shading.UpdateMaterials();
Texture2D[] lookupTextures = new Texture2D[]
{
SrcData.Shading.ColorByHeightMap,
SrcData.Shading.ColorByNormalMap,
SrcData.Shading.ColorBlendMap
};
for (int i = 0; i < lookupTextures.Length; ++i)
{
Texture2D tex = lookupTextures[i];
byte[] data = tex.EncodeToPNG();
string fileName = string.Format("{0}_{1}x{2}_{3}.png", tex.name.Replace(" ", ""), tex.width, tex.height, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
}
}
private void DoExportSplatControlMaps()
{
GUtilities.EnsureDirectoryExists(DataDirectory);
int controlCount = SrcData.Shading.SplatControlMapCount;
for (int i = 0; i < controlCount; ++i)
{
Texture2D tex = GCommon.CloneAndResizeTexture(SrcData.Shading.GetSplatControlOrDefault(i), SrcData.Shading.SplatControlResolution, SrcData.Shading.SplatControlResolution);
byte[] data = tex.EncodeToPNG();
string fileName = string.Format("{0}_{1}x{2}_{3}.png", tex.name.Replace(" ", ""), tex.width, tex.height, SrcData.Id);
string filePath = Path.Combine(DataDirectory, fileName);
File.WriteAllBytes(filePath, data);
GUtilities.DestroyObject(tex);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce364b90f86764448a10f6fdf9dc17ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,140 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEngine;
namespace Pinwheel.Griffin.DataTool
{
public class GTextureImporter
{
public GStylizedTerrain Terrain { get; set; }
public GTerrainData DesData { get; set; }
public Texture2D HeightMap { get; set; }
public Texture2D MaskMap { get; set; }
public Texture2D VisibilityMap { get; set; }
public Texture2D AlbedoMap { get; set; }
public Texture2D MetallicMap { get; set; }
public Texture2D[] SplatControlMaps { get; set; }
public void Import()
{
try
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Working", "Importing textures...", 1f);
#endif
if (HeightMap != null || VisibilityMap != null)
{
Color[] oldHeightMapColors = DesData.Geometry.HeightMap.GetPixels();
Texture2D hm = null;
if (HeightMap != null)
hm = GCommon.CloneTexture(HeightMap);
Texture2D vm = null;
if (VisibilityMap != null)
vm = GCommon.CloneTexture(VisibilityMap);
int desResolution = DesData.Geometry.HeightMapResolution;
Color[] newColor = new Color[desResolution * desResolution];
Vector2 uv = Vector2.zero;
Vector2 enc = Vector2.zero;
for (int y = 0; y < desResolution; ++y)
{
for (int x = 0; x < desResolution; ++x)
{
uv.Set(
Mathf.InverseLerp(0, desResolution, x),
Mathf.InverseLerp(0, desResolution, y));
Color c = Color.clear;
if (hm != null)
{
enc = GCommon.EncodeTerrainHeight(hm.GetPixelBilinear(uv.x, uv.y).r);
c.r = enc.x;
c.g = enc.y;
}
else
{
c = DesData.Geometry.HeightMap.GetPixelBilinear(uv.x, uv.y);
}
if (vm != null)
{
c.a = 1 - vm.GetPixelBilinear(uv.x, uv.y).r;
}
else
{
c.a = DesData.Geometry.HeightMap.GetPixelBilinear(uv.x, uv.y).a;
}
newColor[GUtilities.To1DIndex(x, y, desResolution)] = c;
}
}
DesData.Geometry.HeightMap.SetPixels(newColor);
DesData.Geometry.HeightMap.Apply();
if (hm != null || vm != null)
{
Color[] newHeightMapColors = DesData.Geometry.HeightMap.GetPixels();
IEnumerable<Rect> dirtyRects = GCommon.CompareTerrainTexture(DesData.Geometry.ChunkGridSize, oldHeightMapColors, newHeightMapColors);
DesData.Geometry.SetRegionDirty(dirtyRects);
DesData.SetDirty(GTerrainData.DirtyFlags.GeometryTimeSliced);
if (Terrain != null)
{
DesData.Foliage.SetTreeRegionDirty(GCommon.UnitRect);
DesData.Foliage.SetGrassRegionDirty(GCommon.UnitRect);
Terrain.UpdateTreesPosition();
Terrain.UpdateGrassPatches();
DesData.Foliage.ClearTreeDirtyRegions();
DesData.Foliage.ClearGrassDirtyRegions();
}
}
if (hm != null)
GUtilities.DestroyObject(hm);
if (vm != null)
GUtilities.DestroyObject(vm);
}
if (MaskMap != null)
{
GCommon.CopyTexture(MaskMap, DesData.Mask.MaskMap);
}
if (AlbedoMap != null)
{
GCommon.CopyTexture(AlbedoMap, DesData.Shading.AlbedoMap);
DesData.SetDirty(GTerrainData.DirtyFlags.Shading);
}
if (MetallicMap != null)
{
GCommon.CopyTexture(MetallicMap, DesData.Shading.MetallicMap);
DesData.SetDirty(GTerrainData.DirtyFlags.Shading);
}
if (SplatControlMaps != null)
{
int count = Mathf.Min(SplatControlMaps.Length, DesData.Shading.SplatControlMapCount);
for (int i = 0; i < count; ++i)
{
if (SplatControlMaps[i] != null)
{
GCommon.CopyTexture(SplatControlMaps[i], DesData.Shading.GetSplatControl(i));
}
}
DesData.SetDirty(GTerrainData.DirtyFlags.Shading);
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b866e3498ed5ec4ba8c6b3deee62f41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,248 @@
#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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c2b76fec165bee428b64ab4a8c7d6d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,370 @@
#if GRIFFIN
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using GC = System.GC;
using Rand = System.Random;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Griffin.DataTool
{
public class GUnityTerrainDataImporter
{
public Terrain SrcTerrain { get; set; }
public TerrainData SrcData { get; set; }
public GTerrainData DesData { get; set; }
public GStylizedTerrain DesTerrain { get; set; }
public bool ImportGeometry { get; set; }
public bool UseUnityTerrainSize { get; set; }
public bool ImportSplats { get; set; }
public bool ImportSplatsAsAlbedo { get; set; }
public bool ImportSplatControlMapsOnly { get; set; }
public bool ImportSplatControlMapResolution { get; set; }
public bool CreateNewSplatPrototypesGroup { get; set; }
public bool ImportTrees { get; set; }
public bool ImportTreeInstancesOnly { get; set; }
public bool CreateNewTreePrototypesGroup { get; set; }
public bool ImportGrasses { get; set; }
public bool ImportGrassInstancesOnly { get; set; }
public bool CreateNewGrassPrototypesGroup { get; set; }
public float GrassDensity { get; set; }
public bool SkipFoliageSnap { get; set; }
public void Import()
{
try
{
if (ImportSplats)
{
#if UNITY_EDITOR
GCommonGUI.CancelableProgressBar("Working...", "Importing Splats...", 1f);
#endif
DoImportSplats();
}
if (ImportTrees)
{
#if UNITY_EDITOR
GCommonGUI.CancelableProgressBar("Working...", "Importing Trees...", 1f);
#endif
DoImportTrees();
}
if (ImportGrasses)
{
#if UNITY_EDITOR
GCommonGUI.CancelableProgressBar("Working...", "Importing Grasses & Details...", 1f);
#endif
DoImportGrasses();
}
if (ImportGeometry)
{
#if UNITY_EDITOR
GCommonGUI.CancelableProgressBar("Working...", "Importing Geometry...", 1f);
#endif
DoImportGeometry();
}
}
catch (GProgressCancelledException)
{
Debug.Log("Importing process canceled!");
}
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
private void DoImportGeometry()
{
if (UseUnityTerrainSize)
{
DesData.Geometry.Width = SrcData.size.x;
DesData.Geometry.Height = SrcData.size.y;
DesData.Geometry.Length = SrcData.size.z;
}
int hmResolution = SrcData.heightmapResolution - 1;
DesData.Geometry.HeightMapResolution = hmResolution;
float[,] heightSample = SrcData.GetHeights(0, 0, DesData.Geometry.HeightMapResolution, DesData.Geometry.HeightMapResolution);
Color[] heightMapColor = new Color[DesData.Geometry.HeightMapResolution * DesData.Geometry.HeightMapResolution];
float h = 0;
Vector2 enc;
int length = heightSample.GetLength(0);
int width = heightSample.GetLength(1);
for (int z = 0; z < length; ++z)
{
for (int x = 0; x < width; ++x)
{
h = Mathf.Clamp(heightSample[z, x], 0f, 0.99999f);
enc = GCommon.EncodeTerrainHeight(h);
heightMapColor[GUtilities.To1DIndex(x, z, width)] = new Color(enc.x, enc.y, 0, 0);
}
}
DesData.Geometry.HeightMap.SetPixels(heightMapColor);
DesData.Geometry.HeightMap.Apply();
DesData.Geometry.SetRegionDirty(GCommon.UnitRect);
DesData.SetDirty(GTerrainData.DirtyFlags.GeometryTimeSliced);
if (!SkipFoliageSnap)
{
if (DesTerrain != null)
{
DesData.Foliage.SetTreeRegionDirty(GCommon.UnitRect);
DesData.Foliage.SetGrassRegionDirty(GCommon.UnitRect);
DesTerrain.UpdateTreesPosition();
DesTerrain.UpdateGrassPatches();
DesData.Foliage.ClearTreeDirtyRegions();
DesData.Foliage.ClearGrassDirtyRegions();
}
}
//GC.Collect();
}
private void DoImportSplats()
{
if (!ImportSplatControlMapsOnly)
{
GSplatPrototypeGroup splatGroup = DesData.Shading.Splats;
if (splatGroup == null ||
splatGroup == GRuntimeSettings.Instance.shadingDefault.splats)
{
CreateNewSplatPrototypesGroup = true;
}
if (CreateNewSplatPrototypesGroup)
{
splatGroup = ScriptableObject.CreateInstance<GSplatPrototypeGroup>();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
string path = AssetDatabase.GetAssetPath(DesData);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("Splats_{0}_{1}.asset", DesData.Id, System.DateTime.Now.Ticks));
AssetDatabase.CreateAsset(splatGroup, filePath);
}
#endif
DesData.Shading.Splats = splatGroup;
}
TerrainLayer[] layers = SrcData.terrainLayers;
GSplatPrototype[] prototypes = new GSplatPrototype[layers.Length];
for (int i = 0; i < layers.Length; ++i)
{
if (layers[i] != null)
{
GSplatPrototype p = (GSplatPrototype)layers[i];
prototypes[i] = p;
}
else
{
prototypes[i] = new GSplatPrototype();
}
}
splatGroup.Prototypes = new List<GSplatPrototype>(prototypes);
GCommon.SetDirty(splatGroup);
}
if (ImportSplatControlMapResolution)
{
DesData.Shading.SplatControlResolution = SrcData.alphamapResolution;
}
Texture2D[] alphaMaps = SrcData.alphamapTextures;
int alphaMapCount = Mathf.Min(alphaMaps.Length, DesData.Shading.SplatControlMapCount);
for (int i = 0; i < alphaMapCount; ++i)
{
try
{
Texture2D controlMap = DesData.Shading.GetSplatControl(i);
//controlMap.SetPixels(alphaMaps[i].GetPixels());
//controlMap.Apply();
GCommon.CopyTexture(alphaMaps[i], controlMap);
controlMap.filterMode = alphaMaps[i].filterMode;
}
catch (System.Exception e)
{
Debug.LogError(string.Format("Skip import splat alpha map {0}, error: {1}", alphaMaps[i].name, e.ToString()));
}
}
if (ImportSplatsAsAlbedo)
{
DesData.Shading.ConvertSplatsToAlbedo();
}
DesData.SetDirty(GTerrainData.DirtyFlags.Shading);
//GC.Collect();
}
private void DoImportTrees()
{
if (!ImportTreeInstancesOnly)
{
GTreePrototypeGroup treeGroup = DesData.Foliage.Trees;
if (treeGroup == null ||
treeGroup == GRuntimeSettings.Instance.foliageDefault.trees)
{
CreateNewTreePrototypesGroup = true;
}
if (CreateNewTreePrototypesGroup)
{
treeGroup = ScriptableObject.CreateInstance<GTreePrototypeGroup>();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
string path = AssetDatabase.GetAssetPath(DesData);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("Trees_{0}_{1}.asset", DesData.Id, System.DateTime.Now.Ticks));
AssetDatabase.CreateAsset(treeGroup, filePath);
}
#endif
DesData.Foliage.Trees = treeGroup;
}
treeGroup.Prototypes.Clear();
TreePrototype[] treePrototypes = SrcData.treePrototypes;
for (int i = 0; i < treePrototypes.Length; ++i)
{
GTreePrototype proto = (GTreePrototype)treePrototypes[i];
treeGroup.Prototypes.Add(proto);
}
GCommon.SetDirty(treeGroup);
}
DesData.Foliage.TreeInstances.Clear();
TreeInstance[] treeInstances = SrcData.treeInstances;
for (int i = 0; i < treeInstances.Length; ++i)
{
GTreeInstance t = (GTreeInstance)treeInstances[i];
DesData.Foliage.TreeInstances.Add(t);
}
if (DesTerrain != null)
{
DesData.Foliage.SetTreeRegionDirty(GCommon.UnitRect);
DesTerrain.UpdateTreesPosition();
DesData.Foliage.ClearTreeDirtyRegions();
}
DesData.SetDirty(GTerrainData.DirtyFlags.Foliage);
//GC.Collect();
}
private void DoImportGrasses()
{
if (!ImportGrassInstancesOnly)
{
GGrassPrototypeGroup grassesGroup = DesData.Foliage.Grasses;
if (grassesGroup == null ||
grassesGroup == GRuntimeSettings.Instance.foliageDefault.grasses)
{
CreateNewGrassPrototypesGroup = true;
}
if (CreateNewGrassPrototypesGroup)
{
grassesGroup = ScriptableObject.CreateInstance<GGrassPrototypeGroup>();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
string path = AssetDatabase.GetAssetPath(DesData);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("Grasses_{0}_{1}.asset", DesData.Id, System.DateTime.Now.Ticks));
AssetDatabase.CreateAsset(grassesGroup, filePath);
}
#endif
DesData.Foliage.Grasses = grassesGroup;
}
grassesGroup.Prototypes.Clear();
DetailPrototype[] detailPrototypes = SrcData.detailPrototypes;
for (int i = 0; i < detailPrototypes.Length; ++i)
{
GGrassPrototype proto = (GGrassPrototype)detailPrototypes[i];
grassesGroup.Prototypes.Add(proto);
}
GCommon.SetDirty(grassesGroup);
}
List<GGrassInstance> grasses = new List<GGrassInstance>();
int detailResolution = SrcData.detailResolution;
int detailLayerCount = SrcData.detailPrototypes.Length;
for (int layer = 0; layer < detailLayerCount; ++layer)
{
int[,] density = SrcData.GetDetailLayer(0, 0, detailResolution, detailResolution, layer);
DoImportDetailLayer(layer, density, grasses);
}
DesData.Foliage.ClearGrassInstances();
DesData.Foliage.AddGrassInstances(grasses);
if (DesTerrain != null)
{
DesData.Foliage.SetGrassRegionDirty(GCommon.UnitRect);
DesTerrain.UpdateGrassPatches();
DesData.Foliage.ClearGrassDirtyRegions();
}
DesData.SetDirty(GTerrainData.DirtyFlags.Foliage);
//GC.Collect();
}
private void DoImportDetailLayer(int layerIndex, int[,] density, List<GGrassInstance> grasses)
{
GGrassPrototype prototype = DesData.Foliage.Grasses.Prototypes[layerIndex];
Rand rand = new Rand(layerIndex + SrcData.detailResolution);
int resolution = SrcData.detailResolution;
int d = 0;
float maxOffset = 1.0f / resolution;
Vector2 uv = Vector2.zero;
Vector3 pos = Vector3.zero;
for (int z = 0; z < resolution; ++z)
{
for (int x = 0; x < resolution; ++x)
{
d = density[z, x];
for (int i = 0; i < d; ++i)
{
if (rand.NextDouble() > GrassDensity)
continue;
uv.Set(
Mathf.InverseLerp(0, resolution - 1, x),
Mathf.InverseLerp(0, resolution - 1, z));
pos.Set(
(float)(uv.x + rand.NextDouble() * maxOffset),
0,
(float)(uv.y + rand.NextDouble() * maxOffset));
GGrassInstance grass = GGrassInstance.Create(layerIndex);
grass.Position = pos;
grass.Rotation = Quaternion.Euler(0, (float)rand.NextDouble() * 360f, 0);
grass.Scale = Mathf.Lerp(0.5f, 1f, (float)rand.NextDouble()) * Vector3.one;
grasses.Add(grass);
}
}
}
//GC.Collect();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c85a01858572a784fa54cdff98d3736a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,631 @@
#if GRIFFIN
using UnityEngine;
using System.Collections.Generic;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using Pinwheel.Griffin.Physic;
namespace Pinwheel.Griffin.DataTool
{
public class GUnityTerrainGroupConverter
{
public enum GAlbedoUsage
{
None, ColorMap, VertexColor
}
public GameObject Root { get; set; }
public GTerrainData DataTemplate { get; set; }
public bool ImportGeometry { get; set; }
public bool ImportSplats { get; set; }
public bool ImportSplatsAsAlbedo { get; set; }
public GAlbedoUsage AlbedoUsage { get; set; }
public bool ImportTrees { get; set; }
public bool ImportGrasses { get; set; }
public bool SkipFoliageSnap { get; set; }
public string DataDirectory { get; set; }
private string conversionName;
private string ConversionName
{
get
{
if (string.IsNullOrEmpty(conversionName))
{
conversionName = System.DateTime.Now.Ticks.ToString();
}
return conversionName;
}
set
{
conversionName = value;
}
}
private List<Terrain> terrains;
private List<Terrain> Terrains
{
get
{
if (terrains == null)
{
terrains = new List<Terrain>();
}
return terrains;
}
set
{
terrains = value;
}
}
private List<GStylizedTerrain> convertedTerrains;
private List<GStylizedTerrain> ConvertedTerrains
{
get
{
if (convertedTerrains == null)
{
convertedTerrains = new List<GStylizedTerrain>();
}
return convertedTerrains;
}
set
{
convertedTerrains = value;
}
}
private List<GSplatPrototypeGroup> splatGroups;
private List<GSplatPrototypeGroup> SplatGroups
{
get
{
if (splatGroups == null)
{
splatGroups = new List<GSplatPrototypeGroup>();
}
return splatGroups;
}
set
{
splatGroups = value;
}
}
private List<int> splatGroupIndices;
private List<int> SplatGroupIndices
{
get
{
if (splatGroupIndices == null)
{
splatGroupIndices = new List<int>();
}
return splatGroupIndices;
}
set
{
splatGroupIndices = value;
}
}
private List<GTreePrototypeGroup> treeGroups;
private List<GTreePrototypeGroup> TreeGroups
{
get
{
if (treeGroups == null)
{
treeGroups = new List<GTreePrototypeGroup>();
}
return treeGroups;
}
set
{
treeGroups = value;
}
}
private List<int> treeGroupIndices;
private List<int> TreeGroupIndices
{
get
{
if (treeGroupIndices == null)
{
treeGroupIndices = new List<int>();
}
return treeGroupIndices;
}
set
{
treeGroupIndices = value;
}
}
private List<GGrassPrototypeGroup> grassGroups;
private List<GGrassPrototypeGroup> GrassGroups
{
get
{
if (grassGroups == null)
{
grassGroups = new List<GGrassPrototypeGroup>();
}
return grassGroups;
}
set
{
grassGroups = value;
}
}
private List<int> grassGroupIndices;
private List<int> GrassGroupIndices
{
get
{
if (grassGroupIndices == null)
{
grassGroupIndices = new List<int>();
}
return grassGroupIndices;
}
set
{
grassGroupIndices = value;
}
}
public List<GStylizedTerrain> Convert()
{
try
{
Validate();
Initialize();
if (DataTemplate == null)
{
CreateSharedData();
}
ImportDataAndCreateTerrain();
FinishingUp();
}
catch (GProgressCancelledException)
{
Debug.Log("Converting process canceled!");
}
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
finally
{
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
return ConvertedTerrains;
}
private void Validate()
{
if (Root == null)
throw new System.ArgumentNullException("Root");
Terrain[] terrains = Root.GetComponentsInChildren<Terrain>();
if (terrains.Length == 0)
{
throw new System.Exception("No Terrain found under Root");
}
bool hasData = false;
for (int i = 0; i < terrains.Length; ++i)
{
if (terrains[i].terrainData != null)
{
hasData = true;
}
}
if (!hasData)
{
throw new System.Exception("No Terrain with Terrain Data found under Root");
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
if (string.IsNullOrEmpty(DataDirectory) || !DataDirectory.StartsWith("Assets/"))
{
throw new System.ArgumentException("Data Directory must be related to Assets folder");
}
}
#endif
}
private void SaveAssets()
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Saving", "Saving unsaved assets...", 1f);
AssetDatabase.SaveAssets();
GCommonGUI.ClearProgressBar();
#endif
}
private void Initialize()
{
Terrains = new List<Terrain>();
Terrain[] t = Root.GetComponentsInChildren<Terrain>();
for (int i = 0; i < t.Length; ++i)
{
if (t[i].terrainData != null)
Terrains.Add(t[i]);
}
if (!Application.isPlaying)
{
GUtilities.EnsureDirectoryExists(DataDirectory);
}
}
private void CreateSharedData()
{
if (ImportSplats)
CreateSharedSplats();
if (ImportTrees)
CreateSharedTrees();
if (ImportGrasses)
CreateSharedGrasses();
//SaveAssets();
}
private void CreateSharedSplats()
{
SplatGroups.Clear();
SplatGroupIndices.Clear();
for (int i = 0; i < Terrains.Count; ++i)
{
Terrain t = Terrains[i];
#if UNITY_2018_3_OR_NEWER
TerrainLayer[] layers = t.terrainData.terrainLayers;
#else
SplatPrototype[] layers = t.terrainData.splatPrototypes;
#endif
int splatGroupIndex = -1;
for (int j = 0; j < SplatGroups.Count; ++j)
{
if (SplatGroups[j].Equals(layers))
{
splatGroupIndex = j;
break;
}
}
if (splatGroupIndex >= 0)
{
SplatGroupIndices.Add(splatGroupIndex);
}
else
{
GSplatPrototypeGroup group = GSplatPrototypeGroup.Create(layers);
SplatGroups.Add(group);
SplatGroupIndices.Add(SplatGroups.Count - 1);
}
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
GUtilities.EnsureDirectoryExists(DataDirectory);
for (int i = 0; i < SplatGroups.Count; ++i)
{
GSplatPrototypeGroup group = SplatGroups[i];
group.name = string.Format("{0}{1}_{2}", "SharedSplats", i.ToString(), ConversionName);
string assetPath = string.Format("{0}.asset", Path.Combine(DataDirectory, group.name));
AssetDatabase.CreateAsset(group, assetPath);
}
}
#endif
}
private void CreateSharedTrees()
{
TreeGroups.Clear();
TreeGroupIndices.Clear();
for (int i = 0; i < Terrains.Count; ++i)
{
Terrain t = Terrains[i];
TreePrototype[] treePrototypes = t.terrainData.treePrototypes;
int treeGroupIndex = -1;
for (int j = 0; j < TreeGroups.Count; ++j)
{
if (TreeGroups[j].Equals(treePrototypes))
{
treeGroupIndex = j;
break;
}
}
if (treeGroupIndex >= 0)
{
TreeGroupIndices.Add(treeGroupIndex);
}
else
{
GTreePrototypeGroup group = GTreePrototypeGroup.Create(treePrototypes);
TreeGroups.Add(group);
TreeGroupIndices.Add(TreeGroups.Count - 1);
}
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
GUtilities.EnsureDirectoryExists(DataDirectory);
for (int i = 0; i < TreeGroups.Count; ++i)
{
GTreePrototypeGroup group = TreeGroups[i];
group.name = string.Format("{0}{1}_{2}", "SharedTrees", i.ToString(), ConversionName);
string assetPath = string.Format("{0}.asset", Path.Combine(DataDirectory, group.name));
AssetDatabase.CreateAsset(group, assetPath);
}
}
#endif
}
private void CreateSharedGrasses()
{
GrassGroups.Clear();
GrassGroupIndices.Clear();
for (int i = 0; i < Terrains.Count; ++i)
{
Terrain t = Terrains[i];
DetailPrototype[] detailPrototypes = t.terrainData.detailPrototypes;
int grassGroupIndex = -1;
for (int j = 0; j < GrassGroups.Count; ++j)
{
if (GrassGroups[j].Equals(detailPrototypes))
{
grassGroupIndex = j;
break;
}
}
if (grassGroupIndex >= 0)
{
GrassGroupIndices.Add(grassGroupIndex);
}
else
{
GGrassPrototypeGroup group = GGrassPrototypeGroup.Create(detailPrototypes);
GrassGroups.Add(group);
GrassGroupIndices.Add(GrassGroups.Count - 1);
}
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
GUtilities.EnsureDirectoryExists(DataDirectory);
for (int i = 0; i < GrassGroups.Count; ++i)
{
GGrassPrototypeGroup group = GrassGroups[i];
group.name = string.Format("{0}{1}_{2}", "SharedGrasses", i.ToString(), ConversionName);
string assetPath = string.Format("{0}.asset", Path.Combine(DataDirectory, group.name));
AssetDatabase.CreateAsset(group, assetPath);
}
}
#endif
}
private void ImportDataAndCreateTerrain()
{
GameObject terrainRoot = new GameObject(string.Format("{0}-{1}", Root.name, ConversionName));
terrainRoot.transform.parent = Root.transform.parent;
terrainRoot.transform.position = Root.transform.position;
for (int i = 0; i < Terrains.Count; ++i)
{
#if UNITY_EDITOR
GCommonGUI.CancelableProgressBar("Converting", "Converting " + Terrains[i].name, 1f);
#endif
GTerrainData data = ScriptableObject.CreateInstance<GTerrainData>();
if (DataTemplate != null)
{
DataTemplate.Geometry.CopyTo(data.Geometry);
DataTemplate.Shading.CopyTo(data.Shading);
DataTemplate.Rendering.CopyTo(data.Rendering);
DataTemplate.Foliage.CopyTo(data.Foliage);
DataTemplate.Mask.CopyTo(data.Mask);
}
else
{
if (Application.isPlaying) //Reset() only called in edit mode
{
data.Reset();
data.Geometry.Reset();
data.Shading.Reset();
data.Rendering.Reset();
data.Foliage.Reset();
data.Mask.Reset();
}
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
string assetName = "TerrainData_" + data.Id;
AssetDatabase.CreateAsset(data, string.Format("{0}.asset", Path.Combine(DataDirectory, assetName)));
}
#endif
Material templateMaterial = null;
if (DataTemplate != null)
{
templateMaterial = DataTemplate.Shading.CustomMaterial;
}
Material material = null;
if (templateMaterial != null)
{
material = new Material(templateMaterial.shader);
}
else
{
if (ImportSplats)
{
if (ImportSplatsAsAlbedo && AlbedoUsage == GAlbedoUsage.ColorMap)
{
material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.ColorMap);
}
else if (ImportSplatsAsAlbedo && AlbedoUsage == GAlbedoUsage.VertexColor)
{
material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.VertexColor);
data.Geometry.AlbedoToVertexColorMode = GAlbedoToVertexColorMode.Sharp;
}
else
{
GSplatPrototypeGroup splats = DataTemplate ? DataTemplate.Shading.Splats : SplatGroups[SplatGroupIndices[i]];
GSplatsModel splatModel = (splats == null || splats.Prototypes.Count <= 4) ?
GSplatsModel.Splats4Normals4 :
GSplatsModel.Splats8;
material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.Splat, splatModel);
}
}
else
{
material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.Splat, GSplatsModel.Splats4);
}
}
data.Shading.CustomMaterial = material;
#if UNITY_EDITOR
if (!Application.isPlaying && material != null)
{
string matName = "TerrainMaterial_" + data.Id;
material.name = matName;
AssetDatabase.CreateAsset(material, string.Format("{0}.mat", Path.Combine(DataDirectory, matName)));
}
#endif
if (ImportSplats)
{
data.Shading.Splats = DataTemplate ? DataTemplate.Shading.Splats : SplatGroups[SplatGroupIndices[i]];
data.Shading.UpdateMaterials();
}
if (ImportTrees)
{
data.Foliage.Trees = DataTemplate ? DataTemplate.Foliage.Trees : TreeGroups[TreeGroupIndices[i]];
}
if (ImportGrasses)
{
data.Foliage.Grasses = DataTemplate ? DataTemplate.Foliage.Grasses : GrassGroups[GrassGroupIndices[i]];
}
GUnityTerrainDataImporter importer = new GUnityTerrainDataImporter();
importer.SrcData = Terrains[i].terrainData;
importer.SrcTerrain = Terrains[i];
importer.DesData = data;
importer.DesTerrain = null;
importer.ImportGeometry = ImportGeometry;
importer.UseUnityTerrainSize = true;
importer.ImportSplats = ImportSplats;
importer.ImportSplatsAsAlbedo = ImportSplatsAsAlbedo;
importer.ImportSplatControlMapsOnly = DataTemplate != null && DataTemplate.Shading.Splats != null;
importer.ImportSplatControlMapResolution = DataTemplate == null;
importer.CreateNewSplatPrototypesGroup = false;
importer.ImportTrees = ImportTrees;
importer.ImportTreeInstancesOnly = DataTemplate != null && DataTemplate.Foliage.Trees != null;
importer.CreateNewTreePrototypesGroup = false;
importer.ImportGrasses = ImportGrasses;
importer.ImportGrassInstancesOnly = DataTemplate != null && DataTemplate.Foliage.Grasses != null;
importer.CreateNewGrassPrototypesGroup = false;
importer.GrassDensity = 1;
importer.SkipFoliageSnap = SkipFoliageSnap;
importer.Import();
GStylizedTerrain t = CreateTerrain();
t.transform.parent = terrainRoot.transform;
t.transform.position = Terrains[i].transform.position;
t.name = Terrains[i].name;
#if UNITY_2018_3_OR_NEWER
t.GroupId = Terrains[i].groupingID;
#endif
t.TerrainData = data;
if (ImportTrees || ImportGrasses)
{
data.Foliage.SetTreeRegionDirty(GCommon.UnitRect);
data.Foliage.SetGrassRegionDirty(GCommon.UnitRect);
t.UpdateTreesPosition();
t.UpdateGrassPatches();
data.Foliage.ClearTreeDirtyRegions();
data.Foliage.ClearGrassDirtyRegions();
}
ConvertedTerrains.Add(t);
#if UNITY_EDITOR
//SaveAssets();
GCommonGUI.ClearProgressBar();
#endif
}
}
private GStylizedTerrain CreateTerrain()
{
GameObject g = new GameObject("Stylized Terrain");
g.transform.localPosition = Vector3.zero;
g.transform.localRotation = Quaternion.identity;
g.transform.localScale = Vector3.one;
GStylizedTerrain terrain = g.AddComponent<GStylizedTerrain>();
terrain.GroupId = 0;
GameObject colliderGO = new GameObject("Tree Collider");
colliderGO.transform.parent = terrain.transform;
colliderGO.transform.localPosition = Vector3.zero;
colliderGO.transform.localRotation = Quaternion.identity;
colliderGO.transform.localScale = Vector3.one;
GTreeCollider collider = colliderGO.AddComponent<GTreeCollider>();
collider.Terrain = terrain;
return terrain;
}
private void FinishingUp()
{
#if UNITY_EDITOR
GCommonGUI.ProgressBar("Finishing Up", "Matching geometry...", 1f);
#endif
for (int i = 0; i < ConvertedTerrains.Count; ++i)
{
ConvertedTerrains[i].ConnectNeighbor();
ConvertedTerrains[i].MatchEdges();
}
Root.gameObject.SetActive(false);
#if UNITY_EDITOR
GCommonGUI.ClearProgressBar();
#endif
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3becf2eb46aa7434c8fb2c69c016dfce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: