Exemple #1
0
 public void AddTextureFormat(Texture2D tx, bool isNormalMap)
 {
     //pixel values don't copy correctly from one texture to another when isNormal is set so unset it.
     SetTextureFormat(tx,
                      new TextureFormatInfo(TextureImporterFormat.ARGB32, MBVersionEditor.GetPlatformString(), TextureImporterFormat.AutomaticTruecolor, isNormalMap),
                      true, false);
 }
        public void SaveMeshesToOutputFolderAndAssignToSMRs(Mesh[] targetMeshes, SkinnedMeshRenderer[] targetSMRs)
        {
            //validate meshes
            for (int i = 0; i < targetMeshes.Length; i++)
            {
                if (targetSMRs[i] == null)
                {
                    Debug.LogError(string.Format("Target Mesh {0} is null", i));
                    return;
                }

                if (targetSMRs[i].sharedMesh == null)
                {
                    Debug.LogError(string.Format("Target Mesh {0} does not have a mesh", i));
                    return;
                }
                MB_PrefabType pt = MBVersionEditor.GetPrefabType(targetMeshes[i]);
                if (pt == MB_PrefabType.modelPrefab)
                {
                    Debug.LogError(string.Format("Target Mesh {0} is an imported model prefab. Can't modify these meshes because changes will be overwritten the next time the model is saved or reimported. Try instantiating the prefab and using skinned meshes from the scene instance.", i));
                    return;
                }
            }
            //validate output folder
            if (outputFolderProp.stringValue == null)
            {
                Debug.LogError("Output folder must be set");
                return;
            }
            if (outputFolderProp.stringValue.StartsWith(Application.dataPath))
            {
                string relativePath = "Assets" + outputFolderProp.stringValue.Substring(Application.dataPath.Length);
                string gid          = AssetDatabase.AssetPathToGUID(relativePath);
                if (gid == null)
                {
                    Debug.LogError("Output folder must be a folder in the Unity project Asset folder");
                    return;
                }
            }
            else
            {
                Debug.LogError("Output folder must be a folder in the Unity project Asset folder");
                return;
            }
            for (int i = 0; i < targetMeshes.Length; i++)
            {
                Mesh   m   = targetMeshes[i];
                string pth = ConvertAbsolutePathToUnityPath(outputFolderProp.stringValue + "/" + targetMeshes[i].name + ".Asset");
                if (pth == null)
                {
                    Debug.LogError("The output folder must be a folder in the project Assets folder.");
                    return;
                }
                AssetDatabase.CreateAsset(m, pth);
                targetSMRs[i].sharedMesh = m;
                Debug.Log(string.Format("Created mesh at {0}. Updated Skinned Mesh {1} to use created mesh.", pth, targetSMRs[i].name));
            }
            AssetDatabase.SaveAssets();
        }
Exemple #3
0
        public static void AddDroppedObjects(object[] objs, MB3_MeshBakerRoot momm)
        {
            if (objs != null)
            {
                HashSet <Renderer> renderersToAdd = new HashSet <Renderer>();
                for (int i = 0; i < objs.Length; i++)
                {
                    object obj = objs[i];
                    if (obj is GameObject)
                    {
                        Renderer[] rs = ((GameObject)obj).GetComponentsInChildren <Renderer>();
                        for (int j = 0; j < rs.Length; j++)
                        {
                            if (rs[j] is MeshRenderer || rs[j] is SkinnedMeshRenderer)
                            {
                                renderersToAdd.Add(rs[j]);
                            }
                        }
                    }
                }

                int numAdded = 0;
                List <GameObject> objsToCombine = momm.GetObjectsToCombine();
                bool failedToAddAssets          = false;
                foreach (Renderer r in renderersToAdd)
                {
                    if (!objsToCombine.Contains(r.gameObject))
                    {
                        MB_PrefabType prefabType = MBVersionEditor.GetPrefabType(r.gameObject);
                        if (prefabType == MB_PrefabType.modelPrefab || prefabType == MB_PrefabType.prefab)
                        {
                            failedToAddAssets = true;
                        }
                        else
                        {
                            objsToCombine.Add(r.gameObject);
                            numAdded++;
                        }
                    }
                }

                if (failedToAddAssets)
                {
                    Debug.LogError("Did not add some object(s) because they are not scene objects");
                }
                Debug.Log("Added " + numAdded + " renderers");
            }
        }
