/// <summary>
    ///  Bakes a combined mesh.
    /// </summary>
    /// <param name="so">If this is being called from Inspector code then pass in the SerializedObject for the component.
    /// This is necessary for "bake into prefab" which can corrupt the SerializedObject.</param>
    public static bool BakeIntoCombined(MB3_MeshBakerCommon mom, out bool createdDummyTextureBakeResults, ref SerializedObject so)
    {
        MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption;

        createdDummyTextureBakeResults = false;

        // Initial Validate
        {
            if (mom.meshCombiner.resultSceneObject != null &&
                (MBVersionEditor.PrefabUtility_GetPrefabType(mom.meshCombiner.resultSceneObject) == MB_PrefabType.modelPrefabAsset ||
                 MBVersionEditor.PrefabUtility_GetPrefabType(mom.meshCombiner.resultSceneObject) == MB_PrefabType.prefabAsset))
            {
                Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field.");
                mom.meshCombiner.resultSceneObject = null;
            }

            if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject)
            {
                Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject");
                return(false);
            }

            if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab)
            {
                if (MB3_MeshCombiner.EVAL_VERSION)
                {
                    Debug.LogError("Cannot BakeIntoPrefab with evaluation version.");
                    return(false);
                }

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

                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 a project asset. Is it an instance in the scene?");
                    return(false);
                }
            }
        }

        {
            // Find or create texture bake results
            MB3_TextureBaker tb = mom.GetComponentInParent <MB3_TextureBaker>();
            if (mom.textureBakeResults == null && tb != null)
            {
                mom.textureBakeResults = tb.textureBakeResults;
            }

            if (mom.textureBakeResults == null)
            {
                if (_OkToCreateDummyTextureBakeResult(mom))
                {
                    createdDummyTextureBakeResults = true;
                    List <GameObject> gos = mom.GetObjectsToCombine();
                    if (mom.GetNumObjectsInCombined() > 0)
                    {
                        if (mom.clearBuffersAfterBake)
                        {
                            mom.ClearMesh();
                        }
                        else
                        {
                            Debug.LogError("'Texture Bake Result' must be set to add more objects to a combined mesh that already contains objects. Try enabling 'clear buffers after bake'");
                            return(false);
                        }
                    }
                    mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(gos.ToArray(), mom.meshCombiner.GetMaterialsOnTargetRenderer());
                    if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug)
                    {
                        Debug.Log("'Texture Bake Result' was not set. Creating a temporary one. Each material will be mapped to a separate submesh.");
                    }
                }
            }
        }

        // Second level of validation now that TextureBakeResults exists.
        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);
        }

        // Add Delete Game Objects
        bool success;

        if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject)
        {
            success = _BakeIntoCombinedSceneObject(mom, createdDummyTextureBakeResults, ref so);
        }
        else if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab)
        {
            success = _BakeIntoCombinedPrefab(mom, createdDummyTextureBakeResults, ref so);
        }
        else
        {
            Debug.LogError("Should be impossible.");
            success = false;
        }

        if (mom.clearBuffersAfterBake)
        {
            mom.meshCombiner.ClearBuffers();
        }
        if (createdDummyTextureBakeResults)
        {
            MB_Utility.Destroy(mom.textureBakeResults);
        }
        return(success);
    }
    public static bool BakeIntoCombined(MB3_MeshBakerCommon mom, out bool createdDummyTextureBakeResults)
    {
		MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption;
        createdDummyTextureBakeResults = false;
        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.GetComponentInParent<MB3_TextureBaker>();
		if (mom.textureBakeResults == null && tb != null){
			mom.textureBakeResults = tb.textureBakeResults;	
		}
        if (mom.textureBakeResults == null)
        {
            if (_OkToCreateDummyTextureBakeResult(mom))
            {
                createdDummyTextureBakeResults = true;
                List<GameObject> gos = mom.GetObjectsToCombine();
                if (mom.GetNumObjectsInCombined() > 0)
                {
                    Debug.LogError("'Texture Bake Result' must be set to add more objects to a combined mesh that already contains objects. Try enabling 'clear buffers after bake'");
                    return false;
                }
                mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(gos.ToArray(), mom.meshCombiner.GetMaterialsOnTargetRenderer());
                if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("'Texture Bake Result' was not set. Creating a temporary one. Each material will be mapped to a separate submesh."); }
            }
        }
        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( UnwrapUV2 );
            if (createdDummyTextureBakeResults)
            {
                Debug.Log(String.Format("Successfully baked {0} meshes each material is mapped to its own submesh.", mom.GetObjectsToCombine().Count));
            } else
            {
                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;
	}