portals and dash. Also a bit of terrain building and level design
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
#if GRIFFIN
|
||||
namespace Pinwheel.Griffin.DataTool
|
||||
{
|
||||
public enum GBitDepth
|
||||
{
|
||||
Bit8, Bit16
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97f8aa96543decd419fc44e24ad0b5b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cc359d9748e6d64db0e4c855b8fa160
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b73933ddf39291b48a8409cc82f827ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce364b90f86764448a10f6fdf9dc17ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b866e3498ed5ec4ba8c6b3deee62f41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c2b76fec165bee428b64ab4a8c7d6d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c85a01858572a784fa54cdff98d3736a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3becf2eb46aa7434c8fb2c69c016dfce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user