From 323a816024eb4ab53a5d0108243320461829062a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 30 Mar 2021 13:24:53 +0900 Subject: [PATCH] WIP RuntimeUnityBuilder --- .../ScriptedImporter/ScriptedImporterImpl.cs | 22 +- .../Runtime/UniGLTF/IO/ImporterContext.cs | 9 +- .../ScriptedImporter/VrmScriptedImporter.cs | 225 +------ .../VrmScriptedImporterEditorGUI.cs | 190 +++--- .../VrmScriptedImporterImpl.cs | 567 +++++++++++++----- .../UnityBuilder/RuntimeUnityBuilder.cs | 22 +- 6 files changed, 565 insertions(+), 470 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs index 6857bf7e7..c440b730f 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs @@ -37,22 +37,22 @@ namespace UniGLTF // Import(create unity objects) // var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray(); - + var externalTextures = EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent).ToArray(); - using (var loaded = new ImporterContext(parser, externalObjectMap.Concat(externalTextures))) + using (var loader = new ImporterContext(parser, externalObjectMap.Concat(externalTextures))) { // settings TextureImporters foreach (var textureInfo in GltfTextureEnumerator.Enumerate(parser)) { - TextureImporterConfigurator.Configure(textureInfo, loaded.TextureFactory.ExternalMap); + TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap); } - loaded.InvertAxis = reverseAxis; - loaded.Load(); - loaded.ShowMeshes(); + loader.InvertAxis = reverseAxis; + loader.Load(); + loader.ShowMeshes(); - loaded.TransferOwnership(o => + loader.TransferOwnership(o => { #if VRM_DEVELOP Debug.Log($"[{o.GetType().Name}] {o.name} will not destroy"); @@ -62,7 +62,7 @@ namespace UniGLTF if (o is GameObject) { // Root GameObject is main object - context.SetMainObject(loaded.Root); + context.SetMainObject(loader.Root); } return true; @@ -96,8 +96,10 @@ namespace UniGLTF { // exclude. skip } - else{ - if(used.Add(asset)){ + else + { + if (used.Add(asset)) + { yield return (asset.name, asset); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index d5a7beccf..548432658 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -88,11 +88,6 @@ namespace UniGLTF MeasureTime = new ImporterContextSpeedLog().MeasureTime; } - if (Root == null) - { - Root = new GameObject("GLTF"); - } - if (GLTF.extensionsRequired != null) { var sb = new List(); @@ -165,6 +160,10 @@ namespace UniGLTF NodeImporter.SetupSkinning(this, nodes, i, inverter); } + if (Root == null) + { + Root = new GameObject("GLTF"); + } if (GLTF.rootnodes != null) { // connect root diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporter.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporter.cs index 3645fa4a1..69d994c0e 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporter.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporter.cs @@ -1,8 +1,4 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEditor; -#if UNITY_2020_2_OR_NEWER +#if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else using UnityEditor.Experimental.AssetImporters; @@ -11,227 +7,12 @@ using UnityEditor.Experimental.AssetImporters; namespace UniVRM10 { - [ScriptedImporter(1, "vrm")] public class VrmScriptedImporter : ScriptedImporter { - const string TextureDirName = "Textures"; - const string MaterialDirName = "Materials"; - const string MetaDirName = "MetaObjects"; - const string ExpressionDirName = "Expressions"; - public override void OnImportAsset(AssetImportContext ctx) { - Debug.Log("OnImportAsset to " + ctx.assetPath); - - var parser = new UniGLTF.GltfParser(); - parser.ParsePath(ctx.assetPath); - - // try - // { - // // Create Vrm Model - // VrmLib.Model model = VrmLoader.CreateVrmModel(parser); - // if (model == null) - // { - // // maybe VRM-0.X - // return; - // } - // Debug.Log($"VrmLoader.CreateVrmModel: {model}"); - - // // Build Unity Model - // var assets = EditorUnityBuilder.ToUnityAsset(model, assetPath, this); - // ComponentBuilder.Build10(model, assets); - - // // Texture - // var externalTextures = this.GetExternalUnityObjects(); - // foreach (var texture in assets.Textures) - // { - // if (texture == null) - // continue; - - // if (externalTextures.ContainsValue(texture)) - // { - // } - // else - // { - // ctx.AddObjectToAsset(texture.name, texture); - // } - // } - - // // Material - // var externalMaterials = this.GetExternalUnityObjects(); - // foreach (var material in assets.Materials) - // { - // if (material == null) - // continue; - - // if (externalMaterials.ContainsValue(material)) - // { - - // } - // else - // { - // ctx.AddObjectToAsset(material.name, material); - // } - // } - - // // Mesh - // foreach (var mesh in assets.Meshes) - // { - // ctx.AddObjectToAsset(mesh.name, mesh); - // } - - // //// ScriptableObject - // // avatar - // ctx.AddObjectToAsset("avatar", assets.HumanoidAvatar); - - // // meta - // { - // var external = this.GetExternalUnityObjects().FirstOrDefault(); - // if (external.Value != null) - // { - // var controller = assets.Root.GetComponent(); - // if (controller != null) - // { - // controller.Meta = external.Value; - // } - // } - // else - // { - // var meta = assets.ScriptableObjects - // .FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10MetaObject)) as UniVRM10.VRM10MetaObject; - // if (meta != null) - // { - // meta.name = "meta"; - // ctx.AddObjectToAsset(meta.name, meta); - // } - // } - // } - - // // expression - // { - // var external = this.GetExternalUnityObjects(); - // if (external.Any()) - // { - // } - // else - // { - // var expression = assets.ScriptableObjects - // .Where(x => x.GetType() == typeof(UniVRM10.VRM10Expression)) - // .Select(x => x as UniVRM10.VRM10Expression); - // foreach (var clip in expression) - // { - // clip.name = clip.ExpressionName; - // ctx.AddObjectToAsset(clip.ExpressionName, clip); - // } - // } - // } - // { - // var external = this.GetExternalUnityObjects().FirstOrDefault(); - // if (external.Value != null) - // { - // var controller = assets.Root.GetComponent(); - // if (controller != null) - // { - // controller.Expression.ExpressionAvatar = external.Value; - // } - // } - // else - // { - // var expressionAvatar = assets.ScriptableObjects - // .FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10ExpressionAvatar)) as UniVRM10.VRM10ExpressionAvatar; - // if (expressionAvatar != null) - // { - // expressionAvatar.name = "expressionAvatar"; - // ctx.AddObjectToAsset(expressionAvatar.name, expressionAvatar); - // } - // } - // } - - // // Root - // ctx.AddObjectToAsset(assets.Root.name, assets.Root); - // ctx.SetMainObject(assets.Root); - - // } - // catch (System.Exception ex) - // { - // Debug.LogError(ex); - // } - } - - public void ExtractTextures() - { - this.ExtractTextures(TextureDirName, (path) => - { - var parser = new UniGLTF.GltfParser(); - parser.ParsePath(path); - return VrmLoader.CreateVrmModel(parser); - }); - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - - public void ExtractMaterials() - { - this.ExtractAssets(MaterialDirName, ".mat"); - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - - public void ExtractMaterialsAndTextures() - { - this.ExtractTextures(TextureDirName, (path) => - { - var parser = new UniGLTF.GltfParser(); - parser.ParsePath(path); - return VrmLoader.CreateVrmModel(parser); - }, () => - { - this.ExtractAssets(MaterialDirName, ".mat"); - }); - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - - public void ExtractMeta() - { - this.ExtractAssets(MetaDirName, ".asset"); - var metaObject = this.GetExternalUnityObjects().FirstOrDefault(); - var metaObjectPath = AssetDatabase.GetAssetPath(metaObject.Value); - if (!string.IsNullOrEmpty(metaObjectPath)) - { - EditorUtility.SetDirty(metaObject.Value); - AssetDatabase.WriteImportSettingsIfDirty(metaObjectPath); - } - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - - public void ExtractExpressions() - { - this.ExtractAssets(ExpressionDirName, ".asset"); - this.ExtractAssets(ExpressionDirName, ".asset"); - - var expressionAvatar = this.GetExternalUnityObjects().FirstOrDefault(); - var expressions = this.GetExternalUnityObjects(); - - expressionAvatar.Value.Clips = expressions.Select(x => x.Value).ToList(); - var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar.Value); - if (!string.IsNullOrEmpty(avatarPath)) - { - EditorUtility.SetDirty(expressionAvatar.Value); - AssetDatabase.WriteImportSettingsIfDirty(avatarPath); - } - - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - - public Dictionary GetExternalUnityObjects() where T : UnityEngine.Object - { - return this.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)).ToDictionary(x => x.Key.name, x => (T)x.Value); - } - - public void SetExternalUnityObject(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object - { - this.AddRemap(sourceAssetIdentifier, obj); - AssetDatabase.WriteImportSettingsIfDirty(this.assetPath); - AssetDatabase.ImportAsset(this.assetPath, ImportAssetOptions.ForceUpdate); + VrmScriptedImporterImpl.Import(this, ctx); } } -} \ No newline at end of file +} diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs index a9aacd84d..a7d07ec66 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs @@ -1,6 +1,7 @@ using System.Linq; using UnityEditor; using UnityEngine; +using UniGLTF; #if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else @@ -13,91 +14,128 @@ namespace UniVRM10 [CustomEditor(typeof(VrmScriptedImporter))] public class VrmScriptedImporterEditorGUI : ScriptedImporterEditor { + VrmScriptedImporter m_importer; + GltfParser m_parser; + VrmLib.Model m_model; - private bool _isOpen = true; + public override void OnEnable() + { + base.OnEnable(); + + m_importer = target as VrmScriptedImporter; + m_parser = new GltfParser(); + m_parser.ParsePath(m_importer.assetPath); + m_model = VrmLoader.CreateVrmModel(m_parser); + } + + enum Tabs + { + Model, + Materials, + Vrm, + } + static Tabs s_currentTab; public override void OnInspectorGUI() { - var importer = target as VrmScriptedImporter; + s_currentTab = MeshUtility.TabBar.OnGUI(s_currentTab); + GUILayout.Space(10); - EditorGUILayout.LabelField("Extract settings"); + switch (s_currentTab) + { + case Tabs.Model: + base.OnInspectorGUI(); + break; - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel("Materials And Textures"); - GUI.enabled = !(importer.GetExternalUnityObjects().Any() - && importer.GetExternalUnityObjects().Any()); - if (GUILayout.Button("Extract")) - { - importer.ExtractMaterialsAndTextures(); - } - GUI.enabled = !GUI.enabled; - if (GUILayout.Button("Clear")) - { - importer.ClearExternalObjects(); - importer.ClearExternalObjects(); - } - GUI.enabled = true; - EditorGUILayout.EndHorizontal(); + case Tabs.Materials: + EditorMaterial.OnGUIMaterial(m_importer, m_parser); + break; - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel("Meta"); - GUI.enabled = !importer.GetExternalUnityObjects().Any(); - if (GUILayout.Button("Extract")) - { - importer.ExtractMeta(); + case Tabs.Vrm: + break; } - GUI.enabled = !GUI.enabled; - if (GUILayout.Button("Clear")) - { - importer.ClearExternalObjects(); - } - GUI.enabled = true; - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel("Expressions"); - GUI.enabled = !(importer.GetExternalUnityObjects().Any() - && importer.GetExternalUnityObjects().Any()); - if (GUILayout.Button("Extract")) - { - importer.ExtractExpressions(); - } - GUI.enabled = !GUI.enabled; - if (GUILayout.Button("Clear")) - { - importer.ClearExternalObjects(); - importer.ClearExternalObjects(); - } - GUI.enabled = true; - EditorGUILayout.EndHorizontal(); - - // ObjectMap - DrawRemapGUI("Material Remap", importer); - DrawRemapGUI("Texture Remap", importer); - DrawRemapGUI("Meta Remap", importer); - DrawRemapGUI("ExpressionAvatar Remap", importer); - DrawRemapGUI("Expression Remap", importer); - - base.OnInspectorGUI(); } - private void DrawRemapGUI(string title, VrmScriptedImporter importer) where T : UnityEngine.Object - { - EditorGUILayout.Foldout(_isOpen, title); - EditorGUI.indentLevel++; - var objects = importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)); - foreach (var obj in objects) - { - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel(obj.Key.name); - var asset = EditorGUILayout.ObjectField(obj.Value, obj.Key.type, true) as T; - if (asset != obj.Value) - { - importer.SetExternalUnityObject(obj.Key, asset); - } - EditorGUILayout.EndHorizontal(); - } - EditorGUI.indentLevel--; - } + // var importer = target as VrmScriptedImporter; + + // EditorGUILayout.LabelField("Extract settings"); + + // EditorGUILayout.BeginHorizontal(); + // EditorGUILayout.PrefixLabel("Materials And Textures"); + // GUI.enabled = !(importer.GetExternalUnityObjects().Any() + // && importer.GetExternalUnityObjects().Any()); + // if (GUILayout.Button("Extract")) + // { + // importer.ExtractMaterialsAndTextures(); + // } + // GUI.enabled = !GUI.enabled; + // if (GUILayout.Button("Clear")) + // { + // importer.ClearExternalObjects(); + // importer.ClearExternalObjects(); + // } + // GUI.enabled = true; + // EditorGUILayout.EndHorizontal(); + + // EditorGUILayout.BeginHorizontal(); + // EditorGUILayout.PrefixLabel("Meta"); + // GUI.enabled = !importer.GetExternalUnityObjects().Any(); + // if (GUILayout.Button("Extract")) + // { + // importer.ExtractMeta(); + // } + // GUI.enabled = !GUI.enabled; + // if (GUILayout.Button("Clear")) + // { + // importer.ClearExternalObjects(); + // } + // GUI.enabled = true; + // EditorGUILayout.EndHorizontal(); + + // EditorGUILayout.BeginHorizontal(); + // EditorGUILayout.PrefixLabel("Expressions"); + // GUI.enabled = !(importer.GetExternalUnityObjects().Any() + // && importer.GetExternalUnityObjects().Any()); + // if (GUILayout.Button("Extract")) + // { + // importer.ExtractExpressions(); + // } + // GUI.enabled = !GUI.enabled; + // if (GUILayout.Button("Clear")) + // { + // importer.ClearExternalObjects(); + // importer.ClearExternalObjects(); + // } + // GUI.enabled = true; + // EditorGUILayout.EndHorizontal(); + + // // ObjectMap + // DrawRemapGUI("Material Remap", importer); + // DrawRemapGUI("Texture Remap", importer); + // DrawRemapGUI("Meta Remap", importer); + // DrawRemapGUI("ExpressionAvatar Remap", importer); + // DrawRemapGUI("Expression Remap", importer); + + // base.OnInspectorGUI(); + // } + + // private void DrawRemapGUI(string title, VrmScriptedImporter importer) where T : UnityEngine.Object + // { + // EditorGUILayout.Foldout(_isOpen, title); + // EditorGUI.indentLevel++; + // var objects = importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)); + // foreach (var obj in objects) + // { + // EditorGUILayout.BeginHorizontal(); + // EditorGUILayout.PrefixLabel(obj.Key.name); + // var asset = EditorGUILayout.ObjectField(obj.Value, obj.Key.type, true) as T; + // if (asset != obj.Value) + // { + // importer.SetExternalUnityObject(obj.Key, asset); + // } + // EditorGUILayout.EndHorizontal(); + // } + // EditorGUI.indentLevel--; + // } } } diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs index 5768e88e8..71d1c3efe 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs @@ -1,9 +1,6 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using System; +using System.Linq; using UnityEngine; +using UniGLTF; #if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else @@ -15,167 +12,425 @@ namespace UniVRM10 { public static class VrmScriptedImporterImpl { - public static void ClearExternalObjects(this ScriptedImporter importer) where T : UnityEngine.Object + const string TextureDirName = "Textures"; + const string MaterialDirName = "Materials"; + const string MetaDirName = "MetaObjects"; + const string ExpressionDirName = "Expressions"; + + public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context) { - foreach (var extarnalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T))) +#if VRM_DEVELOP + Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); +#endif + + // + // Parse(parse glb, parser gltf json) + // + var parser = new GltfParser(); + parser.ParsePath(scriptedImporter.assetPath); + + // + // Import(create unity objects) + // + var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray(); + + using (var loader = new RuntimeUnityBuilder(parser, externalObjectMap)) { - importer.RemoveRemap(extarnalObject.Key); - } + // // settings TextureImporters + // foreach (var textureInfo in GltfTextureEnumerator.Enumerate(parser)) + // { + // TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap); + // } - AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); - AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); - } + loader.Load(); + loader.ShowMeshes(); - public static void ClearExtarnalObjects(this ScriptedImporter importer) - { - foreach (var extarnalObject in importer.GetExternalObjectMap()) - { - importer.RemoveRemap(extarnalObject.Key); - } - - AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); - AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); - } - - private static T GetSubAsset(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object - { - return importer.GetSubAssets(assetPath) - .FirstOrDefault(); - } - - public static IEnumerable GetSubAssets(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object - { - return AssetDatabase - .LoadAllAssetsAtPath(assetPath) - .Where(x => AssetDatabase.IsSubAsset(x)) - .Where(x => x is T) - .Select(x => x as T); - } - - private static void ExtractFromAsset(UnityEngine.Object subAsset, string destinationPath, bool isForceUpdate) - { - string assetPath = AssetDatabase.GetAssetPath(subAsset); - - var clone = UnityEngine.Object.Instantiate(subAsset); - AssetDatabase.CreateAsset(clone, destinationPath); - - var assetImporter = AssetImporter.GetAtPath(assetPath); - assetImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(subAsset), clone); - - if (isForceUpdate) - { - AssetDatabase.WriteImportSettingsIfDirty(assetPath); - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - } - } - - public static void ExtractAssets(this ScriptedImporter importer, string dirName, string extension) where T : UnityEngine.Object - { - if (string.IsNullOrEmpty(importer.assetPath)) - return; - - var subAssets = importer.GetSubAssets(importer.assetPath); - - var path = string.Format("{0}/{1}.{2}", - Path.GetDirectoryName(importer.assetPath), - Path.GetFileNameWithoutExtension(importer.assetPath), - dirName - ); - - var info = importer.SafeCreateDirectory(path); - - foreach (var asset in subAssets) - { - ExtractFromAsset(asset, string.Format("{0}/{1}{2}", path, asset.name, extension), false); - } - } - - - public static void ExtractTextures(this ScriptedImporter importer, string dirName, Func CreateModel, Action onComplited = null) - { - if (string.IsNullOrEmpty(importer.assetPath)) - return; - - var subAssets = importer.GetSubAssets(importer.assetPath); - - var path = string.Format("{0}/{1}.{2}", - Path.GetDirectoryName(importer.assetPath), - Path.GetFileNameWithoutExtension(importer.assetPath), - dirName - ); - - importer.SafeCreateDirectory(path); - - Dictionary targetPaths = new Dictionary(); - - // Reload Model - var model = CreateModel(importer.assetPath); - var mimeTypeReg = new System.Text.RegularExpressions.Regex("image/(?.*)$"); - int count = 0; - foreach (var texture in model.Textures) - { - var imageTexture = texture as VrmLib.ImageTexture; - if (imageTexture == null) continue; - - var mimeType = mimeTypeReg.Match(imageTexture.Image.MimeType); - var assetName = !string.IsNullOrEmpty(imageTexture.Name) ? imageTexture.Name : string.Format("{0}_img{1}", model.Root.Name, count); - var targetPath = string.Format("{0}/{1}.{2}", - path, - assetName, - mimeType.Groups["mime"].Value); - imageTexture.Name = assetName; - - if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.MetallicRoughness - || imageTexture.TextureType == VrmLib.Texture.TextureTypes.Occlusion) + loader.TransferOwnership(o => { - var subAssetTexture = subAssets.Where(x => x.name == imageTexture.Name).FirstOrDefault(); - File.WriteAllBytes(targetPath, subAssetTexture.EncodeToPNG()); - } - else - { - File.WriteAllBytes(targetPath, imageTexture.Image.Bytes.ToArray()); - } +#if VRM_DEVELOP + Debug.Log($"[{o.GetType().Name}] {o.name} will not destroy"); +#endif - AssetDatabase.ImportAsset(targetPath); - targetPaths.Add(imageTexture, targetPath); - - count++; - } - - EditorApplication.delayCall += () => - { - foreach (var targetPath in targetPaths) - { - var imageTexture = targetPath.Key; - var targetTextureImporter = AssetImporter.GetAtPath(targetPath.Value) as TextureImporter; - targetTextureImporter.sRGBTexture = (imageTexture.ColorSpace == VrmLib.Texture.ColorSpaceTypes.Srgb); - if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.NormalMap) + context.AddObjectToAsset(o.name, o); + if (o is GameObject) { - targetTextureImporter.textureType = TextureImporterType.NormalMap; + // Root GameObject is main object + context.SetMainObject(loader.Root); } - targetTextureImporter.SaveAndReimport(); - var externalObject = AssetDatabase.LoadAssetAtPath(targetPath.Value, typeof(UnityEngine.Texture2D)); - importer.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), imageTexture.Name), externalObject); - } - - //AssetDatabase.WriteImportSettingsIfDirty(assetPath); - AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); - - if (onComplited != null) - { - onComplited(); - } - }; - } - - public static DirectoryInfo SafeCreateDirectory(this ScriptedImporter importer, string path) - { - if (Directory.Exists(path)) - { - return null; + return true; + }); } - return Directory.CreateDirectory(path); } + + // try + // { + // // Create Vrm Model + // VrmLib.Model model = VrmLoader.CreateVrmModel(parser); + // if (model == null) + // { + // // maybe VRM-0.X + // return; + // } + // Debug.Log($"VrmLoader.CreateVrmModel: {model}"); + + // // Build Unity Model + // var assets = EditorUnityBuilder.ToUnityAsset(model, assetPath, this); + // ComponentBuilder.Build10(model, assets); + + // // Texture + // var externalTextures = this.GetExternalUnityObjects(); + // foreach (var texture in assets.Textures) + // { + // if (texture == null) + // continue; + + // if (externalTextures.ContainsValue(texture)) + // { + // } + // else + // { + // ctx.AddObjectToAsset(texture.name, texture); + // } + // } + + // // Material + // var externalMaterials = this.GetExternalUnityObjects(); + // foreach (var material in assets.Materials) + // { + // if (material == null) + // continue; + + // if (externalMaterials.ContainsValue(material)) + // { + + // } + // else + // { + // ctx.AddObjectToAsset(material.name, material); + // } + // } + + // // Mesh + // foreach (var mesh in assets.Meshes) + // { + // ctx.AddObjectToAsset(mesh.name, mesh); + // } + + // //// ScriptableObject + // // avatar + // ctx.AddObjectToAsset("avatar", assets.HumanoidAvatar); + + // // meta + // { + // var external = this.GetExternalUnityObjects().FirstOrDefault(); + // if (external.Value != null) + // { + // var controller = assets.Root.GetComponent(); + // if (controller != null) + // { + // controller.Meta = external.Value; + // } + // } + // else + // { + // var meta = assets.ScriptableObjects + // .FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10MetaObject)) as UniVRM10.VRM10MetaObject; + // if (meta != null) + // { + // meta.name = "meta"; + // ctx.AddObjectToAsset(meta.name, meta); + // } + // } + // } + + // // expression + // { + // var external = this.GetExternalUnityObjects(); + // if (external.Any()) + // { + // } + // else + // { + // var expression = assets.ScriptableObjects + // .Where(x => x.GetType() == typeof(UniVRM10.VRM10Expression)) + // .Select(x => x as UniVRM10.VRM10Expression); + // foreach (var clip in expression) + // { + // clip.name = clip.ExpressionName; + // ctx.AddObjectToAsset(clip.ExpressionName, clip); + // } + // } + // } + // { + // var external = this.GetExternalUnityObjects().FirstOrDefault(); + // if (external.Value != null) + // { + // var controller = assets.Root.GetComponent(); + // if (controller != null) + // { + // controller.Expression.ExpressionAvatar = external.Value; + // } + // } + // else + // { + // var expressionAvatar = assets.ScriptableObjects + // .FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10ExpressionAvatar)) as UniVRM10.VRM10ExpressionAvatar; + // if (expressionAvatar != null) + // { + // expressionAvatar.name = "expressionAvatar"; + // ctx.AddObjectToAsset(expressionAvatar.name, expressionAvatar); + // } + // } + // } + + // // Root + // ctx.AddObjectToAsset(assets.Root.name, assets.Root); + // ctx.SetMainObject(assets.Root); + + // } + // catch (System.Exception ex) + // { + // Debug.LogError(ex); + // } + + + // public void ExtractTextures() + // { + // this.ExtractTextures(TextureDirName, (path) => + // { + // var parser = new UniGLTF.GltfParser(); + // parser.ParsePath(path); + // return VrmLoader.CreateVrmModel(parser); + // }); + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public void ExtractMaterials() + // { + // this.ExtractAssets(MaterialDirName, ".mat"); + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public void ExtractMaterialsAndTextures() + // { + // this.ExtractTextures(TextureDirName, (path) => + // { + // var parser = new UniGLTF.GltfParser(); + // parser.ParsePath(path); + // return VrmLoader.CreateVrmModel(parser); + // }, () => + // { + // this.ExtractAssets(MaterialDirName, ".mat"); + // }); + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public void ExtractMeta() + // { + // this.ExtractAssets(MetaDirName, ".asset"); + // var metaObject = this.GetExternalUnityObjects().FirstOrDefault(); + // var metaObjectPath = AssetDatabase.GetAssetPath(metaObject.Value); + // if (!string.IsNullOrEmpty(metaObjectPath)) + // { + // EditorUtility.SetDirty(metaObject.Value); + // AssetDatabase.WriteImportSettingsIfDirty(metaObjectPath); + // } + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public void ExtractExpressions() + // { + // this.ExtractAssets(ExpressionDirName, ".asset"); + // this.ExtractAssets(ExpressionDirName, ".asset"); + + // var expressionAvatar = this.GetExternalUnityObjects().FirstOrDefault(); + // var expressions = this.GetExternalUnityObjects(); + + // expressionAvatar.Value.Clips = expressions.Select(x => x.Value).ToList(); + // var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar.Value); + // if (!string.IsNullOrEmpty(avatarPath)) + // { + // EditorUtility.SetDirty(expressionAvatar.Value); + // AssetDatabase.WriteImportSettingsIfDirty(avatarPath); + // } + + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public Dictionary GetExternalUnityObjects() where T : UnityEngine.Object + // { + // return this.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)).ToDictionary(x => x.Key.name, x => (T)x.Value); + // } + + // public void SetExternalUnityObject(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object + // { + // this.AddRemap(sourceAssetIdentifier, obj); + // AssetDatabase.WriteImportSettingsIfDirty(this.assetPath); + // AssetDatabase.ImportAsset(this.assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public static void ClearExternalObjects(this ScriptedImporter importer) where T : UnityEngine.Object + // { + // foreach (var extarnalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T))) + // { + // importer.RemoveRemap(extarnalObject.Key); + // } + + // AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); + // AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); + // } + + // public static void ClearExtarnalObjects(this ScriptedImporter importer) + // { + // foreach (var extarnalObject in importer.GetExternalObjectMap()) + // { + // importer.RemoveRemap(extarnalObject.Key); + // } + + // AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); + // AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); + // } + + // private static T GetSubAsset(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object + // { + // return importer.GetSubAssets(assetPath) + // .FirstOrDefault(); + // } + + // public static IEnumerable GetSubAssets(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object + // { + // return AssetDatabase + // .LoadAllAssetsAtPath(assetPath) + // .Where(x => AssetDatabase.IsSubAsset(x)) + // .Where(x => x is T) + // .Select(x => x as T); + // } + + // private static void ExtractFromAsset(UnityEngine.Object subAsset, string destinationPath, bool isForceUpdate) + // { + // string assetPath = AssetDatabase.GetAssetPath(subAsset); + + // var clone = UnityEngine.Object.Instantiate(subAsset); + // AssetDatabase.CreateAsset(clone, destinationPath); + + // var assetImporter = AssetImporter.GetAtPath(assetPath); + // assetImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(subAsset), clone); + + // if (isForceUpdate) + // { + // AssetDatabase.WriteImportSettingsIfDirty(assetPath); + // AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + // } + // } + + // public static void ExtractAssets(this ScriptedImporter importer, string dirName, string extension) where T : UnityEngine.Object + // { + // if (string.IsNullOrEmpty(importer.assetPath)) + // return; + + // var subAssets = importer.GetSubAssets(importer.assetPath); + + // var path = string.Format("{0}/{1}.{2}", + // Path.GetDirectoryName(importer.assetPath), + // Path.GetFileNameWithoutExtension(importer.assetPath), + // dirName + // ); + + // var info = importer.SafeCreateDirectory(path); + + // foreach (var asset in subAssets) + // { + // ExtractFromAsset(asset, string.Format("{0}/{1}{2}", path, asset.name, extension), false); + // } + // } + + + // public static void ExtractTextures(this ScriptedImporter importer, string dirName, Func CreateModel, Action onComplited = null) + // { + // if (string.IsNullOrEmpty(importer.assetPath)) + // return; + + // var subAssets = importer.GetSubAssets(importer.assetPath); + + // var path = string.Format("{0}/{1}.{2}", + // Path.GetDirectoryName(importer.assetPath), + // Path.GetFileNameWithoutExtension(importer.assetPath), + // dirName + // ); + + // importer.SafeCreateDirectory(path); + + // Dictionary targetPaths = new Dictionary(); + + // // Reload Model + // var model = CreateModel(importer.assetPath); + // var mimeTypeReg = new System.Text.RegularExpressions.Regex("image/(?.*)$"); + // int count = 0; + // foreach (var texture in model.Textures) + // { + // var imageTexture = texture as VrmLib.ImageTexture; + // if (imageTexture == null) continue; + + // var mimeType = mimeTypeReg.Match(imageTexture.Image.MimeType); + // var assetName = !string.IsNullOrEmpty(imageTexture.Name) ? imageTexture.Name : string.Format("{0}_img{1}", model.Root.Name, count); + // var targetPath = string.Format("{0}/{1}.{2}", + // path, + // assetName, + // mimeType.Groups["mime"].Value); + // imageTexture.Name = assetName; + + // if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.MetallicRoughness + // || imageTexture.TextureType == VrmLib.Texture.TextureTypes.Occlusion) + // { + // var subAssetTexture = subAssets.Where(x => x.name == imageTexture.Name).FirstOrDefault(); + // File.WriteAllBytes(targetPath, subAssetTexture.EncodeToPNG()); + // } + // else + // { + // File.WriteAllBytes(targetPath, imageTexture.Image.Bytes.ToArray()); + // } + + // AssetDatabase.ImportAsset(targetPath); + // targetPaths.Add(imageTexture, targetPath); + + // count++; + // } + + // EditorApplication.delayCall += () => + // { + // foreach (var targetPath in targetPaths) + // { + // var imageTexture = targetPath.Key; + // var targetTextureImporter = AssetImporter.GetAtPath(targetPath.Value) as TextureImporter; + // targetTextureImporter.sRGBTexture = (imageTexture.ColorSpace == VrmLib.Texture.ColorSpaceTypes.Srgb); + // if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.NormalMap) + // { + // targetTextureImporter.textureType = TextureImporterType.NormalMap; + // } + // targetTextureImporter.SaveAndReimport(); + + // var externalObject = AssetDatabase.LoadAssetAtPath(targetPath.Value, typeof(UnityEngine.Texture2D)); + // importer.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), imageTexture.Name), externalObject); + // } + + // //AssetDatabase.WriteImportSettingsIfDirty(assetPath); + // AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); + + // if (onComplited != null) + // { + // onComplited(); + // } + // }; + // } + + // public static DirectoryInfo SafeCreateDirectory(this ScriptedImporter importer, string path) + // { + // if (Directory.Exists(path)) + // { + // return null; + // } + // return Directory.CreateDirectory(path); + // } } } \ No newline at end of file diff --git a/Assets/VRM10/Runtime/UnityBuilder/RuntimeUnityBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/RuntimeUnityBuilder.cs index 70286a348..4eb3f2673 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/RuntimeUnityBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/RuntimeUnityBuilder.cs @@ -29,7 +29,7 @@ namespace UniVRM10 m_model = VrmLoader.CreateVrmModel(parser); // for `VRMC_materials_mtoon` - this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, VrmMToonMaterialImporter.TryCreateParam); + // this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, VrmMToonMaterialImporter.TryCreateParam); } /// @@ -59,6 +59,11 @@ namespace UniVRM10 mesh.LoadMesh(src.Meshes[0], src.Skin); m_asset.Map.Meshes.Add(src, mesh); m_asset.Meshes.Add(mesh); + Meshes.Add(new MeshWithMaterials + { + Mesh = mesh, + Materials = src.Meshes[0].Submeshes.Select(x => m_asset.Map.Materials[x.Material]).ToArray(), + }); } else { @@ -69,6 +74,21 @@ namespace UniVRM10 // node: recursive CreateNodes(m_model.Root, null, m_asset.Map.Nodes); + + if (Root == null) + { + Root = m_asset.Map.Nodes[m_model.Root]; + } + else + { + // replace + var modelRoot = m_asset.Map.Nodes[m_model.Root]; + foreach (Transform child in modelRoot.transform) + { + child.SetParent(Root.transform, true); + } + m_asset.Map.Nodes[m_model.Root] = Root; + } m_asset.Root = m_asset.Map.Nodes[m_model.Root]; // renderer