diff --git a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs b/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs index 32b1b603d..0f859c140 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ImporterMenu.cs @@ -21,8 +21,10 @@ namespace UniGLTF // // load into scene // - var context = new ImporterContext(); - context.Load(path); + var parser = new GltfParser(); + parser.ParsePath(path); + var context = new ImporterContext(parser); + context.Load(); context.ShowMeshes(); Selection.activeGameObject = context.Root; } diff --git a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs b/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs index c1e884c08..0b326329f 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/gltfAssetPostprocessor.cs @@ -44,8 +44,9 @@ namespace UniGLTF return; } - var context = new ImporterContext(); - context.Parse(src); + var parser = new GltfParser(); + parser.ParsePath(src); + var context = new ImporterContext(parser); // Extract textures to assets folder context.ExtractImages(prefabPath); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs new file mode 100644 index 000000000..faf3fb02c --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UniJSON; +using UnityEngine; + +namespace UniGLTF +{ + public class GltfParser + { + /// + /// JSON source + /// + public String Json; + + /// + /// GLTF parsed from JSON + /// + public glTF GLTF; + + /// + /// URI access + /// + public IStorage Storage; + + public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor) + { + if (string.IsNullOrEmpty(generatorVersion)) return false; + if (generatorVersion == "UniGLTF") return true; + if (!generatorVersion.FastStartsWith("UniGLTF-")) return false; + + try + { + var splitted = generatorVersion.Substring(8).Split('.'); + var generatorMajor = int.Parse(splitted[0]); + var generatorMinor = int.Parse(splitted[1]); + + if (generatorMajor < major) + { + return true; + } + else if (generatorMajor > major) + { + return false; + } + else + { + if (generatorMinor >= minor) + { + return false; + } + else + { + return true; + } + } + } + catch (Exception ex) + { + Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex); + return false; + } + } + + public bool IsGeneratedUniGLTFAndOlder(int major, int minor) + { + if (GLTF == null) return false; + if (GLTF.asset == null) return false; + return IsGeneratedUniGLTFAndOlderThan(GLTF.asset.generator, major, minor); + } + + #region Parse + public void ParsePath(string path) + { + Parse(path, File.ReadAllBytes(path)); + } + + /// + /// Parse gltf json or Parse json chunk of glb + /// + /// + /// + public virtual void Parse(string path, Byte[] bytes) + { + var ext = Path.GetExtension(path).ToLower(); + switch (ext) + { + case ".gltf": + ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path))); + break; + + case ".zip": + { + var zipArchive = Zip.ZipArchiveStorage.Parse(bytes); + var gltf = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf")); + if (gltf == null) + { + throw new Exception("no gltf in archive"); + } + var jsonBytes = zipArchive.Extract(gltf); + var json = Encoding.UTF8.GetString(jsonBytes); + ParseJson(json, zipArchive); + } + break; + + default: + ParseGlb(bytes); + break; + } + } + + /// + /// + /// + /// + public void ParseGlb(Byte[] bytes) + { + var chunks = glbImporter.ParseGlbChunks(bytes); + + if (chunks.Count != 2) + { + throw new Exception("unknown chunk count: " + chunks.Count); + } + + if (chunks[0].ChunkType != GlbChunkType.JSON) + { + throw new Exception("chunk 0 is not JSON"); + } + + if (chunks[1].ChunkType != GlbChunkType.BIN) + { + throw new Exception("chunk 1 is not BIN"); + } + + try + { + var jsonBytes = chunks[0].Bytes; + ParseJson(Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count), + new SimpleStorage(chunks[1].Bytes)); + } + catch (StackOverflowException ex) + { + throw new Exception("[UniVRM Import Error] json parsing failed, nesting is too deep.\n" + ex); + } + catch + { + throw; + } + } + + public virtual void ParseJson(string json, IStorage storage) + { + Json = json; + Storage = storage; + GLTF = GltfDeserializer.Deserialize(json.ParseAsJson()); + if (GLTF.asset.version != "2.0") + { + throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); + } + + // Version Compatibility + RestoreOlderVersionValues(); + + FixUnique(); + FixNodeName(); + + // parepare byte buffer + //GLTF.baseDir = System.IO.Path.GetDirectoryName(Path); + foreach (var buffer in GLTF.buffers) + { + buffer.OpenStorage(storage); + } + } + + void FixUnique() + { + var used = new HashSet(); + foreach (var mesh in GLTF.meshes) + { + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = "mesh_" + Guid.NewGuid().ToString("N"); + used.Add(mesh.name); + } + else + { + var lname = mesh.name.ToLower(); + if (used.Contains(lname)) + { + // rename + var uname = lname + "_" + Guid.NewGuid().ToString("N"); + Debug.LogWarning($"same name: {lname} => {uname}"); + mesh.name = uname; + lname = uname; + } + + used.Add(lname); + } + } + } + + /// + /// rename empty name to $"{index}" + /// + void FixNodeName() + { + for (var i = 0; i < GLTF.nodes.Count; ++i) + { + var node = GLTF.nodes[i]; + if (string.IsNullOrWhiteSpace(node.name)) + { + node.name = $"{i}"; + } + } + } + + void RestoreOlderVersionValues() + { + var parsed = UniJSON.JsonParser.Parse(Json); + for (int i = 0; i < GLTF.images.Count; ++i) + { + if (string.IsNullOrEmpty(GLTF.images[i].name)) + { + try + { + var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); + if (!string.IsNullOrEmpty(extraName)) + { + //Debug.LogFormat("restore texturename: {0}", extraName); + GLTF.images[i].name = extraName; + } + } + catch (Exception) + { + // do nothing + } + } + } + } + #endregion + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs.meta new file mode 100644 index 000000000..75eba128b --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae3083233546b58449904dca65e76005 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 32ee65408..29359fb5a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -3,8 +3,6 @@ using System.Linq; using System.Collections.Generic; using UnityEngine; using System.IO; -using System.Text; -using UniJSON; using UniGLTF.AltTask; #if UNITY_EDITOR using UnityEditor; @@ -43,247 +41,19 @@ namespace UniGLTF TextureFactory m_textureFactory; public TextureFactory TextureFactory => m_textureFactory; - public ImporterContext() + public ImporterContext(GltfParser parser) { - } - #region Source - - /// - /// JSON source - /// - public String Json; - - /// - /// GLTF parsed from JSON - /// - public glTF GLTF; // parsed - - public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor) - { - if (string.IsNullOrEmpty(generatorVersion)) return false; - if (generatorVersion == "UniGLTF") return true; - if (!generatorVersion.FastStartsWith("UniGLTF-")) return false; - - try - { - var splitted = generatorVersion.Substring(8).Split('.'); - var generatorMajor = int.Parse(splitted[0]); - var generatorMinor = int.Parse(splitted[1]); - - if (generatorMajor < major) - { - return true; - } - else if (generatorMajor > major) - { - return false; - } - else - { - if (generatorMinor >= minor) - { - return false; - } - else - { - return true; - } - } - } - catch (Exception ex) - { - Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex); - return false; - } - } - - public bool IsGeneratedUniGLTFAndOlder(int major, int minor) - { - if (GLTF == null) return false; - if (GLTF.asset == null) return false; - return IsGeneratedUniGLTFAndOlderThan(GLTF.asset.generator, major, minor); - } - - /// - /// URI access - /// - public IStorage Storage; - #endregion - - #region Parse - public void Parse(string path) - { - Parse(path, File.ReadAllBytes(path)); - } - - /// - /// Parse gltf json or Parse json chunk of glb - /// - /// - /// - public virtual void Parse(string path, Byte[] bytes) - { - var ext = Path.GetExtension(path).ToLower(); - switch (ext) - { - case ".gltf": - ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path))); - break; - - case ".zip": - { - var zipArchive = Zip.ZipArchiveStorage.Parse(bytes); - var gltf = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf")); - if (gltf == null) - { - throw new Exception("no gltf in archive"); - } - var jsonBytes = zipArchive.Extract(gltf); - var json = Encoding.UTF8.GetString(jsonBytes); - ParseJson(json, zipArchive); - } - break; - - case ".glb": - ParseGlb(bytes); - break; - - default: - throw new NotImplementedException(); - } - } - - /// - /// - /// - /// - public void ParseGlb(Byte[] bytes) - { - var chunks = glbImporter.ParseGlbChunks(bytes); - - if (chunks.Count != 2) - { - throw new Exception("unknown chunk count: " + chunks.Count); - } - - if (chunks[0].ChunkType != GlbChunkType.JSON) - { - throw new Exception("chunk 0 is not JSON"); - } - - if (chunks[1].ChunkType != GlbChunkType.BIN) - { - throw new Exception("chunk 1 is not BIN"); - } - - try - { - var jsonBytes = chunks[0].Bytes; - ParseJson(Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count), - new SimpleStorage(chunks[1].Bytes)); - } - catch (StackOverflowException ex) - { - throw new Exception("[UniVRM Import Error] json parsing failed, nesting is too deep.\n" + ex); - } - catch - { - throw; - } - } - - public virtual void ParseJson(string json, IStorage storage) - { - Json = json; - Storage = storage; - GLTF = GltfDeserializer.Deserialize(json.ParseAsJson()); - if (GLTF.asset.version != "2.0") - { - throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); - } - + m_parser = parser; m_textureFactory = new TextureFactory(GLTF, Storage); m_materialFactory = new MaterialFactory(GLTF, Storage); - - // Version Compatibility - RestoreOlderVersionValues(); - - FixUnique(); - FixNodeName(); - - // parepare byte buffer - //GLTF.baseDir = System.IO.Path.GetDirectoryName(Path); - foreach (var buffer in GLTF.buffers) - { - buffer.OpenStorage(storage); - } } - void FixUnique() - { - var used = new HashSet(); - foreach (var mesh in GLTF.meshes) - { - if (string.IsNullOrEmpty(mesh.name)) - { - mesh.name = "mesh_" + Guid.NewGuid().ToString("N"); - used.Add(mesh.name); - } - else - { - var lname = mesh.name.ToLower(); - if (used.Contains(lname)) - { - // rename - var uname = lname + "_" + Guid.NewGuid().ToString("N"); - Debug.LogWarning($"same name: {lname} => {uname}"); - mesh.name = uname; - lname = uname; - } - - used.Add(lname); - } - } - } - - /// - /// rename empty name to $"{index}" - /// - void FixNodeName() - { - for (var i = 0; i < GLTF.nodes.Count; ++i) - { - var node = GLTF.nodes[i]; - if (string.IsNullOrWhiteSpace(node.name)) - { - node.name = $"{i}"; - } - } - } - - void RestoreOlderVersionValues() - { - var parsed = UniJSON.JsonParser.Parse(Json); - for (int i = 0; i < GLTF.images.Count; ++i) - { - if (string.IsNullOrEmpty(GLTF.images[i].name)) - { - try - { - var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); - if (!string.IsNullOrEmpty(extraName)) - { - //Debug.LogFormat("restore texturename: {0}", extraName); - GLTF.images[i].name = extraName; - } - } - catch (Exception) - { - // do nothing - } - } - } - } + #region Source + GltfParser m_parser; + public GltfParser Parser => m_parser; + public String Json => m_parser.Json; + public glTF GLTF => m_parser.GLTF; + public IStorage Storage => m_parser.Storage; #endregion #region Load. Build unity objects diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs index 88ef55e69..6d06c9457 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs @@ -6,27 +6,28 @@ namespace UniGLTF { public static class ImporterContextExtensions { - /// - /// ReadAllBytes, Parse, Create GameObject - /// - /// allbytes - public static void Load(this ImporterContext self, string path) - { - var bytes = File.ReadAllBytes(path); - self.Load(path, bytes); - } + // /// + // /// ReadAllBytes, Parse, Create GameObject + // /// + // /// allbytes + // public static void Load(this ImporterContext self, string path) + // { + // var bytes = File.ReadAllBytes(path); + // self.Load(path, bytes); + // } - /// - /// Parse, Create GameObject - /// - /// gltf or glb path - /// allbytes - public static void Load(this ImporterContext self, string path, byte[] bytes) - { - self.Parse(path, bytes); - self.Load(); - self.Root.name = Path.GetFileNameWithoutExtension(path); - } + // /// + // /// Parse, Create GameObject + // /// + // /// gltf or glb path + // /// allbytes + // public static void Load(this ImporterContext self, string path, byte[] bytes) + // { + // var parser = new GltfParser(); + // parser.Parse(path, bytes); + // self.Load(parser); + // self.Root.name = Path.GetFileNameWithoutExtension(path); + // } /// /// Build unity objects from parsed gltf diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs index ce0bdb40c..1409dcb0e 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs @@ -154,7 +154,7 @@ namespace UniGLTF { throw new Exception("different length"); } - if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) + if (ctx.Parser.IsGeneratedUniGLTFAndOlder(1, 16)) { #pragma warning disable 0612 // backward compatibility @@ -317,7 +317,7 @@ namespace UniGLTF // uv if (prim.attributes.TEXCOORD_0 != -1) { - if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) + if (ctx.Parser.IsGeneratedUniGLTFAndOlder(1, 16)) { #pragma warning disable 0612 // backward compatibility diff --git a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs index 8d0ce2d1b..cc2ce351d 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs @@ -98,7 +98,7 @@ namespace UniGLTF public void UniGLTFSimpleSceneTest() { var go = CreateSimpleScene(); - var context = new ImporterContext(); + ImporterContext context = default; try { @@ -117,9 +117,12 @@ namespace UniGLTF json = gltf.ToJson(); } + // parse + var parser = new GltfParser(); + parser.ParseJson(json, new SimpleStorage(new ArraySegment())); + // import - context.ParseJson(json, new SimpleStorage(new ArraySegment())); - //Debug.LogFormat("{0}", context.Json); + context = new ImporterContext(parser); context.Load(); AssertAreEqual(go.transform, context.Root.transform); @@ -128,7 +131,10 @@ namespace UniGLTF { //Debug.LogFormat("Destroy, {0}", go.name); GameObject.DestroyImmediate(go); - context.EditorDestroyRootAndAssets(); + if (context != null) + { + context.EditorDestroyRootAndAssets(); + } } } @@ -191,12 +197,12 @@ namespace UniGLTF [Test] public void VersionChecker() { - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16)); - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16)); - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16)); + Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16)); + Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16)); + Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16)); + Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16)); + Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16)); + Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16)); } [Test] @@ -439,7 +445,7 @@ namespace UniGLTF public void SkinTestEmptyName() { var model = new glTFSkin() - { + { name = "", inverseBindMatrices = 4, joints = new int[] { 1 }, @@ -559,8 +565,9 @@ namespace UniGLTF // import { - var context = new ImporterContext(); - context.ParseJson(json, new SimpleStorage(new ArraySegment(new byte[1024 * 1024]))); + 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(); @@ -577,9 +584,10 @@ namespace UniGLTF // import new version { - var context = new ImporterContext(); - context.ParseJson(json, new SimpleStorage(new ArraySegment(new byte[1024 * 1024]))); + 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(); var importedRed = context.Root.transform.GetChild(0); diff --git a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs index ebbcf2b28..fb7203026 100644 --- a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs +++ b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs @@ -42,8 +42,10 @@ namespace VRM.Samples public void ImportExportTest() { var path = AliciaPath; - var context = new VRMImporterContext(); - context.ParseGlb(File.ReadAllBytes(path)); + var parser = new GltfParser(); + parser.ParseGlb(File.ReadAllBytes(path)); + + var context = new VRMImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); @@ -114,8 +116,9 @@ namespace VRM.Samples public void MeshCopyTest() { var path = AliciaPath; - var context = new VRMImporterContext(); - context.ParseGlb(File.ReadAllBytes(path)); + var parser = new GltfParser(); + parser.ParseGlb(File.ReadAllBytes(path)); + var context = new VRMImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); @@ -133,8 +136,9 @@ namespace VRM.Samples { // Aliciaを古いデシリアライザでロードする var path = AliciaPath; - var context = new VRMImporterContext(); - context.ParseGlb(File.ReadAllBytes(path)); + var parser = new GltfParser(); + parser.ParseGlb(File.ReadAllBytes(path)); + var context = new VRMImporterContext(parser); var oldJson = context.GLTF.ToJson().ParseAsJson().ToString(" "); // 生成シリアライザでJSON化する diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs index 53f846acd..888a4dc66 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs @@ -46,11 +46,11 @@ namespace VRM.Samples var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た - var context = new VRMImporterContext(); - // GLB形式でJSONを取得しParseします - context.ParseGlb(bytes); + var parser = new GltfParser(); + parser.ParseGlb(bytes); + var context = new VRMImporterContext(parser); // metaを取得(todo: thumbnailテクスチャのロード) var meta = await context.ReadMetaAsync(); diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs index 34aba0ad2..192de0f0f 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs @@ -1,14 +1,11 @@ #pragma warning disable 0414 using System.IO; using UniGLTF; -using UniGLTF.AltTask; using UnityEngine; namespace VRM.Samples { - - public class VRMRuntimeLoader : MonoBehaviour { [SerializeField] @@ -89,33 +86,33 @@ namespace VRM.Samples var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た - var context = new VRMImporterContext(); - // GLB形式でJSONを取得しParseします - context.ParseGlb(bytes); + 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) { - await LoadAsync(context); + await context.LoadAsync(); } else { - context.LoadAsync(); - OnLoaded(context); + context.Load(); } + + OnLoaded(context); } /// /// メタが不要な場合のローダー /// - void LoadVRMClicked_without_meta() + async void LoadVRMClicked_without_meta() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); @@ -129,55 +126,23 @@ namespace VRM.Samples return; } -#if true var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た - var context = new VRMImporterContext(); - // GLB形式でJSONを取得しParseします - context.ParseGlb(bytes); + var parser = new GltfParser(); + parser.ParseGlb(bytes); + var context = new VRMImporterContext(parser); if (m_loadAsync) { - // ローカルファイルシステムからロードします - LoadAsync(context); + await context.LoadAsync(); } else { context.Load(); - OnLoaded(context); } - -#else - // ParseしたJSONをシーンオブジェクトに変換していく - if (m_loadAsync) - { - // ローカルファイルシステムからロードします - VRMImporter.LoadVrmAsync(path, OnLoaded); - } - else - { - var root=VRMImporter.LoadFromPath(path); - OnLoaded(root); - } -#endif - } - - - async Awaitable LoadAsync(VRMImporterContext context) - { -#if true - var now = Time.time; - await context.LoadAsync(); - - var delta = Time.time - now; - Debug.LogFormat("LoadAsync {0:0.0} seconds", delta); OnLoaded(context); -#else - // ローカルファイルシステムからロードします - VRMImporter.LoadVrmAsync(path, OnLoaded); -#endif } void LoadBVHClicked() diff --git a/Assets/VRM.Samples/Scripts/ViewerUI.cs b/Assets/VRM.Samples/Scripts/ViewerUI.cs index a760a8fc6..b5fcfb76f 100644 --- a/Assets/VRM.Samples/Scripts/ViewerUI.cs +++ b/Assets/VRM.Samples/Scripts/ViewerUI.cs @@ -309,15 +309,15 @@ namespace VRM.Samples { case ".vrm": { - var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); - context.ParseGlb(file); + + var parser = new GltfParser(); + parser.ParseGlb(file); + + var context = new VRMImporterContext(parser); await m_texts.UpdateMetaAsync(context); -#if true await context.LoadAsync(); -#else - context.Load(); -#endif + context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); @@ -327,9 +327,11 @@ namespace VRM.Samples case ".glb": { - var context = new UniGLTF.ImporterContext(); var file = File.ReadAllBytes(path); - context.ParseGlb(file); + var parser = new GltfParser(); + parser.ParseGlb(file); + + var context = new UniGLTF.ImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); @@ -341,8 +343,10 @@ namespace VRM.Samples case ".gltf": case ".zip": { - var context = new UniGLTF.ImporterContext(); - context.Parse(path); + var parser = new GltfParser(); + parser.ParsePath(path); + + var context = new UniGLTF.ImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); diff --git a/Assets/VRM/Editor/Format/VRMImporterMenu.cs b/Assets/VRM/Editor/Format/VRMImporterMenu.cs index 59d4430a6..0741f360b 100644 --- a/Assets/VRM/Editor/Format/VRMImporterMenu.cs +++ b/Assets/VRM/Editor/Format/VRMImporterMenu.cs @@ -20,8 +20,10 @@ namespace VRM if (Application.isPlaying) { // load into scene - var context = new VRMImporterContext(); - context.Load(path); + var parser = new GltfParser(); + parser.ParsePath(path); + var context = new VRMImporterContext(parser); + context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); Selection.activeGameObject = context.Root; @@ -48,8 +50,9 @@ namespace VRM // import as asset var prefabPath = UnityPath.FromUnityPath(assetPath); - var context = new VRMImporterContext(); - context.ParseGlb(File.ReadAllBytes(path)); + var parser = new GltfParser(); + parser.ParseGlb(File.ReadAllBytes(path)); + var context = new VRMImporterContext(parser); context.ExtractImages(prefabPath); EditorApplication.delayCall += () => diff --git a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs index 8bdcaaab0..5806cdfad 100644 --- a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs +++ b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs @@ -36,11 +36,11 @@ namespace VRM { throw new Exception(); } - var context = new VRMImporterContext(); + var parser = new GltfParser(); try { - context.ParseGlb(File.ReadAllBytes(path.FullPath)); + parser.ParseGlb(File.ReadAllBytes(path.FullPath)); } catch (KeyNotFoundException) { @@ -52,6 +52,7 @@ namespace VRM var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab"); // save texture assets ! + var context = new VRMImporterContext(parser); context.ExtractImages(prefabPath); EditorApplication.delayCall += () => diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 428368341..76c09dc30 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -15,30 +15,8 @@ namespace VRM { public VRM.glTF_VRM_extensions VRM { get; private set; } - public VRMImporterContext() + public VRMImporterContext(GltfParser parser) : base(parser) { - } - - public override void Parse(string path, byte[] bytes) - { - var ext = Path.GetExtension(path).ToLower(); - switch (ext) - { - case ".vrm": - ParseGlb(bytes); - break; - - default: - base.Parse(path, bytes); - break; - } - } - - public override void ParseJson(string json, IStorage storage) - { - // parse GLTF part(core + unlit, textureTransform, targetNames) - base.ParseJson(json, storage); - // parse VRM part if (glTF_VRM_extensions.TryDeserilize(GLTF.extensions, out glTF_VRM_extensions vrm)) { diff --git a/Assets/VRM10.Samples/Runtime/ViewerUI.cs b/Assets/VRM10.Samples/Runtime/ViewerUI.cs index b23a42874..3d87e4089 100644 --- a/Assets/VRM10.Samples/Runtime/ViewerUI.cs +++ b/Assets/VRM10.Samples/Runtime/ViewerUI.cs @@ -333,9 +333,11 @@ namespace UniVRM10.Samples case ".glb": { - var context = new UniGLTF.ImporterContext(); var file = File.ReadAllBytes(path); - context.ParseGlb(file); + var parser = new GltfParser(); + parser.ParseGlb(file); + + var context = new UniGLTF.ImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); @@ -347,8 +349,10 @@ namespace UniVRM10.Samples case ".gltf": case ".zip": { - var context = new UniGLTF.ImporterContext(); - context.Parse(path); + var parser = new GltfParser(); + parser.ParsePath(path); + + var context = new UniGLTF.ImporterContext(parser); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen();