Exemple #1
0
 private void PackTextureAtlasEmissions()
 {
     if (atlasMaterial != null && !String.IsNullOrEmpty(emissionFilename))
     {
         ExporterWindow.ReportProgress(1, "Generating emissive color maps... This may take a while.");
         bool      bilinearScaling   = (textureImageScaling == BabylonTextureScale.Bilinear);
         Texture2D emissionMeshAtlas = new Texture2D(128, 128, TextureFormat.RGBA32, false);
         Tools.PackTextureAtlas(emissionMeshAtlas, emissionTextures.ToArray(), textureAtlasSize, maxTextureImageSize, bilinearScaling, false);
         Texture2D emissionMeshBuffer = emissionMeshAtlas.Copy();
         emissionMeshBuffer.WriteImage(emissionFilename, textureAtlasFormat);
         AssetDatabase.ImportAsset(emissionFilename, ImportAssetOptions.ForceUpdate);
         // Import As Emission Map
         var importTool = new BabylonTextureImporter(emissionFilename);
         importTool.textureImporter.textureType        = TextureImporterType.Default;
         importTool.textureImporter.convertToNormalmap = false;
         importTool.ForceUpdate();
         atlasMaterial.SetTexture("_EmissionMap", (Texture2D)AssetDatabase.LoadAssetAtPath(emissionFilename, typeof(Texture2D)));
     }
 }
Exemple #2
0
 private void PackTextureAtlasNormals()
 {
     if (atlasMaterial != null && !String.IsNullOrEmpty(bumpFilename))
     {
         ExporterWindow.ReportProgress(1, "Generating normal map atlas... This may take a while.");
         //bool jpeg = (textureAtlasFormat == BabylonImageFormat.JPEG);
         bool      bilinearScaling = (textureImageScaling == BabylonTextureScale.Bilinear);
         Texture2D bumpMeshAtlas   = new Texture2D(128, 128, TextureFormat.RGBA32, false);
         Tools.PackTextureAtlas(bumpMeshAtlas, bumpTextures.ToArray(), textureAtlasSize, maxTextureImageSize, bilinearScaling, false, removeAlphaEncoding);
         Texture2D bumpMeshBuffer = bumpMeshAtlas.Copy();
         bumpMeshBuffer.WriteImage(bumpFilename, textureAtlasFormat);
         AssetDatabase.ImportAsset(bumpFilename, ImportAssetOptions.ForceUpdate);
         // Import As Normal Map
         var importTool = new BabylonTextureImporter(bumpFilename);
         importTool.textureImporter.textureType        = TextureImporterType.NormalMap;
         importTool.textureImporter.convertToNormalmap = false;
         importTool.ForceUpdate();
         atlasMaterial.SetTexture("_BumpMap", (Texture2D)AssetDatabase.LoadAssetAtPath(bumpFilename, typeof(Texture2D)));
     }
 }
