Beispiel #1
0
    void populateGroupByFilters()
    {
        string      qualifiedInterfaceName = "DigitalOpus.MB.Core.IGroupByFilter";
        var         interfaceFilter        = new TypeFilter(InterfaceFilter);
        List <Type> types = new List <Type>();

        foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies())
        {
            System.Collections.IEnumerable typesIterator = null;
            try
            {
                typesIterator = ass.GetTypes();
            }
            catch (Exception e)
            {
                //Debug.Log("The assembly that I could not read types for was: " + ass.GetName());
                //suppress error
                e.Equals(null);
            }
            if (typesIterator != null)
            {
                foreach (Type ty in ass.GetTypes())
                {
                    var myInterfaces = ty.FindInterfaces(interfaceFilter, qualifiedInterfaceName);
                    if (myInterfaces.Length > 0)
                    {
                        types.Add(ty);
                    }
                }
            }
        }

        List <string>         filterNames = new List <string>();
        List <IGroupByFilter> filters     = new List <IGroupByFilter>();

        filterNames.Add("None");
        filters.Add(null);
        foreach (Type tt in types)
        {
            if (!tt.IsAbstract && !tt.IsInterface)
            {
                IGroupByFilter instance = (IGroupByFilter)Activator.CreateInstance(tt);
                filterNames.Add(instance.GetName());
                filters.Add(instance);
            }
        }
        groupByOptionNames   = filterNames.ToArray();
        groupByOptionFilters = filters.ToArray();
    }
        /* tried to see if the MultiMaterialConfig could be done using the GroupBy filters. Saddly it didn't work */
        public static void ConfigureMutiMaterialsFromObjsToCombine2(MB3_TextureBaker mom, SerializedProperty resultMaterials, SerializedObject textureBaker)
        {
            if (mom.GetObjectsToCombine().Count == 0)
            {
                Debug.LogError("You need to add some objects to combine before building the multi material list.");
                return;
            }
            if (resultMaterials.arraySize > 0)
            {
                Debug.LogError("You already have some source to combined material mappings configured. You must remove these before doing this operation.");
                return;
            }
            if (mom.textureBakeResults == null)
            {
                Debug.LogError("Texture Bake Result asset must be set before using this operation.");
                return;
            }

            //validate that the objects to be combined are valid
            for (int i = 0; i < mom.GetObjectsToCombine().Count; i++)
            {
                GameObject go = mom.GetObjectsToCombine()[i];
                if (go == null)
                {
                    Debug.LogError("Null object in list of objects to combine at position " + i);
                    return;
                }
                Renderer r = go.GetComponent <Renderer>();
                if (r == null || (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer)))
                {
                    Debug.LogError("GameObject at position " + i + " in list of objects to combine did not have a renderer");
                    return;
                }
                if (r.sharedMaterial == null)
                {
                    Debug.LogError("GameObject at position " + i + " in list of objects to combine has a null material");
                    return;
                }
            }

            IGroupByFilter[] filters = new IGroupByFilter[3];
            filters[0] = new GroupByOutOfBoundsUVs();
            filters[1] = new GroupByShader();
            filters[2] = new MB3_GroupByStandardShaderType();

            List <GameObjectFilterInfo> gameObjects = new List <GameObjectFilterInfo>();
            HashSet <GameObject>        objectsAlreadyIncludedInBakers = new HashSet <GameObject>();

            for (int i = 0; i < mom.GetObjectsToCombine().Count; i++)
            {
                GameObjectFilterInfo goaw = new GameObjectFilterInfo(mom.GetObjectsToCombine()[i], objectsAlreadyIncludedInBakers, filters);
                if (goaw.materials.Length > 0) //don't consider renderers with no materials
                {
                    gameObjects.Add(goaw);
                }
            }

            //analyse meshes
            Dictionary <int, MB_Utility.MeshAnalysisResult> meshAnalysisResultCache = new Dictionary <int, MB_Utility.MeshAnalysisResult>();
            int totalVerts = 0;

            for (int i = 0; i < gameObjects.Count; i++)
            {
                //string rpt = String.Format("Processing {0} [{1} of {2}]", gameObjects[i].go.name, i, gameObjects.Count);
                //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " A", .6f);
                Mesh mm     = MB_Utility.GetMesh(gameObjects[i].go);
                int  nVerts = 0;
                if (mm != null)
                {
                    nVerts += mm.vertexCount;
                    MB_Utility.MeshAnalysisResult mar;
                    if (!meshAnalysisResultCache.TryGetValue(mm.GetInstanceID(), out mar))
                    {
                        //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " Check Out Of Bounds UVs", .6f);
                        MB_Utility.hasOutOfBoundsUVs(mm, ref mar);
                        //Rect dummy = mar.uvRect;
                        MB_Utility.doSubmeshesShareVertsOrTris(mm, ref mar);
                        meshAnalysisResultCache.Add(mm.GetInstanceID(), mar);
                    }
                    if (mar.hasOutOfBoundsUVs)
                    {
                        int w = (int)mar.uvRect.width;
                        int h = (int)mar.uvRect.height;
                        gameObjects[i].outOfBoundsUVs = true;
                        gameObjects[i].warning       += " [WARNING: has uvs outside the range (0,1) tex is tiled " + w + "x" + h + " times]";
                    }
                    if (mar.hasOverlappingSubmeshVerts)
                    {
                        gameObjects[i].submeshesOverlap = true;
                        gameObjects[i].warning         += " [WARNING: Submeshes share verts or triangles. 'Multiple Combined Materials' feature may not work.]";
                    }
                }
                totalVerts += nVerts;
                //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " Validate OBuvs Multi Material", .6f);
                Renderer mr = gameObjects[i].go.GetComponent <Renderer>();
                if (!MB_Utility.AreAllSharedMaterialsDistinct(mr.sharedMaterials))
                {
                    gameObjects[i].warning += " [WARNING: Object uses same material on multiple submeshes. This may produce poor results when used with multiple materials or fix out of bounds uvs.]";
                }
            }

            List <GameObjectFilterInfo> objsNotAddedToBaker = new List <GameObjectFilterInfo>();

            Dictionary <GameObjectFilterInfo, List <List <GameObjectFilterInfo> > > gs2bakeGroupMap = MB3_MeshBakerEditorWindow.sortIntoBakeGroups3(gameObjects, objsNotAddedToBaker, filters, false, mom.maxAtlasSize);

            mom.resultMaterials = new MB_MultiMaterial[gs2bakeGroupMap.Keys.Count];
            string pth        = AssetDatabase.GetAssetPath(mom.textureBakeResults);
            string baseName   = Path.GetFileNameWithoutExtension(pth);
            string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6);
            int    k          = 0;

            foreach (GameObjectFilterInfo m in gs2bakeGroupMap.Keys)
            {
                MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial();
                mm.sourceMaterials = new List <Material>();
                mm.sourceMaterials.Add(m.materials[0]);
                string   matName = folderPath + baseName + "-mat" + k + ".mat";
                Material newMat  = new Material(Shader.Find("Diffuse"));
                MB3_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, m.materials[0]);
                AssetDatabase.CreateAsset(newMat, matName);
                mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material));
                k++;
            }
            MBVersionEditor.UpdateIfDirtyOrScript(textureBaker);
        }
