/// <summary>
        /// Called as a coroutine by ImportFile()
        /// </summary>
        /// <param name="absolutePath"></param>
        /// <param name="parentObject"></param>
        /// TODO: refactor this method, it is too long.
        private IEnumerator ImportFileAsync(string absolutePath, Transform parentObject)
        {
            Loader loader = CreateLoader(absolutePath);

            if (loader == null)
            {
                yield break;
            }
            loader.buildOptions = buildOptions;
            Debug.Log("Loading: " + absolutePath);
            float startTotTime = Time.realtimeSinceStartup;
            float startTime    = Time.realtimeSinceStartup;

            importPhase = ImportPhase.TextureImport;
            string dirName        = Path.GetDirectoryName(absolutePath);
            string sourceBasePath = string.IsNullOrEmpty(dirName) ? "" : dirName;

            if (!sourceBasePath.EndsWith("/"))
            {
                sourceBasePath += "/";
            }

            string newName = Path.GetFileNameWithoutExtension(absolutePath);//fileInfo.Name.Substring(0, fileInfo.Name.Length - 4);

            if (importAssets)
            {
                Debug.LogFormat("Importing assets from {0}...", absolutePath);
                importMessage = "Creating folders...";
                FileInfo fileInfo = new FileInfo(absolutePath);
                string   fileName = fileInfo.Name;
                if (!string.IsNullOrEmpty(importAssetPath))
                {
                    EditorUtil.CreateAssetFolder("Assets", importAssetPath);
                    EditorUtil.CreateAssetFolder("Assets/" + importAssetPath, fileName);
                }
                else
                {
                    EditorUtil.CreateAssetFolder("Assets", fileName);
                }

                string prefabRelPath = (!string.IsNullOrEmpty(importAssetPath)) ? importAssetPath + "/" + fileName : fileName;
                string prefabPath    = "Assets/" + prefabRelPath;
                string prefabName    = prefabPath + "/" + fileName.Replace('.', '_') + ".prefab";

                string[] texturePaths = loader.ParseTexturePaths(absolutePath);
                EditorUtil.CreateAssetFolder(prefabPath, "Textures");
                EditorUtil.CreateAssetFolder(prefabPath, "Materials");
                string destBasePath = Application.dataPath + "/../" + prefabPath;
                foreach (string texPath in texturePaths)
                {
                    string source = texPath;
                    if (!Path.IsPathRooted(source))
                    {
                        source = sourceBasePath + texPath;
                    }
                    FileInfo texFileInfo = new FileInfo(source);
                    string   dest        = destBasePath + "/Textures/" + texFileInfo.Name;
                    importMessage = "Copying texture " + source + "...";
                    File.Copy(source, dest, true);
                    Debug.LogFormat("Texture {0} copied to {1}", source, dest);
                }
                AssetDatabase.Refresh();
                AssetDatabase.StartAssetEditing();
                foreach (string texPath in texturePaths)
                {
                    FileInfo textFileInfo = new FileInfo(texPath);
                    string   texAssetPath = prefabPath + "/Textures/" + textFileInfo.Name;
                    importMessage = "Importing texture " + texAssetPath + "...";
                    EditorUtil.SetTextureReadable(texAssetPath);
                }
                AssetDatabase.SaveAssets();
                AssetDatabase.StopAssetEditing();
                //File.Copy(basePath+mtlLibName, destBasePath+mtlLibName, true);
                //File.Copy(absolutePath, destBasePath+fileName, true);

                importMessage = "Updating assets...";
                AssetDatabase.Refresh();
                Debug.LogFormat("Texture files imported in {0} seconds", Time.realtimeSinceStartup - startTime);
                startTime = Time.realtimeSinceStartup;

                importMessage       = "Loading OBJ file...";
                importPhase         = ImportPhase.ObjLoad;
                loader.altTexPath   = prefabPath + "/Textures/";
                loader.buildOptions = buildOptions;
                yield return(StartCoroutine(loader.Load(newName, absolutePath, parentObject)));

                importMessage = "Saving assets...";
                AssetDatabase.SaveAssets();
                importMessage = "Refreshing assets...";
                AssetDatabase.Refresh();

                Debug.LogFormat("OBJ files loaded in {0} seconds", Time.realtimeSinceStartup - startTime);
                startTime = Time.realtimeSinceStartup;
                GameObject loadedObj = Loader.GetModelByPath(absolutePath);

                importMessage = "Creating mesh assets...";
                importPhase   = ImportPhase.AssetBuild;
                // TODO: check if the prefab already exists
                MeshFilter[] meshFilters = loadedObj.GetComponentsInChildren <MeshFilter>();
                foreach (var filter in meshFilters)
                {
                    Mesh mesh = filter.sharedMesh;
                    if (!AssetDatabase.Contains(mesh))
                    {
                        EditorUtil.CreateAssetFolder(prefabPath, "Meshes");
                        AssetDatabase.CreateAsset(mesh, prefabPath + "/Meshes/" + mesh.name + ".asset");
                    }
                }

                importMessage = "Creating material assets...";
                AssetDatabase.StartAssetEditing();
                MeshRenderer[] meshRend = loadedObj.GetComponentsInChildren <MeshRenderer>();
                foreach (var rend in meshRend)
                {
                    Material mtl = rend.sharedMaterial;
                    if (!AssetDatabase.Contains(mtl))
                    {
                        string mtlAssetPath = prefabPath + "/Materials/" + mtl.name + ".mat";
                        AssetDatabase.CreateAsset(mtl, mtlAssetPath);
                    }
                }

                importMessage = "Saving assets...";
                AssetDatabase.SaveAssets();
                AssetDatabase.StopAssetEditing();
                importMessage = "Updating assets...";
                AssetDatabase.Refresh();

                importMessage = "Creating prefab...";
#if UNITY_2018_3_OR_NEWER
                PrefabUtility.SaveAsPrefabAssetAndConnect(loadedObj, prefabName, InteractionMode.AutomatedAction);
#else
                PrefabUtility.CreatePrefab(prefabName, loadedObj, ReplacePrefabOptions.ConnectToPrefab);
#endif
                //GameObject. objObject.GetComponent<OBJ>();
                Debug.LogFormat("Assets created in {0} seconds", Time.realtimeSinceStartup - startTime);
                importPhase = ImportPhase.Done;
            }
            else
            {
                importPhase = ImportPhase.ObjLoad;
                yield return(StartCoroutine(loader.Load(newName, absolutePath, parentObject)));
            }
            Debug.LogFormat("OBJ files imported in {0} seconds", Time.realtimeSinceStartup - startTotTime);
        }