Exemple #3
0
 private void PackTextureAtlasSpeculars()
 {
     if (atlasMaterial != null && !String.IsNullOrEmpty(specularFilename))
     {
         ExporterWindow.ReportProgress(1, "Generating specular gloss maps... This may take a while.");
         bool      bilinearScaling   = (textureImageScaling == BabylonTextureScale.Bilinear);
         Texture2D specularMeshAtlas = new Texture2D(128, 128, TextureFormat.RGBA32, false);
         Tools.PackTextureAtlas(specularMeshAtlas, specularTextures.ToArray(), textureAtlasSize, maxTextureImageSize, bilinearScaling, false);
         Texture2D specularMeshBuffer = specularMeshAtlas.Copy();
         specularMeshBuffer.WriteImage(specularFilename, textureAtlasFormat);
         AssetDatabase.ImportAsset(specularFilename, ImportAssetOptions.ForceUpdate);
         // Import As Specular Map
         var importTool = new BabylonTextureImporter(specularFilename);
         importTool.textureImporter.textureType        = TextureImporterType.Default;
         importTool.textureImporter.convertToNormalmap = false;
         importTool.ForceUpdate();
         atlasMaterial.SetFloat("_Gloss", 0.5f);         // Default Texture Atlas Scaling
         atlasMaterial.SetFloat("_Glossiness", 0.5f);    // Default Texture Atlas Scaling
         atlasMaterial.SetFloat("_GlossMapScale", 0.5f); // Default Texture Atlas Scaling
         atlasMaterial.SetTexture("_SpecGlossMap", (Texture2D)AssetDatabase.LoadAssetAtPath(specularFilename, typeof(Texture2D)));
     }
 }
        public void Split()
        {
            ExporterWindow.ReportProgress(1, "Splitting cubemap textures... This may take a while.");
            var filePath = AssetDatabase.GetAssetPath(splitCube);
            int splitSize = splitCube.width;
            Color[] CubeMapColors;

            var faceTexturePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
            bool png = (ExporterWindow.exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG);
            string fext = (png == true) ? ".png" : ".jpg";
            string filename = "";
            string preview = "";

            var importTool = new BabylonTextureImporter(filePath);
            bool isReadable = importTool.IsReadable();
            if (!isReadable)
            {
                importTool.SetReadable();
            }
            try
            {
                filename = (faceTexturePath + "_py" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                Texture2D tex = new Texture2D(splitSize, splitSize, TextureFormat.RGB24, false);
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveY);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_ny" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeY);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_px" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveX);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_nx" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeX);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_pz" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveZ);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_nz" + fext);
                preview = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeZ);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogException(ex);
            }
            finally
            {
                if (!isReadable)
                {
                    ExporterWindow.ReportProgress(1, "Finalizing assets database...");
                    importTool.ForceUpdate();
                }
            }
            ExporterWindow.ReportProgress(1, "Refresing assets database...");
            AssetDatabase.Refresh();

            ExporterWindow.ReportProgress(1, "Cubemap split complete.");
            EditorUtility.ClearProgressBar();
            this.Close();
        }
 private static Color[] GetPixels(Texture2D texture)
 {
     Color[] pixels = null;
     string srcTexturePath = AssetDatabase.GetAssetPath(texture);
     var importTool = new BabylonTextureImporter(srcTexturePath);
     bool isReadable = importTool.IsReadable();
     if (!isReadable) importTool.SetReadable();
     try
     {
         pixels = texture.GetPixels();
     }
     catch (Exception ex)
     {
         Debug.LogException(ex);
     }
     finally
     {
         if (!isReadable) importTool.ForceUpdate();
     }
     return pixels;
 }
        private void CopyTexture(string texturePath, Texture2D texture2D, BabylonTexture babylonTexture, bool isLightmap = false)
        {
            string rename = null;
            bool needToDelete = false;
            // Convert unsupported file extensions
            if (texturePath.EndsWith(".psd") || texturePath.EndsWith(".tif") || texturePath.EndsWith(".exr"))
            {
                string srcTexturePath = AssetDatabase.GetAssetPath(texture2D);
                var importTool = new BabylonTextureImporter(srcTexturePath);
                var previousConvertToNormalmap = importTool.textureImporter.convertToNormalmap;
                var previousAlphaSource = importTool.textureImporter.alphaSource;
                var previousTextureType = importTool.textureImporter.textureType;
                importTool.SetReadable();
                importTool.textureImporter.textureType = (isLightmap) ? TextureImporterType.Lightmap : TextureImporterType.Default;
                importTool.textureImporter.alphaSource = TextureImporterAlphaSource.FromInput;
                importTool.textureImporter.convertToNormalmap = false;
                AssetDatabase.ImportAsset(texturePath);

                try
                {
                    var usePNG = texture2D.alphaIsTransparency;
                    var tempTexture = new Texture2D(texture2D.width, texture2D.height, TextureFormat.ARGB32, false);
                    if (isLightmap)
                    {
                        rename = SceneName + Path.GetFileName(texturePath);
                        Color[] pixels = texture2D.GetPixels(0, 0, texture2D.width, texture2D.height);
                        for (int index = 0; index < pixels.Length; index++)
                        {
                            pixels[index].r = pixels[index].r * pixels[index].a * 5;
                            pixels[index].g = pixels[index].g * pixels[index].a * 5;
                            pixels[index].b = pixels[index].b * pixels[index].a * 5;
                        }
                        tempTexture.SetPixels(pixels);
                    }
                    else
                    {
                        Color[] pixels = texture2D.GetPixels(0, 0, texture2D.width, texture2D.height);
                        for (int index = 0; index < pixels.Length; index++)
                        {
                            usePNG |= pixels[index].a <= 0.99999f;
                        }
                        tempTexture.SetPixels32(texture2D.GetPixels32());
                    }
                    tempTexture.Apply();
                    string outputfile = (!String.IsNullOrEmpty(rename)) ? rename : texturePath;
                    texturePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(outputfile));
                    var extension = (usePNG || exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG) ? ".png" : ".jpg";
                    texturePath = texturePath.Replace(".psd", extension).Replace(".tif", extension).Replace(".exr", extension);
                    File.WriteAllBytes(texturePath, (usePNG || exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG) ? tempTexture.EncodeToPNG() : tempTexture.EncodeToJPG(exportationOptions.DefaultQualityLevel));
                    needToDelete = true;
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                }
                finally
                {
                    importTool.textureImporter.textureType = previousTextureType;
                    importTool.textureImporter.alphaSource = previousAlphaSource;
                    importTool.textureImporter.convertToNormalmap = previousConvertToNormalmap;
                    importTool.ForceUpdate();
                }
            }
            else if (texture2D.alphaIsTransparency || texturePath.EndsWith(".png"))
            {
                babylonTexture.hasAlpha = true;
            }
            else
            {
                babylonTexture.hasAlpha = false;
            }
            var textureName = Path.GetFileName(texturePath);
            babylonTexture.name = textureName;
            babylonScene.AddTexture(texturePath);
            if (needToDelete) File.Delete(texturePath);
        }
 private void CopyTextureFace(string texturePath, string textureName, Texture2D textureFace)
 {
     if (!babylonScene.AddTextureCube(textureName))
     {
         return;
     }
     bool png = (exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG);
     bool textureNotExistsMode = (SceneController != null && SceneController.skyboxOptions.textureFile == BabylonTextureExport.IfNotExists);
     bool writeTextureFile = true;
     if (textureNotExistsMode && File.Exists(texturePath))
     {
         writeTextureFile = false;
         ExporterWindow.ReportProgress(1, "Texture cube item exists: " + textureName);
     }
     if (writeTextureFile)
     {
         var srcTexturePath = AssetDatabase.GetAssetPath(textureFace);
         if ((png && srcTexturePath.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) || (!png && (srcTexturePath.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || srcTexturePath.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase))))
         {
             ExporterWindow.ReportProgress(1, "Copying texture cube item: " + textureName);
             File.Copy(srcTexturePath, texturePath, true);
         }
         else
         {
             if (textureFace != null)
             {
                 var importTool = new BabylonTextureImporter(srcTexturePath);
                 bool isReadable = importTool.IsReadable();
                 if (!isReadable) importTool.SetReadable();
                 try
                 {
                     ExporterWindow.ReportProgress(1, "Exporting texture cube item: " + textureName);
                     var tempTexture = new Texture2D(textureFace.width, textureFace.height, TextureFormat.ARGB32, false);
                     Color32[] pixels = textureFace.GetPixels32();
                     tempTexture.SetPixels32(pixels);
                     tempTexture.Apply();
                     if (png)
                     {
                         File.WriteAllBytes(texturePath, tempTexture.EncodeToPNG());
                     }
                     else
                     {
                         File.WriteAllBytes(texturePath, tempTexture.EncodeToJPG(exportationOptions.DefaultQualityLevel));
                     }
                 }
                 catch (Exception ex)
                 {
                     Debug.LogException(ex);
                 }
                 finally
                 {
                     if (!isReadable) importTool.ForceUpdate();
                 }
             }
         }
     }
 }
        private void CopyTextureCube(string texturePath, Cubemap cubemap, BabylonTexture babylonTexture, bool hdr = false)
        {
            if (!babylonScene.AddTextureCube(texturePath))
            {
                return;
            }
            ExporterWindow.ReportProgress(1, "Parsing texture cube: " + texturePath);
            var srcTexturePath = AssetDatabase.GetAssetPath(cubemap);
            bool textureNotExistsMode = (SceneController != null && SceneController.skyboxOptions.textureFile == BabylonTextureExport.IfNotExists);
            bool png = (exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG);
            string fext = (png == true) ? ".png" : ".jpg";
            try
            {
                if (hdr)
                {
                    var hdrTexturePath = Path.Combine(babylonScene.OutputPath, Path.GetFileName(texturePath));
                    bool writeHdrTexture = true;
                    string textureHdrName = Path.GetFileName(hdrTexturePath);
                    if (textureNotExistsMode && File.Exists(hdrTexturePath))
                    {
                        writeHdrTexture = false;
                        ExporterWindow.ReportProgress(1, "Texture hdr cube item exists: " + textureHdrName);
                    }
                    if (writeHdrTexture)
                    {
                        ExporterWindow.ReportProgress(1, "Copying hdr texture cube item: " + textureHdrName);
                        File.Copy(srcTexturePath, hdrTexturePath, true);
                    }
                }
                else
                {
                    var importTool = new BabylonTextureImporter(srcTexturePath);
                    bool isReadable = importTool.IsReadable();
                    if (!isReadable) importTool.SetReadable();
                    try
                    {
                        foreach (CubemapFace face in Enum.GetValues(typeof(CubemapFace)))
                        {
                            var faceTexturePath = Path.Combine(babylonScene.OutputPath, Path.GetFileNameWithoutExtension(texturePath));
                            switch (face)
                            {
                                case CubemapFace.PositiveX:
                                    faceTexturePath += ("_px" + fext);
                                    break;
                                case CubemapFace.NegativeX:
                                    faceTexturePath += ("_nx" + fext);
                                    break;
                                case CubemapFace.PositiveY:
                                    faceTexturePath += ("_py" + fext);
                                    break;
                                case CubemapFace.NegativeY:
                                    faceTexturePath += ("_ny" + fext);
                                    break;
                                case CubemapFace.PositiveZ:
                                    faceTexturePath += ("_pz" + fext);
                                    break;
                                case CubemapFace.NegativeZ:
                                    faceTexturePath += ("_nz" + fext);
                                    break;
                                default:
                                    continue;
                            }
                            bool writeFaceTexture = true;
                            string textureFaceName = Path.GetFileName(faceTexturePath);
                            if (textureNotExistsMode && File.Exists(faceTexturePath))
                            {
                                writeFaceTexture = false;
                                ExporterWindow.ReportProgress(1, "Texture cube item exists: " + textureFaceName);
                            }
                            if (writeFaceTexture)
                            {
                                ExporterWindow.ReportProgress(1, "Exporting texture cube item: " + textureFaceName);
                                var tempTexture = new Texture2D(cubemap.width, cubemap.height, TextureFormat.ARGB32, false);

                                Color[] pixels = cubemap.GetPixels(face);
                                tempTexture.SetPixels(pixels);
                                tempTexture.Apply();

                                // Flip faces in cube texture.
                                tempTexture = FlipTexture(tempTexture);

                                // Encode cube face texture
                                if (png)
                                {
                                    File.WriteAllBytes(faceTexturePath, tempTexture.EncodeToPNG());
                                }
                                else
                                {
                                    File.WriteAllBytes(faceTexturePath, tempTexture.EncodeToJPG(exportationOptions.DefaultQualityLevel));
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (!isReadable) importTool.ForceUpdate();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
            if (babylonTexture != null)
            {
                var textureName = Path.GetFileNameWithoutExtension(texturePath);
                if (hdr) textureName += ".hdr";
                babylonTexture.name = textureName;
                babylonTexture.isCube = true;
                babylonTexture.level = exportationOptions.ReflectionDefaultLevel;
                babylonTexture.coordinatesMode = 3;
            }
        }
Exemple #9
0
        public void CreateTextureAtlas()
        {
            if (skinMeshRenderer != null && skinMeshRenderer.sharedMaterials != null && skinMeshRenderer.sharedMaterials.Length > 1)
            {
                string filename = EditorUtility.SaveFilePanelInProject("Texture Atlas Skin", "", "asset", "Bake Skin Mesh Renderer Texture Atlas");
                if (!String.IsNullOrEmpty(filename))
                {
                    ExporterWindow.ReportProgress(1, "Baking texture atlas skin... This may take a while.");
                    string filepath  = Path.GetDirectoryName(filename);
                    string filelabel = Path.GetFileNameWithoutExtension(filename);
                    Tools.ValidateAssetFolders(filepath.TrimEnd('/'));

                    // Texture atlas file info
                    bool   jpeg         = (textureAtlasFormat == BabylonImageFormat.JPEG);
                    string atlasExt     = (jpeg) ? "jpg" : "png";
                    string atlasName    = String.Format("{0}_Atlas", filelabel);
                    string atlasFile    = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), atlasName, atlasExt);
                    string bumpName     = String.Format("{0}_Normal", filelabel);
                    string bumpFile     = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), bumpName, atlasExt);
                    string materialName = String.Format("{0}_Material", filelabel);
                    string materialFile = String.Format("{0}/Materials/{1}.asset", filepath.TrimEnd('/'), materialName);

                    // Create atlas textures
                    mainTextures = new List <Texture2D>();
                    bumpTextures = new List <Texture2D>();
                    foreach (var material in skinMeshRenderer.sharedMaterials)
                    {
                        Texture2D colorTexture  = null;
                        Texture2D normalTexture = null;
                        if (material.mainTexture != null)
                        {
                            Texture2D primaryTexture = material.mainTexture as Texture2D;
                            primaryTexture.ForceReadable();
                            colorTexture = primaryTexture.Copy();
                            if (bakeTextureNormals)
                            {
                                if (material.HasProperty("_BumpMap"))
                                {
                                    Texture2D bumpTexture = material.GetTexture("_BumpMap") as Texture2D;
                                    if (bumpTexture != null && bumpTexture.width == colorTexture.width && bumpTexture.height == colorTexture.height)
                                    {
                                        // Format texture import settings
                                        string bumpTexturePath = AssetDatabase.GetAssetPath(bumpTexture);
                                        var    importTool      = new BabylonTextureImporter(bumpTexturePath);
                                        var    importType      = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            normalTexture  = bumpTexture.Copy();
                                            hasBumpTexture = true;
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                            }
                        }
                        if (colorTexture == null)
                        {
                            colorTexture = new Texture2D(128, 128, TextureFormat.RGBA32, false);
                            colorTexture.Clear(material.color);
                            normalTexture = null;
                        }
                        if (normalTexture == null)
                        {
                            normalTexture = Tools.CreateBlankNormalMap(colorTexture.width, colorTexture.height);
                        }
                        // Buffer baked material info
                        mainTextures.Add(colorTexture);
                        bumpTextures.Add(normalTexture);
                    }

                    // Encode atlas textures
                    bool      bilinearScaling    = (textureImageScaling == BabylonTextureScale.Bilinear);
                    Texture2D skinnedMeshAtlas   = new Texture2D(128, 128, TextureFormat.RGBA32, false);
                    Rect[]    atlasPackingResult = Tools.PackTextureAtlas(skinnedMeshAtlas, mainTextures.ToArray(), textureAtlasSize, maxTextureImageSize, bilinearScaling, false, removeAlphaEncoding);
                    Texture2D skinnedMeshBuffer  = skinnedMeshAtlas.Copy();
                    skinnedMeshBuffer.WriteImage(atlasFile, textureAtlasFormat);
                    AssetDatabase.ImportAsset(atlasFile, ImportAssetOptions.ForceUpdate);

                    // Create atlas material
                    if (textureAtlasShader == null)
                    {
                        textureAtlasShader = Shader.Find("BabylonJS/System/Standard Material");
                    }
                    atlasMaterial             = new Material(textureAtlasShader);
                    atlasMaterial.name        = materialName;
                    atlasMaterial.mainTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(atlasFile, typeof(Texture2D));
                    AssetDatabase.CreateAsset(atlasMaterial, materialFile);
                    if (bakeTextureNormals && hasBumpTexture)
                    {
                        bumpFilename = bumpFile;
                    }

                    // Texture atlas uv coordinates
                    Mesh           mesh    = skinMeshRenderer.sharedMesh;
                    int            numSubs = mesh.subMeshCount;
                    int            uvCount = mesh.uv.Length;
                    List <Vector2> uvList  = new List <Vector2>();
                    if (atlasPackingResult != null && atlasPackingResult.Length > 0)
                    {
                        for (int ctr = 0; ctr < numSubs; ctr++)
                        {
                            Mesh      sub = mesh.GetSubmesh(ctr);
                            Vector2[] uvs = Tools.GetTextureAtlasCoordinates(sub.uv, ctr, atlasPackingResult, linearInterpolation);
                            uvList.AddRange(uvs);
                        }
                        if (uvList.Count != uvCount)
                        {
                            throw new Exception("Skin vertex count mismatch. Failed to convert uv coordinates.");
                        }
                    }
                    else
                    {
                        UnityEngine.Debug.LogError("Null atlas packing result rects");
                    }

                    // Create new mesh asset
                    Mesh newmesh = mesh.Copy();
                    if (uvList.Count > 0)
                    {
                        newmesh.uv = uvList.ToArray();
                    }

                    // Save new mesh asset
                    string label    = Tools.FirstUpper(materialName.Replace("_Material", ""));
                    string meshName = String.Format("{0}_{1}_Mesh", label, skinMeshRenderer.name);
                    string meshFile = String.Format("{0}/Geometry/{1}.asset", filepath.TrimEnd('/'), meshName);
                    AssetDatabase.CreateAsset(newmesh, meshFile);
                    if (updateSkinRenderer)
                    {
                        skinMeshRenderer.sharedMesh      = (Mesh)AssetDatabase.LoadAssetAtPath(meshFile, typeof(Mesh));
                        skinMeshRenderer.sharedMaterials = new Material[] { (Material)AssetDatabase.LoadAssetAtPath(materialFile, typeof(Material)) };
                    }
                }
            }
            else
            {
                ExporterWindow.ShowMessage("At least 2 materials required for texture atlas skin");
            }
        }
Exemple #10
0
        public void Bake()
        {
            // Validate Project Platform
            if (!Unity3D2Babylon.Tools.ValidateProjectPlatform())
            {
                return;
            }

            try
            {
                string inputFile = AssetDatabase.GetAssetPath(convertCube);
                string inputExt  = Path.GetExtension(inputFile);
                if (cubemapTool == BabylonCubemapTool.ReflectionProbes)
                {
                    if (inputExt.Equals(".hdr", StringComparison.OrdinalIgnoreCase) || inputExt.Equals(".exr", StringComparison.OrdinalIgnoreCase))
                    {
                        ExporterWindow.ReportProgress(1, "Baking cubemap reflection probe... This may take a while.");
                        string            outputFile           = inputFile.Replace(inputExt, "Probe.hdr");
                        int               reflectionResolution = (int)reflectionType;
                        FREE_IMAGE_FORMAT srcType = FREE_IMAGE_FORMAT.FIF_HDR;
                        if (inputExt.Equals(".hdr", StringComparison.OrdinalIgnoreCase))
                        {
                            srcType = FREE_IMAGE_FORMAT.FIF_HDR;
                        }
                        else if (inputExt.Equals(".exr", StringComparison.OrdinalIgnoreCase))
                        {
                            srcType = FREE_IMAGE_FORMAT.FIF_EXR;
                        }
                        FREE_IMAGE_FILTER rescaleFilter = FREE_IMAGE_FILTER.FILTER_LANCZOS3;
                        int        rescaleWidth         = reflectionResolution * 4;
                        int        rescaleHeight        = rescaleWidth / 2;
                        FileStream destStream           = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
                        FileStream sourceStream         = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
                        try
                        {
                            Tools.ConvertFreeImage(sourceStream, srcType, destStream, FREE_IMAGE_FORMAT.FIF_HDR, FREE_IMAGE_TYPE.FIT_UNKNOWN, true, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, FREE_IMAGE_LOAD_FLAGS.DEFAULT, FREE_IMAGE_SAVE_FLAGS.DEFAULT, 0.0, false, false, rescaleWidth, rescaleHeight, rescaleFilter);
                        } catch (Exception ex) {
                            UnityEngine.Debug.LogException(ex);
                        } finally {
                            destStream.Close();
                            sourceStream.Close();
                        }
                        if (System.IO.File.Exists(outputFile))
                        {
                            AssetDatabase.ImportAsset(outputFile, ImportAssetOptions.ForceUpdate);
                            var importTool = new BabylonTextureImporter(outputFile);
                            importTool.textureImporter.textureShape = TextureImporterShape.TextureCube;
                            importTool.textureImporter.isReadable   = true;
                            importTool.ForceUpdate();
                        }
                    }
                    else
                    {
                        ExporterWindow.ShowMessage("You must select a high dynamic range cubemap");
                    }
                }
                else if (cubemapTool == BabylonCubemapTool.CubemapSplitter)
                {
                    ExporterWindow.ReportProgress(1, "Baking cubemap texture faces... This may take a while.");
                    bool   jpeg         = (imageFormat == BabylonImageFormat.JPEG);
                    string faceExt      = (jpeg) ? ".jpg" : ".png";
                    var    splitterOpts = new BabylonSplitterOptions();
                    var    outputFile   = inputFile.Replace(inputExt, faceExt);
                    Tools.ExportCubemap(convertCube, outputFile, imageFormat, splitterOpts);
                    if (createSkyboxMaterial == true)
                    {
                        ExporterWindow.ReportProgress(1, "Generating skybox material assets... This may take a while.");
                        AssetDatabase.Refresh();
                        Material skyboxMaterial = new Material(Shader.Find("Mobile/Skybox"));
                        if (skyboxMaterial != null)
                        {
                            string frontFilename = outputFile.Replace(faceExt, ("_pz" + faceExt));
                            AssetDatabase.ImportAsset(frontFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D frontTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(frontFilename, typeof(Texture2D));
                            if (frontTexture != null)
                            {
                                skyboxMaterial.SetTexture("_FrontTex", frontTexture);
                            }

                            string backFilename = outputFile.Replace(faceExt, ("_nz" + faceExt));
                            AssetDatabase.ImportAsset(backFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D backTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(backFilename, typeof(Texture2D));
                            if (backTexture != null)
                            {
                                skyboxMaterial.SetTexture("_BackTex", backTexture);
                            }

                            string leftFilename = outputFile.Replace(faceExt, ("_px" + faceExt));
                            AssetDatabase.ImportAsset(leftFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D leftTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(leftFilename, typeof(Texture2D));
                            if (leftTexture != null)
                            {
                                skyboxMaterial.SetTexture("_LeftTex", leftTexture);
                            }

                            string rightFilename = outputFile.Replace(faceExt, ("_nx" + faceExt));
                            AssetDatabase.ImportAsset(rightFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D rightTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(rightFilename, typeof(Texture2D));
                            if (rightTexture != null)
                            {
                                skyboxMaterial.SetTexture("_RightTex", rightTexture);
                            }

                            string upFilename = outputFile.Replace(faceExt, ("_py" + faceExt));
                            AssetDatabase.ImportAsset(upFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D upTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(upFilename, typeof(Texture2D));
                            if (upTexture != null)
                            {
                                skyboxMaterial.SetTexture("_UpTex", upTexture);
                            }

                            string downFilename = outputFile.Replace(faceExt, ("_ny" + faceExt));
                            AssetDatabase.ImportAsset(downFilename, ImportAssetOptions.ForceUpdate);
                            Texture2D downTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(downFilename, typeof(Texture2D));
                            if (downTexture != null)
                            {
                                skyboxMaterial.SetTexture("_DownTex", downTexture);
                            }

                            string outputMaterialName = Path.GetFileNameWithoutExtension(inputFile);
                            string outputMaterialPath = Path.GetDirectoryName(inputFile);
                            string outputMaterialFile = outputMaterialPath + "/" + outputMaterialName + ".mat";
                            AssetDatabase.CreateAsset(skyboxMaterial, outputMaterialFile);
                        }
                        else
                        {
                            throw new Exception("Failed to create 'Mobile/Skybox' material");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogException(ex);
            }
            finally
            {
                ExporterWindow.ReportProgress(1, "Refresing assets database...");
                AssetDatabase.Refresh();
            }
            ExporterWindow.ReportProgress(1, "Cubemap conversion complete.");
            EditorUtility.ClearProgressBar();
            if (this.keepGeneratorOpen)
            {
                ExporterWindow.ShowMessage("Cubemap optimzation complete.", "Babylon.js");
            }
            else
            {
                this.Close();
            }
        }
Exemple #11
0
 private void ConvertUnitySkyboxToBabylon(Camera camera, float progress)
 {
     // Note: Only Support Main Camera Skyboxes
     if (Camera.main == camera && (camera.clearFlags & CameraClearFlags.Skybox) == CameraClearFlags.Skybox)
     {
         // Note: Only Support Tone Mapped Skyboxes
         if (RenderSettings.skybox != null)
         {
             BabylonTexture skytex = null;
             if (RenderSettings.skybox.shader.name == "Skybox/Cubemap")
             {
                 var cubeMap = RenderSettings.skybox.GetTexture("_Tex") as Cubemap;
                 if (cubeMap != null)
                 {
                     var cubeTextureFile = AssetDatabase.GetAssetPath(cubeMap);
                     var cubeTextureExt  = Path.GetExtension(cubeTextureFile);
                     if (!cubeTextureExt.Equals(".dds", StringComparison.OrdinalIgnoreCase))
                     {
                         ExporterWindow.ReportProgress(progress, "Baking skybox environment textures... This may take a while.");
                         var faceTextureExt    = ".jpg";
                         var faceTextureFormat = BabylonImageFormat.JPEG;
                         if (exportationOptions.ImageEncodingOptions == (int)BabylonImageFormat.PNG)
                         {
                             faceTextureExt    = ".png";
                             faceTextureFormat = BabylonImageFormat.PNG;
                         }
                         string frontTextureExt = "_pz" + faceTextureExt;
                         string backTextureExt  = "_nz" + faceTextureExt;
                         string leftTextureExt  = "_px" + faceTextureExt;
                         string rightTextureExt = "_nx" + faceTextureExt;
                         string upTextureExt    = "_py" + faceTextureExt;
                         string downTextureExt  = "_ny" + faceTextureExt;
                         skytex                 = new BabylonTexture();
                         skytex.name            = String.Format("{0}_Skybox", SceneName);
                         skytex.isCube          = true;
                         skytex.coordinatesMode = 5;
                         skytex.extensions      = new string[] { leftTextureExt, upTextureExt, frontTextureExt, rightTextureExt, downTextureExt, backTextureExt };
                         Tools.SetTextureWrapMode(skytex, cubeMap);
                         var outputFile   = Path.Combine(babylonScene.OutputPath, skytex.name + faceTextureExt);
                         var splitterOpts = new BabylonSplitterOptions();
                         this.skyboxTextures = Tools.ExportCubemap(cubeMap, outputFile, faceTextureFormat, splitterOpts);
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cubemap texture type of " + cubeTextureExt + " for " + Path.GetFileName(cubeTextureFile));
                         return;
                     }
                 }
             }
             else if (RenderSettings.skybox.shader.name == "Skybox/6 Sided" || RenderSettings.skybox.shader.name == "Mobile/Skybox")
             {
                 // 6-Sided Skybox Textures (Tone Mapped Image Formats Only)
                 var frontTexture = RenderSettings.skybox.GetTexture("_FrontTex") as Texture2D;
                 var backTexture  = RenderSettings.skybox.GetTexture("_BackTex") as Texture2D;
                 var leftTexture  = RenderSettings.skybox.GetTexture("_LeftTex") as Texture2D;
                 var rightTexture = RenderSettings.skybox.GetTexture("_RightTex") as Texture2D;
                 var upTexture    = RenderSettings.skybox.GetTexture("_UpTex") as Texture2D;
                 var downTexture  = RenderSettings.skybox.GetTexture("_DownTex") as Texture2D;
                 if (frontTexture != null && backTexture != null && leftTexture != null && rightTexture != null && upTexture != null && downTexture != null)
                 {
                     ExporterWindow.ReportProgress(progress, "Exporting skybox environment textures... This may take a while.");
                     string frontTextureExt = "_pz.jpg";
                     string backTextureExt  = "_nz.jpg";
                     string leftTextureExt  = "_px.jpg";
                     string rightTextureExt = "_nx.jpg";
                     string upTextureExt    = "_py.jpg";
                     string downTextureExt  = "_ny.jpg";
                     skytex                 = new BabylonTexture();
                     skytex.name            = String.Format("{0}_Skybox", SceneName);
                     skytex.isCube          = true;
                     skytex.coordinatesMode = 5;
                     Tools.SetTextureWrapMode(skytex, frontTexture);
                     List <Tools.TextureInfo> faces = new List <Tools.TextureInfo>();
                     var faceTextureFile            = AssetDatabase.GetAssetPath(frontTexture);
                     var faceTextureExt             = Path.GetExtension(faceTextureFile);
                     var faceImportTool             = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         frontTextureExt = "_pz" + faceTextureExt;
                         var frontTextureName = String.Format("{0}_pz{1}", skytex.name, faceTextureExt);
                         var frontTexturePath = Path.Combine(babylonScene.OutputPath, frontTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(frontTexturePath, frontTextureName, frontTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = frontTexturePath, texture = frontTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     faceTextureFile = AssetDatabase.GetAssetPath(backTexture);
                     faceTextureExt  = Path.GetExtension(faceTextureFile);
                     faceImportTool  = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         backTextureExt = "_nz" + faceTextureExt;
                         var backTextureName = String.Format("{0}_nz{1}", skytex.name, faceTextureExt);
                         var backTexturePath = Path.Combine(babylonScene.OutputPath, backTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(backTexturePath, backTextureName, backTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = backTexturePath, texture = backTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     faceTextureFile = AssetDatabase.GetAssetPath(leftTexture);
                     faceTextureExt  = Path.GetExtension(faceTextureFile);
                     faceImportTool  = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         leftTextureExt = "_px" + faceTextureExt;
                         var leftTextureName = String.Format("{0}_px{1}", skytex.name, faceTextureExt);
                         var leftTexturePath = Path.Combine(babylonScene.OutputPath, leftTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(leftTexturePath, leftTextureName, leftTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = leftTexturePath, texture = leftTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     faceTextureFile = AssetDatabase.GetAssetPath(rightTexture);
                     faceTextureExt  = Path.GetExtension(faceTextureFile);
                     faceImportTool  = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         rightTextureExt = "_nx" + faceTextureExt;
                         var rightTextureName = String.Format("{0}_nx{1}", skytex.name, faceTextureExt);
                         var rightTexturePath = Path.Combine(babylonScene.OutputPath, rightTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(rightTexturePath, rightTextureName, rightTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = rightTexturePath, texture = rightTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     faceTextureFile = AssetDatabase.GetAssetPath(upTexture);
                     faceTextureExt  = Path.GetExtension(faceTextureFile);
                     faceImportTool  = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         upTextureExt = "_py" + faceTextureExt;
                         var upTextureName = String.Format("{0}_py{1}", skytex.name, faceTextureExt);
                         var upTexturePath = Path.Combine(babylonScene.OutputPath, upTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(upTexturePath, upTextureName, upTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = upTexturePath, texture = upTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     faceTextureFile = AssetDatabase.GetAssetPath(downTexture);
                     faceTextureExt  = Path.GetExtension(faceTextureFile);
                     faceImportTool  = new BabylonTextureImporter(faceTextureFile);
                     if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
                     {
                         downTextureExt = "_ny" + faceTextureExt;
                         var downTextureName = String.Format("{0}_ny{1}", skytex.name, faceTextureExt);
                         var downTexturePath = Path.Combine(babylonScene.OutputPath, downTextureName);
                         faceImportTool.SetReadable();
                         CopyTextureFace(downTexturePath, downTexturePath, downTexture);
                         faces.Add(new Tools.TextureInfo {
                             filename = downTexturePath, texture = downTexture.Copy()
                         });
                     }
                     else
                     {
                         UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
                     }
                     skytex.extensions   = new string[] { leftTextureExt, upTextureExt, frontTextureExt, rightTextureExt, downTextureExt, backTextureExt };
                     this.skyboxTextures = (faces.Count > 0) ? faces.ToArray() : null;
                 }
             }
             if (skytex != null)
             {
                 skytex.level = (SceneController != null) ? SceneController.skyboxOptions.skyTextureLevel : 1.0f;
                 string meshTags     = (SceneController != null) ? SceneController.skyboxOptions.meshTags : String.Empty;
                 float  skyboxSize   = (SceneController != null) ? SceneController.skyboxOptions.skyMeshSize : 1000;
                 bool   skyboxSphere = (SceneController != null) ? (SceneController.skyboxOptions.meshType == BabylonSkyboxType.Sphere) : false;
                 // Babylon Skybox Mesh
                 var skybox = new BabylonMesh();
                 skybox.id = Guid.NewGuid().ToString();
                 skybox.infiniteDistance   = true;
                 skybox.numBoneInfluencers = Tools.GetMaxBoneInfluencers();
                 if (!String.IsNullOrEmpty(meshTags))
                 {
                     skybox.tags = meshTags;
                 }
                 if (skyboxSphere)
                 {
                     skybox.name = "sceneSkyboxSphere";
                     Mesh sphereMesh = Tools.CreateSphereMesh(skyboxSize * 0.5f, 48, 48);
                     Tools.GenerateBabylonMeshData(sphereMesh, skybox);
                 }
                 else
                 {
                     skybox.name = "sceneSkyboxCube";
                     Mesh boxMesh = Tools.CreateBoxMesh(skyboxSize, skyboxSize, skyboxSize);
                     Tools.GenerateBabylonMeshData(boxMesh, skybox);
                 }
                 // Babylon Default Skybox
                 var skyboxMaterial = new BabylonDefaultMaterial();
                 skyboxMaterial.name              = "sceneSkyboxMaterial";
                 skyboxMaterial.id                = Guid.NewGuid().ToString();
                 skyboxMaterial.backFaceCulling   = false;
                 skyboxMaterial.disableLighting   = true;
                 skyboxMaterial.diffuse           = Color.black.ToFloat();
                 skyboxMaterial.specular          = Color.black.ToFloat();
                 skyboxMaterial.ambient           = Color.clear.ToFloat();
                 skyboxMaterial.reflectionTexture = skytex;
                 // Babylon Skybox Material
                 skybox.materialId = skyboxMaterial.id;
                 babylonScene.MeshesList.Add(skybox);
                 babylonScene.MaterialsList.Add(skyboxMaterial);
                 babylonScene.AddTextureCube("sceneSkyboxMaterial");
             }
         }
     }
 }
 private void DumpSkyboxTextures(ref BabylonTexture skytex, ref Texture2D frontTexture, ref Texture2D backTexture, ref Texture2D leftTexture, ref Texture2D rightTexture, ref Texture2D upTexture, ref Texture2D downTexture)
 {
     if (frontTexture != null && backTexture != null && leftTexture != null && rightTexture != null && upTexture != null && downTexture != null)
     {
         ExporterWindow.ReportProgress(1, "Exporting skybox environment textures... This may take a while.");
         string frontTextureExt = "_pz.jpg";
         string backTextureExt  = "_nz.jpg";
         string leftTextureExt  = "_px.jpg";
         string rightTextureExt = "_nx.jpg";
         string upTextureExt    = "_py.jpg";
         string downTextureExt  = "_ny.jpg";
         Tools.SetTextureWrapMode(skytex, frontTexture);
         var faceTextureFile = AssetDatabase.GetAssetPath(frontTexture);
         var faceTextureExt  = Path.GetExtension(faceTextureFile);
         var faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             frontTextureExt = "_pz" + faceTextureExt;
             var frontTextureName = String.Format("{0}_pz{1}", skytex.name, faceTextureExt);
             var frontTexturePath = Path.Combine(babylonScene.OutputPath, frontTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(frontTexturePath, frontTextureName, frontTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         faceTextureFile = AssetDatabase.GetAssetPath(backTexture);
         faceTextureExt  = Path.GetExtension(faceTextureFile);
         faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             backTextureExt = "_nz" + faceTextureExt;
             var backTextureName = String.Format("{0}_nz{1}", skytex.name, faceTextureExt);
             var backTexturePath = Path.Combine(babylonScene.OutputPath, backTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(backTexturePath, backTextureName, backTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         faceTextureFile = AssetDatabase.GetAssetPath(leftTexture);
         faceTextureExt  = Path.GetExtension(faceTextureFile);
         faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             leftTextureExt = "_px" + faceTextureExt;
             var leftTextureName = String.Format("{0}_px{1}", skytex.name, faceTextureExt);
             var leftTexturePath = Path.Combine(babylonScene.OutputPath, leftTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(leftTexturePath, leftTextureName, leftTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         faceTextureFile = AssetDatabase.GetAssetPath(rightTexture);
         faceTextureExt  = Path.GetExtension(faceTextureFile);
         faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             rightTextureExt = "_nx" + faceTextureExt;
             var rightTextureName = String.Format("{0}_nx{1}", skytex.name, faceTextureExt);
             var rightTexturePath = Path.Combine(babylonScene.OutputPath, rightTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(rightTexturePath, rightTextureName, rightTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         faceTextureFile = AssetDatabase.GetAssetPath(upTexture);
         faceTextureExt  = Path.GetExtension(faceTextureFile);
         faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             upTextureExt = "_py" + faceTextureExt;
             var upTextureName = String.Format("{0}_py{1}", skytex.name, faceTextureExt);
             var upTexturePath = Path.Combine(babylonScene.OutputPath, upTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(upTexturePath, upTextureName, upTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         faceTextureFile = AssetDatabase.GetAssetPath(downTexture);
         faceTextureExt  = Path.GetExtension(faceTextureFile);
         faceImportTool  = new BabylonTextureImporter(faceTextureFile);
         if (faceTextureExt.Equals(".png", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || faceTextureExt.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
         {
             downTextureExt = "_ny" + faceTextureExt;
             var downTextureName = String.Format("{0}_ny{1}", skytex.name, faceTextureExt);
             var downTexturePath = Path.Combine(babylonScene.OutputPath, downTextureName);
             faceImportTool.SetReadable();
             CopyTextureFace(downTexturePath, downTexturePath, downTexture);
         }
         else
         {
             UnityEngine.Debug.LogWarning("SKYBOX: Unsupported cube face texture type of " + faceTextureExt + " for " + Path.GetFileName(faceTextureFile));
         }
         skytex.extensions = new string[] { leftTextureExt, upTextureExt, frontTextureExt, rightTextureExt, downTextureExt, backTextureExt };
     }
 }
Exemple #13
0
        public void Split()
        {
            ExporterWindow.ReportProgress(1, "Splitting cubemap textures... This may take a while.");
            var filePath  = AssetDatabase.GetAssetPath(splitCube);
            int splitSize = splitCube.width;

            Color[] CubeMapColors;

            var    faceTexturePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
            bool   png             = (ExporterWindow.exportationOptions.DefaultImageFormat == (int)BabylonImageFormat.PNG);
            string fext            = (png == true) ? ".png" : ".jpg";
            string filename        = "";
            string preview         = "";

            var  importTool = new BabylonTextureImporter(filePath);
            bool isReadable = importTool.IsReadable();

            if (!isReadable)
            {
                importTool.SetReadable();
            }
            try
            {
                filename = (faceTexturePath + "_py" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                Texture2D tex = new Texture2D(splitSize, splitSize, TextureFormat.RGB24, false);
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveY);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_ny" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeY);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_px" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveX);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_nx" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeX);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_pz" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveZ);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);

                filename = (faceTexturePath + "_nz" + fext);
                preview  = Path.GetFileName(filename);
                ExporterWindow.ReportProgress(1, "Splitting texture face " + preview + " ... This may take a while.");
                CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeZ);
                tex.SetPixels(CubeMapColors, 0);
                tex.Apply();
                WriteTextureFile(filename, tex, png);
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogException(ex);
            }
            finally
            {
                if (!isReadable)
                {
                    ExporterWindow.ReportProgress(1, "Finalizing assets database...");
                    importTool.ForceUpdate();
                }
            }
            ExporterWindow.ReportProgress(1, "Refresing assets database...");
            AssetDatabase.Refresh();

            ExporterWindow.ReportProgress(1, "Cubemap split complete.");
            EditorUtility.ClearProgressBar();
            this.Close();
        }
Exemple #14
0
        public void CreateTextureAtlas()
        {
            if (skinMeshRenderer != null && skinMeshRenderer.sharedMaterials != null && skinMeshRenderer.sharedMaterials.Length > 1)
            {
                string filename = EditorUtility.SaveFilePanelInProject("Texture Atlas Skin", "", "asset", "Bake Skin Mesh Renderer Texture Atlas");
                if (!String.IsNullOrEmpty(filename))
                {
                    ExporterWindow.ReportProgress(1, "Baking texture atlas skin... This may take a while.");
                    string filepath  = Path.GetDirectoryName(filename);
                    string filelabel = Path.GetFileNameWithoutExtension(filename);
                    Tools.ValidateAssetFolders(filepath.TrimEnd('/'));

                    // Texture atlas file info
                    string atlasExt     = "png";
                    string atlasName    = String.Format("{0}_Texture_Atlas", filelabel);
                    string atlasFile    = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), atlasName, atlasExt);
                    string bumpName     = String.Format("{0}_Normal_Atlas", filelabel);
                    string bumpFile     = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), bumpName, atlasExt);
                    string ambientName  = String.Format("{0}_Ambient_Atlas", filelabel);
                    string ambientFile  = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), ambientName, atlasExt);
                    string emissionName = String.Format("{0}_Emission_Atlas", filelabel);
                    string emissionFile = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), emissionName, atlasExt);
                    string metallicName = String.Format("{0}_Metallic_Atlas", filelabel);
                    string metallicFile = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), metallicName, atlasExt);
                    string specularName = String.Format("{0}_Specular_Atlas", filelabel);
                    string specularFile = String.Format("{0}/Textures/{1}.{2}", filepath.TrimEnd('/'), specularName, atlasExt);
                    string materialName = String.Format("{0}_Material", filelabel);
                    string materialFile = String.Format("{0}/Materials/{1}.asset", filepath.TrimEnd('/'), materialName);

                    // Create atlas textures
                    mainTextures     = new List <Texture2D>();
                    bumpTextures     = new List <Texture2D>();
                    ambientTextures  = new List <Texture2D>();
                    emissionTextures = new List <Texture2D>();
                    metallicTextures = new List <Texture2D>();
                    specularTextures = new List <Texture2D>();
                    foreach (var material in skinMeshRenderer.sharedMaterials)
                    {
                        Texture2D colorTexture        = null;
                        Texture2D normalTexture       = null;
                        Texture2D ambientTexture      = null;
                        Texture2D emissionTexture     = null;
                        Texture2D metallicTexture     = null;
                        Texture2D specularTexture     = null;
                        bool      metallicTextureSRGB = true;
                        if (material.mainTexture != null)
                        {
                            Texture2D primaryTexture = material.mainTexture as Texture2D;
                            primaryTexture.ForceReadable();
                            colorTexture = primaryTexture.Copy();
                            if (colorTexture != null && bakeTextureMaps == true)
                            {
                                if (material.HasProperty("_BumpMap"))
                                {
                                    Texture2D bumpTexture = material.GetTexture("_BumpMap") as Texture2D;
                                    if (bumpTexture != null)
                                    {
                                        // Format texture import settings
                                        string bumpTexturePath = AssetDatabase.GetAssetPath(bumpTexture);
                                        var    importTool      = new BabylonTextureImporter(bumpTexturePath);
                                        var    importType      = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            normalTexture = bumpTexture.Copy();
                                            if (normalTexture.width != colorTexture.width || normalTexture.height != colorTexture.height)
                                            {
                                                normalTexture.Scale(colorTexture.width, colorTexture.height);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                                if (material.HasProperty("_EmissionMap"))
                                {
                                    Texture2D emitTexture = material.GetTexture("_EmissionMap") as Texture2D;
                                    if (emitTexture != null)
                                    {
                                        // Format texture import settings
                                        string emissionTexturePath = AssetDatabase.GetAssetPath(emitTexture);
                                        var    importTool          = new BabylonTextureImporter(emissionTexturePath);
                                        var    importType          = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            emissionTexture = emitTexture.Copy();
                                            if (emissionTexture.width != colorTexture.width || emissionTexture.height != colorTexture.height)
                                            {
                                                emissionTexture.Scale(colorTexture.width, colorTexture.height);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                                if (material.HasProperty("_OcclusionMap"))
                                {
                                    Texture2D occlusionTexture = material.GetTexture("_OcclusionMap") as Texture2D;
                                    if (occlusionTexture != null)
                                    {
                                        // Format texture import settings
                                        string occlusionTexturePath = AssetDatabase.GetAssetPath(occlusionTexture);
                                        var    importTool           = new BabylonTextureImporter(occlusionTexturePath);
                                        var    importType           = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            ambientTexture = occlusionTexture.Copy();
                                            if (ambientTexture.width != colorTexture.width || ambientTexture.height != colorTexture.height)
                                            {
                                                ambientTexture.Scale(colorTexture.width, colorTexture.height);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                                if (material.HasProperty("_MetallicGlossMap"))
                                {
                                    Texture2D metalnessTexture = material.GetTexture("_MetallicGlossMap") as Texture2D;
                                    if (metalnessTexture != null)
                                    {
                                        // Format texture import settings
                                        metallicTextureSRGB = metalnessTexture.IsSRGB();
                                        string metalnessTexturePath = AssetDatabase.GetAssetPath(metalnessTexture);
                                        var    importTool           = new BabylonTextureImporter(metalnessTexturePath);
                                        var    importType           = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            metallicTexture = metalnessTexture.Copy();
                                            if (metallicTexture.width != colorTexture.width || metallicTexture.height != colorTexture.height)
                                            {
                                                metallicTexture.Scale(colorTexture.width, colorTexture.height);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                                if (material.HasProperty("_SpecGlossMap"))
                                {
                                    Texture2D glossTexture = material.GetTexture("_SpecGlossMap") as Texture2D;
                                    if (glossTexture != null)
                                    {
                                        // Format texture import settings
                                        string specularTexturePath = AssetDatabase.GetAssetPath(glossTexture);
                                        var    importTool          = new BabylonTextureImporter(specularTexturePath);
                                        var    importType          = importTool.textureImporter.textureType;
                                        try
                                        {
                                            importTool.textureImporter.isReadable  = true;
                                            importTool.textureImporter.textureType = TextureImporterType.Default;
                                            importTool.ForceUpdate();
                                            specularTexture = glossTexture.Copy();
                                            if (specularTexture.width != colorTexture.width || specularTexture.height != colorTexture.height)
                                            {
                                                specularTexture.Scale(colorTexture.width, colorTexture.height);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            UnityEngine.Debug.LogException(ex);
                                        }
                                        finally
                                        {
                                            // Restore texture importer type
                                            importTool.textureImporter.textureType = importType;
                                            importTool.ForceUpdate();
                                        }
                                    }
                                }
                            }
                        }
                        if (colorTexture == null)
                        {
                            colorTexture    = Tools.CreateBlankTextureMap(256, 256, material.color);
                            normalTexture   = null;
                            ambientTexture  = null;
                            emissionTexture = null;
                            metallicTexture = null;
                            specularTexture = null;
                        }
                        var mode = material.HasProperty("_Mode") ? (BlendMode)material.GetFloat("_Mode") : BlendMode.Opaque;
                        if (colorTexture != null && mode == BlendMode.Opaque)
                        {
                            colorTexture.MakeAlpha(1.0f);
                        }
                        if (normalTexture == null)
                        {
                            normalTexture = Tools.CreateBlankNormalMap(colorTexture.width, colorTexture.height);
                        }
                        if (emissionTexture == null)
                        {
                            Color emissionColor = material.HasProperty("_EmissionColor") ? material.GetColor("_EmissionColor") : material.HasProperty("_Emission") ? material.GetColor("_Emission") : Color.black;
                            emissionTexture = Tools.CreateBlankTextureMap(colorTexture.width, colorTexture.height, emissionColor);
                        }
                        if (ambientTexture == null)
                        {
                            Color ambientColor = material.HasProperty("_AmbientColor") ? material.GetColor("_AmbientColor") : Color.white;
                            ambientTexture = Tools.CreateBlankTextureMap(colorTexture.width, colorTexture.height, ambientColor);
                        }
                        float metalness = 0.0f, glossiness = 0.5f;
                        if (material.HasProperty("_Metallic"))
                        {
                            metalness = Tools.GammaToLinearSpace(material.GetFloat("_Metallic"));
                        }
                        if (material.HasProperty("_Roughness"))
                        {
                            glossiness = (1.0f - material.GetFloat("_Roughness"));
                        }
                        else if (material.HasProperty("_Glossiness"))
                        {
                            glossiness = material.GetFloat("_Glossiness");
                        }
                        else if (material.HasProperty("_Gloss"))
                        {
                            glossiness = material.GetFloat("_Gloss");
                        }
                        float glossinessScale   = material.HasProperty("_GlossMapScale") ? material.GetFloat("_GlossMapScale") : 0.5f;
                        bool  glossyRelfections = (material.HasProperty("_GlossyReflections") && material.GetFloat("_GlossyReflections") != 0.0f);
                        if (glossyRelfections == false)
                        {
                            glossiness      = 0.0f;
                            glossinessScale = 0.0f;
                        }
                        glossiness      = Tools.GetGlossinessScale(glossiness);
                        glossinessScale = Tools.GetGlossinessScale(glossinessScale);
                        if (metallicTexture == null)
                        {
                            Color metallicColor = Color.white;
                            metallicTexture = Tools.CreateBlankTextureMap(colorTexture.width, colorTexture.height, metallicColor);
                            metallicTexture = Tools.EncodeMetallicTextureMap(metallicTexture, metalness, glossinessScale);
                        }
                        else
                        {
                            metallicTexture = Tools.CreateMetallicTextureMap(metallicTexture, glossinessScale, metallicTextureSRGB);
                        }
                        if (specularTexture == null)
                        {
                            Color specularColor = material.HasProperty("_SpecColor") ? material.GetColor("_SpecColor") : Color.black;
                            specularColor.a *= glossiness;
                            specularTexture  = Tools.CreateBlankTextureMap(colorTexture.width, colorTexture.height, specularColor);
                        }
                        else
                        {
                            specularTexture = Tools.CreateSpecularTextureMap(specularTexture, glossiness);
                        }
                        // Buffer baked material info
                        mainTextures.Add(colorTexture);
                        bumpTextures.Add(normalTexture);
                        ambientTextures.Add(ambientTexture);
                        emissionTextures.Add(emissionTexture);
                        metallicTextures.Add(metallicTexture);
                        specularTextures.Add(specularTexture);
                    }

                    // Encode atlas textures
                    bool      bilinearScaling    = (textureImageScaling == BabylonTextureScale.Bilinear);
                    Texture2D skinnedMeshAtlas   = new Texture2D(128, 128, TextureFormat.RGBA32, false);
                    Rect[]    atlasPackingResult = Tools.PackTextureAtlas(skinnedMeshAtlas, mainTextures.ToArray(), textureAtlasSize, maxTextureImageSize, bilinearScaling, false);
                    Texture2D skinnedMeshBuffer  = skinnedMeshAtlas.Copy();
                    skinnedMeshBuffer.alphaIsTransparency = true;
                    skinnedMeshBuffer.WriteImage(atlasFile, textureAtlasFormat);
                    AssetDatabase.ImportAsset(atlasFile, ImportAssetOptions.ForceUpdate);

                    // Create atlas material(s)
                    if (textureAtlasShader == null)
                    {
                        textureAtlasShader = Shader.Find("Standard");
                    }
                    atlasMaterial             = new Material(textureAtlasShader);
                    atlasMaterial.name        = materialName;
                    atlasMaterial.mainTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(atlasFile, typeof(Texture2D));
                    AssetDatabase.CreateAsset(atlasMaterial, materialFile);
                    if (bakeTextureMaps)
                    {
                        bumpFilename     = bumpFile;
                        ambientFilename  = ambientFile;
                        emissionFilename = emissionFile;
                        metallicFilename = metallicFile;
                        specularFilename = specularFile;
                    }

                    // Texture atlas uv coordinates
                    Mesh           mesh    = skinMeshRenderer.sharedMesh;
                    int            numSubs = mesh.subMeshCount;
                    int            uvCount = mesh.uv.Length;
                    List <Vector2> uvList  = new List <Vector2>();
                    if (atlasPackingResult != null && atlasPackingResult.Length > 0)
                    {
                        for (int ctr = 0; ctr < numSubs; ctr++)
                        {
                            Mesh      sub = mesh.GetSubmesh(ctr);
                            Vector2[] uvs = Tools.GetTextureAtlasCoordinates(sub.uv, ctr, atlasPackingResult, linearInterpolation);
                            uvList.AddRange(uvs);
                        }
                        if (uvList.Count != uvCount)
                        {
                            throw new Exception("Skin vertex count mismatch. Failed to convert uv coordinates.");
                        }
                    }
                    else
                    {
                        UnityEngine.Debug.LogError("Null atlas packing result rects");
                    }

                    // Create new mesh asset
                    Mesh newmesh = mesh.Copy();
                    if (uvList.Count > 0)
                    {
                        newmesh.uv = uvList.ToArray();
                    }

                    // Save new mesh asset
                    string label    = Tools.FirstUpper(materialName.Replace("_Material", ""));
                    string meshName = String.Format("{0}_{1}_Mesh", label, skinMeshRenderer.name.MakeSafe());
                    string meshFile = String.Format("{0}/Geometry/{1}.asset", filepath.TrimEnd('/'), meshName);
                    AssetDatabase.CreateAsset(newmesh, meshFile);
                    if (updateSkinRenderer)
                    {
                        skinMeshRenderer.sharedMesh      = (Mesh)AssetDatabase.LoadAssetAtPath(meshFile, typeof(Mesh));
                        skinMeshRenderer.sharedMaterials = new Material[] { (Material)AssetDatabase.LoadAssetAtPath(materialFile, typeof(Material)) };
                    }
                }
            }
            else
            {
                ExporterWindow.ShowMessage("At least 2 materials required for texture atlas skin");
            }
        }