private static void _generateMeshBakers(UnityEngine.Object target)
        {
            MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;
            MB3_TextureBaker     tb  = tbg.GetComponent <MB3_TextureBaker>();

            if (tb == null)
            {
                Debug.LogError("There must be an MB3_TextureBaker attached to this game object.");
                return;
            }

            if (tb.GetObjectsToCombine().Count == 0)
            {
                Debug.LogError("The MB3_MeshBakerGrouper creates clusters based on the objects to combine in the MB3_TextureBaker component. There were no objects in this list.");
                return;
            }

            if (tbg.parentSceneObject == null ||
                !MB_Utility.IsSceneInstance(tbg.parentSceneObject.gameObject))
            {
                GameObject g = new GameObject("CombinedMeshes-" + tbg.name);
                tbg.parentSceneObject = g.transform;
            }

            //check if any of the objes that will be added to bakers already exist in child bakers
            List <GameObject> objsWeAreGrouping = tb.GetObjectsToCombine();

            MB3_MeshBakerCommon[] alreadyExistBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>();
            bool foundChildBakersWithObjsToCombine   = false;

            for (int i = 0; i < alreadyExistBakers.Length; i++)
            {
                List <GameObject> childOjs2Combine = alreadyExistBakers[i].GetObjectsToCombine();
                for (int j = 0; j < childOjs2Combine.Count; j++)
                {
                    if (childOjs2Combine[j] != null && objsWeAreGrouping.Contains(childOjs2Combine[j]))
                    {
                        foundChildBakersWithObjsToCombine = true;
                        break;
                    }
                }
            }

            bool proceed = true;

            if (foundChildBakersWithObjsToCombine)
            {
                proceed = EditorUtility.DisplayDialog("Replace Previous Generated Bakers", "Delete child bakers?\n\n" +
                                                      "This grouper has child Mesh Baker objects from a previous clustering. Do you want to delete these and create new ones?", "OK", "Cancel");
            }

            if (tbg.prefabOptions_autoGeneratePrefabs)
            {
                if (!MB_BatchPrefabBakerEditorFunctions.ValidateFolderIsInProject("Output Folder", tbg.prefabOptions_outputFolder))
                {
                    Debug.LogError("If " + gc_prefabOptions_autoGeneratePrefabs.text + " is enabled, you must provide an output folder. Prefabs will be saved in this folder.");
                    proceed = false;
                }
            }

            if (proceed)
            {
                if (foundChildBakersWithObjsToCombine)
                {
                    tbg.DeleteAllChildMeshBakers();
                }
                List <MB3_MeshBakerCommon> newBakers = tbg.grouper.DoClustering(tb, tbg);
                if (newBakers.Count > 0)
                {
                    DoGeneratePrefabsIfNecessary(tbg, newBakers);
                }
            }
        }
        public override void OnInspectorGUI()
        {
            grouper.Update();
            DrawGrouperInspector();
            if (GUILayout.Button("Generate Mesh Bakers"))
            {
                for (int tIdx = 0; tIdx < targets.Length; tIdx++)
                {
                    _generateMeshBakers(targets[tIdx]);
                }
            }

            if (GUILayout.Button("Bake All Child MeshBakers"))
            {
                for (int tIdx = 0; tIdx < targets.Length; tIdx++)
                {
                    _bakeAllChildMeshBakers(targets[tIdx], ref grouper);
                }
            }

            string buttonTextEnableRenderers = "Disable Renderers On All Child MeshBaker Source Objs";
            bool   enableRenderers           = false;

            {
                MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;
                MB3_MeshBakerCommon  bc  = tbg.GetComponentInChildren <MB3_MeshBakerCommon>();
                if (bc != null && bc.GetObjectsToCombine().Count > 0)
                {
                    GameObject go = bc.GetObjectsToCombine()[0];
                    if (go != null && go.GetComponent <Renderer>() != null && go.GetComponent <Renderer>().enabled == false)
                    {
                        buttonTextEnableRenderers = "Enable Renderers On All Child MeshBaker Source Objs";
                        enableRenderers           = true;
                    }
                }
            }

            if (GUILayout.Button(buttonTextEnableRenderers))
            {
                for (int tIdx = 0; tIdx < targets.Length; tIdx++)
                {
                    _enableDisableRenderers(targets[tIdx], enableRenderers);
                }
            }

            if (GUILayout.Button("Delete All Child Mesh Bakers & Combined Meshes"))
            {
                if (EditorUtility.DisplayDialog("Delete Mesh Bakers", "Delete all child mesh bakers", "OK", "Cancel"))
                {
                    for (int i = 0; i < targets.Length; i++)
                    {
                        MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)targets[i];
                        tbg.DeleteAllChildMeshBakers();
                    }
                }
            }


            if (DateTime.UtcNow.Ticks - lastBoundsCheckRefreshTime > 10000000)
            {
                MB3_TextureBaker tb = ((MB3_MeshBakerGrouper)target).GetComponent <MB3_TextureBaker>();
                if (tb != null)
                {
                    MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;
                    List <GameObject>    gos = tb.GetObjectsToCombine();
                    Bounds b = new Bounds(Vector3.zero, Vector3.one);
                    if (gos.Count > 0 && gos[0] != null && gos[0].GetComponent <Renderer>() != null)
                    {
                        b = gos[0].GetComponent <Renderer>().bounds;
                    }
                    for (int i = 0; i < gos.Count; i++)
                    {
                        if (gos[i] != null && gos[i].GetComponent <Renderer>() != null)
                        {
                            b.Encapsulate(gos[i].GetComponent <Renderer>().bounds);
                        }
                    }

                    tbg.sourceObjectBounds     = b;
                    lastBoundsCheckRefreshTime = DateTime.UtcNow.Ticks;
                }
            }

            grouper.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;
            MB3_TextureBaker     tb  = ((MB3_MeshBakerGrouper)target).GetComponent <MB3_TextureBaker>();

            grouper.Update();
            DrawGrouperInspector();
            if (GUILayout.Button("Generate Mesh Bakers"))
            {
                if (tb == null)
                {
                    Debug.LogError("There must be an MB3_TextureBaker attached to this game object.");
                    return;
                }

                if (tb.GetObjectsToCombine().Count == 0)
                {
                    Debug.LogError("The MB3_MeshBakerGrouper creates clusters based on the objects to combine in the MB3_TextureBaker component. There were no objects in this list.");
                    return;
                }

                //check if any of the objes that will be added to bakers already exist in child bakers
                List <GameObject>     objsWeAreGrouping  = tb.GetObjectsToCombine();
                MB3_MeshBakerCommon[] alreadyExistBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>();
                bool foundChildBakersWithObjsToCombine   = false;
                for (int i = 0; i < alreadyExistBakers.Length; i++)
                {
                    List <GameObject> childOjs2Combine = alreadyExistBakers[i].GetObjectsToCombine();
                    for (int j = 0; j < childOjs2Combine.Count; j++)
                    {
                        if (childOjs2Combine[j] != null && objsWeAreGrouping.Contains(childOjs2Combine[j]))
                        {
                            foundChildBakersWithObjsToCombine = true;
                            break;
                        }
                    }
                }

                bool proceed = true;
                if (foundChildBakersWithObjsToCombine)
                {
                    proceed = EditorUtility.DisplayDialog("Replace Previous Generated Bakers", "Delete child bakers?\n\n" +
                                                          "This grouper has child Mesh Baker objects from a previous clustering. Do you want to delete these and create new ones?", "OK", "Cancel");
                }

                if (proceed)
                {
                    if (foundChildBakersWithObjsToCombine)
                    {
                        tbg.DeleteAllChildMeshBakers();
                    }
                    ((MB3_MeshBakerGrouper)target).grouper.DoClustering(tb, tbg);
                }
            }
            if (GUILayout.Button("Bake All Child MeshBakers"))
            {
                try
                {
                    MB3_MeshBakerCommon[] mBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>();
                    for (int i = 0; i < mBakers.Length; i++)
                    {
                        bool createdDummyMaterialBakeResult;
                        MB3_MeshBakerEditorFunctions.BakeIntoCombined(mBakers[i], out createdDummyMaterialBakeResult, ref grouper);
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
                finally
                {
                    EditorUtility.ClearProgressBar();
                }
            }
            string buttonTextEnableRenderers = "Disable Renderers On All Child MeshBaker Source Objs";
            bool   enableRenderers           = false;
            MB3_MeshBakerCommon bc           = tbg.GetComponentInChildren <MB3_MeshBakerCommon>();

            if (bc != null && bc.GetObjectsToCombine().Count > 0)
            {
                GameObject go = bc.GetObjectsToCombine()[0];
                if (go != null && go.GetComponent <Renderer>() != null && go.GetComponent <Renderer>().enabled == false)
                {
                    buttonTextEnableRenderers = "Enable Renderers On All Child MeshBaker Source Objs";
                    enableRenderers           = true;
                }
            }

            if (GUILayout.Button(buttonTextEnableRenderers))
            {
                try
                {
                    MB3_MeshBakerCommon[] mBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>();
                    for (int i = 0; i < mBakers.Length; i++)
                    {
                        mBakers[i].EnableDisableSourceObjectRenderers(enableRenderers);
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
                finally
                {
                    EditorUtility.ClearProgressBar();
                }
            }

            if (GUILayout.Button("Delete All Child Mesh Bakers & Combined Meshes"))
            {
                if (EditorUtility.DisplayDialog("Delete Mesh Bakers", "Delete all child mesh bakers", "OK", "Cancel"))
                {
                    tbg.DeleteAllChildMeshBakers();
                }
            }


            if (DateTime.UtcNow.Ticks - lastBoundsCheckRefreshTime > 10000000 && tb != null)
            {
                List <GameObject> gos = tb.GetObjectsToCombine();
                Bounds            b   = new Bounds(Vector3.zero, Vector3.one);
                if (gos.Count > 0 && gos[0] != null && gos[0].GetComponent <Renderer>() != null)
                {
                    b = gos[0].GetComponent <Renderer>().bounds;
                }
                for (int i = 0; i < gos.Count; i++)
                {
                    if (gos[i] != null && gos[i].GetComponent <Renderer>() != null)
                    {
                        b.Encapsulate(gos[i].GetComponent <Renderer>().bounds);
                    }
                }
                tbg.sourceObjectBounds     = b;
                lastBoundsCheckRefreshTime = DateTime.UtcNow.Ticks;
            }
            grouper.ApplyModifiedProperties();
        }