From d1a18fdd4ed8e2610294410b45e33a5a584e8110 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 30 Mar 2018 16:51:56 +0900 Subject: [PATCH] add VRMImporterContext.ParseVrm and VRMImporterContext.ReadMeta --- Scripts/Editor/VRMTest.cs | 2 +- .../Format/Editor/vrmAssetPostprocessor.cs | 4 +- Scripts/Format/VRMImporter.cs | 156 ++---------------- Scripts/Format/VRMImporterContext.cs | 32 ++++ Scripts/RuntimeLoader/VRMRuntimeLoader.cs | 60 ++++--- 5 files changed, 82 insertions(+), 172 deletions(-) diff --git a/Scripts/Editor/VRMTest.cs b/Scripts/Editor/VRMTest.cs index fe607c0b8..6f475dd31 100644 --- a/Scripts/Editor/VRMTest.cs +++ b/Scripts/Editor/VRMTest.cs @@ -46,7 +46,7 @@ public class VRMTest public void VRMSimpleSceneTest() { var go = CreateSimpelScene(); - var context = new VRMImporterContext(); + var context = new VRMImporterContext(null); try { diff --git a/Scripts/Format/Editor/vrmAssetPostprocessor.cs b/Scripts/Format/Editor/vrmAssetPostprocessor.cs index ddf649074..b7c5a5f06 100644 --- a/Scripts/Format/Editor/vrmAssetPostprocessor.cs +++ b/Scripts/Format/Editor/vrmAssetPostprocessor.cs @@ -15,10 +15,10 @@ namespace VRM var ext = Path.GetExtension(path).ToLower(); if (ext == ".vrm") { - VRMImporterContext context = null; + var context = new VRMImporterContext(path); try { - context=VRMImporter.LoadFromPath(path); + VRMImporter.LoadFromPath(context); /* var prefabPath = String.Format("{0}/{1}.prefab", diff --git a/Scripts/Format/VRMImporter.cs b/Scripts/Format/VRMImporter.cs index 1fe7ce5f1..d6a7366b3 100644 --- a/Scripts/Format/VRMImporter.cs +++ b/Scripts/Format/VRMImporter.cs @@ -16,43 +16,17 @@ namespace VRM const string HUMANOID_KEY = "humanoid"; const string MATERIAL_KEY = "materialProperties"; - public static VRMImporterContext LoadFromPath(string path) + public static void LoadFromPath(VRMImporterContext context) { - return LoadFromBytes(File.ReadAllBytes(path), path); + var dataChunk = context.ParseVrm(File.ReadAllBytes(context.Path)); + LoadFromBytes(context, dataChunk); } - public static VRMImporterContext LoadFromBytes(byte[] bytes, string path=null) + public static void LoadFromBytes(VRMImporterContext context, ArraySegment dataChunk) { - var context = new VRMImporterContext(); - if (!string.IsNullOrEmpty(path)) - { - context.Path = path; - } + context.CreateMaterial = VRMImporter.GetMaterialFunc(glTF_VRM_Material.Parse(context.Json)); - var chunks = glbImporter.ParseGlbChanks(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"); - } - - var jsonBytes = chunks[0].Bytes; - var json = Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count); - - context.Json = json; - context.CreateMaterial = VRMImporter.GetMaterialFunc(glTF_VRM_Material.Parse(json)); - - gltfImporter.Import(context, chunks[1].Bytes); + gltfImporter.Import(context, dataChunk); if (string.IsNullOrEmpty(context.Path)) { if (string.IsNullOrEmpty(context.VRM.extensions.VRM.meta.title)) @@ -72,8 +46,6 @@ namespace VRM OnLoadModel(context); context.ShowMeshes(); - - return context; } public static CreateMaterialFunc GetMaterialFunc(List materials) @@ -156,17 +128,8 @@ namespace VRM static void LoadMeta(VRMImporterContext context) { - var meta = ScriptableObject.CreateInstance(); - meta.name = "Meta"; - var gltfMeta = context.VRM.extensions.VRM.meta; - meta.Author = gltfMeta.author; - meta.ContactInformation = gltfMeta.contactInformation; - meta.Title = gltfMeta.title; - if (gltfMeta.texture != -1) - { - meta.Thumbnail = context.Textures[gltfMeta.texture].Texture; - } - else + var meta = context.ReadMeta(); + if (meta.Thumbnail == null) { // 作る var lookAt = context.Root.GetComponent(); @@ -175,10 +138,6 @@ namespace VRM meta.Thumbnail = thumbnail; context.Textures.Add(new TextureItem(thumbnail)); } - meta.LicenseType = gltfMeta.licenseType; - meta.OtherLicenseUrl = gltfMeta.otherLicenseUrl; - meta.Reference = gltfMeta.reference; - var _meta = context.Root.AddComponent(); _meta.Meta = meta; context.Meta = meta; @@ -497,100 +456,21 @@ namespace VRM yield return null; } - public static void LoadVrmAsync(Byte[] bytes, Action onLoaded) - { - var ctx = new VRMImporterContext(); - LoadVrmAsync(ctx, bytes, onLoaded); - } - - public static void LoadVrmAsync(string path, Action onLoaded) - { - var ctx = new VRMImporterContext - { - Path = path, - }; - - var schedule = Schedulable.Create(); - - schedule.AddTask(MainThreadDispatcher.Instance.ThreadScheduler, () => - { - return File.ReadAllBytes(path); - }) - .Subscribe(MainThreadDispatcher.Instance.UnityScheduler, - bytes => - { - LoadVrmAsync(ctx, bytes, onLoaded); - }, - ex => - { - ctx.Destroy(true); - Debug.LogErrorFormat("Error in scheduler: {0}", ex); - }) - ; - } - - public static void LoadVrmAsync(VRMImporterContext ctx, Byte[] bytes, Action onLoaded) - { - var schedule = Schedulable.Create(); - - schedule - .AddTask(MainThreadDispatcher.Instance.ThreadScheduler, () => - { - return glbImporter.ParseGlbChanks(bytes); - }) - .ContinueWith(MainThreadDispatcher.Instance.ThreadScheduler, chunks => - { - 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"); - } - - var jsonBytes = chunks[0].Bytes; - ctx.Json = Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count); - - //var parsed = json.ParseAsJson(); - ctx.GLTF = JsonUtility.FromJson(ctx.Json); - if (ctx.GLTF.asset.version != "2.0") - { - throw new VRMException("unknown gltf version {0}", ctx.GLTF.asset.version); - } - ctx.GLTF.baseDir = Path.GetDirectoryName(ctx.Path); - foreach (var buffer in ctx.GLTF.buffers) - { - buffer.OpenStorage(ctx.GLTF.baseDir, chunks[1].Bytes); - } - - return Unit.Default; - }) - .Subscribe(MainThreadDispatcher.Instance.UnityScheduler, - _ => - { - BuildAsync(ctx, onLoaded); - }, - ex => - { - ctx.Destroy(true); - Debug.LogErrorFormat("Error in scheduler: {0}", ex); - }) - ; - } - - static void BuildAsync(VRMImporterContext ctx, Action onLoaded) + public static void LoadVrmAsync(VRMImporterContext ctx, ArraySegment chunkData, Action onLoaded) { var schedulable = Schedulable.Create(); schedulable .AddTask(MainThreadDispatcher.Instance.ThreadScheduler, () => + { + ctx.GLTF.baseDir = Path.GetDirectoryName(ctx.Path); + foreach (var buffer in ctx.GLTF.buffers) + { + buffer.OpenStorage(ctx.GLTF.baseDir, chunkData); + } + return Unit.Default; + }) + .ContinueWith(MainThreadDispatcher.Instance.ThreadScheduler, _ => { return glTF_VRM_Material.Parse(ctx.Json); }) diff --git a/Scripts/Format/VRMImporterContext.cs b/Scripts/Format/VRMImporterContext.cs index b0f407204..758325366 100644 --- a/Scripts/Format/VRMImporterContext.cs +++ b/Scripts/Format/VRMImporterContext.cs @@ -7,6 +7,15 @@ namespace VRM { public class VRMImporterContext : ImporterContext { + public VRMImporterContext() + { + + } + public VRMImporterContext(string path) + { + Path = path; + } + public UniHumanoid.AvatarDescription AvatarDescription; public Avatar HumanoidAvatar; public BlendShapeAvatar BlendShapeAvatar; @@ -20,6 +29,29 @@ namespace VRM } } + public System.ArraySegment ParseVrm(byte[] bytes) + { + return ParseGlb(bytes); + } + + public VRMMetaObject ReadMeta() + { + var meta=ScriptableObject.CreateInstance(); + meta.name = "Meta"; + var gltfMeta = VRM.extensions.VRM.meta; + meta.Author = gltfMeta.author; + meta.ContactInformation = gltfMeta.contactInformation; + meta.Title = gltfMeta.title; + if (gltfMeta.texture != -1) + { + meta.Thumbnail = Textures[gltfMeta.texture].Texture; + } + meta.LicenseType = gltfMeta.licenseType; + meta.OtherLicenseUrl = gltfMeta.otherLicenseUrl; + meta.Reference = gltfMeta.reference; + return meta; + } + #if UNITY_EDITOR protected override IEnumerable ObjectsForSubAsset() { diff --git a/Scripts/RuntimeLoader/VRMRuntimeLoader.cs b/Scripts/RuntimeLoader/VRMRuntimeLoader.cs index 25d0bf412..49cef8e52 100644 --- a/Scripts/RuntimeLoader/VRMRuntimeLoader.cs +++ b/Scripts/RuntimeLoader/VRMRuntimeLoader.cs @@ -140,26 +140,42 @@ namespace VRM #else var path = Application.dataPath + "/default.vrm"; #endif - if (!string.IsNullOrEmpty(path)) + if (string.IsNullOrEmpty(path)) { - if (m_loadAsync) - { - LoadAsync(path); - } - else - { - LoadSync(path); - } + return; + } + + var bytes = File.ReadAllBytes(path); + // なんらかの方法でByte列を得た + + var context = new VRMImporterContext(path); + + // GLB形式でJSONを取得しParseします + var dataChunk = context.ParseVrm(bytes); + + + // metaを取得(todo: thumbnailテクスチャのロード) + var meta = context.ReadMeta(); + Debug.LogFormat("meta: title:{0}", meta.Title); + + + // ParseしたJSONをシーンオブジェクトに変換していく + if (m_loadAsync) + { + LoadAsync(context, dataChunk); + } + else + { + VRMImporter.LoadFromBytes(context, dataChunk); + OnLoaded(context.Root); } } - void LoadAsync(string path) + void LoadAsync(VRMImporterContext context, ArraySegment dataChunk) { #if true var now = Time.time; - // ネットワーク経由等でbyte列が取得できる場合はこちら - var bytes = File.ReadAllBytes(path); - VRMImporter.LoadVrmAsync(bytes, go=> { + VRMImporter.LoadVrmAsync(context, dataChunk, go=> { var delta = Time.time - now; Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta); OnLoaded(go); @@ -170,24 +186,6 @@ namespace VRM #endif } - void LoadSync(string path) - { -#if true - // ネットワーク経由等でbyte列が取得できる場合はこちら - var bytes = File.ReadAllBytes(path); - LoadSync(bytes); -#else - // ローカルファイルシステムからロードします - VRMImporter.LoadFromPath(path); -#endif - } - - void LoadSync(byte[] bytes) - { - var context = VRMImporter.LoadFromBytes(bytes); - OnLoaded(context.Root); - } - void LoadBVHClicked() { var path = FileDialog("open BVH", ".bvh");