Exemple #4
0
 public bool CheckPrefabTypes(MB_ObjsToCombineTypes objToCombineType, List <GameObject> objsToMesh)
 {
     for (int i = 0; i < objsToMesh.Count; i++)
     {
         MB_PrefabType pt = MBVersionEditor.GetPrefabType(objsToMesh[i]);
         if (pt == MB_PrefabType.sceneInstance)
         {
             // these are scene objects
             if (objToCombineType == MB_ObjsToCombineTypes.prefabOnly)
             {
                 Debug.LogWarning("The list of objects to combine contains scene objects. You probably want prefabs. If using scene objects ensure position is zero, rotation is zero and scale is one. Translation, Rotation and Scale will be baked into the generated mesh." + objsToMesh[i] + " is a scene object");
                 return(false);
             }
         }
         else if (objToCombineType == MB_ObjsToCombineTypes.sceneObjOnly)
         {
             //these are prefabs
             Debug.LogWarning("The list of objects to combine contains prefab assets. You probably want scene objects." + objsToMesh[i] + " is a prefab object");
             return(false);
         }
     }
     return(true);
 }
Exemple #5
0
        public void AddTextureFormat(Texture2D tx, bool isNormalMap)
        {
            //pixel values don't copy correctly from one texture to another when isNormal is set so unset it.
            TextureFormatInfo toFormat = new TextureFormatInfo(TextureImporterCompression.Uncompressed, false, MBVersionEditor.GetPlatformString(), TextureImporterFormat.RGBA32, isNormalMap);

            SetTextureFormat(tx, toFormat, true, false);
        }