Пример #2
0
 private static void Screenshot()
 {
     EditorUtil.AutoCaptureScreenshot("AsImpL");
 }
Пример #3
0
        /// <summary>
        /// Build a Unity Material from MaterialData
        /// </summary>
        /// <param name="md">material data</param>
        /// <returns>Unity material</returns>
        private Material BuildMaterial(MaterialData md)
        {
            string shaderName   = "Standard"; // (md.illumType == 2) ? "Standard (Specular setup)" : "Standard";
            bool   specularMode = false;      // (md.specularTex != null);

            ModelUtil.MtlBlendMode mode = md.overallAlpha < 1.0f ? ModelUtil.MtlBlendMode.TRANSPARENT : ModelUtil.MtlBlendMode.OPAQUE;

            bool useUnlit = buildOptions != null && buildOptions.litDiffuse &&
                            md.diffuseTex != null &&
                            md.bumpTex == null &&
                            md.opacityTex == null &&
                            md.specularTex == null &&
                            !md.hasReflectionTex;

            bool?diffuseIsTransparent = null;

            if (useUnlit)
            {
                // do not use unlit shader if the texture has transparent pixels
                diffuseIsTransparent = ModelUtil.ScanTransparentPixels(md.diffuseTex, ref mode);
            }

            if (useUnlit && !diffuseIsTransparent.Value)
            {
                shaderName = "Unlit/Texture";
            }
            else if (specularMode)
            {
                shaderName = "Standard (Specular setup)";
            }
            Material newMaterial = new Material(Shader.Find(shaderName)); // "Standard (Specular setup)"

            newMaterial.name = md.materialName;

            float shinLog = Mathf.Log(md.shininess, 2);
            // get the metallic value from the shininess
            float metallic = Mathf.Clamp01(shinLog / 10.0f);
            // get the smoothness from the shininess
            float smoothness = Mathf.Clamp01(shinLog / 10.0f);

            if (specularMode)
            {
                newMaterial.SetColor("_SpecColor", md.specularColor);
                newMaterial.SetFloat("_Shininess", md.shininess / 1000.0f);
                //m.color = new Color( md.diffuse.r, md.diffuse.g, md.diffuse.b, md.alpha);
            }
            else
            {
                newMaterial.SetFloat("_Metallic", metallic);
                //m.SetFloat( "_Glossiness", md.shininess );
            }


            if (md.diffuseTex != null)
            {
                // diffuse

                if (md.opacityTex != null)
                {
                    // diffuse + opacity:
                    // update diffuse texture if an opacity map was found
                    int       w             = md.diffuseTex.width;
                    int       h             = md.diffuseTex.width;
                    Texture2D albedoTexture = new Texture2D(w, h, TextureFormat.ARGB32, false);
                    Color     col           = new Color();
                    for (int x = 0; x < albedoTexture.width; x++)
                    {
                        for (int y = 0; y < albedoTexture.height; y++)
                        {
                            col    = md.diffuseTex.GetPixel(x, y);
                            col.a *= md.opacityTex.GetPixel(x, y).grayscale;
                            // blend diffuse and opacity textures
                            albedoTexture.SetPixel(x, y, col);
                        }
                    }
                    albedoTexture.name = md.diffuseTexPath;
                    albedoTexture.Apply();
                    // mode = ModelUtil.MtlBlendMode.TRANSPARENT;
                    // The map_d value is multiplied by the d value --> Fade mode
                    mode = ModelUtil.MtlBlendMode.FADE;
#if UNITY_EDITOR
                    if (!string.IsNullOrEmpty(alternativeTexPath))
                    {
                        string texAssetPath = AssetDatabase.GetAssetPath(md.opacityTex);
                        if (!string.IsNullOrEmpty(texAssetPath))
                        {
                            EditorUtil.SaveAndReimportPngTexture(ref albedoTexture, texAssetPath, "_alpha");
                        }
                    }
#endif
                    newMaterial.SetTexture("_MainTex", albedoTexture);
                }
                else
                {// md.opacityTex == null
                    // diffuse without opacity: if there are transparent pixels ==> transparent material
                    if (!diffuseIsTransparent.HasValue)
                    {
                        diffuseIsTransparent = ModelUtil.ScanTransparentPixels(md.diffuseTex, ref mode);
                    }
                    newMaterial.SetTexture("_MainTex", md.diffuseTex);
                }
                //Debug.LogFormat("Diffuse set for {0}",m.name);
            }
            else if (md.opacityTex != null)
            {
                // opacity without diffuse
                //mode = ModelUtil.MtlBlendMode.TRANSPARENT;
                mode = ModelUtil.MtlBlendMode.FADE;
                int       w             = md.opacityTex.width;
                int       h             = md.opacityTex.width;
                Texture2D albedoTexture = new Texture2D(w, h, TextureFormat.ARGB32, false);
                Color     col           = new Color();
                bool      detected      = false;
                for (int x = 0; x < albedoTexture.width; x++)
                {
                    for (int y = 0; y < albedoTexture.height; y++)
                    {
                        col   = md.diffuseColor;
                        col.a = md.overallAlpha * md.opacityTex.GetPixel(x, y).grayscale;
                        ModelUtil.DetectMtlBlendFadeOrCutout(col.a, ref mode, ref detected);
                        //if (md.alpha == 1.0f && col.a == 0.0f) mode = ModelUtil.MtlBlendMode.CUTOUT;
                        albedoTexture.SetPixel(x, y, col);
                    }
                }
                albedoTexture.name = md.diffuseTexPath;
                albedoTexture.Apply();
#if UNITY_EDITOR
                if (!string.IsNullOrEmpty(alternativeTexPath))
                {
                    string texAssetPath = AssetDatabase.GetAssetPath(md.opacityTex);
                    if (!string.IsNullOrEmpty(texAssetPath))
                    {
                        EditorUtil.SaveAndReimportPngTexture(ref albedoTexture, texAssetPath, "_op");
                    }
                }
#endif
                newMaterial.SetTexture("_MainTex", albedoTexture);
            }

            md.diffuseColor.a = md.overallAlpha;
            newMaterial.SetColor("_Color", md.diffuseColor);

            md.emissiveColor.a = md.overallAlpha;
            newMaterial.SetColor("_EmissionColor", md.emissiveColor);
            if (md.emissiveColor.r > 0 || md.emissiveColor.g > 0 || md.emissiveColor.b > 0)
            {
                newMaterial.EnableKeyword("_EMISSION");
            }

            if (md.bumpTex != null)
            {
                // bump map defined

                // TODO: if importing assets do not create a nomal map, change importer settings

                // let (improperly) assign a normal map to the bumb map
                // if the file name contains a specific tag
                // TODO: customize normal map tag
                if (md.bumpTexPath.Contains("_normal_map"))
                {
                    newMaterial.EnableKeyword("_NORMALMAP");
                    newMaterial.SetFloat("_BumpScale", 0.25f); // lower the bump effect with the normal map
                    newMaterial.SetTexture("_BumpMap", md.bumpTex);
                }
                else
                {
                    // calculate normal map
                    Texture2D normalMap = ModelUtil.HeightToNormalMap(md.bumpTex);
#if UNITY_EDITOR
                    if (!string.IsNullOrEmpty(alternativeTexPath))
                    {
                        string texAssetPath = AssetDatabase.GetAssetPath(md.bumpTex);
                        if (!string.IsNullOrEmpty(texAssetPath))
                        {
                            EditorUtil.SaveAndReimportPngTexture(ref normalMap, texAssetPath, "_nm", true);
                        }
                    }
                    else
#endif
                    {
                        newMaterial.SetTexture("_BumpMap", normalMap);
                        //newMaterial.SetTexture("_BumpMap", md.bumpTex);
                        newMaterial.EnableKeyword("_NORMALMAP");
                        newMaterial.SetFloat("_BumpScale", 1.0f); // adjust the bump effect with the normal map
                    }
                }
            }

            if (md.specularTex != null)
            {
                Texture2D glossTexture = new Texture2D(md.specularTex.width, md.specularTex.height, TextureFormat.ARGB32, false);
                Color     col          = new Color();
                float     pix          = 0.0f;
                for (int x = 0; x < glossTexture.width; x++)
                {
                    for (int y = 0; y < glossTexture.height; y++)
                    {
                        pix = md.specularTex.GetPixel(x, y).grayscale;

                        // red = metallic

                        col.r = metallic * pix;// md.specular.grayscale*pix;
                        col.g = col.r;
                        col.b = col.r;

                        // alpha = smoothness

                        // if reflecting set maximum smoothness value, else use a precomputed value
                        if (md.hasReflectionTex)
                        {
                            col.a = pix;
                        }
                        else
                        {
                            col.a = pix * smoothness;
                        }

                        glossTexture.SetPixel(x, y, col);
                    }
                }
                glossTexture.Apply();
#if UNITY_EDITOR
                if (!string.IsNullOrEmpty(alternativeTexPath))
                {
                    string texAssetPath = AssetDatabase.GetAssetPath(md.specularTex);
                    if (!string.IsNullOrEmpty(texAssetPath))
                    {
                        EditorUtil.SaveAndReimportPngTexture(ref glossTexture, texAssetPath, "_spec");
                    }
                }
#endif

                if (specularMode)
                {
                    newMaterial.EnableKeyword("_SPECGLOSSMAP");
                    newMaterial.SetTexture("_SpecGlossMap", glossTexture);
                }
                else
                {
                    newMaterial.EnableKeyword("_METALLICGLOSSMAP");
                    newMaterial.SetTexture("_MetallicGlossMap", glossTexture);
                }

                //m.SetTexture( "_MetallicGlossMap", md.specularLevelTex );
            }

            // replace the texture with Unity environment reflection
            if (md.hasReflectionTex)
            {
                if (md.overallAlpha < 1.0f)
                {
                    Color col = Color.white;
                    col.a = md.overallAlpha;
                    newMaterial.SetColor("_Color", col);
                    mode = ModelUtil.MtlBlendMode.FADE;
                }
                // the "amount of" info is missing, using a default value
                if (md.specularTex != null)
                {
                    newMaterial.SetFloat("_Metallic", metallic);// 1.0f);
                }
                // usually the reflection texture is not blurred
                newMaterial.SetFloat("_Glossiness", 1.0f);
            }

            ModelUtil.SetupMaterialWithBlendMode(newMaterial, mode);

            //#if UNITY_EDITOR
            //        if (!string.IsNullOrEmpty(alternateTexPath))
            //        {
            //            string path = alternateTexPath + "../Materials/" + m.name + ".mat";
            //            path = path.Replace("Textures/../", "");
            //            Debug.LogFormat("Creating material asset in {0}", path);
            //            AssetDatabase.CreateAsset(m, path);
            //        m = AssetDatabase.LoadAssetAtPath<Material>(path);
            //        }
            //#endif
            return(newMaterial);
        }