Beispiel #3
0
    void drawTabAnalyseScene()
    {
        //first time we are displaying collect the filters
        if (groupByOptionNames == null || groupByOptionNames.Length == 0)
        {
            var type  = typeof(IGroupByFilter);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                        .SelectMany(s => s.GetTypes())
                        .Where(p => type.IsAssignableFrom(p));

            List <string>         filterNames = new List <string>();
            List <IGroupByFilter> filters     = new List <IGroupByFilter>();
            filterNames.Add("None");
            filters.Add(null);
            foreach (Type tt in types)
            {
                if (!tt.IsAbstract && !tt.IsInterface)
                {
                    IGroupByFilter instance = (IGroupByFilter)Activator.CreateInstance(tt);
                    filterNames.Add(instance.GetName());
                    filters.Add(instance);
                }
            }
            groupByOptionNames   = filterNames.ToArray();
            groupByOptionFilters = filters.ToArray();

            //set filter initial values
            for (int i = 0; i < groupByOptionFilters.Length; i++)
            {
                if (groupByOptionFilters[i] is GroupByShader)
                {
                    groupByFilterIdxs[0] = i;
                    break;
                }
            }
            for (int i = 0; i < groupByOptionFilters.Length; i++)
            {
                if (groupByOptionFilters[i] is GroupByStatic)
                {
                    groupByFilterIdxs[1] = i;
                    break;
                }
            }
            for (int i = 0; i < groupByOptionFilters.Length; i++)
            {
                if (groupByOptionFilters[i] is GroupByRenderType)
                {
                    groupByFilterIdxs[2] = i;
                    break;
                }
            }
            for (int i = 0; i < groupByOptionFilters.Length; i++)
            {
                if (groupByOptionFilters[i] is GroupByOutOfBoundsUVs)
                {
                    groupByFilterIdxs[3] = i;
                    break;
                }
            }
            groupByFilterIdxs[4] = 0;             //none
        }
        if (groupByFilterIdxs == null || groupByFilterIdxs.Length < NUM_FILTERS)
        {
            groupByFilterIdxs = new int[] {
                0, 0, 0, 0, 0
            };
        }
        EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None);

        groupByFilterIdxs[0] = EditorGUILayout.Popup("Group By:", groupByFilterIdxs[0], groupByOptionNames);
        for (int i = 1; i < NUM_FILTERS; i++)
        {
            groupByFilterIdxs[i] = EditorGUILayout.Popup("Then Group By:", groupByFilterIdxs[i], groupByOptionNames);
        }

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Select Folder For Combined Material Assets"))
        {
            generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", "");
            generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(Application.dataPath, "") + "/";
        }
        EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("List Shaders In Scene"))
        {
            EditorUtility.DisplayProgressBar("Analysing Scene", "", .05f);
            try{
                listMaterialsInScene();
            } catch (Exception ex) {
                Debug.LogError(ex.StackTrace);
            } finally {
                EditorUtility.ClearProgressBar();
            }
        }

        if (GUILayout.Button("Bake Every MeshBaker In Scene"))
        {
            try{
                MB3_TextureBaker[] texBakers = (MB3_TextureBaker[])FindObjectsOfType(typeof(MB3_TextureBaker));
                for (int i = 0; i < texBakers.Length; i++)
                {
                    texBakers[i].CreateAtlases(updateProgressBar, true, new MB3_EditorMethods());
                }
                MB3_MeshBakerCommon[] mBakers = (MB3_MeshBakerCommon[])FindObjectsOfType(typeof(MB3_MeshBakerCommon));
                for (int i = 0; i < mBakers.Length; i++)
                {
                    if (mBakers[i].textureBakeResults != null)
                    {
                        MB3_MeshBakerEditorFunctions.BakeIntoCombined(mBakers[i]);
                    }
                }
            } catch (Exception e) {
                Debug.LogError(e);
            }finally{
                EditorUtility.ClearProgressBar();
            }
        }
        EditorGUILayout.EndHorizontal();

        if (sceneAnalysisResults.Count > 0)
        {
            float height = position.height - 150f;
            if (height < 500f)
            {
                height = 500f;
            }
            MB_EditorUtil.DrawSeparator();
            scrollPos2 = EditorGUILayout.BeginScrollView(scrollPos2, false, true);           //(scrollPos2,, GUILayout.Width(position.width - 20f), GUILayout.Height(height));
            EditorGUILayout.LabelField("Shaders In Scene", EditorStyles.boldLabel);
            for (int i = 0; i < sceneAnalysisResults.Count; i++)
            {
                List <GameObjectFilterInfo> gows = sceneAnalysisResults[i];
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Generate Baker", GUILayout.Width(200)))
                {
                    createAndSetupBaker(gows, generate_AssetsFolder);
                }
                string descr = gows[0].GetDescription(GameObjectFilterInfo.filters, gows[0]);

                EditorGUILayout.LabelField(descr, EditorStyles.wordWrappedLabel);
                EditorGUILayout.EndHorizontal();
                sceneAnalysisResultsFoldouts[i] = EditorGUILayout.Foldout(sceneAnalysisResultsFoldouts[i], "");
                if (sceneAnalysisResultsFoldouts[i])
                {
                    EditorGUI.indentLevel += 1;
                    for (int j = 0; j < gows.Count; j++)
                    {
                        if (gows[j].go != null)
                        {
                            EditorGUILayout.LabelField(gows[j].go.name + "  " + gows[j].GetDescription(GameObjectFilterInfo.filters, gows[j]));
                        }
                    }
                    EditorGUI.indentLevel -= 1;
                }
            }
            EditorGUILayout.EndScrollView();
            MB_EditorUtil.DrawSeparator();
        }
    }