/// <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); }
private static void Screenshot() { EditorUtil.AutoCaptureScreenshot("AsImpL"); }
/// <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); }