static Texture2D SaveTexture(Texture2D texture, string name) { var path = SceneLOD.GetSceneLODPath() + name; path = Path.ChangeExtension(path, "PNG"); var assetPath = "Assets" + Path.DirectorySeparatorChar + path; var dataPath = Application.dataPath + Path.DirectorySeparatorChar + path; var dirPath = Path.GetDirectoryName(dataPath); if (Directory.Exists(dirPath) == false) { Directory.CreateDirectory(dirPath); } byte[] binary = texture.EncodeToPNG(); File.WriteAllBytes(dataPath, binary); AssetDatabase.ImportAsset(assetPath); return(AssetDatabase.LoadAssetAtPath <Texture2D>(assetPath)); }
private static string GetConfigPath() { return("Assets/" + SceneLOD.GetScenePath() + "SceneLODConfig.asset"); }
public void Destroy() { MonoBehaviourHelper.StartCoroutine(ObjectUtils.FindGameObject("HLODs", root => { DestroyImmediate(root); })); Utilities.FileUtils.DeleteDirectory(Application.dataPath + Path.DirectorySeparatorChar + SceneLOD.GetSceneLODPath()); AssetDatabase.Refresh(); }
public IEnumerator Batch(GameObject hlodRoot, System.Action <float> progress) { yield return(PackTextures(hlodRoot)); Dictionary <Texture2D, Material> createdMaterials = new Dictionary <Texture2D, Material>(); for (int childIndex = 0; childIndex < hlodRoot.transform.childCount; ++childIndex) { var child = hlodRoot.transform.GetChild(childIndex); var go = child.gameObject; var renderers = go.GetComponentsInChildren <Renderer>(); var materials = new HashSet <Material>(renderers.SelectMany(r => r.sharedMaterials)); TextureAtlas atlas = packer.GetAtlas(go); var atlasLookup = new Dictionary <Texture2D, Rect>(); var atlasTextures = atlas.textures; for (int i = 0; i < atlasTextures.Length; i++) { atlasLookup[atlasTextures[i]] = atlas.uvs[i]; } MeshFilter[] meshFilters = go.GetComponentsInChildren <MeshFilter>(); var combine = new List <CombineInstance>(); for (int i = 0; i < meshFilters.Length; i++) { var mf = meshFilters[i]; var sharedMesh = mf.sharedMesh; if (!sharedMesh) { continue; } if (!sharedMesh.isReadable) { var assetPath = AssetDatabase.GetAssetPath(sharedMesh); if (!string.IsNullOrEmpty(assetPath)) { var importer = AssetImporter.GetAtPath(assetPath) as ModelImporter; if (importer) { importer.isReadable = true; importer.SaveAndReimport(); } } } var mesh = Object.Instantiate(sharedMesh); var mr = mf.GetComponent <MeshRenderer>(); var sharedMaterials = mr.sharedMaterials; var uv = mesh.uv; var colors = mesh.colors; if (colors == null || colors.Length == 0) { colors = new Color[uv.Length]; } var updated = new bool[uv.Length]; var triangles = new List <int>(); // Some meshes have submeshes that either aren't expected to render or are missing a material, so go ahead and skip var subMeshCount = Mathf.Min(mesh.subMeshCount, sharedMaterials.Length); for (int j = 0; j < subMeshCount; j++) { var sharedMaterial = sharedMaterials[Mathf.Min(j, sharedMaterials.Length - 1)]; var mainTexture = whiteTexture; var materialColor = Color.white; if (sharedMaterial) { var texture = GetTexture(sharedMaterial); if (texture) { mainTexture = texture; } if (sharedMaterial.HasProperty("_Color")) { materialColor = sharedMaterial.color; } } if (mesh.GetTopology(j) != MeshTopology.Triangles) { Debug.LogWarning("Mesh must have triangles", mf); continue; } triangles.Clear(); mesh.GetTriangles(triangles, j); var uvOffset = atlasLookup[mainTexture]; foreach (var t in triangles) { if (!updated[t]) { var uvCoord = uv[t]; if (mainTexture == whiteTexture) { // Sample at center of white texture to avoid sampling edge colors incorrectly uvCoord.x = 0.5f; uvCoord.y = 0.5f; } uvCoord.x = Mathf.Lerp(uvOffset.xMin, uvOffset.xMax, uvCoord.x); uvCoord.y = Mathf.Lerp(uvOffset.yMin, uvOffset.yMax, uvCoord.y); uv[t] = uvCoord; if (mainTexture == whiteTexture) { colors[t] = materialColor; } else { colors[t] = Color.white; } updated[t] = true; } } } mesh.uv = uv; mesh.uv2 = null; mesh.colors = colors; for (int j = 0; j < subMeshCount; ++j) { var ci = new CombineInstance(); ci.mesh = mesh; ci.subMeshIndex = j; ci.transform = mf.transform.localToWorldMatrix; combine.Add(ci); } mf.gameObject.SetActive(false); } var combinedMesh = new Mesh(); #if UNITY_2017_3_OR_NEWER combinedMesh.indexFormat = IndexFormat.UInt32; #endif combinedMesh.CombineMeshes(combine.ToArray(), true, true); combinedMesh.RecalculateBounds(); var meshFilter = go.AddComponent <MeshFilter>(); meshFilter.sharedMesh = combinedMesh; for (int i = 0; i < meshFilters.Length; i++) { Object.DestroyImmediate(meshFilters[i].gameObject); } var meshRenderer = go.AddComponent <MeshRenderer>(); Material material = null; if (createdMaterials.ContainsKey(atlas.textureAtlas) == false) { if (option.BatchMaterial == null) { material = new Material(Shader.Find("Custom/AutoLOD/SimpleBatcher")); } else { material = new Material(option.BatchMaterial); } material.mainTexture = atlas.textureAtlas; string matName = hlodRoot.name + "_" + createdMaterials.Count; AssetDatabase.CreateAsset(material, "Assets/" + SceneLOD.GetSceneLODPath() + matName + ".mat"); createdMaterials.Add(atlas.textureAtlas, material); } else { material = createdMaterials[atlas.textureAtlas]; } meshRenderer.sharedMaterial = material; string assetName = hlodRoot.name + "_" + go.name; AssetDatabase.CreateAsset(combinedMesh, "Assets/" + SceneLOD.GetSceneLODPath() + assetName + ".asset"); AssetDatabase.SaveAssets(); if (progress != null) { progress((float)childIndex / (float)hlodRoot.transform.childCount); } yield return(null); } }