Пример #1
0
 //检查是否为所在树的贴图集
 bool CheckInCurrLittleOctree(LODVolume lodVolume, TextureAtlasData rootData)
 {
     LODVolume[] parents = lodVolume.GetComponentsInParent <LODVolume>();
     foreach (LODVolume p in parents)
     {
         if (p.gameObject == rootData.m_Root)//找到我是该大贴图的孩子
         {
             return(true);
         }
     }
     return(false);
 }
Пример #2
0
        /*导出单独一个TextureAtlas*/
        public static void ExportOnlyOneTextureAtlasData(TextureAtlasData data, string atlasPath, string materialPath, string name)
        {
            string paths = AssetDatabase.GetAssetPath(data.m_Atlases);

            if (paths != "")
            {
                return;
            }
            data.m_Atlases.textureAtlas = SaveUniqueAtlasAsset <Texture2D>(data.m_Atlases.textureAtlas, atlasPath, name);
            if (data.m_Atlases.textureAtlas_N)//有法线贴图就保存
            {
                data.m_Atlases.textureAtlas_N = SaveUniqueAtlasAsset <Texture2D>(data.m_Atlases.textureAtlas_N, atlasPath, name + "_N");
            }
            data.m_Material.mainTexture = data.m_Atlases.textureAtlas;
            SaveMaterialsAsset(data.m_Material, materialPath, name);

            SaveUniqueAtlasAsset(data.m_Atlases, atlasPath, name);
        }
Пример #3
0
        /*删除单独一个TextureAtlas*/
        public static void DeleteOnlyOneTextureAtlasData(TextureAtlasData data)
        {
            string paths = AssetDatabase.GetAssetPath(data.m_Atlases.textureAtlas);

            if (paths != "")
            {
                AssetDatabase.DeleteAsset(paths);
            }
            paths = AssetDatabase.GetAssetPath(data.m_Atlases.textureAtlas_N);
            if (paths != "")
            {
                AssetDatabase.DeleteAsset(paths);
            }
            paths = AssetDatabase.GetAssetPath(data.m_Atlases);
            if (paths != "")
            {
                AssetDatabase.DeleteAsset(paths);
            }
            paths = AssetDatabase.GetAssetPath(data.m_Material);
            if (paths != "")
            {
                AssetDatabase.DeleteAsset(paths);
            }
        }
