mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-02 00:10:58 -05:00
Vrm10Parser を導入して、ここで extension の取り出しと migrate を呼び出すようにした。
This commit is contained in:
parent
b07eda0caa
commit
e7d461fac1
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -16,83 +16,13 @@ namespace UniVRM10
|
|||
{
|
||||
public static class VrmScriptedImporterImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// VRM1 で パースし、失敗したら Migration してから VRM1 でパースする
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="migrateToVrm1"></param>
|
||||
/// <returns></returns>
|
||||
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())
|
||||
|
|
|
|||
|
|
@ -23,11 +23,22 @@ namespace UniVRM10
|
|||
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> m_externalMap;
|
||||
|
||||
public Vrm10Importer(
|
||||
UniGLTF.GltfParser parser,
|
||||
UniGLTF.GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm,
|
||||
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> 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<SubAssetKey, UnityEngine.Object>();
|
||||
}
|
||||
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<VrmLib.Node, GameObject> Nodes = new Dictionary<VrmLib.Node, GameObject>();
|
||||
|
|
|
|||
109
Assets/VRM10/Runtime/IO/Vrm10Parser.cs
Normal file
109
Assets/VRM10/Runtime/IO/Vrm10Parser.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VRM1 で パースし、失敗したら Migration してから VRM1 でパースする
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="doMigrate"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/IO/Vrm10Parser.cs.meta
Normal file
11
Assets/VRM10/Runtime/IO/Vrm10Parser.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e4bece9378632bd4682bf5551630fafe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<VRMShaders.MaterialFactory.MaterialLoadInfo>) 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<VRMShaders.MaterialFactory.MaterialLoadInfo>) ToUnity(GltfParser parser)
|
||||
private (GameObject, IReadOnlyList<VRMShaders.MaterialFactory.MaterialLoadInfo>) 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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user