diff --git a/Assets/VRM10.Samples/Runtime/ViewerUI.cs b/Assets/VRM10.Samples/Runtime/ViewerUI.cs
index d879d40a2..35b441433 100644
--- a/Assets/VRM10.Samples/Runtime/ViewerUI.cs
+++ b/Assets/VRM10.Samples/Runtime/ViewerUI.cs
@@ -308,7 +308,12 @@ namespace UniVRM10.Samples
{
case ".vrm":
{
- using (var loader = Vrm10Importer.OpenOrMigrate(path))
+ if(!Vrm10Parser.TryParseOrMigrate(path, doMigrate: true, out Vrm10Parser.Result result, out string error))
+ {
+ Debug.LogError(error);
+ return;
+ }
+ using (var loader = new Vrm10Importer(result.Parser, result.Vrm))
{
loader.Load();
loader.ShowMeshes();
diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs
index 443cc4dba..99d71171d 100644
--- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs
+++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs
@@ -27,7 +27,7 @@ namespace UniVRM10
base.OnEnable();
m_importer = target as VrmScriptedImporter;
- if (!VrmScriptedImporterImpl.TryParseOrMigrate(m_importer.assetPath, m_importer.MigrateToVrm1, out m_parser, out m_message))
+ if (!Vrm10Parser.TryParseOrMigrate(m_importer.assetPath, m_importer.MigrateToVrm1, out Vrm10Parser.Result result, out m_message))
{
// error
return;
diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
index 1107ec3b9..948295c4f 100644
--- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
+++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
@@ -16,83 +16,13 @@ namespace UniVRM10
{
public static class VrmScriptedImporterImpl
{
- ///
- /// VRM1 で パースし、失敗したら Migration してから VRM1 でパースする
- ///
- ///
- ///
- ///
- public static bool TryParseOrMigrate(string path, bool migrateToVrm1, out GltfParser parser, out string error)
- {
- //
- // Parse(parse glb, parser gltf json)
- //
- parser = new GltfParser();
- parser.ParsePath(path);
- if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
- {
- // success
- error = default;
- return true;
- }
-
- if (!migrateToVrm1)
- {
- error = "vrm1 not found";
- return false;
- }
-
- // try migrateion
- Byte[] migrated = default;
- try
- {
- var src = File.ReadAllBytes(path);
- var glb = UniGLTF.Glb.Parse(src);
- var json = glb.Json.Bytes.ParseAsJson();
- if (!json.TryGet("extensions", out JsonNode extensions))
- {
- error = "no gltf.extensions";
- return false;
- }
- if (!extensions.TryGet("VRM", out JsonNode vrm0))
- {
- error = "vrm0 not found";
- return false;
- }
-
- migrated = MigrationVrm.Migrate(json, glb.Binary.Bytes);
- if (migrated == null)
- {
- error = "cannot migrate";
- return false;
- }
- }
- catch (Exception ex)
- {
- error = $"migration error: {ex}";
- return false;
- }
-
- parser = new GltfParser();
- parser.Parse(path, migrated);
- if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out vrm))
- {
- // success
- error = default;
- return true;
- }
-
- error = "migrate but no vrm1. unknown";
- return false;
- }
-
public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1)
{
#if VRM_DEVELOP
Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
#endif
- if (!TryParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out GltfParser parser, out string message))
+ if (!Vrm10Parser.TryParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out Vrm10Parser.Result result, out string message))
{
// fail to parse vrm1
return;
@@ -104,7 +34,7 @@ namespace UniVRM10
var extractedObjects = scriptedImporter.GetExternalObjectMap()
.ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);
- using (var loader = new Vrm10Importer(parser, extractedObjects))
+ using (var loader = new Vrm10Importer(result.Parser, result.Vrm, extractedObjects))
{
// settings TextureImporters
foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable())
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
index ab19bd18f..1e96fe11c 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
@@ -23,11 +23,22 @@ namespace UniVRM10
IReadOnlyDictionary m_externalMap;
public Vrm10Importer(
- UniGLTF.GltfParser parser,
+ UniGLTF.GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm,
IReadOnlyDictionary externalObjectMap = null,
ITextureDeserializer textureDeserializer = null)
: base(parser, externalObjectMap, textureDeserializer)
{
+ if (parser == null)
+ {
+ throw new ArgumentNullException("parser");
+ }
+
+ if (vrm == null)
+ {
+ throw new ArgumentNullException("vrm");
+ }
+ m_vrm = vrm;
+
TextureDescriptorGenerator = new Vrm10TextureDescriptorGenerator(parser);
MaterialDescriptorGenerator = new Vrm10MaterialDescriptorGenerator();
@@ -36,12 +47,9 @@ namespace UniVRM10
{
m_externalMap = new Dictionary();
}
- m_model = ModelReader.Read(parser);
- if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out m_vrm))
- {
- throw new Vrm10NoExtensionException();
- }
+ // bin に対して右手左手変換を破壊的に実行することに注意 !(bin が変換済みになる)
+ m_model = ModelReader.Read(parser);
// assign humanoid bones
if (m_vrm.Humanoid != null)
@@ -104,29 +112,6 @@ namespace UniVRM10
}
}
- public static Vrm10Importer OpenOrMigrate(byte[] bytes, string path)
- {
- try
- {
- var parser = new GltfParser();
- parser.Parse(path, bytes);
- return new Vrm10Importer(parser);
- }
- catch (Vrm10NoExtensionException)
- {
- Debug.Log("vrm1 not found. try migration...");
- bytes = MigrationVrm.Migrate(bytes);
- var parser = new GltfParser();
- parser.Parse(path, bytes);
- return new Vrm10Importer(parser);
- }
- }
-
- public static Vrm10Importer OpenOrMigrate(string path)
- {
- return OpenOrMigrate(File.ReadAllBytes(path), path);
- }
-
public class ModelMap
{
public readonly Dictionary Nodes = new Dictionary();
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Parser.cs b/Assets/VRM10/Runtime/IO/Vrm10Parser.cs
new file mode 100644
index 000000000..e9e876b03
--- /dev/null
+++ b/Assets/VRM10/Runtime/IO/Vrm10Parser.cs
@@ -0,0 +1,109 @@
+using System;
+using System.IO;
+using UniGLTF;
+using UniGLTF.Extensions.VRMC_vrm;
+using UniJSON;
+
+namespace UniVRM10
+{
+ public static class Vrm10Parser
+ {
+ public readonly struct Result
+ {
+ public readonly GltfParser Parser;
+ public readonly VRMC_vrm Vrm;
+
+ public Result(GltfParser parser, VRMC_vrm vrm)
+ {
+ Parser = parser;
+ Vrm = vrm;
+ }
+ }
+
+ public static bool TryParseOrMigrate(string path, bool doMigrate, out Result result, out string error)
+ {
+ return TryParseOrMigrate(path, File.ReadAllBytes(path), doMigrate, out result, out error);
+ }
+
+ ///
+ /// VRM1 で パースし、失敗したら Migration してから VRM1 でパースする
+ ///
+ ///
+ ///
+ ///
+ public static bool TryParseOrMigrate(string path, byte[] bytes, bool doMigrate, out Result result, out string error)
+ {
+ //
+ // Parse(parse glb, parser gltf json)
+ //
+ {
+ var parser = new GltfParser();
+ parser.Parse(path, bytes);
+ if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
+ {
+ // success
+ error = default;
+ result = new Result(parser, vrm);
+ return true;
+ }
+ }
+
+ if (!doMigrate)
+ {
+ error = "vrm1 not found";
+ result = default;
+ return false;
+ }
+
+ // try migrateion
+ byte[] migrated = default;
+ try
+ {
+ var glb = UniGLTF.Glb.Parse(bytes);
+ var json = glb.Json.Bytes.ParseAsJson();
+ if (!json.TryGet("extensions", out JsonNode extensions))
+ {
+ error = "no gltf.extensions";
+ result = default;
+ return false;
+ }
+ if (!extensions.TryGet("VRM", out JsonNode vrm0))
+ {
+ error = "vrm0 not found";
+ result = default;
+ return false;
+ }
+
+ migrated = MigrationVrm.Migrate(json, glb.Binary.Bytes);
+ if (migrated == null)
+ {
+ error = "cannot migrate";
+ result = default;
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ error = $"migration error: {ex}";
+ result = default;
+ return false;
+ }
+
+ {
+ var parser = new GltfParser();
+ parser.Parse(path, migrated);
+ if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out VRMC_vrm vrm))
+ {
+ // success
+ error = default;
+ result = new Result(parser, vrm);
+ return true;
+ }
+ }
+
+ error = "migrate but no vrm1. unknown";
+ result = default;
+ return false;
+ }
+ }
+}
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Parser.cs.meta b/Assets/VRM10/Runtime/IO/Vrm10Parser.cs.meta
new file mode 100644
index 000000000..551bbe96c
--- /dev/null
+++ b/Assets/VRM10/Runtime/IO/Vrm10Parser.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e4bece9378632bd4682bf5551630fafe
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/VRM10/Runtime/Scenes/Sample.cs b/Assets/VRM10/Runtime/Scenes/Sample.cs
index 1b509341e..211d1ce36 100644
--- a/Assets/VRM10/Runtime/Scenes/Sample.cs
+++ b/Assets/VRM10/Runtime/Scenes/Sample.cs
@@ -15,7 +15,12 @@ namespace UniVRM10.Sample
static GameObject Import(byte[] bytes, FileInfo path)
{
- using (var loader = Vrm10Importer.OpenOrMigrate(bytes, path.FullName))
+ if (!Vrm10Parser.TryParseOrMigrate(path.FullName, bytes, doMigrate: true, out Vrm10Parser.Result result, out string message))
+ {
+ return null;
+ }
+
+ using (var loader = new Vrm10Importer(result.Parser, result.Vrm))
{
loader.Load();
loader.ShowMeshes();
diff --git a/Assets/VRM10/Tests.PlayMode/MaterialTests.cs b/Assets/VRM10/Tests.PlayMode/MaterialTests.cs
index 7103cc7bf..55a099959 100644
--- a/Assets/VRM10/Tests.PlayMode/MaterialTests.cs
+++ b/Assets/VRM10/Tests.PlayMode/MaterialTests.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using NUnit.Framework;
using UniGLTF;
+using UniGLTF.Extensions.VRMC_vrm;
using UnityEngine;
using UnityEngine.TestTools;
using UniVRM10;
@@ -30,16 +31,18 @@ namespace UniVRM10.Test
private (GameObject, IReadOnlyList) ToUnity(byte[] bytes)
{
// Vrm => Model
- var parser = new UniGLTF.GltfParser();
- parser.Parse("tmp.vrm", bytes);
+ if(!Vrm10Parser.TryParseOrMigrate("tpm.vrm", bytes, true, out Vrm10Parser.Result result, out string error))
+ {
+ throw new Exception();
+ }
- return ToUnity(parser);
+ return ToUnity(result.Parser, result.Vrm);
}
- private (GameObject, IReadOnlyList) ToUnity(GltfParser parser)
+ private (GameObject, IReadOnlyList) ToUnity(GltfParser parser, VRMC_vrm vrm)
{
// Model => Unity
- using (var loader = new Vrm10Importer(parser))
+ using (var loader = new Vrm10Importer(parser, vrm))
{
loader.Load();
loader.DisposeOnGameObjectDestroyed();
diff --git a/Assets/VRM10/Tests/ApiSampleTests.cs b/Assets/VRM10/Tests/ApiSampleTests.cs
index 4e80f29a3..e4d1c722a 100644
--- a/Assets/VRM10/Tests/ApiSampleTests.cs
+++ b/Assets/VRM10/Tests/ApiSampleTests.cs
@@ -1,6 +1,7 @@
using System.IO;
using NUnit.Framework;
using UniGLTF;
+using UniGLTF.Extensions.VRMC_vrm;
using UnityEngine;
using VRMShaders;
@@ -19,9 +20,9 @@ namespace UniVRM10.Test
return model;
}
- GameObject BuildGameObject(GltfParser parser, bool showMesh)
+ GameObject BuildGameObject(GltfParser parser, VRMC_vrm vrm, bool showMesh)
{
- using (var loader = new Vrm10Importer(parser))
+ using (var loader = new Vrm10Importer(parser, vrm))
{
loader.Load();
if (showMesh)
@@ -39,12 +40,9 @@ namespace UniVRM10.Test
var path = "Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm";
Debug.Log($"load: {path}");
- var migrated = MigrationVrm.Migrate(File.ReadAllBytes(path));
+ Assert.IsTrue(Vrm10Parser.TryParseOrMigrate(path, true, out Vrm10Parser.Result result, out string error));
- var parser = new GltfParser();
- parser.Parse(path, migrated);
-
- var go = BuildGameObject(parser, true);
+ var go = BuildGameObject(result.Parser, result.Vrm, true);
Debug.Log(go);
// export