void bake(MB3_MeshBakerCommon mom)
        {
            try{
                if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject)
                {
                    MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom);
                }
                else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab)
                {
                    MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom);
                }
                else
                {
                    if (mom is MB3_MeshBaker)
                    {
                        if (MB3_MeshCombiner.EVAL_VERSION)
                        {
                            Debug.LogError("Bake Meshes In Place is disabled in the evaluation version.");
                        }
                        else
                        {
                            if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.prefabOnly, new MB3_EditorMethods()))
                            {
                                return;
                            }

                            List <GameObject> objsToMesh = mom.objsToMesh;
                            if (mom.useObjsToMeshFromTexBaker && mom.GetComponent <MB3_TextureBaker>() != null)
                            {
                                objsToMesh = mom.GetComponent <MB3_TextureBaker>().objsToMesh;
                            }
                            MB3_BakeInPlace.BakeMeshesInPlace((MB3_MeshCombinerSingle)((MB3_MeshBaker)mom).meshCombiner, objsToMesh, mom.bakeAssetsInPlaceFolderPath, updateProgressBar);
                        }
                    }
                    else
                    {
                        Debug.LogError("Multi-mesh Baker components cannot be used for Bake In Place. Use an ordinary Mesh Baker object instead.");
                    }
                }
            } catch (Exception e) {
                Debug.LogError(e);
            } finally {
                EditorUtility.ClearProgressBar();
            }
        }
    public static bool BakeIntoCombined(MB3_MeshBakerCommon mom)
    {
        MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption;

        if (MB3_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab)
        {
            Debug.LogError("Cannot BakeIntoPrefab with evaluation version.");
            return(false);
        }
        if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject)
        {
            Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject");
            return(false);
        }

        MB3_TextureBaker tb = mom.GetComponent <MB3_TextureBaker>();

        if (mom.textureBakeResults == null && tb != null)
        {
            mom.textureBakeResults = tb.textureBakeResults;
        }
        MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust;

        if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(), vl))
        {
            return(false);
        }
        if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab &&
            mom.resultPrefab == null)
        {
            Debug.LogError("Need to set the Combined Mesh Prefab field. Create a prefab asset, drag an empty game object into it, and drag it to the 'Combined Mesh Prefab' field.");
            return(false);
        }
        if (mom.meshCombiner.resultSceneObject != null &&
            (PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab ||
             PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.Prefab))
        {
            Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field.");
            mom.meshCombiner.resultSceneObject = null;
        }

        mom.ClearMesh();
        if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(), null, false))
        {
            mom.Apply(Unwrapping.GenerateSecondaryUVSet);
            Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count));
            if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject)
            {
                PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject);
                if (pt == PrefabType.Prefab || pt == PrefabType.ModelPrefab)
                {
                    Debug.LogError("Combined Mesh Object is a prefab asset. If output option bakeIntoSceneObject then this must be an instance in the scene.");
                    return(false);
                }
            }
            else if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab)
            {
                string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab);
                if (prefabPth == null || prefabPth.Length == 0)
                {
                    Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset.");
                    return(false);
                }
                string baseName    = Path.GetFileNameWithoutExtension(prefabPth);
                string folderPath  = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7);
                string newFilename = folderPath + baseName + "-mesh";
                SaveMeshsToAssetDatabase(mom, folderPath, newFilename);

                if (mom.meshCombiner.renderType == MB_RenderType.skinnedMeshRenderer)
                {
                    Debug.LogWarning("Render type is skinned mesh renderer. " +
                                     "Can't create prefab until all bones have been added to the combined mesh object " + mom.resultPrefab +
                                     " Add the bones then drag the combined mesh object to the prefab.");
                }
                else
                {
                    RebuildPrefab(mom);
                }
            }
            else
            {
                Debug.LogError("Unknown parameter");
                return(false);
            }
        }
        return(true);
    }
	public static bool BakeIntoCombined(MB3_MeshBakerCommon mom){
		MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption;
		if (MB3_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab){
			Debug.LogError("Cannot BakeIntoPrefab with evaluation version.");
			return false;
		}
		if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject){
			Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject");
			return false;
		}

		MB3_TextureBaker tb = mom.GetComponent<MB3_TextureBaker>();
		if (mom.textureBakeResults == null && tb != null){
			mom.textureBakeResults = tb.textureBakeResults;	
		}
		MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; 
		if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(),vl)) return false;	
		if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab && 
			mom.resultPrefab == null){
			Debug.LogError("Need to set the Combined Mesh Prefab field. Create a prefab asset, drag an empty game object into it, and drag it to the 'Combined Mesh Prefab' field.");
			return false;
		}
		if (mom.meshCombiner.resultSceneObject != null &&
						(PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab ||
						PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.Prefab)) {
			Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field.");
			mom.meshCombiner.resultSceneObject = null;
		}

		mom.ClearMesh();
		if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(),null,false)){
			mom.Apply( Unwrapping.GenerateSecondaryUVSet );
			Debug.Log(String.Format("Successfully baked {0} meshes",mom.GetObjectsToCombine().Count));
			if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject){
				PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject);
				if (pt == PrefabType.Prefab || pt == PrefabType.ModelPrefab){
					Debug.LogError("Combined Mesh Object is a prefab asset. If output option bakeIntoSceneObject then this must be an instance in the scene.");
					return false;
				}
			} else if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab){
				string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab);
				if (prefabPth == null || prefabPth.Length == 0){
					Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset.");
					return false;
				}
				string baseName = Path.GetFileNameWithoutExtension(prefabPth);
				string folderPath = prefabPth.Substring(0,prefabPth.Length - baseName.Length - 7);		
				string newFilename = folderPath + baseName + "-mesh";
				SaveMeshsToAssetDatabase(mom, folderPath,newFilename);
				
				if (mom.meshCombiner.renderType == MB_RenderType.skinnedMeshRenderer){
					Debug.LogWarning("Render type is skinned mesh renderer. " +
							"Can't create prefab until all bones have been added to the combined mesh object " + mom.resultPrefab + 
							" Add the bones then drag the combined mesh object to the prefab.");	
					
				} else {
					RebuildPrefab(mom);
				}
			} else {
				Debug.LogError("Unknown parameter");
				return false;
			}
		}
		return true;
	}
        public void DrawGUI(MB3_MeshBakerCommon target, System.Type editorWindowType)
        {
            if (meshBaker == null)
            {
                _init(target);
            }

            meshBaker.Update();

            showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:");
            if (showInstructions)
            {
                EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" +
                                        "2. If necessary set the 'Material Bake Results' field.\n\n" +
                                        "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" +
                                        "4. Select options and 'Bake'.\n\n" +
                                        "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" +
                                        "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None);

                EditorGUILayout.Separator();
            }

            MB3_MeshBakerCommon mom = (MB3_MeshBakerCommon)target;

            mom.meshCombiner.LOG_LEVEL = (MB2_LogLevel)EditorGUILayout.EnumPopup("Log Level", mom.meshCombiner.LOG_LEVEL);

            EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent);
            if (textureBakeResults.objectReferenceValue != null)
            {
                showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained");
                if (showContainsReport)
                {
                    EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info);
                }
            }

            EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel);
            if (mom.GetComponent <MB3_TextureBaker>() != null)
            {
                EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, useTextureBakerObjsGUIContent);
            }
            else
            {
                useObjsToMeshFromTexBaker.boolValue = false;
            }

            if (!mom.useObjsToMeshFromTexBaker)
            {
                if (GUILayout.Button(openToolsWindowLabelContent))
                {
                    MB3_MeshBakerEditorWindowInterface mmWin = (MB3_MeshBakerEditorWindowInterface)EditorWindow.GetWindow(editorWindowType);
                    mmWin.target = (MB3_MeshBakerRoot)target;
                }
                EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true);
            }

            EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
            if (mom is MB3_MultiMeshBaker)
            {
                MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner)mom.meshCombiner;
                mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh);
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doNorm, doNormGUIContent);
            EditorGUILayout.PropertyField(doTan, doTanGUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(doUV, doUVGUIContent);
            EditorGUILayout.PropertyField(doUV1, doUV1GUIContent);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(doCol, doColGUIContent);

            if (mom.meshCombiner.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
            {
                EditorGUILayout.HelpBox("Generating new lightmap UVs can split vertices which can push the number of vertices over the 64k limit.", MessageType.Warning);
            }
            EditorGUILayout.PropertyField(lightmappingOption, lightmappingOptionGUIContent);

            EditorGUILayout.PropertyField(outputOptions, outputOptoinsGUIContent);
            EditorGUILayout.PropertyField(renderType, renderTypeGUIContent);
            if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject)
            {
                //todo switch to renderer
                mom.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("Combined Mesh Object", mom.meshCombiner.resultSceneObject, typeof(GameObject), true);
                if (mom is MB3_MeshBaker)
                {
                    string l = "Mesh";
                    if (mesh.objectReferenceValue != null)
                    {
                        l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")";
                    }
                    EditorGUILayout.PropertyField(mesh, new GUIContent(l));
                }
            }
            else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab)
            {
                mom.resultPrefab = (GameObject)EditorGUILayout.ObjectField(combinedMeshPrefabGUIContent, mom.resultPrefab, typeof(GameObject), true);
                if (mom is MB3_MeshBaker)
                {
                    string l = "Mesh";
                    if (mesh.objectReferenceValue != null)
                    {
                        l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")";
                    }
                    EditorGUILayout.PropertyField(mesh, new GUIContent(l));
                }
            }
            else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace)
            {
                EditorGUILayout.HelpBox("NEW! Try the BatchPrefabBaker component. It makes preparing a batch of prefabs for static/ dynamic batching much easier.", MessageType.Info);
                if (GUILayout.Button("Choose Folder For Bake In Place Meshes"))
                {
                    string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, "");
                    if (!newFolder.Contains(Application.dataPath))
                    {
                        Debug.LogWarning("The chosen folder must be in your assets folder.");
                    }
                    mom.bakeAssetsInPlaceFolderPath = "Assets" + newFolder.Replace(Application.dataPath, "");
                }
                EditorGUILayout.LabelField("Folder For Meshes: " + mom.bakeAssetsInPlaceFolderPath);
            }

            if (GUILayout.Button("Bake"))
            {
                bake(mom);
            }

            string enableRenderersLabel;
            bool   disableRendererInSource = false;

            if (mom.GetObjectsToCombine().Count > 0)
            {
                Renderer r = MB_Utility.GetRenderer(mom.GetObjectsToCombine()[0]);
                if (r != null && r.enabled)
                {
                    disableRendererInSource = true;
                }
            }
            if (disableRendererInSource)
            {
                enableRenderersLabel = "Disable Renderers On Source Objects";
            }
            else
            {
                enableRenderersLabel = "Enable Renderers On Source Objects";
            }
            if (GUILayout.Button(enableRenderersLabel))
            {
                mom.EnableDisableSourceObjectRenderers(!disableRendererInSource);
            }

            meshBaker.ApplyModifiedProperties();
            meshBaker.SetIsDifferentCacheDirty();
        }