Exemple #6
0
//		public int GetMaximumAtlasDimension(){
//			return MBVersionEditor.GetMaximumAtlasDimension();
//		}

        public string GetPlatformString()
        {
            return(MBVersionEditor.GetPlatformString());
        }
        //posibilities
        //  using fixOutOfBoundsUVs or not
        //
        public static void ConfigureMutiMaterialsFromObjsToCombine(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;
            }
            Dictionary <MultiMatSubmeshInfo, List <List <Material> > > shader2Material_map = new Dictionary <MultiMatSubmeshInfo, List <List <Material> > >();
            Dictionary <Material, Mesh> obUVobject2mesh_map = new Dictionary <Material, Mesh>();

            //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;
                }
            }

            //first pass put any meshes with obUVs on their own submesh if not fixing OB uvs
            if (mom.doMultiMaterialSplitAtlasesIfOBUVs)
            {
                for (int i = 0; i < mom.GetObjectsToCombine().Count; i++)
                {
                    GameObject go = mom.GetObjectsToCombine()[i];
                    Mesh       m  = MB_Utility.GetMesh(go);
                    MB_Utility.MeshAnalysisResult dummyMar = new MB_Utility.MeshAnalysisResult();
                    Renderer r = go.GetComponent <Renderer>();
                    for (int j = 0; j < r.sharedMaterials.Length; j++)
                    {
                        if (MB_Utility.hasOutOfBoundsUVs(m, ref dummyMar, j))
                        {
                            if (!obUVobject2mesh_map.ContainsKey(r.sharedMaterials[j]))
                            {
                                Debug.LogWarning("Object " + go + " submesh " + j + " uses UVs outside the range 0,0..1,1 to generate tiling. This object has been mapped to its own submesh in the combined mesh. It can share a submesh with other objects that use different materials if you use the fix out of bounds UVs feature which will bake the tiling");
                                obUVobject2mesh_map.Add(r.sharedMaterials[j], m);
                            }
                        }
                    }
                }
            }

            //second pass  put other materials without OB uvs in a shader to material map
            for (int i = 0; i < mom.GetObjectsToCombine().Count; i++)
            {
                Renderer r = mom.GetObjectsToCombine()[i].GetComponent <Renderer>();
                for (int j = 0; j < r.sharedMaterials.Length; j++)
                {
                    if (!obUVobject2mesh_map.ContainsKey(r.sharedMaterials[j]))
                    { //if not already added
                        if (r.sharedMaterials[j] == null)
                        {
                            continue;
                        }
                        List <List <Material> > binsOfMatsThatUseShader = null;
                        MultiMatSubmeshInfo     newKey = new MultiMatSubmeshInfo(r.sharedMaterials[j].shader, r.sharedMaterials[j]);
                        if (!shader2Material_map.TryGetValue(newKey, out binsOfMatsThatUseShader))
                        {
                            binsOfMatsThatUseShader = new List <List <Material> >();
                            binsOfMatsThatUseShader.Add(new List <Material>());
                            shader2Material_map.Add(newKey, binsOfMatsThatUseShader);
                        }
                        if (!binsOfMatsThatUseShader[0].Contains(r.sharedMaterials[j]))
                        {
                            binsOfMatsThatUseShader[0].Add(r.sharedMaterials[j]);
                        }
                    }
                }
            }

            int numResMats = shader2Material_map.Count;

            //third pass for each shader grouping check how big the atlas would be and group into bins that would fit in an atlas
            if (mom.doMultiMaterialSplitAtlasesIfTooBig)
            {
                if (mom.packingAlgorithm == MB2_PackingAlgorithmEnum.UnitysPackTextures)
                {
                    Debug.LogWarning("Unity texture packer does not support splitting atlases if too big. Atlases will not be split.");
                }
                else
                {
                    numResMats = 0;
                    foreach (MultiMatSubmeshInfo sh in shader2Material_map.Keys)
                    {
                        List <List <Material> > binsOfMatsThatUseShader = shader2Material_map[sh];
                        List <Material>         allMatsThatUserShader   = binsOfMatsThatUseShader[0];//at this point everything is in the same list
                        binsOfMatsThatUseShader.RemoveAt(0);
                        MB3_TextureCombiner combiner = mom.CreateAndConfigureTextureCombiner();
                        combiner.saveAtlasesAsAssets = false;
                        if (allMatsThatUserShader.Count > 1)
                        {
                            combiner.fixOutOfBoundsUVs = mom.fixOutOfBoundsUVs;
                        }
                        else
                        {
                            combiner.fixOutOfBoundsUVs = false;
                        }

                        // Do the texture pack
                        List <AtlasPackingResult> packingResults = new List <AtlasPackingResult>();
                        Material tempMat = new Material(sh.shader);
                        combiner.CombineTexturesIntoAtlases(null, null, tempMat, mom.GetObjectsToCombine(), allMatsThatUserShader, null, packingResults, true);
                        for (int i = 0; i < packingResults.Count; i++)
                        {
                            List <MatsAndGOs> matsData = (List <MatsAndGOs>)packingResults[i].data;
                            List <Material>   mats     = new List <Material>();
                            for (int j = 0; j < matsData.Count; j++)
                            {
                                for (int kk = 0; kk < matsData[j].mats.Count; kk++)
                                {
                                    if (!mats.Contains(matsData[j].mats[kk].mat))
                                    {
                                        mats.Add(matsData[j].mats[kk].mat);
                                    }
                                }
                            }
                            binsOfMatsThatUseShader.Add(mats);
                        }
                        numResMats += binsOfMatsThatUseShader.Count;
                    }
                }
            }

            //build the result materials
            if (shader2Material_map.Count == 0 && obUVobject2mesh_map.Count == 0)
            {
                Debug.LogError("Found no materials in list of objects to combine");
            }
            mom.resultMaterials = new MB_MultiMaterial[numResMats + obUVobject2mesh_map.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 (MultiMatSubmeshInfo sh in shader2Material_map.Keys)
            {
                foreach (List <Material> matsThatUse in shader2Material_map[sh])
                {
                    MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial();
                    mm.sourceMaterials = matsThatUse;
                    if (mm.sourceMaterials.Count == 1)
                    {
                        mm.considerMeshUVs = false;
                    }
                    else
                    {
                        mm.considerMeshUVs = mom.fixOutOfBoundsUVs;
                    }
                    string   matName = folderPath + baseName + "-mat" + k + ".mat";
                    Material newMat  = new Material(Shader.Find("Diffuse"));
                    if (matsThatUse.Count > 0 && matsThatUse[0] != null)
                    {
                        MB3_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, matsThatUse[0]);
                    }
                    AssetDatabase.CreateAsset(newMat, matName);
                    mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material));
                    k++;
                }
            }
            foreach (Material m in obUVobject2mesh_map.Keys)
            {
                MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial();
                mm.sourceMaterials = new List <Material>();
                mm.sourceMaterials.Add(m);
                mm.considerMeshUVs = false;
                string   matName = folderPath + baseName + "-mat" + k + ".mat";
                Material newMat  = new Material(Shader.Find("Diffuse"));
                MB3_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, m);
                AssetDatabase.CreateAsset(newMat, matName);
                mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material));
                k++;
            }
            MBVersionEditor.UpdateIfDirtyOrScript(textureBaker);
        }
        /* 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);
        }
Exemple #9
0
        private bool _SetTextureFormat2017(Texture2D tx, TextureFormatInfo toThisFormat, bool addToList, bool setNormalMap, TextureImporter textureImporter)
        {
            bool is2017 = Application.unityVersion.StartsWith("20");

            if (!is2017)
            {
                Debug.LogError("Wrong texture format converter. 2017 Should not be called for Unity Version " + Application.unityVersion);
                return(false);
            }

            bool doImport = false;
            TextureFormatInfo restoreTfi = new TextureFormatInfo(textureImporter.textureCompression,
                                                                 textureImporter.crunchedCompression,
                                                                 toThisFormat.platform,
                                                                 TextureImporterFormat.RGBA32,
                                                                 textureImporter.textureType == TextureImporterType.NormalMap);
            string platform    = toThisFormat.platform;
            bool   isAutoPVRTC = false;

            if (platform != null)
            {
                TextureImporterPlatformSettings tips = textureImporter.GetPlatformTextureSettings(platform);
                if (tips.overridden)
                {
                    restoreTfi.platformFormat             = tips.format;
                    restoreTfi.platformCompressionQuality = tips.compressionQuality;
                    restoreTfi.doCrunchCompression        = tips.crunchedCompression;
                    restoreTfi.isNormalMap = textureImporter.textureType == TextureImporterType.NormalMap;
                    TextureImporterPlatformSettings tipsOverridden = new TextureImporterPlatformSettings();
                    tips.CopyTo(tipsOverridden);
                    tipsOverridden.compressionQuality  = toThisFormat.platformCompressionQuality;
                    tipsOverridden.crunchedCompression = toThisFormat.doCrunchCompression;
                    tipsOverridden.format = toThisFormat.platformFormat;
                    textureImporter.SetPlatformTextureSettings(tipsOverridden);
                    doImport = true;
                }

                isAutoPVRTC = MBVersionEditor.IsAutoPVRTC(tips.format, textureImporter.GetAutomaticFormat(platform));
            }


            if (isAutoPVRTC && textureImporter.textureCompression != toThisFormat.compression)
            {
                textureImporter.textureCompression = toThisFormat.compression;
                doImport = true;
            }

            if (textureImporter.crunchedCompression != toThisFormat.doCrunchCompression)
            {
                textureImporter.crunchedCompression = toThisFormat.doCrunchCompression;
                doImport = true;
            }
            if (_ChangeNormalMapTypeIfNecessary(textureImporter, setNormalMap))
            {
                doImport = true;
            }

            if (doImport)
            {
                string s;
                if (addToList)
                {
                    s = "Setting texture compression for ";
                }
                else
                {
                    s = "Restoring texture compression for ";
                }
                s += String.Format("{0}  FROM: compression={1} isNormal{2} TO: compression={3} isNormal={4} ", tx, restoreTfi.compression, restoreTfi.isNormalMap, toThisFormat.compression, setNormalMap);
                if (toThisFormat.platform != null)
                {
                    s += String.Format(" setting platform override format for platform {0} to {1} compressionQuality {2}", toThisFormat.platform, toThisFormat.platformFormat, toThisFormat.platformCompressionQuality);
                }
                Debug.Log(s);
                if (doImport && addToList && !_textureFormatMap.ContainsKey(tx))
                {
                    _textureFormatMap.Add(tx, restoreTfi);
                }
            }
            return(doImport);
        }
        public void CopyBoneWeightsFromSeamMeshToOtherMeshes(MB3_BoneWeightCopier bwc)
        {
            if (bwc.seamMesh == null)
            {
                Debug.LogError("The seamMesh cannot be null.");
                return;
            }

            UnityEngine.Object pr        = (UnityEngine.Object)PrefabUtility.GetPrefabObject(bwc.seamMesh.gameObject);
            string             assetPath = null;

            if (pr != null)
            {
                assetPath = AssetDatabase.GetAssetPath(pr);
            }
            if (assetPath != null)
            {
                ModelImporter mi = (ModelImporter)AssetImporter.GetAtPath(assetPath);
                if (mi != null)
                {
                    if (mi.optimizeMesh)
                    {
                        Debug.LogError(string.Format("The seam mesh has 'optimized' checked in the asset importer. This will result in no vertices. Uncheck 'optimized'."));
                        return;
                    }
                }
            }
            //todo check that output game object exists and is a prefab
            if (bwc.outputPrefab == null)
            {
                Debug.LogError(string.Format("The output game object must be assigned and must be a prefab of a game object in the project folder."));
                return;
            }
            if (MBVersionEditor.GetPrefabType(bwc.outputPrefab) != MB_PrefabType.prefab)
            {
                Debug.LogError("The output game object must be a prefab. Create a prefab in the project and drag an empty game object to it.");
                return;
            }

            //duplicate the source prefab and the meshes
            if (copyOfInput != null)
            {
                DestroyImmediate(copyOfInput);
            }
            copyOfInput = (GameObject)GameObject.Instantiate(bwc.inputGameObject);
            SkinnedMeshRenderer[] targSkinnedMeshes = copyOfInput.GetComponentsInChildren <SkinnedMeshRenderer>();
            Mesh[] targs = new Mesh[targSkinnedMeshes.Length];
            for (int i = 0; i < targSkinnedMeshes.Length; i++)
            {
                if (targSkinnedMeshes[i].sharedMesh == null)
                {
                    Debug.LogError(string.Format("Skinned Mesh {0} does not have a mesh", targSkinnedMeshes[i]));
                    return;
                }
                MB_PrefabType pt = MBVersionEditor.GetPrefabType(targSkinnedMeshes[i].gameObject);
                if (pt == MB_PrefabType.modelPrefab)
                {
                    Debug.LogError(string.Format("Target Mesh {0} is an imported model prefab. Can't modify these meshes because changes will be overwritten the next time the model is saved or reimported. Try instantiating the prefab and using skinned meshes from the scene instance.", i));
                    return;
                }
                targs[i] = (Mesh)GameObject.Instantiate(targSkinnedMeshes[i].sharedMesh);
            }
            MB3_CopyBoneWeights.CopyBoneWeightsFromSeamMeshToOtherMeshes(bwc.radius, bwc.seamMesh.sharedMesh, targs);
            SaveMeshesToOutputFolderAndAssignToSMRs(targs, targSkinnedMeshes);

            EditorUtility.SetDirty(copyOfInput);


            // TODO tried using 2018 replace prefab but there were errors.
            //MBVersionEditor.ReplacePrefab(copyOfInput, assetPath, MB_ReplacePrefabOption.connectToPrefab | MB_ReplacePrefabOption.nameBased);
            PrefabUtility.ReplacePrefab(copyOfInput, bwc.outputPrefab, ReplacePrefabOptions.ConnectToPrefab | ReplacePrefabOptions.ReplaceNameBased);

            AssetDatabase.SaveAssets();
            DestroyImmediate(copyOfInput);
        }
 public int GetMaximumAtlasDimension()
 {
     return(MBVersionEditor.GetMaximumAtlasDimension());
 }