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