Пример #4
0
        /*更新合批贴图、材质球*/
        void UpdataCombineMatsAndTexs(HLODGenerate hlodGenerate)
        {
            Dictionary <HLODGenerate, List <TextureAtlasData> > m_AllAtlases = TextureAtlasModule.instance.AllAtlases;
            List <TextureAtlasData> data = null;

            if (m_AllAtlases.TryGetValue(hlodGenerate, out data))
            {
                List <TextureAtlasData> remove = m_RemovedTextureAtlasData;
                List <TextureAtlasData> add    = m_AddedTextureAtlasData;
                remove.Clear();
                add.Clear();

                //标记delete的就删除并删除资源,标记add就添加或更新
                for (int i = 0; i < data.Count; i++)
                {
                    TextureAtlasData taData = data[i];
                    switch (taData.m_State)
                    {
                    case TextureAtlasData.State.Delete:
                        remove.Add(taData);
                        break;

                    case TextureAtlasData.State.Add:
                        taData.m_MeshRenderers.RemoveAll(r => r == null);
                        if (taData.m_MeshRenderers.Count > 0)
                        {
                            add.Add(taData);
                        }
                        else
                        {
                            taData.m_State = TextureAtlasData.State.Delete;
                            remove.Add(taData);
                        }
                        //删除空renderer

                        break;
                    }
                }
                data.RemoveAll(r => r.m_State == TextureAtlasData.State.Delete);

                if (hlodGenerate.m_IsExportMatTex)
                {
                    if (hlodGenerate.m_TextureAssetPath == "")
                    {
                        EditorUtility.DisplayDialog("警告", "没有选择textures路径,请先选择路径", "是");
                        hlodGenerate.m_IsExportMatTex = false;
                        return;
                    }
                    if (hlodGenerate.m_MaterialAssetPath == "")
                    {
                        EditorUtility.DisplayDialog("警告", "没有选择materials路径,请先选择路径", "是");
                        hlodGenerate.m_IsExportMatTex = false;
                        return;
                    }
                    int progressCount = 1;
                    foreach (TextureAtlasData r in remove)
                    {
                        EditorUtility.DisplayProgressBar("删除图集", r.m_Root.name, (float)progressCount++ / remove.Count);
                        TextureAtlasModule.DeleteOnlyOneTextureAtlasData(r);
                    }
                    progressCount = 1;
                    foreach (TextureAtlasData a in add)
                    {
                        EditorUtility.DisplayProgressBar("保存图集", a.m_Root.name, (float)progressCount++ / add.Count);
                        TextureAtlasModule.ExportOnlyOneTextureAtlasData(a, hlodGenerate.m_TextureAssetPath, hlodGenerate.m_MaterialAssetPath, a.m_MeshRenderers[0].name);
                        foreach (MeshRenderer mr in a.m_MeshRenderers)
                        {
                            mr.sharedMaterial = a.m_Material;
                        }
                        a.m_State = TextureAtlasData.State.None;
                    }
                }
                remove.Clear();
                add.Clear();
                EditorUtility.ClearProgressBar();
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
Пример #5
0
        public IEnumerator Batch(HLODGenerate hg, LODVolume lodVolume)
        {
            GameObject go        = lodVolume.combined._hlodRoot;
            var        renderers = go.GetComponentsInChildren <Renderer>();
            var        materials = new HashSet <Material>(renderers.SelectMany(r => r.sharedMaterials));

            List <Texture2D> textures = new List <Texture2D>();
            List <Texture2D> normals  = new List <Texture2D>();


            textures = new HashSet <Texture2D>(materials.Select(m =>
            {
                if (m)
                {
                    return(m.mainTexture as Texture2D);
                }

                return(null);
            }).Where(t => t != null)).ToList();
            textures.Add(whiteTexture);

            /*
             * foreach(var t2d in textures)
             * {
             *  foreach(var rd in renderers)
             *  {
             *      if(rd.sharedMaterial.mainTexture == t2d)
             *      {
             *          Texture2D t = rd.sharedMaterial.GetTexture("_BumpMap") as Texture2D;
             *          if (t == null)
             *          {
             *              var texture = new Texture2D(rd.sharedMaterial.mainTexture.width, rd.sharedMaterial.mainTexture.height, TextureFormat.RGB24, false, PlayerSettings.colorSpace == ColorSpace.Linear);
             *
             *              t = texture;
             *              //texture.Apply();
             *          }
             *          else if(t.width != rd.sharedMaterial.mainTexture.width || t.height != rd.sharedMaterial.mainTexture.height)
             *          {
             *              int width = rd.sharedMaterial.mainTexture.width;
             *              int height = rd.sharedMaterial.mainTexture.height;
             *              var texture = new Texture2D(rd.sharedMaterial.mainTexture.width, rd.sharedMaterial.mainTexture.height, t.format, false, PlayerSettings.colorSpace == ColorSpace.Linear);
             *
             *
             *              for(int i = 0; i < height; i++)
             *              {
             *                  for(int j = 0; j <width; j++)
             *                  {
             *                      //EditorUtility.DisplayProgressBar("fsdfasd", (height * width).ToString(), (float)(i * j) / (height * width));
             *                     // Color newColor = t.GetPixelBilinear(j / width, i / height);
             *                      texture.SetPixel(j, i, Color.white);
             *                  }
             *              }
             *              //EditorUtility.ClearProgressBar();
             *              texture.Apply();
             *              t = texture;
             *          }
             *          normals.Add(t);
             *          break;
             *      }
             *  }
             * }
             * normals.Add(whiteTexture);
             */

            TextureAtlasData atlasData = null;

            yield return(TextureAtlasModule.instance.GetTextureAtlas(hg, lodVolume, textures.ToArray(), normals.ToArray(), a => atlasData = a));

            var mainAtlasLookup = new Dictionary <Texture2D, Rect>();
            //var normalAtlasLookup = new Dictionary<Texture2D, Rect>();
            var atlasTextures = atlasData.m_Atlases.textures;

            for (int i = 0; i < atlasTextures.Length; i++)
            {
                mainAtlasLookup[atlasTextures[i]] = atlasData.m_Atlases.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 ci = new CombineInstance();

                var mesh = UnityEngine.Object.Instantiate(sharedMesh);

                var mr = mf.GetComponent <MeshRenderer>();
                var sharedMaterials = mr.sharedMaterials;
                var uv = mesh.uv;
                if (uv == null)
                {
                    uv = mesh.uv2;
                }
                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 = sharedMaterial.mainTexture as Texture2D;
                        //sharedMaterial.texture
                        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 = mainAtlasLookup[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;
                            }

                            while (uvCoord.x < 0)
                            {
                                uvCoord.x += 1;
                            }
                            while (uvCoord.y < 0)
                            {
                                uvCoord.y += 1;
                            }
                            while (uvCoord.x > 1)
                            {
                                uvCoord.x -= 1;
                            }
                            while (uvCoord.y > 1)
                            {
                                uvCoord.y -= 1;
                            }

                            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;
                        }
                    }

                    yield return(null);
                }
                mesh.uv     = uv;
                mesh.uv2    = null;
                mesh.colors = colors;

                ci.mesh      = mesh;
                ci.transform = mf.transform.localToWorldMatrix;
                combine.Add(ci);

                mf.gameObject.SetActive(false);

                yield return(null);
            }
            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++)
            {
                UnityEngine.Object.DestroyImmediate(meshFilters[i].gameObject);
            }

            var meshRenderer = go.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = atlasData.m_Material;

            atlasData.m_MeshRenderers.Add(meshRenderer);
        }
