diff --git a/com.unity.hlod/Editor/Batcher/SimpleBatcher.cs b/com.unity.hlod/Editor/Batcher/SimpleBatcher.cs index 1ab7b4fc..62211a72 100644 --- a/com.unity.hlod/Editor/Batcher/SimpleBatcher.cs +++ b/com.unity.hlod/Editor/Batcher/SimpleBatcher.cs @@ -23,10 +23,11 @@ static void RegisterType() BatcherTypes.RegisterBatcherType(typeof(SimpleBatcher)); } - private DisposableDictionary m_createdMaterials = new DisposableDictionary(); + private DisposableDictionary m_createdMaterials = + new DisposableDictionary(); + private SerializableDynamicObject m_batcherOptions; - - + [Serializable] public class TextureInfo @@ -60,24 +61,23 @@ public void Batch(Transform rootTransform, DisposableList targets { Combine(rootTransform, packer, targets[i], options); if (onProgress != null) - onProgress(0.5f + ((float)i / (float)targets.Count) * 0.5f); + onProgress(0.5f + ((float) i / (float) targets.Count) * 0.5f); } } - } class MaterialTextureCache : IDisposable { private NativeArray m_detector = new NativeArray(1, Allocator.Persistent); - + private List m_textureInfoList; private DisposableDictionary m_textureCache; private DisposableDictionary m_defaultTextures; - + private bool m_enableTintColor; private string m_tintColorName; - + public MaterialTextureCache(dynamic options) { m_defaultTextures = CreateDefaultTextures(); @@ -86,6 +86,7 @@ public MaterialTextureCache(dynamic options) m_textureInfoList = options.TextureInfoList; m_textureCache = new DisposableDictionary(); } + public TexturePacker.MaterialTexture GetMaterialTextures(WorkingMaterial material) { if (m_textureCache.ContainsKey(material.Guid) == false) @@ -108,7 +109,6 @@ public void Dispose() m_textureCache.Dispose(); m_defaultTextures.Dispose(); m_detector.Dispose(); - } private void AddToCache(WorkingMaterial material) @@ -120,7 +120,7 @@ private void AddToCache(WorkingMaterial material) { texture = m_defaultTextures[m_textureInfoList[0].Type]; } - + TexturePacker.MaterialTexture materialTexture = new TexturePacker.MaterialTexture(); if (m_enableTintColor) @@ -136,7 +136,7 @@ private void AddToCache(WorkingMaterial material) { materialTexture.Add(texture); } - + for (int ti = 1; ti < m_textureInfoList.Count; ++ti) { @@ -153,6 +153,7 @@ private void AddToCache(WorkingMaterial material) m_textureCache.Add(material.Guid, materialTexture); } + private void ApplyTintColor(WorkingTexture texture, Color tintColor) { for (int ty = 0; ty < texture.Height; ++ty) @@ -160,12 +161,12 @@ private void ApplyTintColor(WorkingTexture texture, Color tintColor) for (int tx = 0; tx < texture.Width; ++tx) { Color c = texture.GetPixel(tx, ty); - + c.r = c.r * tintColor.r; c.g = c.g * tintColor.g; c.b = c.b * tintColor.b; c.a = c.a * tintColor.a; - + texture.SetPixel(tx, ty, c); } } @@ -173,7 +174,8 @@ private void ApplyTintColor(WorkingTexture texture, Color tintColor) private static DisposableDictionary CreateDefaultTextures() { - DisposableDictionary textures = new DisposableDictionary(); + DisposableDictionary textures = + new DisposableDictionary(); textures.Add(PackingType.White, CreateEmptyTexture(4, 4, Color.white, false)); textures.Add(PackingType.Black, CreateEmptyTexture(4, 4, Color.black, false)); @@ -181,11 +183,11 @@ private static DisposableDictionary CreateDefaultTe return textures; } - } - private void PackingTexture(TexturePacker packer, DisposableList targets, dynamic options, Action onProgress) - { + private void PackingTexture(TexturePacker packer, DisposableList targets, dynamic options, + Action onProgress) + { List textureInfoList = options.TextureInfoList; using (MaterialTextureCache cache = new MaterialTextureCache(options)) { @@ -222,7 +224,7 @@ private void PackingTexture(TexturePacker packer, DisposableList } packer.Pack(TextureFormat.RGBA32, options.PackTextureSize, options.LimitTextureSize, false); - if ( onProgress != null) onProgress(0.3f); + if (onProgress != null) onProgress(0.3f); int index = 1; var atlases = packer.GetAllAtlases(); @@ -240,7 +242,7 @@ private void PackingTexture(TexturePacker packer, DisposableList textures.Add(textureInfoList[i].OutputName, wt); } - + WorkingMaterial mat = CreateMaterial(options.MaterialGUID, textures); mat.Name = "CombinedMaterial " + index; m_createdMaterials.Add(atlas, mat); @@ -265,12 +267,12 @@ static WorkingMaterial CreateMaterial(string guidstr, Dictionary materials, TexturePacker.TextureAtlas atlas, string mainTextureName) + private void ConvertMesh(WorkingMesh mesh, DisposableList materials, + TexturePacker.TextureAtlas atlas, string mainTextureName) { var uv = mesh.uv; var updated = new bool[uv.Length]; @@ -335,11 +338,11 @@ private void ConvertMesh(WorkingMesh mesh, DisposableList mater int[] indices = mesh.GetTriangles(mi); foreach (var i in indices) { - if ( updated[i] == false ) + if (updated[i] == false) { var uvCoord = uv[i]; var texture = materials[mi].GetTexture(mainTextureName); - + if (texture == null || texture.GetGUID() == Guid.Empty) { // Sample at center of white texture to avoid sampling edge colors incorrectly @@ -349,26 +352,25 @@ private void ConvertMesh(WorkingMesh mesh, DisposableList mater else { var uvOffset = atlas.GetUV(texture.GetGUID()); - + uvCoord.x = Mathf.Lerp(uvOffset.xMin, uvOffset.xMax, uvCoord.x); uvCoord.y = Mathf.Lerp(uvOffset.yMin, uvOffset.yMax, uvCoord.y); } - + uv[i] = uvCoord; updated[i] = true; } } - } mesh.uv = uv; } - static private WorkingTexture CreateEmptyTexture(int width, int height, Color color, bool linear) { - WorkingTexture texture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, width, height, linear); + WorkingTexture texture = + new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, width, height, linear); for (int y = 0; y < height; ++y) { @@ -380,19 +382,21 @@ static private WorkingTexture CreateEmptyTexture(int width, int height, Color co return texture; } - + static class Styles { public static int[] PackTextureSizes = new int[] { 256, 512, 1024, 2048, 4096 }; + public static string[] PackTextureSizeNames; public static int[] LimitTextureSizes = new int[] { 32, 64, 128, 256, 512, 1024 }; + public static string[] LimitTextureSizeNames; @@ -415,9 +419,10 @@ static Styles() private static string[] inputTexturePropertyNames = null; private static string[] outputTexturePropertyNames = null; private static TextureInfo addingTextureInfo = new TextureInfo(); + public static void OnGUI(HLOD hlod, bool isFirst) { - if (isFirst ) + if (isFirst) { inputTexturePropertyNames = null; outputTexturePropertyNames = null; @@ -448,8 +453,12 @@ public static void OnGUI(HLOD hlod, bool isFirst) if (batcherOptions.TintColorName == null) batcherOptions.TintColorName = ""; - batcherOptions.PackTextureSize = EditorGUILayout.IntPopup("Pack texture size", batcherOptions.PackTextureSize, Styles.PackTextureSizeNames, Styles.PackTextureSizes); - batcherOptions.LimitTextureSize = EditorGUILayout.IntPopup("Limit texture size", batcherOptions.LimitTextureSize, Styles.LimitTextureSizeNames, Styles.LimitTextureSizes); + batcherOptions.PackTextureSize = EditorGUILayout.IntPopup("Pack texture size", + batcherOptions.PackTextureSize, + Styles.PackTextureSizeNames, Styles.PackTextureSizes); + batcherOptions.LimitTextureSize = EditorGUILayout.IntPopup("Limit texture size", + batcherOptions.LimitTextureSize, + Styles.LimitTextureSizeNames, Styles.LimitTextureSizes); Material mat = null; @@ -460,35 +469,38 @@ public static void OnGUI(HLOD hlod, bool isFirst) path = AssetDatabase.GUIDToAssetPath(matGUID); mat = AssetDatabase.LoadAssetAtPath(path); } + mat = EditorGUILayout.ObjectField("Material", mat, typeof(Material), false) as Material; - if( mat == null) + if (mat == null) mat = new Material(Shader.Find("Standard")); - + path = AssetDatabase.GetAssetPath(mat); matGUID = AssetDatabase.AssetPathToGUID(path); - + if (matGUID != batcherOptions.MaterialGUID) { batcherOptions.MaterialGUID = matGUID; outputTexturePropertyNames = mat.GetTexturePropertyNames(); } + if (inputTexturePropertyNames == null) { inputTexturePropertyNames = GetAllMaterialTextureProperties(hlod.gameObject); } + if (outputTexturePropertyNames == null) { outputTexturePropertyNames = mat.GetTexturePropertyNames(); } - + //apply tint color batcherOptions.EnableTintColor = EditorGUILayout.Toggle("Enable tint color", batcherOptions.EnableTintColor); if (batcherOptions.EnableTintColor == true) { EditorGUI.indentLevel += 1; - + var shader = mat.shader; List colorPropertyNames = new List(); int propertyCount = ShaderUtil.GetPropertyCount(shader); @@ -511,7 +523,7 @@ public static void OnGUI(HLOD hlod, bool isFirst) { batcherOptions.TintColorName = ""; } - + EditorGUI.indentLevel -= 1; } @@ -535,7 +547,7 @@ public static void OnGUI(HLOD hlod, bool isFirst) info.InputName = StringPopup(info.InputName, inputTexturePropertyNames); info.OutputName = StringPopup(info.OutputName, outputTexturePropertyNames); - info.Type = (PackingType)EditorGUILayout.EnumPopup(info.Type); + info.Type = (PackingType) EditorGUILayout.EnumPopup(info.Type); if (i == 0) GUI.enabled = false; @@ -544,6 +556,7 @@ public static void OnGUI(HLOD hlod, bool isFirst) batcherOptions.TextureInfoList.RemoveAt(i); i -= 1; } + if (i == 0) GUI.enabled = true; EditorGUILayout.EndHorizontal(); @@ -566,6 +579,7 @@ public static void OnGUI(HLOD hlod, bool isFirst) inputTexturePropertyNames = null; outputTexturePropertyNames = null; } + EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel -= 1; @@ -595,21 +609,17 @@ static string[] GetAllMaterialTextureProperties(GameObject root) for (int m = 0; m < meshRenderers.Length; ++m) { var mesh = meshRenderers[m]; - foreach (Material material in mesh.sharedMaterials) + foreach (var material in mesh.sharedMaterials) { var names = material.GetTexturePropertyNames(); for (int n = 0; n < names.Length; ++n) { texturePropertyNames.Add(names[n]); - } + } } - } return texturePropertyNames.ToArray(); } - - } - -} +} \ No newline at end of file diff --git a/com.unity.hlod/Editor/SpaceManager/QuadTreeSpaceSplitter.cs b/com.unity.hlod/Editor/SpaceManager/QuadTreeSpaceSplitter.cs index 3affe365..d0a2074b 100644 --- a/com.unity.hlod/Editor/SpaceManager/QuadTreeSpaceSplitter.cs +++ b/com.unity.hlod/Editor/SpaceManager/QuadTreeSpaceSplitter.cs @@ -18,9 +18,9 @@ public static bool IsPartOf(this Bounds bounds, Bounds target) (double) bounds.max.z <= (double) target.max.z; } } + public class QuadTreeSpaceSplitter : ISpaceSplitter { - [InitializeOnLoadMethod] static void RegisterType() { @@ -31,7 +31,7 @@ static void RegisterType() private bool m_useSubHLODTree; private float m_subHLODTreeSize; - + public QuadTreeSpaceSplitter(SerializableDynamicObject spaceSplitterOptions) { @@ -39,27 +39,26 @@ public QuadTreeSpaceSplitter(SerializableDynamicObject spaceSplitterOptions) m_useSubHLODTree = false; m_subHLODTreeSize = 0.0f; - + if (spaceSplitterOptions == null) { return; } - + dynamic options = spaceSplitterOptions; - if(options.LooseSize1 != null) + if (options.LooseSize1 != null) m_looseSizeFromOptions = options.LooseSize; - if(options.UseSubHLODTree != null) + if (options.UseSubHLODTree != null) m_useSubHLODTree = options.UseSubHLODTree; - if(options.SubHLODTreeSize != null) + if (options.SubHLODTreeSize != null) m_subHLODTreeSize = options.SubHLODTreeSize; - } public int CalculateSubTreeCount(Bounds bounds) { if (m_useSubHLODTree == false) return 1; - + List splittedBounds = SplitBounds(bounds, m_subHLODTreeSize); return splittedBounds.Count; } @@ -76,7 +75,7 @@ public int CalculateTreeDepth(Bounds bounds, float chunkSize) } else { - maxLength = Mathf.Max(bounds.extents.x, bounds.extents.z); + maxLength = Mathf.Max(bounds.extents.x, bounds.extents.z); } } else @@ -99,6 +98,7 @@ public List CreateSpaceTree(Bounds initBounds, float chunkSize, Trans List targetObjects, Action onProgress) { List nodes = new List(); + List targetInfos = CreateTargetInfoList(targetObjects, transform); if (m_useSubHLODTree == true) @@ -106,7 +106,7 @@ public List CreateSpaceTree(Bounds initBounds, float chunkSize, Trans List splittedBounds = SplitBounds(initBounds, m_subHLODTreeSize); List> splittedTargetInfos = SplitTargetObjects(targetInfos, splittedBounds); - float progressSize = 1.0f / splittedTargetInfos.Count; + float progressSize = 1.0f / splittedTargetInfos.Count; for (int i = 0; i < splittedTargetInfos.Count; ++i) { nodes.Add(CreateSpaceTreeImpl(splittedBounds[i], chunkSize, splittedTargetInfos[i], (p => @@ -123,34 +123,35 @@ public List CreateSpaceTree(Bounds initBounds, float chunkSize, Trans return nodes; } - private SpaceNode CreateSpaceTreeImpl(Bounds initBounds, float chunkSize, List targetObjects, Action onProgress) + + private SpaceNode CreateSpaceTreeImpl(Bounds initBounds, float chunkSize, List targetObjects, + Action onProgress) { float looseSize = CalcLooseSize(chunkSize); SpaceNode rootNode = new SpaceNode(); rootNode.Bounds = initBounds; - if ( onProgress != null) + if (onProgress != null) onProgress(0.0f); - //space split first - Stack nodeStack = new Stack(); - nodeStack.Push(rootNode); - - while(nodeStack.Count > 0 ) - { - SpaceNode node = nodeStack.Pop(); - if ( node.Bounds.size.x > chunkSize ) - { + //space split first + Stack nodeStack = new Stack(); + nodeStack.Push(rootNode); + + while (nodeStack.Count > 0) + { + SpaceNode node = nodeStack.Pop(); + if (node.Bounds.size.x > chunkSize) + { List childNodes = CreateChildSpaceNodes(node, looseSize); - - for ( int i = 0; i < childNodes.Count; ++i ) + + for (int i = 0; i < childNodes.Count; ++i) { childNodes[i].ParentNode = node; - nodeStack.Push(childNodes[i]); - } - - } - } + nodeStack.Push(childNodes[i]); + } + } + } if (targetObjects == null) return rootNode; @@ -194,12 +195,12 @@ private SpaceNode CreateSpaceTreeImpl(Bounds initBounds, float chunkSize, List CreateTargetInfoList(List gameObjects, Transform transform) { + if (gameObjects == null) + { + return new List(0); + } + List targetInfos = new List(gameObjects.Count); for (int i = 0; i < gameObjects.Count; ++i) { Bounds? bounds = CalculateBounds(gameObjects[i], transform); - if ( bounds == null ) + if (bounds == null) continue; targetInfos.Add(new TargetInfo() { @@ -253,7 +259,7 @@ private List SplitBounds(Bounds bounds, float splitSize) List boundsList = new List(); Vector3 splitBoundSize = new Vector3(xsize, bounds.size.y, zsize); - + for (int z = 0; z < zcount; ++z) { for (int x = 0; x < xcount; ++x) @@ -262,8 +268,8 @@ private List SplitBounds(Bounds bounds, float splitSize) x * xsize + xsize * 0.5f, bounds.extents.y, z * zsize + zsize * 0.5f) + bounds.min; - - boundsList.Add(new Bounds(center,splitBoundSize)); + + boundsList.Add(new Bounds(center, splitBoundSize)); } } @@ -298,15 +304,13 @@ private float CalcLooseSize(float chunkSize) //If the chunk size is small, there is a problem that it may get caught in an infinite loop. //So, the size can be determined according to the chunk size. return Mathf.Min(chunkSize * 0.3f, m_looseSizeFromOptions); - } - private List CreateChildSpaceNodes(SpaceNode parentNode, float looseSize) { List childSpaceNodes = new List(4); - + float size = parentNode.Bounds.size.x; float extend = size * 0.5f; float offset = extend * 0.5f; @@ -330,7 +334,7 @@ private List CreateChildSpaceNodes(SpaceNode parentNode, float looseS SpaceNode.CreateSpaceNodeWithBounds( new Bounds(center + new Vector3(offset, 0.0f, offset), looseBoundsSize) )); - + return childSpaceNodes; } @@ -373,10 +377,6 @@ public static void OnGUI(SerializableDynamicObject spaceSplitterOptions) options.SubHLODTreeSize = EditorGUILayout.FloatField("Sub tree size", options.SubHLODTreeSize); EditorGUI.indentLevel -= 1; } - } - - } - } \ No newline at end of file diff --git a/com.unity.hlod/Editor/Streaming/Unsupported.cs b/com.unity.hlod/Editor/Streaming/Unsupported.cs index 66e57d19..2febba63 100644 --- a/com.unity.hlod/Editor/Streaming/Unsupported.cs +++ b/com.unity.hlod/Editor/Streaming/Unsupported.cs @@ -12,8 +12,14 @@ namespace Unity.HLODSystem.Streaming { - class Unsupported : IStreamingBuilder + public class Unsupported : IStreamingBuilder { + public Unsupported(IGeneratedResourceManager mManager, SerializableDynamicObject mStreamingOptions) + { + m_manager = mManager; + m_streamingOptions = mStreamingOptions; + } + static class Styles { public static TextureFormat[] SupportTextureFormats = new[] @@ -49,8 +55,7 @@ static Styles() } } } - - + [InitializeOnLoadMethod] static void RegisterType() { @@ -61,14 +66,15 @@ static void RegisterType() private SerializableDynamicObject m_streamingOptions; private int m_controllerID; - public Unsupported(IGeneratedResourceManager manager, int controllerID, SerializableDynamicObject streamingOptions) + public Unsupported(IGeneratedResourceManager manager, int controllerID, + SerializableDynamicObject streamingOptions) { m_manager = manager; m_streamingOptions = streamingOptions; m_controllerID = controllerID; } - public void Build(SpaceNode rootNode, DisposableList infos, GameObject root, + public void Build(SpaceNode rootNode, DisposableList infos, GameObject root, float cullDistance, float lodDistance, bool writeNoPrefab, bool extractMaterial, Action onProgress) { dynamic options = m_streamingOptions; @@ -86,19 +92,19 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO compressionData.AndroidTextureFormat = options.AndroidCompression; compressionData.iOSTextureFormat = options.iOSCompression; compressionData.tvOSTextureFormat = options.tvOSCompression; - + string filename = $"{path}{root.name}.hlod"; if (Directory.Exists(path) == false) { Directory.CreateDirectory(path); } - + using (Stream stream = new FileStream(filename, FileMode.Create)) { HLODData data = new HLODData(); data.CompressionData = compressionData; - + for (int i = 0; i < infos.Count; ++i) { data.AddFromWokringObjects(infos[i].Name, infos[i].WorkingObjects); @@ -112,7 +118,7 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO for (int ii = 0; ii < infos.Count; ++ii) { var spaceNode = infos[ii].Target; - + for (int oi = 0; oi < spaceNode.Objects.Count; ++oi) { if (PrefabUtility.IsAnyPrefabInstanceRoot(spaceNode.Objects[oi]) == false) @@ -123,22 +129,22 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO } } - if (extractMaterial == true ) + if (extractMaterial == true) { ExtractMaterial(data, $"{path}{root.name}"); } - + HLODDataSerializer.Write(stream, data); } AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate); RootData rootData = AssetDatabase.LoadAssetAtPath(filename); m_manager.AddGeneratedResource(rootData); - + var defaultController = root.AddComponent(); defaultController.ControllerID = m_controllerID; m_manager.AddGeneratedResource(defaultController); - + GameObject hlodRoot = new GameObject("HLODRoot"); hlodRoot.transform.SetParent(root.transform, false); m_manager.AddGeneratedResource(hlodRoot); @@ -167,7 +173,7 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO m_manager.AddGeneratedResource(go); else m_manager.AddConvertedPrefabResource(go); - + Object.DestroyImmediate(obj); } else @@ -175,11 +181,10 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO int highId = defaultController.AddHighObject(obj); hlodTreeNode.HighObjectIds.Add(highId); } - } - if ( infos[ii].WorkingObjects.Count > 0 ) + if (infos[ii].WorkingObjects.Count > 0) { GameObject prefab = rootData.GetRootObject(infos[ii].Name); if (prefab == null) @@ -194,7 +199,6 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO int lowId = defaultController.AddLowObject(go); hlodTreeNode.LowObjectIds.Add(lowId); m_manager.AddGeneratedResource(go); - } } } @@ -203,13 +207,14 @@ public void Build(SpaceNode rootNode, DisposableList infos, GameO defaultController.Root = convertedRootNode; defaultController.CullDistance = cullDistance; defaultController.LODDistance = lodDistance; - + defaultController.UpdateMaxManualLevel(); } private void ExtractMaterial(HLODData hlodData, string filenamePrefix) { - Dictionary extractedMaterials = new Dictionary(); + Dictionary extractedMaterials = + new Dictionary(); //save files to disk foreach (var hlodMaterial in hlodData.GetMaterials()) { @@ -233,7 +238,8 @@ private void ExtractMaterial(HLODData hlodData, string filenamePrefix) if (textureImporter) { textureImporter.wrapMode = serializeTexture.WrapMode; - textureImporter.sRGBTexture = GraphicsFormatUtility.IsSRGBFormat(serializeTexture.GraphicsFormat); + textureImporter.sRGBTexture = + GraphicsFormatUtility.IsSRGBFormat(serializeTexture.GraphicsFormat); textureImporter.SaveAndReimport(); } @@ -257,7 +263,6 @@ private void ExtractMaterial(HLODData hlodData, string filenamePrefix) extractedMaterials.Add(id, newSM); } - } //apply to HLODData @@ -287,7 +292,7 @@ private void ExtractMaterial(HLODData hlodData, string filenamePrefix) Dictionary convertedTable = new Dictionary(); - private HLODTreeNode ConvertNode(HLODTreeNodeContainer container, SpaceNode rootNode ) + private HLODTreeNode ConvertNode(HLODTreeNodeContainer container, SpaceNode rootNode) { HLODTreeNode root = new HLODTreeNode(); root.SetContainer(container); @@ -325,7 +330,6 @@ private HLODTreeNode ConvertNode(HLODTreeNodeContainer container, SpaceNode root } hlodTreeNode.SetChildTreeNode(childTreeNodes); - } } @@ -333,12 +337,13 @@ private HLODTreeNode ConvertNode(HLODTreeNodeContainer container, SpaceNode root } static bool showFormat = true; + public static void OnGUI(SerializableDynamicObject streamingOptions) { - dynamic options = streamingOptions; -#region Setup default values + #region Setup default values + if (options.OutputDirectory == null) { string path = Application.dataPath; @@ -353,23 +358,28 @@ public static void OnGUI(SerializableDynamicObject streamingOptions) { options.PCCompression = TextureFormat.BC7; } + if (options.WebGLCompression == null) { options.WebGLCompression = TextureFormat.DXT5; } + if (options.AndroidCompression == null) { options.AndroidCompression = TextureFormat.ETC2_RGBA8; } - if (options.iOSCompression== null) + + if (options.iOSCompression == null) { options.iOSCompression = TextureFormat.PVRTC_RGBA4; } + if (options.tvOSCompression == null) { options.tvOSCompression = TextureFormat.ASTC_4x4; } -#endregion + + #endregion EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("OutputDirectory"); @@ -390,19 +400,19 @@ public static void OnGUI(SerializableDynamicObject streamingOptions) EditorUtility.DisplayDialog("Error", $"Select directory under {Application.dataPath}", "OK"); } } + EditorGUILayout.EndHorizontal(); if (showFormat = EditorGUILayout.Foldout(showFormat, "Compress Format")) { EditorGUI.indentLevel += 1; - options.PCCompression = PopupFormat("PC & Console", (TextureFormat)options.PCCompression); - options.WebGLCompression = PopupFormat("WebGL", (TextureFormat)options.WebGLCompression); - options.AndroidCompression = PopupFormat("Android", (TextureFormat)options.AndroidCompression); - options.iOSCompression = PopupFormat("iOS", (TextureFormat)options.iOSCompression); - options.tvOSCompression = PopupFormat("tvOS", (TextureFormat)options.tvOSCompression); - EditorGUI.indentLevel -= 1; + options.PCCompression = PopupFormat("PC & Console", (TextureFormat) options.PCCompression); + options.WebGLCompression = PopupFormat("WebGL", (TextureFormat) options.WebGLCompression); + options.AndroidCompression = PopupFormat("Android", (TextureFormat) options.AndroidCompression); + options.iOSCompression = PopupFormat("iOS", (TextureFormat) options.iOSCompression); + options.tvOSCompression = PopupFormat("tvOS", (TextureFormat) options.tvOSCompression); + EditorGUI.indentLevel -= 1; } - } private static TextureFormat PopupFormat(string label, TextureFormat format) @@ -413,6 +423,5 @@ private static TextureFormat PopupFormat(string label, TextureFormat format) selectIndex = 0; return Styles.SupportTextureFormats[selectIndex]; } - } -} +} \ No newline at end of file diff --git a/com.unity.hlod/Editor/TerrainHLODCreator.cs b/com.unity.hlod/Editor/TerrainHLODCreator.cs index bb8a7671..84d934e4 100644 --- a/com.unity.hlod/Editor/TerrainHLODCreator.cs +++ b/com.unity.hlod/Editor/TerrainHLODCreator.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Linq; using Unity.Collections; using Unity.HLODSystem.Simplifier; @@ -19,11 +18,18 @@ namespace Unity.HLODSystem { public class TerrainHLODCreator { + public static IEnumerator Create(TerrainHLOD hlod, Action callback) + { + TerrainHLODCreator creator = new TerrainHLODCreator(hlod); + yield return creator.CreateImpl(callback); + } + public static IEnumerator Create(TerrainHLOD hlod) { TerrainHLODCreator creator = new TerrainHLODCreator(hlod); - yield return creator.CreateImpl(); + yield return creator.CreateImpl(null); } + public static IEnumerator Destroy(TerrainHLOD hlod) { var controller = hlod.GetComponent(); @@ -40,7 +46,7 @@ public static IEnumerator Destroy(TerrainHLOD hlod) InteractionMode.AutomatedAction); } - + var generatedObjects = hlod.GeneratedObjects; for (int i = 0; i < generatedObjects.Count; ++i) { @@ -58,8 +64,10 @@ public static IEnumerator Destroy(TerrainHLOD hlod) Object.DestroyImmediate(generatedObjects[i]); } - EditorUtility.DisplayProgressBar("Destroy HLOD", "Destroying HLOD files", (float)i / (float)generatedObjects.Count); + EditorUtility.DisplayProgressBar("Destroy HLOD", "Destroying HLOD files", + (float) i / (float) generatedObjects.Count); } + generatedObjects.Clear(); Object.DestroyImmediate(controller); } @@ -67,19 +75,18 @@ public static IEnumerator Destroy(TerrainHLOD hlod) { EditorUtility.ClearProgressBar(); } - + EditorUtility.SetDirty(hlod.gameObject); EditorUtility.SetDirty(hlod); } - class Layer : IDisposable { private NativeArray m_detector = new NativeArray(1, Allocator.Persistent); public float NormalScale => m_normalScale; - + public Layer(TerrainLayer layer, float chunkSize) { m_diffuseTextures = new DisposableList(); @@ -92,12 +99,24 @@ public Layer(TerrainLayer layer, float chunkSize) m_chunkSize = chunkSize; - MakeTexture(layer, layer.diffuseTexture, layer.diffuseRemapMin, layer.diffuseRemapMax, m_diffuseTextures); - MakeTexture(layer, layer.maskMapTexture, layer.maskMapRemapMin, layer.maskMapRemapMax, m_maskTextures); - MakeTexture(layer, layer.normalMapTexture, Vector4.zero, Vector4.one, m_normalTextures); + + MakeTexture(layer, layer.diffuseTexture, layer.diffuseRemapMin, layer.diffuseRemapMax, + m_diffuseTextures); + + if (layer.maskMapTexture) + { + MakeTexture(layer, layer.maskMapTexture, layer.maskMapRemapMin, layer.maskMapRemapMax, + m_maskTextures); + } + + if (layer.normalMapTexture) + { + MakeTexture(layer, layer.normalMapTexture, Vector4.zero, Vector4.one, m_normalTextures); + } } - void MakeTexture(TerrainLayer layer, Texture2D texture, Vector4 min, Vector4 max, DisposableList results) + void MakeTexture(TerrainLayer layer, Texture2D texture, Vector4 min, Vector4 max, + DisposableList results) { bool linear = !GraphicsFormatUtility.IsSRGBFormat(texture.graphicsFormat); @@ -135,7 +154,8 @@ void MakeTexture(TerrainLayer layer, Texture2D texture, Vector4 min, Vector4 max { int width = texture.width >> i; int height = texture.height >> i; - WorkingTexture workingTexture = new WorkingTexture(Allocator.Persistent, texture.format, width, height, linear); + WorkingTexture workingTexture = + new WorkingTexture(Allocator.Persistent, texture.format, width, height, linear); Color[] colors = texture.GetPixels(i); for (int y = 0; y < height; ++y) { @@ -159,7 +179,7 @@ void MakeTexture(TerrainLayer layer, Texture2D texture, Vector4 min, Vector4 max } } } - + public void Dispose() { m_diffuseTextures?.Dispose(); @@ -174,7 +194,7 @@ public Color GetColor(float u, float v, int mipLevel = 0) v = v - Mathf.Floor(v); mipLevel = Mathf.Min(mipLevel, m_diffuseTextures.Count - 1); - + return m_diffuseTextures[mipLevel].GetPixel(u, v); } @@ -236,7 +256,7 @@ private WorkingTexture GenerateMipmap(WorkingTexture source) { int sx = Mathf.Max(source.Width >> 1, 1); int sy = Mathf.Max(source.Height >> 1, 1); - + WorkingTexture mipmap = new WorkingTexture(Allocator.Persistent, source.Format, sx, sy, source.Linear); mipmap.Name = source.Name; @@ -246,7 +266,7 @@ private WorkingTexture GenerateMipmap(WorkingTexture source) { Color color = new Color(); - int x1 = Mathf.Min(x * 2 + 0, source.Width -1); + int x1 = Mathf.Min(x * 2 + 0, source.Width - 1); int x2 = Mathf.Min(x * 2 + 1, source.Width - 1); int y1 = Mathf.Min(y * 2 + 0, source.Height - 1); int y2 = Mathf.Min(y * 2 + 1, source.Height - 1); @@ -287,7 +307,6 @@ private void RemapTexture(WorkingTexture source, Color min, Color max) private float m_normalScale; } - private TerrainHLOD m_hlod; @@ -313,22 +332,24 @@ private TerrainHLODCreator(TerrainHLOD hlod) private Heightmap CreateSubHightmap(Bounds bounds) { - int beginX = Mathf.RoundToInt(bounds.min.x / m_size.x * (m_heightmap.Width-1)); - int beginZ = Mathf.RoundToInt(bounds.min.z / m_size.z * (m_heightmap.Height-1)); - int endX = Mathf.RoundToInt(bounds.max.x / m_size.x * (m_heightmap.Width-1)); - int endZ = Mathf.RoundToInt(bounds.max.z / m_size.z * (m_heightmap.Height-1)); + int beginX = Mathf.RoundToInt(bounds.min.x / m_size.x * (m_heightmap.Width - 1)); + int beginZ = Mathf.RoundToInt(bounds.min.z / m_size.z * (m_heightmap.Height - 1)); + int endX = Mathf.RoundToInt(bounds.max.x / m_size.x * (m_heightmap.Width - 1)); + int endZ = Mathf.RoundToInt(bounds.max.z / m_size.z * (m_heightmap.Height - 1)); int width = endX - beginX + 1; int height = endZ - beginZ + 1; return m_heightmap.GetHeightmap(beginX, beginZ, width, height); } - private WorkingObject CreateBakedTerrain(string name, Bounds bounds, Heightmap heightmap, int distance, bool isLeaf) + + private WorkingObject CreateBakedTerrain(string name, Bounds bounds, Heightmap heightmap, int distance, + bool isLeaf) { WorkingObject wo = new WorkingObject(Allocator.Persistent); wo.Name = name; wo.LightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; - + m_queue.EnqueueJob(() => { WorkingMesh mesh = CreateBakedGeometry(name, heightmap, bounds, distance); @@ -337,7 +358,7 @@ private WorkingObject CreateBakedTerrain(string name, Bounds bounds, Heightmap h m_queue.EnqueueJob(() => { - WorkingMaterial material = CreateBakedMaterial(name, bounds, isLeaf); + WorkingMaterial material = CreateBakedMaterial(name, bounds, isLeaf); wo.Materials.Add(material); }); @@ -349,7 +370,7 @@ private WorkingMesh CreateBakedGeometry(string name, Heightmap heightmap, Bounds { int borderWidth = CalcBorderWidth(heightmap, distance); int borderWidth2x = borderWidth * 2; - + WorkingMesh mesh = new WorkingMesh(Allocator.Persistent, heightmap.Width * heightmap.Height, (heightmap.Width - borderWidth2x - 1) * (heightmap.Height - borderWidth2x - 1) * 6, 1, 0); @@ -357,17 +378,18 @@ private WorkingMesh CreateBakedGeometry(string name, Heightmap heightmap, Bounds mesh.name = name + "_Mesh"; - Vector3[] vertices = new Vector3[(heightmap.Width - borderWidth2x) * (heightmap.Height - borderWidth2x)]; + Vector3[] vertices = new Vector3[(heightmap.Width - borderWidth2x) * (heightmap.Height - borderWidth2x)]; Vector3[] normals = new Vector3[(heightmap.Width - borderWidth2x) * (heightmap.Height - borderWidth2x)]; Vector2[] uvs = new Vector2[(heightmap.Width - borderWidth2x) * (heightmap.Height - borderWidth2x)]; - int[] triangles = new int[(heightmap.Width - borderWidth2x - 1) * (heightmap.Height - borderWidth2x - 1) * 6]; + int[] triangles = + new int[(heightmap.Width - borderWidth2x - 1) * (heightmap.Height - borderWidth2x - 1) * 6]; int vi = 0; //except boder line - for (int z = borderWidth; z < heightmap.Height -borderWidth; ++z) + for (int z = borderWidth; z < heightmap.Height - borderWidth; ++z) { - for (int x = borderWidth; x < heightmap.Width -borderWidth; ++x) + for (int x = borderWidth; x < heightmap.Width - borderWidth; ++x) { int index = vi++; @@ -375,12 +397,10 @@ private WorkingMesh CreateBakedGeometry(string name, Heightmap heightmap, Bounds vertices[index].y = heightmap.Size.y * heightmap[z, x]; vertices[index].z = bounds.size.z * (z) / (heightmap.Height - 1) + bounds.min.z; - uvs[index].x = (float)x / (heightmap.Width - 1); - uvs[index].y = (float)z / (heightmap.Height - 1); - + uvs[index].x = (float) x / (heightmap.Width - 1); + uvs[index].y = (float) z / (heightmap.Height - 1); + normals[index] = heightmap.GetInterpolatedNormal(uvs[index].x, uvs[index].y); - - } } @@ -389,10 +409,10 @@ private WorkingMesh CreateBakedGeometry(string name, Heightmap heightmap, Bounds { for (int x = 0; x < heightmap.Width - borderWidth2x - 1; ++x) { - int i00 = z * (heightmap.Width -borderWidth2x)+ x; - int i10 = z * (heightmap.Width -borderWidth2x)+ x + 1; - int i01 = (z + 1) * (heightmap.Width -borderWidth2x)+ x; - int i11 = (z + 1) * (heightmap.Width -borderWidth2x)+ x + 1; + int i00 = z * (heightmap.Width - borderWidth2x) + x; + int i10 = z * (heightmap.Width - borderWidth2x) + x + 1; + int i01 = (z + 1) * (heightmap.Width - borderWidth2x) + x; + int i11 = (z + 1) * (heightmap.Width - borderWidth2x) + x + 1; triangles[ii + 0] = i00; triangles[ii + 1] = i11; @@ -463,7 +483,9 @@ private Color PackNormal(Color c) return c; } - private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int resolution, System.Func getColor, System.Func packColor = null) + private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int resolution, + System.Func getColor, + System.Func packColor = null) { bool linear = texture.Linear; @@ -478,8 +500,8 @@ private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int r { for (int x = 0; x < resolution; ++x) { - float u = (float)x / (float)resolution * usize + ustart; - float v = (float)y / (float)resolution * vsize + vstart; + float u = (float) x / (float) resolution * usize + ustart; + float v = (float) y / (float) resolution * vsize + vstart; Color color = new Color(0.0f, 0.0f, 0.0f, 0.0f); @@ -506,8 +528,8 @@ private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int r if (weight < 0.01f) continue; - float wx = (float)x / (float)resolution * bounds.size.x + bounds.min.x; - float wy = (float)y / (float)resolution * bounds.size.z + bounds.min.z; + float wx = (float) x / (float) resolution * bounds.size.x + bounds.min.x; + float wy = (float) y / (float) resolution * bounds.size.z + bounds.min.z; Color c = getColor(li, wx, wy, bounds.size.x, bounds.size.z, linear); @@ -536,11 +558,12 @@ private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int r private WorkingTexture BakeAlbedo(string name, Bounds bounds, int resolution) { - WorkingTexture albedoTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, false); + WorkingTexture albedoTexture = + new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, false); albedoTexture.Name = name + "_Albedo"; albedoTexture.WrapMode = TextureWrapMode.Clamp; - EnqueueBlendTextureJob(albedoTexture, bounds, resolution, (layer, wx, wz, sx, sz, linear) => + EnqueueBlendTextureJob(albedoTexture, bounds, resolution, (layer, wx, wz, sx, sz, linear) => { Color c = m_layers[layer].GetColorByWorld(wx, wz, sx, sz); if (!linear) @@ -548,13 +571,14 @@ private WorkingTexture BakeAlbedo(string name, Bounds bounds, int resolution) return c; }); - + return albedoTexture; } private WorkingTexture BakeMask(string name, Bounds bounds, int resolution) { - WorkingTexture maskTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.ARGB32, resolution, resolution, false); + WorkingTexture maskTexture = + new WorkingTexture(Allocator.Persistent, TextureFormat.ARGB32, resolution, resolution, false); maskTexture.Name = name + "_Mask"; maskTexture.WrapMode = TextureWrapMode.Clamp; @@ -571,7 +595,8 @@ private WorkingTexture BakeMask(string name, Bounds bounds, int resolution) private WorkingTexture BakeNormal(string name, Bounds bounds, int resolution) { - WorkingTexture normalTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, true); + WorkingTexture normalTexture = + new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, true); normalTexture.Name = name + "_Normal"; normalTexture.WrapMode = TextureWrapMode.Clamp; @@ -580,14 +605,14 @@ private WorkingTexture BakeNormal(string name, Bounds bounds, int resolution) Color c = m_layers[layer].GetNormalByWorld(wx, wz, sx, sz); c = UnPackNormal(c, m_layers[layer].NormalScale); return c; - },(c) => + }, (c) => { Vector3 n = new Vector3(c.r, c.g, c.b); n.Normalize(); c = new Color(n.x, n.y, n.z); return PackNormal(c); }); - + return normalTexture; } @@ -619,7 +644,7 @@ private List GetEdgeList(List tris) } } } - + return candidates.ToList(); } @@ -635,16 +660,16 @@ private List GenerateBorderVertices(Heightmap heightmap, int borde //generate border vertices List borderVertices = new List((heightmap.Width + heightmap.Height) * 2); - int xBorderOffset = Mathf.Max((heightmap.Width - 1) / borderCount, 1 ); //< avoid 0 - int yBorderOffset = Mathf.Max((heightmap.Height - 1) / borderCount, 1); //< avoid 0 - + int xBorderOffset = Mathf.Max((heightmap.Width - 1) / borderCount, 1); //< avoid 0 + int yBorderOffset = Mathf.Max((heightmap.Height - 1) / borderCount, 1); //< avoid 0 + //upside - for (int i = 0; i < heightmap.Width-1; i += xBorderOffset) + for (int i = 0; i < heightmap.Width - 1; i += xBorderOffset) { float h = heightmap[0, i]; BorderVertex v; - v.Pos.x = (heightmap.Size.x * i) / (heightmap.Width-1); + v.Pos.x = (heightmap.Size.x * i) / (heightmap.Width - 1); v.Pos.y = (heightmap.Size.y * h); v.Pos.z = 0.0f; v.Pos += heightmap.Offset; @@ -655,14 +680,14 @@ private List GenerateBorderVertices(Heightmap heightmap, int borde } //rightside - for (int i = 0; i < heightmap.Height-1; i += yBorderOffset) + for (int i = 0; i < heightmap.Height - 1; i += yBorderOffset) { float h = heightmap[i, heightmap.Width - 1]; BorderVertex v; v.Pos.x = heightmap.Size.x; v.Pos.y = (heightmap.Size.y * h); - v.Pos.z = (heightmap.Size.z * i) / (heightmap.Height-1); + v.Pos.z = (heightmap.Size.z * i) / (heightmap.Height - 1); v.Pos += heightmap.Offset; v.ClosestIndex = -1; @@ -671,12 +696,12 @@ private List GenerateBorderVertices(Heightmap heightmap, int borde } //downside - for (int i = heightmap.Width-1; i > 0; i -= xBorderOffset) + for (int i = heightmap.Width - 1; i > 0; i -= xBorderOffset) { float h = heightmap[heightmap.Height - 1, i]; BorderVertex v; - v.Pos.x = (heightmap.Size.x * i) / (heightmap.Width-1); + v.Pos.x = (heightmap.Size.x * i) / (heightmap.Width - 1); v.Pos.y = (heightmap.Size.y * h); v.Pos.z = heightmap.Size.z; v.Pos += heightmap.Offset; @@ -694,7 +719,7 @@ private List GenerateBorderVertices(Heightmap heightmap, int borde BorderVertex v; v.Pos.x = 0.0f; v.Pos.y = (heightmap.Size.y * h); - v.Pos.z = (heightmap.Size.z * i) / (heightmap.Height-1); + v.Pos.z = (heightmap.Size.z * i) / (heightmap.Height - 1); v.Pos += heightmap.Offset; v.ClosestIndex = -1; @@ -704,7 +729,7 @@ private List GenerateBorderVertices(Heightmap heightmap, int borde return borderVertices; } - + private WorkingMesh MakeBorder(WorkingMesh source, Heightmap heightmap, int borderCount) { @@ -721,15 +746,15 @@ private WorkingMesh MakeBorder(WorkingMesh source, Heightmap heightmap, int bord List edges = GetEdgeList(tris); HashSet vertexIndces = new HashSet(); List edgeVertices = new List(); - + for (int ei = 0; ei < edges.Count; ++ei) { vertexIndces.Add(edges[ei].x); vertexIndces.Add(edges[ei].y); } - + List borderVertices = GenerateBorderVertices(heightmap, borderCount); - + //calculate closest vertex from border vertices. for (int i = 0; i < borderVertices.Count; ++i) { @@ -748,13 +773,13 @@ private WorkingMesh MakeBorder(WorkingMesh source, Heightmap heightmap, int bord borderVertices[i] = v; } - + //generate tris int startAddIndex = vertices.Count; for (int bi = 0; bi < borderVertices.Count; ++bi) { int next = (bi == borderVertices.Count - 1) ? 0 : bi + 1; - + tris.Add(bi + startAddIndex); tris.Add(borderVertices[bi].ClosestIndex); tris.Add(next + startAddIndex); @@ -763,19 +788,17 @@ private WorkingMesh MakeBorder(WorkingMesh source, Heightmap heightmap, int bord uv.x = (borderVertices[bi].Pos.x - heightmap.Offset.x) / heightmap.Size.x; uv.y = (borderVertices[bi].Pos.z - heightmap.Offset.z) / heightmap.Size.z; vertices.Add(borderVertices[bi].Pos); - + normals.Add(heightmap.GetInterpolatedNormal(uv.x, uv.y)); - + uvs.Add(uv); - + if (borderVertices[bi].ClosestIndex == borderVertices[next].ClosestIndex) continue; - + tris.Add(borderVertices[bi].ClosestIndex); tris.Add(borderVertices[next].ClosestIndex); tris.Add(next + startAddIndex); - - } maxTris += tris.Count; @@ -812,14 +835,16 @@ private void ReampUV(WorkingMesh mesh, Heightmap heightmap) mesh.uv = uvs; } + private int CalcBorderWidth(Heightmap heightmap, int distance) { if (m_hlod.SimplifierType == typeof(Simplifier.None)) { return 1; } + dynamic options = m_hlod.SimplifierOptions; - + int maxPolygonCount = options.SimplifyMaxPolygonCount; int minPolygonCount = options.SimplifyMinPolygonCount; float polygonRatio = options.SimplifyPolygonRatio; @@ -827,23 +852,23 @@ private int CalcBorderWidth(Heightmap heightmap, int distance) float maxQuality = Mathf.Min((float) maxPolygonCount / (float) triangleCount, polygonRatio); float minQuality = Mathf.Max((float) minPolygonCount / (float) triangleCount, 0.0f); - + var ratio = maxQuality * Mathf.Pow(polygonRatio, distance); ratio = Mathf.Max(ratio, minQuality); - int expectPolygonCount = (int)(triangleCount * ratio); + int expectPolygonCount = (int) (triangleCount * ratio); - float areaSize = (heightmap.Size.x * heightmap.Size.z); - float sourceSizePerTri = areaSize/ triangleCount; + float areaSize = (heightmap.Size.x * heightmap.Size.z); + float sourceSizePerTri = areaSize / triangleCount; float targetSizePerTri = areaSize / expectPolygonCount; float sizeRatio = targetSizePerTri / sourceSizePerTri; float sizeRatioSqrt = Mathf.Sqrt(sizeRatio); - + //sizeRatioSqrt is little bit big i think. //So I adjust the value by divide 2. return Mathf.Max((int) sizeRatioSqrt / 2, 1); } - + public class EdgeGroup { @@ -856,13 +881,13 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) { int totalTris = 0; List newTris = new List(); - + for (int si = 0; si < source.subMeshCount; ++si) { List tris = source.GetTriangles(si).ToList(); List edgeList = GetEdgeList(tris); - - + + List groups = new List(); for (int i = 0; i < edgeList.Count; ++i) { @@ -870,7 +895,7 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) group.Begin = edgeList[i].x; group.End = edgeList[i].y; group.EdgeList.Add(edgeList[i]); - + groups.Add(group); } @@ -917,7 +942,7 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) for (int gi = 0; gi < groups.Count; ++gi) { EdgeGroup group = groups[gi]; - for (int ei1 = 1; ei1 < group.EdgeList.Count-1; ++ei1) + for (int ei1 = 1; ei1 < group.EdgeList.Count - 1; ++ei1) { for (int ei2 = ei1 + 1; ei2 < group.EdgeList.Count; ++ei2) { @@ -936,7 +961,7 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) { group.EdgeList.RemoveAt(i); } - + groups.Add(ng); ei1 = 0; // goto first @@ -948,9 +973,9 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) if (groups.Count == 0) continue; - + groups.Sort((g1, g2) => { return g2.EdgeList.Count - g1.EdgeList.Count; }); - + //first group( longest group ) is outline. for (int i = 1; i < groups.Count; ++i) { @@ -961,14 +986,14 @@ private WorkingMesh MakeFillHoleMesh(WorkingMesh source) tris.Add(group.EdgeList[ei].y); tris.Add(group.EdgeList[ei].x); } - } totalTris += tris.Count; newTris.Add(tris.ToArray()); } - - WorkingMesh mesh = new WorkingMesh(Allocator.Persistent, source.vertexCount, totalTris, source.subMeshCount, 0); + + WorkingMesh mesh = new WorkingMesh(Allocator.Persistent, source.vertexCount, totalTris, source.subMeshCount, + 0); mesh.name = source.name; mesh.vertices = source.vertices; mesh.normals = source.normals; @@ -996,7 +1021,7 @@ private DisposableList CreateBuildInfo(TerrainData data, SpaceNod parentQueue.Enqueue(-1); nameQueue.Enqueue("HLOD"); depthQueue.Enqueue(0); - + while (trevelQueue.Count > 0) { @@ -1018,12 +1043,13 @@ private DisposableList CreateBuildInfo(TerrainData data, SpaceNod nameQueue.Enqueue(name + "_" + (i + 1)); depthQueue.Enqueue(depth + 1); } - + info.Heightmap = CreateSubHightmap(node.Bounds); - info.WorkingObjects.Add(CreateBakedTerrain(name, node.Bounds, info.Heightmap, depth, node.GetChildCount() == 0)); + info.WorkingObjects.Add(CreateBakedTerrain(name, node.Bounds, info.Heightmap, depth, + node.GetChildCount() == 0)); info.Distances.Add(depth); results.Add(info); - + if (depth > maxDepth) maxDepth = depth; } @@ -1040,8 +1066,8 @@ private DisposableList CreateBuildInfo(TerrainData data, SpaceNod return results; } - - public IEnumerator CreateImpl() + + public IEnumerator CreateImpl(Action callback) { try { @@ -1068,7 +1094,8 @@ public IEnumerator CreateImpl() string materialPath = AssetDatabase.GUIDToAssetPath(m_hlod.MaterialGUID); m_terrainMaterial = AssetDatabase.LoadAssetAtPath(materialPath); if (m_terrainMaterial == null) - m_terrainMaterial = new Material(Shader.Find("Lightweight Render Pipeline/Lit-Terrain-HLOD-High")); + m_terrainMaterial = + new Material(Shader.Find("Lightweight Render Pipeline/Lit-Terrain-HLOD-High")); m_terrainMaterialInstanceId = m_terrainMaterial.GetInstanceID(); m_terrainMaterialName = m_terrainMaterial.name; @@ -1076,7 +1103,8 @@ public IEnumerator CreateImpl() materialPath = AssetDatabase.GUIDToAssetPath(m_hlod.MaterialLowGUID); m_terrainMaterialLow = AssetDatabase.LoadAssetAtPath(materialPath); if (m_terrainMaterialLow == null) - m_terrainMaterialLow = new Material(Shader.Find("Lightweight Render Pipeline/Lit-Terrain-HLOD-Low")); + m_terrainMaterialLow = + new Material(Shader.Find("Lightweight Render Pipeline/Lit-Terrain-HLOD-Low")); m_terrainMaterialLowInstanceId = m_terrainMaterialLow.GetInstanceID(); m_terrainMaterialLowName = m_terrainMaterialLow.name; @@ -1097,8 +1125,9 @@ public IEnumerator CreateImpl() QuadTreeSpaceSplitter splitter = new QuadTreeSpaceSplitter(null); - List rootNodeList = splitter.CreateSpaceTree(m_hlod.GetBounds(), m_hlod.ChunkSize * 2.0f, - m_hlod.transform, null, progress => { }); + List rootNodeList = splitter.CreateSpaceTree(m_hlod.GetBounds(), + m_hlod.ChunkSize * 2.0f, + m_hlod.transform, null, progress => { }); EditorUtility.DisplayProgressBar("Bake HLOD", "Create mesh", 0.0f); foreach (var rootNode in rootNodeList) @@ -1113,9 +1142,9 @@ public IEnumerator CreateImpl() int curIndex = i; m_queue.EnqueueJob(() => { - ISimplifier simplifier = (ISimplifier)Activator.CreateInstance( + ISimplifier simplifier = (ISimplifier) Activator.CreateInstance( m_hlod.SimplifierType, - new object[] { m_hlod.SimplifierOptions }); + new object[] {m_hlod.SimplifierOptions}); simplifier.SimplifyImmidiate(buildInfos[curIndex]); }); } @@ -1138,7 +1167,7 @@ public IEnumerator CreateImpl() WorkingObject o = info.WorkingObjects[oi]; int borderVertexCount = m_hlod.BorderVertexCount * Mathf.RoundToInt(Mathf.Pow(2.0f, - (float)info.Distances[oi])); + (float) info.Distances[oi])); using (WorkingMesh m = MakeBorder(o.Mesh, info.Heightmap, borderVertexCount)) { @@ -1184,7 +1213,6 @@ public IEnumerator CreateImpl() List materials = new List(); for (int mi = 0; mi < wo.Materials.Count; ++mi) { - WorkingMaterial wm = wo.Materials[mi]; if (wm.NeedWrite() == false) { @@ -1225,8 +1253,8 @@ public IEnumerator CreateImpl() //controller IStreamingBuilder builder = - (IStreamingBuilder)Activator.CreateInstance(m_hlod.StreamingType, - new object[] { m_hlod, m_hlod.StreamingOptions }); + (IStreamingBuilder) Activator.CreateInstance(m_hlod.StreamingType, + new object[] {m_hlod, m_hlod.StreamingOptions}); builder.Build(rootNode, buildInfos, m_hlod.gameObject, m_hlod.CullDistance, m_hlod.LODDistance, true, false, @@ -1237,7 +1265,6 @@ public IEnumerator CreateImpl() }); Debug.Log("[TerrainHLOD] Build: " + sw.Elapsed.ToString("g")); - } } } @@ -1250,9 +1277,8 @@ public IEnumerator CreateImpl() EditorUtility.ClearProgressBar(); GC.Collect(); } - } - + callback?.Invoke(); + } } - } \ No newline at end of file diff --git a/com.unity.hlod/Runtime/TerrainHLOD.cs b/com.unity.hlod/Runtime/TerrainHLOD.cs index 540cbe35..b9963bad 100644 --- a/com.unity.hlod/Runtime/TerrainHLOD.cs +++ b/com.unity.hlod/Runtime/TerrainHLOD.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using UnityEngine; using Object = UnityEngine.Object; @@ -33,12 +32,10 @@ public class TerrainHLOD : MonoBehaviour, ISerializationCallbackReceiver, IGener [SerializeField] private string m_albedoPropertyName = ""; [SerializeField] private string m_normalPropertyName = ""; [SerializeField] private string m_maskPropertyName = ""; - - [SerializeField] - private List m_generatedObjects = new List(); - [SerializeField] - private List m_convertedPrefabObjects = new List(); - + + [SerializeField] private List m_generatedObjects = new List(); + [SerializeField] private List m_convertedPrefabObjects = new List(); + public Type SimplifierType { set { m_SimplifierType = value; } @@ -53,14 +50,16 @@ public Type StreamingType public TerrainData TerrainData { - set { m_TerrainData = value;} + set { m_TerrainData = value; } get { return m_TerrainData; } } + public bool DestroyTerrain { set { m_DestroyTerrain = value; } get { return m_DestroyTerrain; } } + public float ChunkSize { get { return m_ChunkSize; } @@ -84,15 +83,17 @@ public float CullDistance get { return m_CullDistance; } set { m_CullDistance = value; } } - + public SerializableDynamicObject SimplifierOptions { get { return m_SimplifierOptions; } + set => m_SimplifierOptions = value; } public SerializableDynamicObject StreamingOptions { - get { return m_StreamingOptions; } + get => m_StreamingOptions; + set => m_SimplifierOptions = value; } public int TextureSize @@ -142,16 +143,17 @@ public string MaskPropertyName set { m_maskPropertyName = value; } get { return m_maskPropertyName; } } - + public List GeneratedObjects { get { return m_generatedObjects; } } + public List ConvertedPrefabObjects { get { return m_convertedPrefabObjects; } } - + public void OnBeforeSerialize() { if (m_SimplifierType != null) @@ -179,7 +181,6 @@ public void OnAfterDeserialize() { m_StreamingType = Type.GetType(m_StreamingTypeStr); } - } public void AddGeneratedResource(Object obj) @@ -196,13 +197,12 @@ public void AddConvertedPrefabResource(GameObject obj) { m_convertedPrefabObjects.Add(obj); } - + public Bounds GetBounds() { - if ( m_TerrainData == null ) + if (m_TerrainData == null) return new Bounds(); return new Bounds(m_TerrainData.size * 0.5f, m_TerrainData.size); } - } } \ No newline at end of file