diff --git a/Assets/UniGLTF/Editor/EditorImporterContext.cs b/Assets/UniGLTF/Editor/EditorImporterContext.cs deleted file mode 100644 index 33197de02..000000000 --- a/Assets/UniGLTF/Editor/EditorImporterContext.cs +++ /dev/null @@ -1,249 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEngine; - - -namespace UniGLTF -{ - /// - /// Editor で Asset 化する場合専用 - /// - /// GameObject を prefab 化するので、prefab の元になった GameObject は破棄対象となる。 - /// - /// - public class EditorImporterContext : IDisposable - { - ImporterContext m_context; - - public EditorImporterContext(ImporterContext context) - { - m_context = context; - } - - public void Dispose() - { - m_context.Dispose(); - - if (m_context.Root != null) - { - // Destroy the GameObject that became the basis of Prefab - GameObject.DestroyImmediate(m_context.Root); - } - } - - public virtual IEnumerable ObjectsForSubAsset() - { - foreach (var x in m_context.TextureFactory.ObjectsForSubAsset()) - { - yield return x; - } - foreach (var x in m_context.MaterialFactory.ObjectsForSubAsset()) - { - yield return x; - } - foreach (var x in m_context.Meshes) { yield return x.Mesh; } - foreach (var x in m_context.AnimationClips) { yield return x; } - } - - /// - /// Destroy assets that created ImporterContext. This function is clean up for importer error. - /// - public virtual void EditorDestroyRootAndAssets() - { - // Remove hierarchy - if (m_context.Root != null) GameObject.DestroyImmediate(m_context.Root); - - // Remove resources. materials, textures meshes etc... - foreach (var o in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(o, true); - } - } - - public virtual UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o, bool meshAsSubAsset) - { - if (o is Material) - { - var materialDir = prefabPath.GetAssetFolder(".Materials"); - var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); - return materialPath; - } - else if (o is Texture2D) - { - var textureDir = prefabPath.GetAssetFolder(".Textures"); - var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); - return texturePath; - } - else if (o is Mesh && !meshAsSubAsset) - { - var meshDir = prefabPath.GetAssetFolder(".Meshes"); - var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); - return meshPath; - } - else - { - return default(UnityPath); - } - } - - public virtual bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) - { - if (o is Material) - { - var loaded = assetPath.LoadAsset(); - - // replace component reference - foreach (var mesh in m_context.Meshes) - { - foreach (var r in mesh.Renderers) - { - for (int i = 0; i < r.sharedMaterials.Length; ++i) - { - if (r.sharedMaterials.Contains(o)) - { - r.sharedMaterials = r.sharedMaterials.Select(x => x == o ? loaded : x).ToArray(); - } - } - } - } - - return true; - } - - return false; - } - - public void SaveAsAsset(UnityPath prefabPath, bool meshAsSubAsset = false) - { - m_context.ShowMeshes(); - - //var prefabPath = PrefabPath; - if (prefabPath.IsFileExists) - { - // clear SubAssets - foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) - { - GameObject.DestroyImmediate(x, true); - } - } - - // - // save sub assets - // - var paths = new List(){ - prefabPath - }; - foreach (var o in ObjectsForSubAsset()) - { - if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o))) - { - // already exists - continue; - } - - var assetPath = GetAssetPath(prefabPath, o, meshAsSubAsset); - if (!assetPath.IsNull) - { - if (assetPath.IsFileExists) - { - if (AvoidOverwriteAndLoad(assetPath, o)) - { - // 上書きせずに既存のアセットからロードして置き換えた - continue; - } - } - - // アセットとして書き込む - assetPath.Parent.EnsureFolder(); - assetPath.CreateAsset(o); - paths.Add(assetPath); - } - else - { - // save as subasset - prefabPath.AddObjectToAsset(o); - } - } - - // Create or update Main Asset - if (prefabPath.IsFileExists) - { - Debug.LogFormat("replace prefab: {0}", prefabPath); - var prefab = prefabPath.LoadAsset(); -#if UNITY_2018_3_OR_NEWER - PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, prefabPath.Value, InteractionMode.AutomatedAction); -#else - PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased); -#endif - - } - else - { - Debug.LogFormat("create prefab: {0}", prefabPath); -#if UNITY_2018_3_OR_NEWER - PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, prefabPath.Value, InteractionMode.AutomatedAction); -#else - PrefabUtility.CreatePrefab(prefabPath.Value, Root); -#endif - } - foreach (var x in paths) - { - x.ImportAsset(); - } - } - - /// - /// Extract images from glb or gltf out of Assets folder. - /// - /// - public void ExtractImages(UnityPath prefabPath) - { - var prefabParentDir = prefabPath.Parent; - - // glb buffer - var folder = prefabPath.GetAssetFolder(".Textures"); - - // - // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html - // - int created = 0; - for (int i = 0; i < m_context.GLTF.textures.Count; ++i) - { - folder.EnsureFolder(); - - var gltfTexture = m_context.GLTF.textures[i]; - var gltfImage = m_context.GLTF.images[gltfTexture.source]; - var src = m_context.Storage.GetPath(gltfImage.uri); - if (UnityPath.FromFullpath(src).IsUnderAssetsFolder) - { - // asset is exists. - } - else - { - var byteSegment = m_context.GLTF.GetImageBytes(m_context.Storage, gltfTexture.source); - var textureName = gltfTexture.name; - - // path - var dst = folder.Child(textureName + gltfImage.GetExt()); - File.WriteAllBytes(dst.FullPath, byteSegment.ToArray()); - dst.ImportAsset(); - - // make relative path from PrefabParentDir - gltfImage.uri = dst.Value.Substring(prefabParentDir.Value.Length + 1); - ++created; - } - } - - if (created > 0) - { - AssetDatabase.Refresh(); - } - - // texture will load from assets - m_context.TextureFactory.ImageBaseDir = prefabParentDir; - } - } -} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs b/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs deleted file mode 100644 index 30d799abc..000000000 --- a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if false -using System.IO; -using UnityEditor; -using UnityEngine; - - -namespace UniGLTF -{ - public static class ImporterMenu - { - [MenuItem(UniGLTFVersion.MENU + "/Import(gltf, glb)", priority = 20)] - public static void ImportMenu() - { - var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb"); - if (string.IsNullOrEmpty(path)) - { - return; - } - - if (Application.isPlaying) - { - // - // load into scene - // - var parser = new GltfParser(); - parser.ParsePath(path); - var context = new ImporterContext(parser); - context.Load(); - context.ShowMeshes(); - Selection.activeGameObject = context.Root; - } - else - { - // - // save as asset - // - if (path.StartsWithUnityAssetPath()) - { - Debug.LogWarningFormat("disallow import from folder under the Assets"); - return; - } - - var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab"); - if (string.IsNullOrEmpty(path)) - { - return; - } - - // import as asset - gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath)); - } - } - } -} -#endif \ No newline at end of file diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs new file mode 100644 index 000000000..821939c3d --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace UniGLTF +{ + public static class EditorAnimation + { + public static void OnGUIAnimation(GltfParser parser) + { + for (int i = 0; i < parser.GLTF.animations.Count; ++i) + { + var a = parser.GLTF.animations[i]; + GUILayout.Label($"{i}: {a.name}"); + } + } + } +} diff --git a/Assets/UniGLTF/Editor/EditorImporterContext.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs.meta similarity index 83% rename from Assets/UniGLTF/Editor/EditorImporterContext.cs.meta rename to Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs.meta index bb14f8f6b..c426102d8 100644 --- a/Assets/UniGLTF/Editor/EditorImporterContext.cs.meta +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorAnimation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1c496f43ae12f9041a16af0489727587 +guid: 005298fbae4759b4896174bb6e129e9d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs new file mode 100644 index 000000000..294b875a7 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + +namespace UniGLTF +{ + public static class EditorMaterial + { + class TmpGuiEnable : IDisposable + { + bool m_backup; + public TmpGuiEnable(bool enable) + { + m_backup = GUI.enabled; + GUI.enabled = enable; + } + + public void Dispose() + { + GUI.enabled = m_backup; + } + } + + static bool s_foldMaterials; + static bool s_foldTextures; + + public static void OnGUIMaterial(ScriptedImporter importer, GltfParser parser) + { + var canExtract = !importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); + using (new TmpGuiEnable(canExtract)) + { + if (GUILayout.Button("Extract Materials And Textures ...")) + { + ExtractMaterialsAndTextures(importer); + } + } + + // + // Draw ExternalObjectMap + // + s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); + if (s_foldMaterials) + { + DrawRemapGUI(importer, parser.GLTF.materials.Select(x => x.name)); + } + + s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); + if (s_foldTextures) + { + DrawRemapGUI(importer, parser.EnumerateTextures().Select(x => x.ConvertedName)); + } + + if (GUILayout.Button("Clear")) + { + importer.ClearExternalObjects(); + importer.ClearExternalObjects(); + } + } + + static void DrawRemapGUI(ScriptedImporter importer, IEnumerable names) where T : UnityEngine.Object + { + EditorGUI.indentLevel++; + var map = importer.GetExternalObjectMap() + .Select(x => (x.Key.name, x.Value as T)) + .Where(x => x.Item2 != null) + .ToDictionary(x => x.Item1, x => x.Item2) + ; + foreach (var name in names) + { + if (string.IsNullOrEmpty(name)) + { + throw new System.ArgumentNullException(); + } + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel(name); + map.TryGetValue(name, out T value); + var asset = EditorGUILayout.ObjectField(value, typeof(T), true) as T; + if (asset != value) + { + importer.SetExternalUnityObject(new AssetImporter.SourceAssetIdentifier(value), asset); + } + EditorGUILayout.EndHorizontal(); + } + EditorGUI.indentLevel--; + } + + public static void SetExternalUnityObject(this ScriptedImporter self, UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object + { + self.AddRemap(sourceAssetIdentifier, obj); + AssetDatabase.WriteImportSettingsIfDirty(self.assetPath); + AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate); + } + + static void ExtractMaterialsAndTextures(ScriptedImporter self) + { + if (string.IsNullOrEmpty(self.assetPath)) + { + return; + } + + Action addRemap = externalObject => + { + self.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject); + }; + Action> onCompleted = _ => + { + AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate); + self.ExtractMaterials(); + AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate); + }; + + TextureExtractor.ExtractTextures(self.assetPath, + self.GetSubAssets(self.assetPath).ToArray(), + addRemap, + onCompleted + ); + } + + public static void ExtractMaterials(this ScriptedImporter importer) + { + if (string.IsNullOrEmpty(importer.assetPath)) + { + return; + } + var path = $"{Path.GetDirectoryName(importer.assetPath)}/{Path.GetFileNameWithoutExtension(importer.assetPath)}.Materials"; + var info = TextureExtractor.SafeCreateDirectory(path); + + foreach (var asset in importer.GetSubAssets(importer.assetPath)) + { + ExtractSubAsset(asset, $"{path}/{asset.name}.mat", false); + } + } + + private static void ExtractSubAsset(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(clone), clone); + + if (isForceUpdate) + { + AssetDatabase.WriteImportSettingsIfDirty(assetPath); + AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); + } + } + } +} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs.meta similarity index 71% rename from Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs.meta rename to Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs.meta index 47d70b596..ae9423568 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs.meta +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs.meta @@ -1,7 +1,5 @@ fileFormatVersion: 2 -guid: ae2833922b06981439883d1e924b4cd0 -timeCreated: 1517153624 -licenseType: Free +guid: d87d4a592573eb048916575e202af37f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs new file mode 100644 index 000000000..ae92a0387 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs @@ -0,0 +1,25 @@ +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + + +namespace UniGLTF +{ + [ScriptedImporter(1, "glb")] + public class GlbScriptedImporter : ScriptedImporter + { + [SerializeField] + Axises m_reverseAxis = default; + + public override void OnImportAsset(AssetImportContext ctx) + { + try + { + ScriptedImporterImpl.Import(this, ctx, m_reverseAxis); + } + catch (System.Exception ex) + { + Debug.LogError(ex); + } + } + } +} diff --git a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs.meta similarity index 69% rename from Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs.meta rename to Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs.meta index bf1323947..7866ddd3f 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs.meta +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporter.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 7bbb264b34e75dd438622e1f29f0f46c -timeCreated: 1517119659 -licenseType: Free +guid: cc45016b844e7624dae3aec10fb443ea MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs new file mode 100644 index 000000000..fb1b4634b --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs @@ -0,0 +1,49 @@ +using UnityEditor; +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + +namespace UniGLTF +{ + [CustomEditor(typeof(GlbScriptedImporter))] + public class GlbScriptedImporterEditorGUI : ScriptedImporterEditor + { + GlbScriptedImporter m_importer; + GltfParser m_parser; + + public override void OnEnable() + { + m_importer = target as GlbScriptedImporter; + m_parser = new GltfParser(); + m_parser.ParsePath(m_importer.assetPath); + } + + enum Tabs + { + Model, + Animation, + Materials, + } + static Tabs s_currentTab; + + public override void OnInspectorGUI() + { + s_currentTab = MeshUtility.TabBar.OnGUI(s_currentTab); + GUILayout.Space(10); + + switch (s_currentTab) + { + case Tabs.Model: + base.OnInspectorGUI(); + break; + + case Tabs.Animation: + EditorAnimation.OnGUIAnimation(m_parser); + break; + + case Tabs.Materials: + EditorMaterial.OnGUIMaterial(m_importer, m_parser); + break; + } + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs.meta similarity index 69% rename from Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs.meta rename to Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs.meta index 1a21d6618..f20742643 100644 --- a/Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs.meta +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: ff15446e31b14ac409251c931b7c2038 -timeCreated: 1531893103 -licenseType: Free +guid: 706590752e82d004e99da97aff535f67 MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs index 5e1a9d151..fe4fc605b 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs @@ -1,102 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; using UnityEditor.Experimental.AssetImporters; using UnityEngine; namespace UniGLTF { - [ScriptedImporter(1, "glb")] + [ScriptedImporter(1, "gltf")] public class GltfScriptedImporter : ScriptedImporter { [SerializeField] Axises m_reverseAxis = default; - const string TextureDirName = "Textures"; - const string MaterialDirName = "Materials"; - public override void OnImportAsset(AssetImportContext ctx) { - Debug.Log("OnImportAsset to " + ctx.assetPath); - try { - // Parse - var parser = new GltfParser(); - parser.ParsePath(ctx.assetPath); - - // Build Unity Model - var externalObjectMap = GetExternalObjectMap() - .Select(kv => (kv.Key.name, kv.Value)) - ; - - var context = new ImporterContext(parser, null, externalObjectMap); - context.InvertAxis = m_reverseAxis; - context.Load(); - context.ShowMeshes(); - - // Texture - foreach (var info in context.TextureFactory.Textures) - { - if (!info.IsUsed) - { - continue; - } - if (!info.IsExternal) - { - var texture = info.Texture; - ctx.AddObjectToAsset(texture.name, texture); - } - } - - // Material - foreach (var info in context.MaterialFactory.Materials) - { - if (!info.UseExternal) - { - var material = info.Asset; - ctx.AddObjectToAsset(material.name, material); - } - } - - // Mesh - foreach (var mesh in context.Meshes.Select(x => x.Mesh)) - { - ctx.AddObjectToAsset(mesh.name, mesh); - } - - // Animation - foreach (var clip in context.AnimationClips) - { - ctx.AddObjectToAsset(clip.name, clip); - } - - // Root - ctx.AddObjectToAsset(context.Root.name, context.Root); - ctx.SetMainObject(context.Root); + ScriptedImporterImpl.Import(this, ctx, m_reverseAxis); } catch (System.Exception ex) { Debug.LogError(ex); } } - - public void ExtractMaterialsAndTextures() - { - this.ExtractTextures(TextureDirName, () => - { - this.ExtractAssets(MaterialDirName, ".mat"); - AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); - }); - } - - 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); - } } } diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs index 579ba7c36..b1c4723d5 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; using UnityEditor; using UnityEditor.Experimental.AssetImporters; using UnityEngine; @@ -40,98 +37,13 @@ namespace UniGLTF break; case Tabs.Animation: - OnGUIAnimation(m_importer, m_parser); + EditorAnimation.OnGUIAnimation(m_parser); break; case Tabs.Materials: - OnGUIMaterial(m_importer, m_parser); + EditorMaterial.OnGUIMaterial(m_importer, m_parser); break; } } - - static bool s_foldMaterials; - static bool s_foldTextures; - - class TmpGuiEnable : IDisposable - { - bool m_backup; - public TmpGuiEnable(bool enable) - { - m_backup = GUI.enabled; - GUI.enabled = enable; - } - - public void Dispose() - { - GUI.enabled = m_backup; - } - } - - static void OnGUIMaterial(GltfScriptedImporter importer, GltfParser parser) - { - var canExtract = !importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); - using (new TmpGuiEnable(canExtract)) - { - if (GUILayout.Button("Extract Materials And Textures ...")) - { - importer.ExtractMaterialsAndTextures(); - } - } - - // ObjectMap - s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); - if (s_foldMaterials) - { - DrawRemapGUI(importer, parser.GLTF.materials.Select(x => x.name)); - } - - s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); - if (s_foldTextures) - { - DrawRemapGUI(importer, parser.EnumerateTextures().Select(x => x.Name)); - } - - if (GUILayout.Button("Clear")) - { - importer.ClearExternalObjects(); - importer.ClearExternalObjects(); - } - } - - static void DrawRemapGUI(GltfScriptedImporter importer, IEnumerable names) where T : UnityEngine.Object - { - EditorGUI.indentLevel++; - var map = importer.GetExternalObjectMap() - .Select(x => (x.Key.name, x.Value as T)) - .Where(x => x.Item2 != null) - .ToDictionary(x => x.Item1, x => x.Item2) - ; - foreach (var name in names) - { - if (string.IsNullOrEmpty(name)) - { - throw new System.ArgumentNullException(); - } - - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel(name); - map.TryGetValue(name, out T value); - var asset = EditorGUILayout.ObjectField(value, typeof(T), true) as T; - if (asset != value) - { - importer.SetExternalUnityObject(new AssetImporter.SourceAssetIdentifier(value), asset); - } - EditorGUILayout.EndHorizontal(); - } - EditorGUI.indentLevel--; - } - - static void OnGUIAnimation(GltfScriptedImporter importer, GltfParser parser) - { - foreach (var a in parser.GLTF.animations) - { - GUILayout.Label(a.name); - } - } } } diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs.meta index f20742643..20e7e95c7 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs.meta +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 706590752e82d004e99da97aff535f67 +guid: 16c69c858a1da5e4088d72a546a2963e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterExtension.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterExtension.cs index c60524427..41f91f6df 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterExtension.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterExtension.cs @@ -3,9 +3,6 @@ using System.IO; using System.Linq; using UnityEditor.Experimental.AssetImporters; using UnityEditor; -using System; -using UnityEngine; -using System.Text.RegularExpressions; namespace UniGLTF { @@ -13,32 +10,15 @@ namespace UniGLTF { public static void ClearExternalObjects(this ScriptedImporter importer) where T : UnityEngine.Object { - foreach (var extarnalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T))) + foreach (var externalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T))) { - importer.RemoveRemap(extarnalObject.Key); + importer.RemoveRemap(externalObject.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 @@ -47,177 +27,5 @@ namespace UniGLTF .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); - } - } - - class TextureExtractor - { - GltfParser m_parser; - public GltfParser Parser => m_parser; - - public glTF GLTF => m_parser.GLTF; - public IStorage Storage => m_parser.Storage; - - public readonly Dictionary Textures = new Dictionary(); - UnityEngine.Texture2D[] m_subAssets; - string m_path; - - public TextureExtractor(ScriptedImporter importer) - { - // parse GLTF - m_parser = new GltfParser(); - m_parser.ParsePath(importer.assetPath); - - m_path = $"{Path.GetDirectoryName(importer.assetPath)}/{Path.GetFileNameWithoutExtension(importer.assetPath)}.Textures"; - m_subAssets = importer.GetSubAssets(importer.assetPath).ToArray(); - } - - static Regex s_mimeTypeReg = new Regex("image/(?.*)$"); - - public void Extract(GetTextureParam param) - { - var subAsset = m_subAssets.FirstOrDefault(x => x.name == param.Name); - string targetPath = ""; - - switch (param.TextureType) - { - case GetTextureParam.METALLIC_GLOSS_PROP: - case GetTextureParam.OCCLUSION_PROP: - { - // write converted texture - targetPath = string.Format("{0}/{1}{2}", - m_path, - param.Name, - ".png" - ); - File.WriteAllBytes(targetPath, subAsset.EncodeToPNG().ToArray()); - break; - } - - default: - { - // write original bytes - targetPath = string.Format("{0}/{1}{2}", - m_path, - param.Name, - ".png" - ); - var gltfTexture = GLTF.textures[param.Index0.Value]; - File.WriteAllBytes(targetPath, GLTF.GetImageBytes(Storage, gltfTexture.source).ToArray()); - break; - } - } - AssetDatabase.ImportAsset(targetPath); - Textures.Add(targetPath, param); - } - } - - public static void ExtractTextures(this ScriptedImporter importer, string dirName, Action onCompleted = null) - { - if (string.IsNullOrEmpty(importer.assetPath)) - { - return; - } - - var path = string.Format("{0}/{1}.{2}", - Path.GetDirectoryName(importer.assetPath), - Path.GetFileNameWithoutExtension(importer.assetPath), - dirName - ); - importer.SafeCreateDirectory(path); - - // Reload Model - var extractor = new TextureExtractor(importer); - - foreach (var material in extractor.GLTF.materials) - { - foreach (var x in extractor.Parser.EnumerateTextures(material)) - { - extractor.Extract(x); - } - } - - EditorApplication.delayCall += () => - { - foreach (var kv in extractor.Textures) - { - var targetPath = kv.Key; - var param = kv.Value; - - // TextureImporter - var targetTextureImporter = AssetImporter.GetAtPath(targetPath) as TextureImporter; - - switch (param.TextureType) - { - case GetTextureParam.OCCLUSION_PROP: - case GetTextureParam.METALLIC_GLOSS_PROP: - targetTextureImporter.sRGBTexture = false; - break; - - case GetTextureParam.NORMAL_PROP: - targetTextureImporter.textureType = TextureImporterType.NormalMap; - break; - } - - targetTextureImporter.SaveAndReimport(); - - // remap - var externalObject = AssetDatabase.LoadAssetAtPath(targetPath); - importer.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject); - } - - AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); - - if (onCompleted != null) - { - onCompleted(); - } - }; - } - - public static DirectoryInfo SafeCreateDirectory(this ScriptedImporter importer, string path) - { - if (Directory.Exists(path)) - { - return null; - } - return Directory.CreateDirectory(path); - } } } diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs new file mode 100644 index 000000000..0a93dff14 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + +namespace UniGLTF +{ + public static class ScriptedImporterImpl + { + /// + /// glb をパースして、UnityObject化、さらにAsset化する + /// + /// + /// + /// + public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axises reverseAxis) + { +#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(); + + using (var loaded = new ImporterContext(parser, null, + externalObjectMap.Where(x => x.Value != null).Select(x => (x.Value.name, x.Value)).Concat( + EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent)))) + { + loaded.InvertAxis = reverseAxis; + loaded.Load(); + loaded.ShowMeshes(); + + loaded.TransferOwnership(o => + { +#if VRM_DEVELOP + Debug.Log($"[{o.GetType().Name}] {o.name} will not destroy"); +#endif + + context.AddObjectToAsset(o.name, o); + if (o is GameObject) + { + // Root GameObject is main object + context.SetMainObject(loaded.Root); + } + + return true; + }); + } + } + + public static IEnumerable<(string, UnityEngine.Object)> EnumerateTexturesFromUri(Dictionary exclude, + GltfParser parser, UnityPath dir) + { + foreach (var texParam in parser.EnumerateTextures()) + { + switch (texParam.TextureType) + { + case GetTextureParam.METALLIC_GLOSS_PROP: + case GetTextureParam.OCCLUSION_PROP: + break; + + default: + { + var gltfTexture = parser.GLTF.textures.First(y => y.name == texParam.GltflName); + var gltfImage = parser.GLTF.images[gltfTexture.source]; + if (!string.IsNullOrEmpty(gltfImage.uri)) + { + var child = dir.Child(gltfImage.uri); + var asset = AssetDatabase.LoadAssetAtPath(child.Value); + if (asset == null) + { + throw new System.IO.FileNotFoundException($"{child}"); + } + // Debug.Log($"exists: {child}: {asset}"); + if (exclude == null || !exclude.Any(kv => kv.Value.name == asset.name)) + { + yield return (asset.name, asset); + } + } + } + break; + } + } + } + } +} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs.meta new file mode 100644 index 000000000..0581f26f1 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85bf14b48ed135743828ee49a830b1c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs new file mode 100644 index 000000000..64db7ab81 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using UnityEditor; +using System.Linq; + +namespace UniGLTF +{ + public class TextureExtractor + { + const string TextureDirName = "Textures"; + + GltfParser m_parser; + public GltfParser Parser => m_parser; + + public glTF GLTF => m_parser.GLTF; + public IStorage Storage => m_parser.Storage; + + public readonly Dictionary Textures = new Dictionary(); + UnityEngine.Texture2D[] m_subAssets; + string m_path; + + public TextureExtractor(string assetPath, UnityEngine.Texture2D[] subAssets) + { + // parse GLTF + m_parser = new GltfParser(); + m_parser.ParsePath(assetPath); + + m_path = $"{Path.GetDirectoryName(assetPath)}/{Path.GetFileNameWithoutExtension(assetPath)}.Textures"; + SafeCreateDirectory(m_path); + + if (assetPath == null) + { + throw new ArgumentNullException(); + } + m_subAssets = subAssets; + } + + public static string GetExt(string mime, string uri) + { + switch (mime) + { + case "image/png": return ".png"; + case "image/jpeg": return ".jpg"; + } + + return Path.GetExtension(uri).ToLower(); + } + + public void Extract(GetTextureParam param, bool hasUri) + { + if (Textures.Values.Contains(param)) + { + return; + } + + var subAsset = m_subAssets.FirstOrDefault(x => x.name == param.ConvertedName); + string targetPath = ""; + + if (hasUri && !param.ExtractConverted) + { + var gltfTexture = GLTF.textures[param.Index0.Value]; + var gltfImage = GLTF.images[gltfTexture.source]; + var ext = GetExt(gltfImage.mimeType, gltfImage.uri); + targetPath = $"{Path.GetDirectoryName(m_path)}/{param.GltflName}{ext}"; + } + else + { + + switch (param.TextureType) + { + case GetTextureParam.METALLIC_GLOSS_PROP: + case GetTextureParam.OCCLUSION_PROP: + { + // write converted texture + targetPath = $"{m_path}/{param.ConvertedName}.png"; + File.WriteAllBytes(targetPath, subAsset.EncodeToPNG().ToArray()); + AssetDatabase.ImportAsset(targetPath); + break; + } + + default: + { + // write original bytes + var gltfTexture = GLTF.textures[param.Index0.Value]; + var gltfImage = GLTF.images[gltfTexture.source]; + var ext = GetExt(gltfImage.mimeType, gltfImage.uri); + targetPath = $"{m_path}/{param.GltflName}{ext}"; + File.WriteAllBytes(targetPath, GLTF.GetImageBytes(Storage, gltfTexture.source).ToArray()); + AssetDatabase.ImportAsset(targetPath); + break; + } + } + } + + Textures.Add(targetPath, param); + } + + public static DirectoryInfo SafeCreateDirectory(string path) + { + if (Directory.Exists(path)) + { + return null; + } + return Directory.CreateDirectory(path); + } + + /// + /// + /// * Texture(.png etc...)をディスクに書き出す + /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ + /// * 書き出した Asset から TextureImporter を取得して設定する + /// + /// + /// + /// + /// + public static void ExtractTextures(string assetPath, Texture2D[] subAssets, Action addRemap, Action> onCompleted = null) + { + var extractor = new TextureExtractor(assetPath, subAssets); + var normalMaps = new List(); + foreach (var material in extractor.GLTF.materials) + { + foreach (var x in extractor.Parser.EnumerateTextures(material)) + { + var gltfTexture = extractor.GLTF.textures[x.Index0.Value]; + var gltfImage = extractor.GLTF.images[gltfTexture.source]; + extractor.Extract(x, !string.IsNullOrEmpty(gltfImage.uri)); + } + } + + EditorApplication.delayCall += () => + { + foreach (var kv in extractor.Textures) + { + var targetPath = kv.Key; + var param = kv.Value; + + // TextureImporter + var targetTextureImporter = AssetImporter.GetAtPath(targetPath) as TextureImporter; + if (targetTextureImporter != null) + { + switch (param.TextureType) + { + case GetTextureParam.OCCLUSION_PROP: + case GetTextureParam.METALLIC_GLOSS_PROP: +#if VRM_DEVELOP + Debug.Log($"{targetPath} => linear"); +#endif + targetTextureImporter.sRGBTexture = false; + targetTextureImporter.SaveAndReimport(); + break; + + case GetTextureParam.NORMAL_PROP: +#if VRM_DEVELOP + Debug.Log($"{targetPath} => normalmap"); +#endif + targetTextureImporter.textureType = TextureImporterType.NormalMap; + targetTextureImporter.SaveAndReimport(); + break; + } + } + else + { + throw new FileNotFoundException(targetPath); + } + + // remap + var externalObject = AssetDatabase.LoadAssetAtPath(targetPath); + if (externalObject != null) + { + addRemap(externalObject); + } + } + + if (onCompleted != null) + { + onCompleted(extractor.Textures.Keys); + } + }; + } + } +} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs.meta new file mode 100644 index 000000000..503d37228 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 556e0ca7f0824e44b9000d04e0e9914c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs b/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs deleted file mode 100644 index e12c8b02c..000000000 --- a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs +++ /dev/null @@ -1,89 +0,0 @@ -#if false -using System; -using System.IO; -using UnityEditor; -using UnityEngine; - - -namespace UniGLTF -{ - public class gltfAssetPostprocessor : AssetPostprocessor - { - static void OnPostprocessAllAssets(string[] importedAssets, - string[] deletedAssets, - string[] movedAssets, - string[] movedFromAssetPaths) - { - foreach (string path in importedAssets) - { - if (UnityPath.FromUnityPath(path).IsStreamingAsset) - { - Debug.LogFormat("Skip StreamingAssets: {0}", path); - continue; - } - - var ext = Path.GetExtension(path).ToLower(); - switch (ext) - { - case ".gltf": - case ".glb": - { - var gltfPath = UnityPath.FromUnityPath(path); - var prefabPath = gltfPath.Parent.Child(gltfPath.FileNameWithoutExtension + ".prefab"); - ImportAsset(UnityPath.FromUnityPath(path).FullPath, ext, prefabPath); - break; - } - } - } - } - - public static void ImportAsset(string src, string ext, UnityPath prefabPath) - { - if (!prefabPath.IsUnderAssetsFolder) - { - Debug.LogWarningFormat("out of asset path: {0}", prefabPath); - return; - } - - var parser = new GltfParser(); - parser.ParsePath(src); - var context = new ImporterContext(parser); - - // Extract textures to assets folder - context.ExtractImages(prefabPath); - - ImportDelayed(src, prefabPath, context); - } - - static void ImportDelayed(string src, UnityPath prefabPath, ImporterContext context) - { - EditorApplication.delayCall += () => - { - // - // After textures imported(To ensure TextureImporter be accessible). - // - try - { - context.Load(); - context.SaveAsAsset(prefabPath); - context.EditorDestroyRoot(); - } - catch (UniGLTFNotSupportedException ex) - { - Debug.LogWarningFormat("{0}: {1}", - src, - ex.Message - ); - context.EditorDestroyRootAndAssets(); - } - catch (Exception ex) - { - Debug.LogErrorFormat("import error: {0}", src); - Debug.LogErrorFormat("{0}", ex); - context.EditorDestroyRootAndAssets(); - } - }; - } - } -} -#endif \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs index 63d352b11..92b5445cf 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs @@ -229,13 +229,20 @@ namespace UniGLTF for (int i = 0; i < GLTF.textures.Count; ++i) { var gltfTexture = GLTF.textures[i]; - if (string.IsNullOrEmpty(gltfTexture.name)) + var gltfImage = GLTF.images[gltfTexture.source]; + if (!string.IsNullOrEmpty(gltfImage.uri)) { - // use image name - gltfTexture.name = GLTF.images[gltfTexture.source].name; + // from image uri + gltfTexture.name = Path.GetFileNameWithoutExtension(gltfImage.uri); } if (string.IsNullOrEmpty(gltfTexture.name)) { + // use image name + gltfTexture.name = gltfImage.name; + } + if (string.IsNullOrEmpty(gltfTexture.name)) + { + // no name var newName = $"texture_{i}"; if (!used.Add(newName)) { @@ -250,15 +257,17 @@ namespace UniGLTF else { var lower = gltfTexture.name.ToLower(); - if (used.Contains(lower)) + if (!used.Add(lower)) { // rename var uname = lower + "_" + Guid.NewGuid().ToString("N"); Debug.LogWarning($"same name: {lower} => {uname}"); gltfTexture.name = uname; - lower = uname; + if (!used.Add(uname)) + { + throw new Exception(); + } } - used.Add(lower); } } } @@ -325,62 +334,6 @@ namespace UniGLTF } } - public string GetTextureExtension(int imageIndex) - { - foreach (var m in GLTF.materials) - { - if (m.pbrMetallicRoughness != null) - { - // base color - if (m.pbrMetallicRoughness?.baseColorTexture != null) - { - if (m.pbrMetallicRoughness.baseColorTexture.index == imageIndex) - { - return ""; - } - } - - // metallic roughness - if (m.pbrMetallicRoughness?.metallicRoughnessTexture != null) - { - if (m.pbrMetallicRoughness.metallicRoughnessTexture.index == imageIndex) - { - return ".metallicRoughness"; - } - } - } - - // emission - if (m.emissiveTexture != null) - { - if (m.emissiveTexture.index == imageIndex) - { - return ""; - } - } - - // normal - if (m.normalTexture != null) - { - if (m.normalTexture.index == imageIndex) - { - return ""; - } - } - - // occlusion - if (m.occlusionTexture != null) - { - if (m.occlusionTexture.index == imageIndex) - { - return ".occlusion"; - } - } - } - - return ""; - } - public IEnumerable EnumerateTextures(glTFMaterial m) { if (m.pbrMetallicRoughness != null) @@ -425,7 +378,7 @@ namespace UniGLTF var m = GLTF.materials[i]; foreach (var x in EnumerateTextures(m)) { - if (used.Add(x.Name)) + if (used.Add(x.ConvertedName)) { yield return x; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 305a74182..991ce537c 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -103,17 +103,6 @@ namespace UniGLTF throw new UniGLTFNotSupportedException("draco is not supported"); } - // using (MeasureTime("LoadTextures")) - // { - // for (int i = 0; i < GLTF.materials.Count; ++i) - // { - // foreach (var param in MaterialFactory.EnumerateGetTextureparam(i)) - // { - // await m_textureFactory.GetTextureAsync(GLTF, param); - // } - // } - // } - using (MeasureTime("LoadMaterials")) { await m_materialFactory.LoadMaterialsAsync(m_awaitCaller, m_textureFactory.GetTextureAsync); @@ -201,8 +190,9 @@ namespace UniGLTF } #endregion - #region Imported + #region Imported public GameObject Root; + bool m_ownRoot = true; public List Nodes = new List(); public List Meshes = new List(); @@ -216,6 +206,14 @@ namespace UniGLTF } } } + void RemoveMesh(Mesh mesh) + { + var index = Meshes.FindIndex(x => x.Mesh == mesh); + if (index >= 0) + { + Meshes.RemoveAt(index); + } + } public void EnableUpdateWhenOffscreen() { @@ -236,20 +234,39 @@ namespace UniGLTF #endregion /// - /// Importに使った一時オブジェクトを破棄する - /// - /// 変換のあるテクスチャで、変換前のもの - /// normal, occlusion, metallicRoughness + /// ImporterContextが所有する UnityEngine.Object を破棄する /// public virtual void Dispose() { - foreach (var x in m_textureFactory.Textures) + Action destroy = UnityResourceDestroyer.DestroyResource(); + + foreach (var x in AnimationClips) { - if (!x.IsUsed) - { - // Destroy temporary texture object - UnityEngine.Object.Destroy(x.Texture); - } +#if VRM_DEVELOP + Debug.Log($"Destroy {x}"); +#endif + destroy(x); + } + AnimationClips.Clear(); + + foreach (var x in Meshes) + { +#if VRM_DEVELOP + Debug.Log($"Destroy {x}"); +#endif + destroy(x.Mesh); + } + Meshes.Clear(); + + m_materialFactory.Dispose(); + m_textureFactory.Dispose(); + + if (m_ownRoot && Root != null) + { +#if VRM_DEVELOP + Debug.Log($"Destroy {Root}"); +#endif + destroy(Root); } } @@ -257,33 +274,64 @@ namespace UniGLTF /// Root ヒエラルキーで使っているリソース /// /// - public virtual IEnumerable ModelOwnResources() + public virtual void TransferOwnership(TakeOwnershipFunc take) { + var list = new List(); foreach (var mesh in Meshes) { - yield return mesh.Mesh; + if (take(mesh.Mesh)) + { + list.Add(mesh.Mesh); + } } - foreach (var material in m_materialFactory.Materials) + foreach (var x in list) { - yield return material.Asset; - } - foreach (var texture in m_textureFactory.Textures) - { - yield return texture.Texture; + RemoveMesh(x as Mesh); } + + TextureFactory.TransferOwnership(take); + MaterialFactory.TransferOwnership(take); + + list.Clear(); foreach (var animation in AnimationClips) { - yield return animation; + if (take(animation)) + { + list.Add(animation); + } + } + foreach (var x in list) + { + AnimationClips.Remove(x as AnimationClip); + } + + if (m_ownRoot && Root != null) + { + if (take(Root)) + { + // 所有権(Dispose権) + m_ownRoot = false; + } } } + /// + /// RootにUnityResourceDestroyerをアタッチして、 + /// RootをUnityEngine.Object.Destroyしたときに、 + /// 関連するUnityEngine.Objectを破棄するようにする。 + /// Mesh, Material, Texture, AnimationClip, GameObject の所有者が + /// ImporterContext から UnityResourceDestroyer に移動する。 + /// ImporterContext.Dispose の対象から外れる。 + /// + /// public UnityResourceDestroyer DisposeOnGameObjectDestroyed() { var destroyer = Root.AddComponent(); - foreach (var x in ModelOwnResources()) + TransferOwnership(o => { - destroyer.Resources.Add(x); - } + destroyer.Resources.Add(o); + return true; + }); return destroyer; } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs index ef0de6ce6..b975dbfbd 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs @@ -16,10 +16,21 @@ namespace UniGLTF { throw new Exception(); } + if (task.IsFaulted) + { + if (task.Exception is AggregateException ae && ae.InnerExceptions.Count == 1) + { + throw ae.InnerException; + } + else + { + throw task.Exception; + } + } + #if VRM_DEVELOP Debug.Log(meassureTime.GetSpeedLog()); #endif - } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs index fb3f6ca5f..b36126eba 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs @@ -64,6 +64,8 @@ namespace UniGLTF public readonly Material Asset; public readonly bool UseExternal; + public bool IsSubAsset => !UseExternal; + public MaterialLoadInfo(Material asset, bool useExternal) { Asset = asset; @@ -73,19 +75,52 @@ namespace UniGLTF List m_materials = new List(); public IReadOnlyList Materials => m_materials; - public void Dispose() + void Remove(Material material) { - foreach (var x in ObjectsForSubAsset()) + var index = m_materials.FindIndex(x => x.Asset == material); + if (index >= 0) { - UnityEngine.Object.DestroyImmediate(x, true); + m_materials.RemoveAt(index); + } } - public IEnumerable ObjectsForSubAsset() + public void Dispose() { foreach (var x in m_materials) { - yield return x.Asset; + if (!x.UseExternal) + { + // 外部の '.asset' からロードしていない +#if VRM_DEVELOP + Debug.Log($"Destroy {x.Asset}"); +#endif + UnityEngine.Object.DestroyImmediate(x.Asset, false); + } + } + } + + /// + /// 所有権(Dispose権)を移譲する + /// + /// + public void TransferOwnership(TakeOwnershipFunc take) + { + var list = new List(); + foreach (var x in m_materials) + { + if (!x.UseExternal) + { + // 外部の '.asset' からロードしていない + if (take(x.Asset)) + { + list.Add(x.Asset); + } + } + } + foreach (var x in list) + { + Remove(x); } } @@ -200,22 +235,5 @@ namespace UniGLTF var task = DefaultCreateMaterialAsync(default(ImmediateCaller), gltf, i, null); return task.Result; } - - public IEnumerable EnumerateGetTextureparam(int i) - { - var m = m_gltf.materials[i]; - - // color texture - var colorIndex = m.pbrMetallicRoughness?.baseColorTexture?.index; - if (colorIndex.HasValue) - { - yield return GetTextureParam.Create(m_gltf, i); - } - - if (!glTF_KHR_materials_unlit.IsEnable(m)) - { - // PBR - } - } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs index 7503a6a18..4ea932bb5 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs @@ -71,13 +71,13 @@ namespace UniGLTF { getTexture = (_x, _y, _z) => Task.FromResult(null); } - var src = gltf.materials[i]; - - var material = MaterialFactory.CreateMaterial(i, src, ShaderName); // PBR material - if (src != null) + var material = default(Material); + if (i >= 0 && i < gltf.materials.Count) { + var src = gltf.materials[i]; + material = MaterialFactory.CreateMaterial(i, src, ShaderName); if (src.pbrMetallicRoughness != null) { if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) @@ -214,6 +214,10 @@ namespace UniGLTF material.SetFloat("_Mode", (float)blendMode); } + else + { + material = MaterialFactory.CreateMaterial(i, null, ShaderName); + } return material; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs new file mode 100644 index 000000000..4cb91856c --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs @@ -0,0 +1,13 @@ +namespace UniGLTF +{ + /// + /// 所有権を移動する関数。 + /// + /// * 所有権が移動する。return true => ImporterContext.Dispose の対象から外れる + /// * 所有権が移動しない。return false => Importer.Context.Dispose でDestroyされる + /// + /// + /// 対象のオブジェクト + /// 所有権が移動したらtrue + public delegate bool TakeOwnershipFunc(UnityEngine.Object o); +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs.meta new file mode 100644 index 000000000..0b34ae7e0 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TakeOwnershipFunc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab2b998b9235dc94a90ccaf2e40a50a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs index 61b160eed..aff199ce9 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs @@ -154,7 +154,7 @@ namespace UniGLTF ); } - public virtual int ExportTexture(glTF gltf, int bufferIndex, Texture texture, glTFTextureTypes textureType) + public int ExportTexture(glTF gltf, int bufferIndex, Texture texture, glTFTextureTypes textureType) { var bytesWithMime = GetBytesWithMime(texture, textureType); ; @@ -166,7 +166,7 @@ namespace UniGLTF var imageIndex = gltf.images.Count; gltf.images.Add(new glTFImage { - name = texture.name, + name = GetTextureParam.RemoveSuffix(texture.name), bufferView = viewIndex, mimeType = bytesWithMime.mine, }); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs index bc3f1c5b7..b5334756d 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs @@ -5,10 +5,50 @@ namespace UniGLTF public struct GetTextureParam { public const string NORMAL_PROP = "_BumpMap"; + public const string NORMAL_SUFFIX = ".normal"; public const string METALLIC_GLOSS_PROP = "_MetallicGlossMap"; + public const string METALLIC_GLOSS_SUFFIX = ".metallicRoughness"; public const string OCCLUSION_PROP = "_OcclusionMap"; + public const string OCCLUSION_SUFFIX = ".occlusion"; + + public static string RemoveSuffix(string src) + { + if (src.EndsWith(NORMAL_SUFFIX)) + { + return src.Substring(0, src.Length - NORMAL_SUFFIX.Length); + } + else if (src.EndsWith(METALLIC_GLOSS_SUFFIX)) + { + return src.Substring(0, src.Length - METALLIC_GLOSS_SUFFIX.Length); + } + else if (src.EndsWith(OCCLUSION_SUFFIX)) + { + return src.Substring(0, src.Length - OCCLUSION_SUFFIX.Length); + } + else + { + return src; + } + } + + readonly string m_name; + + public string GltflName => m_name; + + public string ConvertedName + { + get + { + switch (TextureType) + { + case METALLIC_GLOSS_PROP: return $"{m_name}{METALLIC_GLOSS_SUFFIX}"; + case OCCLUSION_PROP: return $"{m_name}{OCCLUSION_SUFFIX}"; + case NORMAL_PROP: return $"{m_name}{NORMAL_SUFFIX}"; + default: return m_name; + } + } + } - public readonly string Name; public readonly string TextureType; public readonly float MetallicFactor; public readonly ushort? Index0; @@ -18,13 +58,18 @@ namespace UniGLTF public readonly ushort? Index4; public readonly ushort? Index5; + /// + /// この2種類は変換済みをExtract + /// + public bool ExtractConverted => TextureType == OCCLUSION_PROP || TextureType == METALLIC_GLOSS_PROP; + public GetTextureParam(string name, string textureType, float metallicFactor, int i0, int i1, int i2, int i3, int i4, int i5) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(); } - Name = name; + m_name = name; TextureType = textureType; MetallicFactor = metallicFactor; @@ -69,13 +114,13 @@ namespace UniGLTF public static GetTextureParam CreateMetallic(glTF gltf, int textureIndex, float metallicFactor) { var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name + ".metallicRoughness", METALLIC_GLOSS_PROP, metallicFactor, textureIndex, default, default, default, default, default); + return new GetTextureParam(name, METALLIC_GLOSS_PROP, metallicFactor, textureIndex, default, default, default, default, default); } public static GetTextureParam CreateOcclusion(glTF gltf, int textureIndex) { var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name + ".occlusion", OCCLUSION_PROP, default, textureIndex, default, default, default, default, default); + return new GetTextureParam(name, OCCLUSION_PROP, default, textureIndex, default, default, default, default, default); } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs index 667b45b11..b695d701f 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs @@ -24,6 +24,8 @@ namespace UniGLTF public bool IsUsed => Flags.HasFlag(TextureLoadFlags.Used); public bool IsExternal => Flags.HasFlag(TextureLoadFlags.External); + public bool IsSubAsset => IsUsed && !IsExternal; + public TextureLoadInfo(Texture2D texture, bool used, bool isExternal) { Texture = texture; @@ -49,10 +51,15 @@ namespace UniGLTF { if (param.Index0.HasValue && m_externalMap != null) { - if (m_externalMap.TryGetValue(param.Name, out external)) + var cacheName = param.ConvertedName; + if (param.TextureType == GetTextureParam.NORMAL_PROP) { - // Debug.Log($"use external: {param.Name}"); - m_textureCache.Add(param.Name, new TextureLoadInfo(external, used, true)); + cacheName = param.GltflName; + } + + if (m_externalMap.TryGetValue(cacheName, out external)) + { + m_textureCache.Add(cacheName, new TextureLoadInfo(external, used, true)); return external; } } @@ -77,17 +84,42 @@ namespace UniGLTF public void Dispose() { - foreach (var x in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(x, true); - } - } - - public IEnumerable ObjectsForSubAsset() - { + Action destroy = UnityResourceDestroyer.DestroyResource(); foreach (var kv in m_textureCache) { - yield return kv.Value.Texture; + if (!kv.Value.IsExternal) + { +#if VRM_DEVELOP + Debug.Log($"Destroy {kv.Value.Texture}"); +#endif + destroy(kv.Value.Texture); + } + } + m_textureCache.Clear(); + } + + /// + /// 所有権(Dispose権)を移譲する + /// + /// + public void TransferOwnership(TakeOwnershipFunc take) + { + var keys = new List(); + foreach (var x in m_textureCache) + { + if (x.Value.IsUsed && !x.Value.IsExternal) + { + // マテリアルから参照されていて + // 外部のAssetからロードしていない。 + if (take(x.Value.Texture)) + { + keys.Add(x.Key); + } + } + } + foreach (var x in keys) + { + m_textureCache.Remove(x); } } @@ -118,7 +150,7 @@ namespace UniGLTF /// public async Task GetTextureAsync(IAwaitCaller awaitCaller, glTF gltf, GetTextureParam param) { - if (m_textureCache.TryGetValue(param.Name, out TextureLoadInfo cacheInfo)) + if (m_textureCache.TryGetValue(param.ConvertedName, out TextureLoadInfo cacheInfo)) { return cacheInfo.Texture; } @@ -131,26 +163,12 @@ namespace UniGLTF { case GetTextureParam.NORMAL_PROP: { - if (Application.isPlaying) - { - var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); - var converted = new NormalConverter().GetImportTexture(baseTexture.Texture); - var info = new TextureLoadInfo(converted, true, false); - m_textureCache.Add(param.Name, info); - return info.Texture; - } - else - { -#if UNITY_EDITOR - var info = await LoadTextureAsync(awaitCaller, param.Index0.Value, true); - var name = gltf.textures[param.Index0.Value].name; - m_textureCache.Add(name, info); - - var textureAssetPath = AssetDatabase.GetAssetPath(info.Texture); - TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); -#endif - return info.Texture; - } + var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); + var converted = new NormalConverter().GetImportTexture(baseTexture.Texture); + converted.name = param.ConvertedName; + var info = new TextureLoadInfo(converted, true, false); + m_textureCache.Add(converted.name, info); + return info.Texture; } case GetTextureParam.METALLIC_GLOSS_PROP: @@ -158,9 +176,9 @@ namespace UniGLTF // Bake roughnessFactor values into a texture. var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(baseTexture.Texture); - converted.name = param.Name; + converted.name = param.ConvertedName; var info = new TextureLoadInfo(converted, true, false); - m_textureCache.Add(param.Name, info); + m_textureCache.Add(converted.name, info); return info.Texture; } @@ -168,9 +186,9 @@ namespace UniGLTF { var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); var converted = new OcclusionConverter().GetImportTexture(baseTexture.Texture); - converted.name = param.Name; + converted.name = param.ConvertedName; var info = new TextureLoadInfo(converted, true, false); - m_textureCache.Add(param.Name, info); + m_textureCache.Add(converted.name, info); return info.Texture; } diff --git a/Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs b/Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs similarity index 50% rename from Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs rename to Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs index 0882c254b..b14ae9b45 100644 --- a/Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using UnityEngine; @@ -9,7 +10,7 @@ namespace UniGLTF /// public class UnityResourceDestroyer : MonoBehaviour { - List m_resources = new List(); + List m_resources = new List(); public IList Resources => m_resources; void OnDestroy() @@ -23,5 +24,16 @@ namespace UniGLTF Destroy(x); } } + + public static Action DestroyResource() + { + Action des = (UnityEngine.Object o) => UnityEngine.Object.Destroy(o); + Action desi = (UnityEngine.Object o) => UnityEngine.Object.DestroyImmediate(o); + Action func = Application.isPlaying + ? des + : desi + ; + return func; + } } } diff --git a/Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs.meta similarity index 83% rename from Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs.meta index f4dc3b668..b07ef89ae 100644 --- a/Assets/UniGLTF/Runtime/UnityResourceDestroyer.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/UnityResourceDestroyer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ca87b3d02ce67634a9ebcfe8cca70ece +guid: 93b3af59a4d8b704a883260f2fd40c44 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs b/Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs deleted file mode 100644 index 09d6c0804..000000000 --- a/Assets/UniGLTF/Runtime/UniJSON/ActionDisposer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - - -namespace UniJSON -{ - public struct ActionDisposer : IDisposable - { - Action m_action; - - public ActionDisposer(Action action) - { - m_action = action; - } - - public void Dispose() - { - m_action(); - } - } -} diff --git a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs index 620577672..b2750e424 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs @@ -98,44 +98,31 @@ namespace UniGLTF public void UniGLTFSimpleSceneTest() { var go = CreateSimpleScene(); - ImporterContext context = default; - try + // export + var gltf = new glTF(); + + string json = null; + using (var exporter = new gltfExporter(gltf)) { - // export - var gltf = new glTF(); + exporter.Prepare(go); + exporter.Export(MeshExportSettings.Default); - string json = null; - using (var exporter = new gltfExporter(gltf)) - { - exporter.Prepare(go); - exporter.Export(MeshExportSettings.Default); + // remove empty buffer + gltf.buffers.Clear(); - // remove empty buffer - gltf.buffers.Clear(); - - json = gltf.ToJson(); - } - - // parse - var parser = new GltfParser(); - parser.ParseJson(json, new SimpleStorage(new ArraySegment())); - - // import - context = new ImporterContext(parser); - context.Load(); - - AssertAreEqual(go.transform, context.Root.transform); + json = gltf.ToJson(); } - finally + + // parse + var parser = new GltfParser(); + parser.ParseJson(json, new SimpleStorage(new ArraySegment())); + + // import + using (var context = new ImporterContext(parser)) { - //Debug.LogFormat("Destroy, {0}", go.name); - GameObject.DestroyImmediate(go); - if (context != null) - { - var editor = new EditorImporterContext(context); - editor.EditorDestroyRootAndAssets(); - } + context.Load(); + AssertAreEqual(go.transform, context.Root.transform); } } @@ -568,19 +555,22 @@ namespace UniGLTF { var parser = new GltfParser(); parser.ParseJson(json, new SimpleStorage(new ArraySegment(new byte[1024 * 1024]))); - var context = new ImporterContext(parser); - //Debug.LogFormat("{0}", context.Json); - context.Load(); - var importedRed = context.Root.transform.GetChild(0); - var importedRedMaterial = importedRed.GetComponent().sharedMaterial; - Assert.AreEqual("red", importedRedMaterial.name); - Assert.AreEqual(Color.red, importedRedMaterial.color); + using (var context = new ImporterContext(parser)) + { + //Debug.LogFormat("{0}", context.Json); + context.Load(); - var importedBlue = context.Root.transform.GetChild(1); - var importedBlueMaterial = importedBlue.GetComponent().sharedMaterial; - Assert.AreEqual("blue", importedBlueMaterial.name); - Assert.AreEqual(Color.blue, importedBlueMaterial.color); + var importedRed = context.Root.transform.GetChild(0); + var importedRedMaterial = importedRed.GetComponent().sharedMaterial; + Assert.AreEqual("red", importedRedMaterial.name); + Assert.AreEqual(Color.red, importedRedMaterial.color); + + var importedBlue = context.Root.transform.GetChild(1); + var importedBlueMaterial = importedBlue.GetComponent().sharedMaterial; + Assert.AreEqual("blue", importedBlueMaterial.name); + Assert.AreEqual(Color.blue, importedBlueMaterial.color); + } } // import new version @@ -588,18 +578,20 @@ namespace UniGLTF var parser = new GltfParser(); parser.ParseJson(json, new SimpleStorage(new ArraySegment(new byte[1024 * 1024]))); //Debug.LogFormat("{0}", context.Json); - var context = new ImporterContext(parser); - context.Load(); + using (var context = new ImporterContext(parser)) + { + context.Load(); - var importedRed = context.Root.transform.GetChild(0); - var importedRedMaterial = importedRed.GetComponent().sharedMaterial; - Assert.AreEqual("red", importedRedMaterial.name); - Assert.AreEqual(Color.red, importedRedMaterial.color); + var importedRed = context.Root.transform.GetChild(0); + var importedRedMaterial = importedRed.GetComponent().sharedMaterial; + Assert.AreEqual("red", importedRedMaterial.name); + Assert.AreEqual(Color.red, importedRedMaterial.color); - var importedBlue = context.Root.transform.GetChild(1); - var importedBlueMaterial = importedBlue.GetComponent().sharedMaterial; - Assert.AreEqual("blue", importedBlueMaterial.name); - Assert.AreEqual(Color.blue, importedBlueMaterial.color); + var importedBlue = context.Root.transform.GetChild(1); + var importedBlueMaterial = importedBlue.GetComponent().sharedMaterial; + Assert.AreEqual("blue", importedBlueMaterial.name); + Assert.AreEqual(Color.blue, importedBlueMaterial.color); + } } } finally diff --git a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs index ae051e2e1..852ae2b2c 100644 --- a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs +++ b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs @@ -45,13 +45,12 @@ namespace VRM.Samples var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); - var context = new VRMImporterContext(parser); - context.Load(); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - - using (new ActionDisposer(() => { GameObject.DestroyImmediate(context.Root); })) + using (var context = new VRMImporterContext(parser)) { + context.Load(); + context.ShowMeshes(); + context.EnableUpdateWhenOffscreen(); + var importedJson = JsonParser.Parse(context.Json); importedJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION, (f, x) => f.Value(x)); importedJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION, (f, x) => f.Value(x)); @@ -118,16 +117,18 @@ namespace VRM.Samples var path = AliciaPath; var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); - var context = new VRMImporterContext(parser); - context.Load(); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - foreach (var mesh in context.Meshes) + using (var context = new VRMImporterContext(parser)) { - var src = mesh.Mesh; - var dst = src.Copy(true); - MeshTests.MeshEquals(src, dst); + context.Load(); + context.ShowMeshes(); + context.EnableUpdateWhenOffscreen(); + foreach (var mesh in context.Meshes) + { + var src = mesh.Mesh; + var dst = src.Copy(true); + MeshTests.MeshEquals(src, dst); + } } } @@ -138,28 +139,31 @@ namespace VRM.Samples var path = AliciaPath; var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); - var context = new VRMImporterContext(parser); - var oldJson = context.GLTF.ToJson().ParseAsJson().ToString(" "); - // 生成シリアライザでJSON化する - var f = new JsonFormatter(); - GltfSerializer.Serialize(f, context.GLTF); - var parsed = f.ToString().ParseAsJson(); - var newJson = parsed.ToString(" "); + using (var context = new VRMImporterContext(parser)) + { + var oldJson = context.GLTF.ToJson().ParseAsJson().ToString(" "); - // File.WriteAllText("old.json", oldJson); - // File.WriteAllText("new.json", newJson); + // 生成シリアライザでJSON化する + var f = new JsonFormatter(); + GltfSerializer.Serialize(f, context.GLTF); + var parsed = f.ToString().ParseAsJson(); + var newJson = parsed.ToString(" "); - // 比較 - Assert.AreEqual(oldJson.ParseAsJson().ToString(), newJson.ParseAsJson().ToString()); + // File.WriteAllText("old.json", oldJson); + // File.WriteAllText("new.json", newJson); - // 生成デシリアライザでロードする - var ff = new JsonFormatter(); - var des = GltfDeserializer.Deserialize(parsed); - ff.Clear(); - GltfSerializer.Serialize(ff, des); - var desJson = ff.ToString().ParseAsJson().ToString(" "); - Assert.AreEqual(oldJson.ParseAsJson().ToString(), desJson.ParseAsJson().ToString()); + // 比較 + Assert.AreEqual(oldJson.ParseAsJson().ToString(), newJson.ParseAsJson().ToString()); + + // 生成デシリアライザでロードする + var ff = new JsonFormatter(); + var des = GltfDeserializer.Deserialize(parsed); + ff.Clear(); + GltfSerializer.Serialize(ff, des); + var desJson = ff.ToString().ParseAsJson().ToString(" "); + Assert.AreEqual(oldJson.ParseAsJson().ToString(), desJson.ParseAsJson().ToString()); + } } } } diff --git a/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity b/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity deleted file mode 100644 index 68ba0aa45..000000000 --- a/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity +++ /dev/null @@ -1,1743 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44664878, g: 0.49649704, b: 0.57486165, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 0 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &147376043 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 147376044} - - component: {fileID: 147376046} - - component: {fileID: 147376045} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &147376044 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 147376043} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 2108006564} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 1, y: 1} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -88.7, y: -23.7} - m_SizeDelta: {x: 177.4, y: 47.4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &147376045 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 147376043} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 32 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 3 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: FirstPerson ---- !u!222 &147376046 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 147376043} - m_CullTransparentMesh: 0 ---- !u!1 &267321008 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 267321009} - - component: {fileID: 267321012} - - component: {fileID: 267321011} - - component: {fileID: 267321010} - m_Layer: 5 - m_Name: BottomLeft - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &267321009 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 267321008} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 2036452538} - - {fileID: 555566559} - m_Father: {fileID: 2082684587} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 1} ---- !u!114 &267321010 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 267321008} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Padding: - m_Left: 0 - m_Right: 0 - m_Top: 0 - m_Bottom: 0 - m_ChildAlignment: 0 - m_Spacing: 0 - m_ChildForceExpandWidth: 1 - m_ChildForceExpandHeight: 0 - m_ChildControlWidth: 0 - m_ChildControlHeight: 0 ---- !u!114 &267321011 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 267321008} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.392} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &267321012 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 267321008} - m_CullTransparentMesh: 0 ---- !u!1 &283664911 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 283664914} - - component: {fileID: 283664913} - - component: {fileID: 283664912} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &283664912 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 283664911} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &283664913 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 283664911} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 5 ---- !u!4 &283664914 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 283664911} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 5 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &555566558 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 555566559} - - component: {fileID: 555566562} - - component: {fileID: 555566561} - - component: {fileID: 555566560} - m_Layer: 5 - m_Name: LoadBVH - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &555566559 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 555566558} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 605703266} - m_Father: {fileID: 267321009} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 80, y: -45} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &555566560 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 555566558} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 555566561} - m_OnClick: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &555566561 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 555566558} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &555566562 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 555566558} - m_CullTransparentMesh: 0 ---- !u!1 &568975773 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 568975775} - - component: {fileID: 568975774} - m_Layer: 0 - m_Name: CameraManager - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &568975774 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 568975773} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 6b34fb2c039c3ce4881f04e476a2128f, type: 3} - m_Name: - m_EditorClassIdentifier: - m_topLeft: - Camera: {fileID: 1468129204} - Texture: {fileID: 0} - Image: {fileID: 2108006565} - m_topRight: - Camera: {fileID: 772693251} - Texture: {fileID: 0} - Image: {fileID: 635962097} - m_bottomRight: - Camera: {fileID: 1919635067} - Texture: {fileID: 0} - Image: {fileID: 991744090} - m_firstPersonCamera: {fileID: 1468129204} - m_thirdPersonCameras: - - {fileID: 1919635067} - - {fileID: 772693251} ---- !u!4 &568975775 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 568975773} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1468129205} - - {fileID: 772693254} - - {fileID: 1919635063} - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &605703265 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 605703266} - - component: {fileID: 605703268} - - component: {fileID: 605703267} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &605703266 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 605703265} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 555566559} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &605703267 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 605703265} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Load BVH ---- !u!222 &605703268 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 605703265} - m_CullTransparentMesh: 0 ---- !u!1 &635962095 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 635962096} - - component: {fileID: 635962098} - - component: {fileID: 635962097} - m_Layer: 5 - m_Name: TopRight - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &635962096 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 635962095} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 646222219} - m_Father: {fileID: 2082684587} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 1} ---- !u!114 &635962097 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 635962095} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &635962098 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 635962095} - m_CullTransparentMesh: 0 ---- !u!1 &646222218 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 646222219} - - component: {fileID: 646222221} - - component: {fileID: 646222220} - m_Layer: 5 - m_Name: Text (1) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &646222219 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 646222218} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 635962096} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 88.7, y: -23.700012} - m_SizeDelta: {x: 177.4, y: 47.4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &646222220 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 646222218} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 32 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 3 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ThirdPerson ---- !u!222 &646222221 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 646222218} - m_CullTransparentMesh: 0 ---- !u!1 &772693250 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 772693254} - - component: {fileID: 772693251} - - component: {fileID: 772693253} - - component: {fileID: 772693252} - m_Layer: 0 - m_Name: OutPov - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!20 &772693251 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 772693250} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294966783 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!81 &772693252 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 772693250} - m_Enabled: 0 ---- !u!124 &772693253 -Behaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 772693250} - m_Enabled: 0 ---- !u!4 &772693254 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 772693250} - m_LocalRotation: {x: 0, y: 1, z: 0, w: 0} - m_LocalPosition: {x: 0, y: 1.2, z: 1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 568975775} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} ---- !u!1 &936781945 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 936781946} - - component: {fileID: 936781948} - - component: {fileID: 936781947} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &936781946 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 936781945} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 2036452538} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &936781947 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 936781945} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Load VRM ---- !u!222 &936781948 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 936781945} - m_CullTransparentMesh: 0 ---- !u!1 &991744088 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 991744089} - - component: {fileID: 991744091} - - component: {fileID: 991744090} - m_Layer: 5 - m_Name: BottomRight - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &991744089 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 991744088} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1382317302} - m_Father: {fileID: 2082684587} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0} - m_AnchorMax: {x: 1, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 1} ---- !u!114 &991744090 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 991744088} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &991744091 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 991744088} - m_CullTransparentMesh: 0 ---- !u!1 &1148284494 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1148284495} - - component: {fileID: 1148284496} - m_Layer: 0 - m_Name: VRMRuntimeLoader - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1148284495 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1148284494} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1148284496 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1148284494} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 649886f2803ade846a93be89f73e35c7, type: 3} - m_Name: - m_EditorClassIdentifier: - m_loadAsync: 1 - m_canvas: {fileID: 2082684588} - m_faceCamera: {fileID: 1919635064} - m_source: {fileID: 0} - m_target: {fileID: 0} - m_firstPerson: {fileID: 0} ---- !u!1 &1175289393 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1175289395} - - component: {fileID: 1175289394} - m_Layer: 0 - m_Name: Directional light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1175289394 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1175289393} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_Intensity: 0.33 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 0 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1175289395 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1175289393} - m_LocalRotation: {x: 0.2571214, y: -0.8612099, z: 0.4380491, w: 0.017861776} - m_LocalPosition: {x: 2.84, y: 1.7, z: 2.02} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 130.209, y: -17.533997, z: 138.566} ---- !u!1 &1382317301 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1382317302} - - component: {fileID: 1382317304} - - component: {fileID: 1382317303} - m_Layer: 5 - m_Name: Text (2) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1382317302 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1382317301} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 991744089} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 242.4, y: -23.699997} - m_SizeDelta: {x: 484.7, y: 47.4} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1382317303 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1382317301} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 32 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 3 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ThirdPerson(BlendShapeCheck) ---- !u!222 &1382317304 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1382317301} - m_CullTransparentMesh: 0 ---- !u!1 &1396766179 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1396766183} - - component: {fileID: 1396766182} - - component: {fileID: 1396766181} - - component: {fileID: 1396766180} - m_Layer: 0 - m_Name: Plane - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!23 &1396766180 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1396766179} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 4294967295 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!64 &1396766181 -MeshCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1396766179} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 3 - m_Convex: 0 - m_CookingOptions: 14 - m_SkinWidth: 0.01 - m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} ---- !u!33 &1396766182 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1396766179} - m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1396766183 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1396766179} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 1.41} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1468129200 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1468129205} - - component: {fileID: 1468129204} - - component: {fileID: 1468129203} - - component: {fileID: 1468129202} - - component: {fileID: 1468129201} - m_Layer: 0 - m_Name: FirstPerson - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1468129201 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1468129200} - m_Enabled: 0 ---- !u!92 &1468129202 -Behaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1468129200} - m_Enabled: 0 ---- !u!124 &1468129203 -Behaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1468129200} - m_Enabled: 0 ---- !u!20 &1468129204 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1468129200} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294966271 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1468129205 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1468129200} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1.13, z: -1.29} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 568975775} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1919635062 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1919635063} - - component: {fileID: 1919635067} - - component: {fileID: 1919635066} - - component: {fileID: 1919635065} - - component: {fileID: 1919635064} - m_Layer: 0 - m_Name: OutFace - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1919635063 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1919635062} - m_LocalRotation: {x: -0, y: 1, z: -0, w: 0} - m_LocalPosition: {x: -0.261, y: 1.497, z: 0.048} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 568975775} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} ---- !u!114 &1919635064 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1919635062} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d1cc319f70f55264eb38d1959c4222c6, type: 3} - m_Name: - m_EditorClassIdentifier: - Target: {fileID: 0} - m_offset: {x: 0, y: 0.05, z: 0} - m_distance: 0.7 - m_offsetTransform: - Transform: {fileID: 0} - OffsetRotation: - e00: 0 - e01: 0 - e02: 0 - e03: 0 - e10: 0 - e11: 0 - e12: 0 - e13: 0 - e20: 0 - e21: 0 - e22: 0 - e23: 0 - e30: 0 - e31: 0 - e32: 0 - e33: 0 ---- !u!81 &1919635065 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1919635062} - m_Enabled: 0 ---- !u!124 &1919635066 -Behaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1919635062} - m_Enabled: 0 ---- !u!20 &1919635067 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1919635062} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.01 - far clip plane: 2 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294966783 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!1 &2036452537 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2036452538} - - component: {fileID: 2036452541} - - component: {fileID: 2036452540} - - component: {fileID: 2036452539} - m_Layer: 5 - m_Name: LoadVRM - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &2036452538 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2036452537} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 936781946} - m_Father: {fileID: 267321009} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 80, y: -15} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &2036452539 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2036452537} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 2036452540} - m_OnClick: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &2036452540 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2036452537} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 ---- !u!222 &2036452541 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2036452537} - m_CullTransparentMesh: 0 ---- !u!1 &2082684583 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2082684587} - - component: {fileID: 2082684586} - - component: {fileID: 2082684585} - - component: {fileID: 2082684584} - - component: {fileID: 2082684588} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &2082684584 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2082684583} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &2082684585 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2082684583} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &2082684586 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2082684583} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &2082684587 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2082684583} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 2108006564} - - {fileID: 635962096} - - {fileID: 991744089} - - {fileID: 267321009} - m_Father: {fileID: 0} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!114 &2082684588 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2082684583} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 1ae08a6ba07c0864c9132bc8a004030d, type: 3} - m_Name: - m_EditorClassIdentifier: - LoadVRMButton: {fileID: 2036452539} - LoadBVHButton: {fileID: 555566560} ---- !u!1 &2108006563 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2108006564} - - component: {fileID: 2108006566} - - component: {fileID: 2108006565} - m_Layer: 5 - m_Name: TopLeft - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &2108006564 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2108006563} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 147376044} - m_Father: {fileID: 2082684587} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.5} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 1} ---- !u!114 &2108006565 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2108006563} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &2108006566 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 2108006563} - m_CullTransparentMesh: 0 diff --git a/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity.meta b/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity.meta deleted file mode 100644 index b2e4bb311..000000000 --- a/Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.Net4.unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2f563e7bcfaebb74dbf9748df1f4824c -timeCreated: 1520832729 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs index 888a4dc66..16119365e 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs @@ -50,16 +50,18 @@ namespace VRM.Samples var parser = new GltfParser(); parser.ParseGlb(bytes); - var context = new VRMImporterContext(parser); + using (var context = new VRMImporterContext(parser)) + { - // metaを取得(todo: thumbnailテクスチャのロード) - var meta = await context.ReadMetaAsync(); - Debug.LogFormat("meta: title:{0}", meta.Title); + // metaを取得(todo: thumbnailテクスチャのロード) + var meta = await context.ReadMetaAsync(); + Debug.LogFormat("meta: title:{0}", meta.Title); - // ParseしたJSONをシーンオブジェクトに変換していく - await context.LoadAsync(); + // ParseしたJSONをシーンオブジェクトに変換していく + await context.LoadAsync(); - OnLoaded(context); + OnLoaded(context); + } } void OnLoaded(VRMImporterContext context) diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs index 192de0f0f..023690a18 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs @@ -90,23 +90,24 @@ namespace VRM.Samples var parser = new GltfParser(); parser.Parse(path, bytes); - var context = new VRMImporterContext(parser); - - // metaを取得(todo: thumbnailテクスチャのロード) - var meta = await context.ReadMetaAsync(); - Debug.LogFormat("meta: title:{0}", meta.Title); - - // ParseしたJSONをシーンオブジェクトに変換していく - if (m_loadAsync) + using (var context = new VRMImporterContext(parser)) { - await context.LoadAsync(); - } - else - { - context.Load(); - } + // metaを取得(todo: thumbnailテクスチャのロード) + var meta = await context.ReadMetaAsync(); + Debug.LogFormat("meta: title:{0}", meta.Title); - OnLoaded(context); + // ParseしたJSONをシーンオブジェクトに変換していく + if (m_loadAsync) + { + await context.LoadAsync(); + } + else + { + context.Load(); + } + + OnLoaded(context); + } } /// @@ -167,10 +168,12 @@ namespace VRM.Samples void OnLoaded(VRMImporterContext context) { var root = context.Root; + root.transform.SetParent(transform, false); //メッシュを表示します context.ShowMeshes(); + context.DisposeOnGameObjectDestroyed(); // add motion var humanPoseTransfer = root.AddComponent(); diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs deleted file mode 100644 index 928361913..000000000 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs +++ /dev/null @@ -1,188 +0,0 @@ -#pragma warning disable 0414 -using System; -using System.IO; -using UnityEngine; -#if (NET_4_6 && UNITY_2017_1_OR_NEWER) -using System.Threading.Tasks; -#endif - - -namespace VRM.Samples -{ - public class VRMRuntimeLoaderNet4 : MonoBehaviour - { - [SerializeField, Header("GUI")] - CanvasManager m_canvas; - - [SerializeField] - LookTarget m_faceCamera; - - [SerializeField, Header("loader")] - UniHumanoid.HumanPoseTransfer m_source; - - [SerializeField] - UniHumanoid.HumanPoseTransfer m_target; - - [SerializeField, Header("runtime")] - VRMFirstPerson m_firstPerson; - -#if (NET_4_6 && UNITY_2017_1_OR_NEWER && !UNITY_WEBGL) - VRMBlendShapeProxy m_blendShape; - - void SetupTarget() - { - if (m_target != null) - { - m_target.Source = m_source; - m_target.SourceType = UniHumanoid.HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer; - - m_blendShape = m_target.GetComponent(); - - m_firstPerson = m_target.GetComponent(); - - var animator = m_target.GetComponent(); - if (animator != null) - { - m_firstPerson.Setup(); - - if (m_faceCamera != null) - { - m_faceCamera.Target = animator.GetBoneTransform(HumanBodyBones.Head); - } - } - } - } - - private void Awake() - { - SetupTarget(); - } - - private void Start() - { - if (m_canvas == null) - { - Debug.LogWarning("no canvas"); - return; - } - - m_canvas.LoadVRMButton.onClick.AddListener(LoadVRMClicked); - m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked); - } - - // Byte列を得る - async static Task ReadBytesAsync(string path) - { - return File.ReadAllBytes(path); - } - - async static Task LoadAsync(Byte[] bytes) - { - var context = new VRMImporterContext(); - - // GLB形式でJSONを取得しParseします - context.ParseGlb(bytes); - - // ParseしたJSONをシーンオブジェクトに変換していく - await context.LoadAsyncTask(); - - return context; - } - - /// - /// Taskで非同期にロードする例 - /// - async void LoadVRMClicked() - { -#if UNITY_STANDALONE_WIN - var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); -#elif UNITY_EDITOR - var path = UnityEditor.EditorUtility.OpenFilePanel("Open VRM", "", "vrm"); -#else - var path = Application.dataPath + "/default.vrm"; -#endif - if (string.IsNullOrEmpty(path)) - { - return; - } - - - var context = new VRMImporterContext(); - - var bytes = await ReadBytesAsync(path); - - // GLB形式でJSONを取得しParseします - context.ParseGlb(bytes); - - // metaを取得(todo: thumbnailテクスチャのロード) - var meta = context.ReadMeta(); - Debug.LogFormat("meta: title:{0}", meta.Title); - - // ParseしたJSONをシーンオブジェクトに変換していく - var now = Time.time; - await context.LoadAsyncTask(); - - var delta = Time.time - now; - Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta); - OnLoaded(context); - - } - - void LoadBVHClicked() - { -#if UNITY_STANDALONE_WIN - var path = FileDialogForWindows.FileDialog("open BVH", ".bvh"); - if (!string.IsNullOrEmpty(path)) - { - LoadBvh(path); - } -#elif UNITY_EDITOR - var path = UnityEditor.EditorUtility.OpenFilePanel("Open BVH", "", "bvh"); - if (!string.IsNullOrEmpty(path)) - { - LoadBvh(path); - } -#else - LoadBvh(Application.dataPath + "/default.bvh"); -#endif - } - - void OnLoaded(VRMImporterContext context) - { - var root = context.Root; - root.transform.SetParent(transform, false); - - //メッシュを表示します - context.ShowMeshes(); - - // add motion - var humanPoseTransfer = root.AddComponent(); - if (m_target != null) - { - GameObject.Destroy(m_target.gameObject); - } - m_target = humanPoseTransfer; - SetupTarget(); - } - - void LoadBvh(string path) - { - Debug.LogFormat("ImportBvh: {0}", path); - - var context = new UniHumanoid.BvhImporterContext(); - - context.Parse(path); - - context.Load(); - - if (m_source != null) - { - GameObject.Destroy(m_source.gameObject); - } - m_source = context.Root.GetComponent(); - - SetupTarget(); - } -#endif - } -} diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs.meta b/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs.meta deleted file mode 100644 index 88dbaa226..000000000 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoaderNet4.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 649886f2803ade846a93be89f73e35c7 -timeCreated: 1517899576 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM.Samples/Scripts/ViewerUI.cs b/Assets/VRM.Samples/Scripts/ViewerUI.cs index 7c83452fa..81af05dc5 100644 --- a/Assets/VRM.Samples/Scripts/ViewerUI.cs +++ b/Assets/VRM.Samples/Scripts/ViewerUI.cs @@ -314,15 +314,15 @@ namespace VRM.Samples var parser = new GltfParser(); parser.ParseGlb(file); - var context = new VRMImporterContext(parser); - await m_texts.UpdateMetaAsync(context); - await context.LoadAsync(); - - context.DisposeOnGameObjectDestroyed(); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - context.ShowMeshes(); - SetModel(context.Root); + using (var context = new VRMImporterContext(parser)) + { + await m_texts.UpdateMetaAsync(context); + await context.LoadAsync(); + context.EnableUpdateWhenOffscreen(); + context.ShowMeshes(); + context.DisposeOnGameObjectDestroyed(); + SetModel(context.Root); + } break; } @@ -334,10 +334,9 @@ namespace VRM.Samples var context = new UniGLTF.ImporterContext(parser); context.Load(); - context.DisposeOnGameObjectDestroyed(); - context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); + context.DisposeOnGameObjectDestroyed(); SetModel(context.Root); break; } @@ -350,10 +349,9 @@ namespace VRM.Samples var context = new UniGLTF.ImporterContext(parser); context.Load(); - context.DisposeOnGameObjectDestroyed(); - context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); + context.DisposeOnGameObjectDestroyed(); SetModel(context.Root); break; } diff --git a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs index 3d37da6cf..350052dca 100644 --- a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs +++ b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs @@ -1,42 +1,26 @@ -using System.Collections; +using System; using System.Collections.Generic; +using System.Linq; using UniGLTF; +using UnityEditor; using UnityEngine; namespace VRM { - public class VRMEditorImporterContext : EditorImporterContext + public class VRMEditorImporterContext { VRMImporterContext m_context; + UnityPath m_prefabPath; + List m_paths = new List(); - public VRMEditorImporterContext(VRMImporterContext context) : base(context) + + public VRMEditorImporterContext(VRMImporterContext context, UnityPath prefabPath) { m_context = context; + m_prefabPath = prefabPath; } - public override IEnumerable ObjectsForSubAsset() - { - foreach (var x in base.ObjectsForSubAsset()) - { - yield return x; - } - - yield return m_context.AvatarDescription; - yield return m_context.HumanoidAvatar; - - if (m_context.BlendShapeAvatar != null && m_context.BlendShapeAvatar.Clips != null) - { - foreach (var x in m_context.BlendShapeAvatar.Clips) - { - yield return x; - } - } - yield return m_context.BlendShapeAvatar; - - yield return m_context.Meta; - } - - public override bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) + public bool AvoidOverwriteAndLoad(UnityPath assetPath, UnityEngine.Object o) { if (o is BlendShapeAvatar) { @@ -52,10 +36,36 @@ namespace VRM return true; } - return base.AvoidOverwriteAndLoad(assetPath, o); + if (o is Material) + { + var loaded = assetPath.LoadAsset(); + if (loaded == null) + { + throw new Exception(); + } + + // replace component reference + foreach (var mesh in m_context.Meshes) + { + foreach (var r in mesh.Renderers) + { + for (int i = 0; i < r.sharedMaterials.Length; ++i) + { + if (r.sharedMaterials.Contains(o)) + { + r.sharedMaterials = r.sharedMaterials.Select(x => x == o ? loaded : x).ToArray(); + } + } + } + } + + return true; + } + + return false; } - public override UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o, bool meshAsSubAsset) + public UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o) { if (o is BlendShapeAvatar || o is BlendShapeClip) @@ -82,9 +92,141 @@ namespace VRM var assetPath = dir.Child(o.name.EscapeFilePath() + ".asset"); return assetPath; } + else if (o is Material) + { + var materialDir = prefabPath.GetAssetFolder(".Materials"); + var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); + return materialPath; + } + // texture is already extracted + // else if (o is Texture2D) + // { + // var textureDir = prefabPath.GetAssetFolder(".Textures"); + // var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); + // return texturePath; + // } + else if (o is Mesh) + { + var meshDir = prefabPath.GetAssetFolder(".Meshes"); + var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); + return meshPath; + } else { - return base.GetAssetPath(prefabPath, o, meshAsSubAsset); + return default(UnityPath); + } + } + + /// + /// Extract images from glb or gltf out of Assets folder. + /// + /// + public void ConvertAndExtractImages(UnityPath assetPath, Action> onTextureReloaded) + { + // + // convert images(metallic roughness, occlusion map) + // + var task = m_context.MaterialFactory.LoadMaterialsAsync(default(ImmediateCaller), m_context.TextureFactory.GetTextureAsync); + if (!task.IsCompleted) + { + throw new Exception(); + } + if (task.IsFaulted) + { + if (task.Exception is AggregateException ae && ae.InnerExceptions.Count == 1) + { + throw ae.InnerException; + } + else + { + throw task.Exception; + } + } + + // + // extract converted textures + // + var subAssets = m_context.TextureFactory.Textures + .Where(x => x.IsUsed) + .Select(x => x.Texture) + .ToArray(); + var prefabParentDir = assetPath.Parent; + var folder = assetPath.GetAssetFolder(".Textures"); + TextureExtractor.ExtractTextures(assetPath.Value, subAssets, _ => { }, onTextureReloaded); + } + + bool SaveAsAsset(UnityEngine.Object o) + { + if (o is GameObject) + { + return false; + } + + if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o))) + { + // already exists. not dispose +#if VRM_DEVELOP + Debug.Log($"Loaded. skip: {o}"); +#endif + return true; + } + + var assetPath = GetAssetPath(m_prefabPath, o); + if (assetPath.IsNull) + { + // not dispose + return true; + } + +// if (assetPath.IsFileExists) +// { +// if (AvoidOverwriteAndLoad(assetPath, o)) +// { +// #if VRM_DEVELOP +// Debug.Log($"AvoidOverwriteAndLoad: {assetPath}"); +// #endif +// // 上書きせずに既存のアセットからロードして置き換えた +// return true; +// } +// } + + // アセットとして書き込む + assetPath.Parent.EnsureFolder(); + assetPath.CreateAsset(o); + m_paths.Add(assetPath); + + // 所有権が移動 + return true; + } + + public void SaveAsAsset() + { + m_context.ShowMeshes(); + + // + // save sub assets + // + m_paths.Clear(); + m_paths.Add(m_prefabPath); + m_context.TransferOwnership(SaveAsAsset); + + // Create or update Main Asset + if (m_prefabPath.IsFileExists) + { + Debug.LogFormat("replace prefab: {0}", m_prefabPath); + var prefab = m_prefabPath.LoadAsset(); + PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, m_prefabPath.Value, InteractionMode.AutomatedAction); + + } + else + { + Debug.LogFormat("create prefab: {0}", m_prefabPath); + PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, m_prefabPath.Value, InteractionMode.AutomatedAction); + } + + foreach (var x in m_paths) + { + x.ImportAsset(); } } } diff --git a/Assets/VRM/Editor/Format/VRMImporterMenu.cs b/Assets/VRM/Editor/Format/VRMImporterMenu.cs index ca5e8f7ed..61be120de 100644 --- a/Assets/VRM/Editor/Format/VRMImporterMenu.cs +++ b/Assets/VRM/Editor/Format/VRMImporterMenu.cs @@ -2,7 +2,8 @@ using UnityEditor; using UnityEngine; using UniGLTF; - +using System; +using System.Collections.Generic; namespace VRM { @@ -22,11 +23,15 @@ namespace VRM // load into scene var parser = new GltfParser(); parser.ParsePath(path); - var context = new VRMImporterContext(parser); - context.Load(); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - Selection.activeGameObject = context.Root; + + using (var context = new VRMImporterContext(parser)) + { + context.Load(); + context.EnableUpdateWhenOffscreen(); + context.ShowMeshes(); + context.DisposeOnGameObjectDestroyed(); + Selection.activeGameObject = context.Root; + } } else { @@ -52,19 +57,25 @@ namespace VRM var prefabPath = UnityPath.FromUnityPath(assetPath); var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); - var context = new VRMImporterContext(parser); - var editor = new VRMEditorImporterContext(context); - editor.ExtractImages(prefabPath); - EditorApplication.delayCall += () => + Action> onCompleted = _ => { // // after textures imported // - context.Load(); - editor.SaveAsAsset(prefabPath); - editor.Dispose(); + using (var context = new VRMImporterContext(parser)) + { + var editor = new VRMEditorImporterContext(context, prefabPath); + context.Load(); + editor.SaveAsAsset(); + } }; + + using (var context = new VRMImporterContext(parser)) + { + var editor = new VRMEditorImporterContext(context, prefabPath); + editor.ConvertAndExtractImages(UnityPath.FromFullpath(path), onCompleted); + } } } } diff --git a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs index d48480048..630bffa37 100644 --- a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs +++ b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using UniGLTF; using UnityEditor; using UnityEngine; @@ -37,41 +38,31 @@ namespace VRM } var parser = new GltfParser(); - try - { - parser.ParseGlb(File.ReadAllBytes(path.FullPath)); - } - catch (KeyNotFoundException) - { - // invalid VRM-0.X. - // maybe VRM-1.0.do nothing - return; - } + parser.ParseGlb(File.ReadAllBytes(path.FullPath)); var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab"); - // save texture assets ! - LoadTextureAsyncFunc textureLoader = async (caller, textureIndex, used) => + Action> onCompleted = texturePaths => { - var gltfTexture = parser.GLTF.textures[textureIndex]; - var gltfImage = parser.GLTF.images[gltfTexture.source]; - var assetPath = prefabPath.Parent.Child(gltfImage.uri); - var texture = await UniGLTF.AssetTextureLoader.LoadTaskAsync(assetPath, parser.GLTF, textureIndex); - return new TextureLoadInfo(texture, used, false); + var map = texturePaths.Select(x => + { + var texture = AssetDatabase.LoadAssetAtPath(x, typeof(Texture2D)); + return (texture.name, texture); + }).ToArray(); + using (var context = new VRMImporterContext(parser, null, map)) + { + var editor = new VRMEditorImporterContext(context, prefabPath); + context.Load(); + editor.SaveAsAsset(); + } }; - var context = new VRMImporterContext(parser, textureLoader); - var editor = new VRMEditorImporterContext(context); - editor.ExtractImages(prefabPath); - EditorApplication.delayCall += () => + // extract texture images + using (var context = new VRMImporterContext(parser)) { - // - // after textures imported - // - context.Load(); - editor.SaveAsAsset(prefabPath); - editor.Dispose(); - }; + var editor = new VRMEditorImporterContext(context, prefabPath); + editor.ConvertAndExtractImages(path, onCompleted); + } } } #endif diff --git a/Assets/VRM/Runtime/Format/glTF_VRM_extensions.cs b/Assets/VRM/Runtime/Format/glTF_VRM_extensions.cs index 26340156d..19b41c3d4 100644 --- a/Assets/VRM/Runtime/Format/glTF_VRM_extensions.cs +++ b/Assets/VRM/Runtime/Format/glTF_VRM_extensions.cs @@ -28,7 +28,7 @@ VRM extension is for 3d humanoid avatars (and models) in VR applications. public glTF_VRM_SecondaryAnimation secondaryAnimation = new glTF_VRM_SecondaryAnimation(); public List materialProperties = new List(); - public static bool TryDeserilize(glTFExtension extension, out glTF_VRM_extensions vrm) + public static bool TryDeserialize(glTFExtension extension, out glTF_VRM_extensions vrm) { if (extension is glTFExtensionImport import) { diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index cf6fa6d51..8279fc9cf 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -8,16 +8,16 @@ using System.Threading.Tasks; namespace VRM { - - public class VRMImporterContext : ImporterContext { public VRM.glTF_VRM_extensions VRM { get; private set; } - public VRMImporterContext(GltfParser parser, UniGLTF.LoadTextureAsyncFunc asyncTextureLoader = null) : base(parser, asyncTextureLoader) + public VRMImporterContext(GltfParser parser, + UniGLTF.LoadTextureAsyncFunc asyncTextureLoader = null, + IEnumerable<(string, UnityEngine.Object)> externalObjectMap = null) : base(parser, asyncTextureLoader, externalObjectMap) { // parse VRM part - if (glTF_VRM_extensions.TryDeserilize(GLTF.extensions, out glTF_VRM_extensions vrm)) + if (glTF_VRM_extensions.TryDeserialize(GLTF.extensions, out glTF_VRM_extensions vrm)) { VRM = vrm; // override material importer @@ -290,7 +290,10 @@ namespace VRM meta.ContactInformation = gltfMeta.contactInformation; meta.Reference = gltfMeta.reference; meta.Title = gltfMeta.title; - meta.Thumbnail = await TextureFactory.GetTextureAsync(awaitCaller, GLTF, GetTextureParam.Create(GLTF, gltfMeta.texture)); + if (gltfMeta.texture >= 0) + { + meta.Thumbnail = await TextureFactory.GetTextureAsync(awaitCaller, GLTF, GetTextureParam.Create(GLTF, gltfMeta.texture)); + } meta.AllowedUser = gltfMeta.allowedUser; meta.ViolentUssage = gltfMeta.violentUssage; meta.SexualUssage = gltfMeta.sexualUssage; @@ -303,22 +306,44 @@ namespace VRM return meta; } - public override IEnumerable ModelOwnResources() + public override void TransferOwnership(TakeOwnershipFunc take) { - foreach (var x in base.ModelOwnResources()) + // VRM 固有のリソース(ScriptableObject) + if (take(HumanoidAvatar)) { - yield return x; + HumanoidAvatar = null; } - // VRM 固有のリソース(ScriptableObject) - yield return HumanoidAvatar; - yield return AvatarDescription; - yield return Meta; + if (take(Meta)) + { + Meta = null; + } + + if (take(AvatarDescription)) + { + AvatarDescription = null; + } + + var list = new List(); foreach (var x in BlendShapeAvatar.Clips) { - yield return x; + if (take(x)) + { + list.Add(x); + } } - yield return BlendShapeAvatar; + foreach (var x in list) + { + BlendShapeAvatar.Clips.Remove(x); + } + + if (take(BlendShapeAvatar)) + { + BlendShapeAvatar = null; + } + + // GLTF のリソース + base.TransferOwnership(take); } } } diff --git a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs index ca927176e..042bbd7e2 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs @@ -37,7 +37,9 @@ namespace VRM } else { - Debug.LogWarningFormat("unknown shader {0}.", shaderName); +// #if VRM_DEVELOP +// Debug.LogWarningFormat("unknown shader {0}.", shaderName); +// #endif } return await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, gltf, m_index, getTexture); }