Пример #6
0
        public IEnumerator GetTextureAtlas(HLODGenerate hg, LODVolume lodVolume, Texture2D[] textures, Texture2D[] normals, Action <TextureAtlasData> callback)
        {
            TextureAtlasData atlasData = null;

            List <TextureAtlasData> atlasesData = null;

            GetTextureAtlasList(hg, out atlasesData);

            yield return(null);

            foreach (var a in atlasesData)
            {
                if (a.m_State == TextureAtlasData.State.Delete)
                {
                    continue;
                }
                //检查是否为所在树的贴图集
                if (!CheckInCurrLittleOctree(lodVolume, a))
                {
                    continue;
                }
                //是否重新生成
                if (IsReGenerate(lodVolume, textures, a.m_Atlases))
                {
                    a.m_State = TextureAtlasData.State.Delete;
                    break;
                }
                // At a minimum the atlas should have all of the textures requested, but can be a superset
                if (!textures.Except(a.m_Atlases.textures).Any())
                {
                    atlasData = a;
                    break;
                }

                yield return(null);
            }
            //m_Atlases.Remove(deleteAtlas);
            if (atlasData == null)//没有找到图集就创建一个
            {
                atlasData            = new TextureAtlasData(null, TextureAtlasData.State.Add);
                atlasData.m_Material = new Material(Shader.Find("Standard"));
                /*先序遍历,所有根节点就是第一个创建的对象,子节点会找到这个图集而不会继续创建*/
                atlasData.m_Root = lodVolume.gameObject;
            }
            if (!atlasData.m_Atlases)
            {
                atlasData.m_Atlases = ScriptableObject.CreateInstance <TextureAtlas>();

                TextureReadableSetting(textures);
                //TextureReadableSetting(normals);

                CombineTexture(textures, atlasData.m_Atlases, false, callback);
                //CombineTexture(normals, atlasData.m_Atlases, true, callback);

                atlasData.m_Material.mainTexture = atlasData.m_Atlases.textureAtlas;
                //material.SetTexture("_NormalMap", atlasData.m_Atlases.textureAtlas_N);
                atlasesData.Add(atlasData);
                yield return(null);
            }

            if (callback != null)
            {
                callback(atlasData);
            }
        }