diff --git a/Assets/VRM10/Runtime/IO/Vrm10.cs b/Assets/VRM10/Runtime/IO/Vrm10.cs
new file mode 100644
index 000000000..3a2f3e452
--- /dev/null
+++ b/Assets/VRM10/Runtime/IO/Vrm10.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using UniGLTF;
+using UnityEngine;
+using VRMShaders;
+
+namespace UniVRM10
+{
+ ///
+ /// High-level VRM-1.0 loading API.
+ ///
+ public static class Vrm10
+ {
+ ///
+ /// You can receive the thumbnail texture and the meta information.
+ /// `vrm10Meta` will be available if the model was vrm-1.0.
+ /// `vrm0Meta` will be available if the model was vrm-0.x.
+ ///
+ public delegate void VrmMetaInformationCallback(Texture2D thumbnail, UniGLTF.Extensions.VRMC_vrm.Meta vrm10Meta, Migration.Vrm0Meta vrm0Meta);
+
+ ///
+ /// Load the VRM file from the path.
+ ///
+ /// vrm file path
+ /// if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.
+ /// if true, vrm-1.0 models' transforms are normalized. (e.g. rotation, scaling)
+ /// if true, show meshes when loaded.
+ /// this loader use specified await strategy.
+ /// this loader use specified material generation strategy.
+ /// return callback that notify meta information before loading.
+ /// CancellationToken
+ /// vrm-1.0 instance
+ public static async Task LoadPathAsync(
+ string path,
+ bool canLoadVrm0X = true,
+ bool normalizeTransform = true,
+ bool showMeshes = true,
+ IAwaitCaller awaitCaller = null,
+ IMaterialDescriptorGenerator materialGenerator = null,
+ VrmMetaInformationCallback vrmMetaInformationCallback = null,
+ CancellationToken ct = default)
+ {
+ return await LoadAsync(
+ path,
+ System.IO.File.ReadAllBytes(path),
+ canLoadVrm0X,
+ normalizeTransform,
+ showMeshes,
+ awaitCaller,
+ materialGenerator,
+ vrmMetaInformationCallback,
+ ct);
+ }
+
+ ///
+ /// Load the VRM file from the binary.
+ ///
+ /// vrm file data
+ /// if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.
+ /// if true, vrm-1.0 models' transforms are normalized. (e.g. rotation, scaling)
+ /// if true, show meshes when loaded.
+ /// this loader use specified await strategy.
+ /// this loader use specified material generation strategy.
+ /// return callback that notify meta information before loading.
+ /// CancellationToken
+ /// vrm-1.0 instance
+ public static async Task LoadBytesAsync(
+ byte[] bytes,
+ bool canLoadVrm0X = true,
+ bool normalizeTransform = true,
+ bool showMeshes = true,
+ IAwaitCaller awaitCaller = null,
+ IMaterialDescriptorGenerator materialGenerator = null,
+ VrmMetaInformationCallback vrmMetaInformationCallback = null,
+ CancellationToken ct = default)
+ {
+ return await LoadAsync(
+ string.Empty,
+ bytes,
+ canLoadVrm0X,
+ normalizeTransform,
+ showMeshes,
+ awaitCaller,
+ materialGenerator,
+ vrmMetaInformationCallback,
+ ct);
+ }
+
+ private static async Task LoadAsync(
+ string name,
+ byte[] bytes,
+ bool canLoadVrm0X,
+ bool normalizeTransform,
+ bool showMeshes,
+ IAwaitCaller awaitCaller,
+ IMaterialDescriptorGenerator materialGenerator,
+ VrmMetaInformationCallback vrmMetaInformationCallback,
+ CancellationToken ct)
+ {
+ using (var data = new GlbLowLevelParser(name, bytes).Parse())
+ {
+ // 1. Try loading as vrm-1.0
+ var vrm10Data = Vrm10Data.Parse(data);
+ var vrm10Instance = await LoadVrm10DataAsync(
+ vrm10Data,
+ null,
+ normalizeTransform,
+ showMeshes,
+ awaitCaller,
+ materialGenerator,
+ vrmMetaInformationCallback,
+ ct);
+ if (vrm10Instance != null) return vrm10Instance;
+
+ if (!canLoadVrm0X)
+ {
+ return default;
+ }
+
+ // 2. Try migration from vrm-0.x into vrm-1.0
+ MigrationData migrationData;
+ using (var migrated = Vrm10Data.Migrate(data, out vrm10Data, out migrationData))
+ {
+ var instance = await LoadVrm10DataAsync(
+ vrm10Data,
+ migrationData,
+ normalizeTransform,
+ showMeshes,
+ awaitCaller,
+ materialGenerator,
+ vrmMetaInformationCallback,
+ ct);
+ if (instance != null) return instance;
+ }
+
+ // 3. failed
+ if (migrationData != null)
+ {
+ Debug.LogWarning(migrationData.Message);
+ }
+ return default;
+ }
+ }
+
+ private static async Task LoadVrm10DataAsync(
+ Vrm10Data vrm10Data,
+ MigrationData migrationData,
+ bool normalizeTransform,
+ bool showMeshes,
+ IAwaitCaller awaitCaller,
+ IMaterialDescriptorGenerator materialGenerator,
+ VrmMetaInformationCallback vrmMetaInformationCallback,
+ CancellationToken ct)
+ {
+ if (vrm10Data == null)
+ {
+ return default;
+ }
+
+ using (var loader = new Vrm10Importer(vrm10Data, materialGenerator: materialGenerator, doNormalize: normalizeTransform))
+ {
+ // 1. Load meta information if callback was available.
+ if (vrmMetaInformationCallback != null)
+ {
+ var thumbnail = await loader.LoadVrmThumbnailAsync();
+ if (migrationData != null)
+ {
+ vrmMetaInformationCallback(thumbnail, default, migrationData.OriginalMetaBeforeMigration);
+ }
+ else
+ {
+ vrmMetaInformationCallback(thumbnail, vrm10Data.VrmExtension.Meta, default);
+ }
+ }
+
+ // 2. Load
+ var gltfInstance = await loader.LoadAsync(awaitCaller);
+ if (ct.IsCancellationRequested)
+ {
+ gltfInstance.Dispose();
+ return default;
+ }
+
+ var vrm10Instance = gltfInstance.GetComponent();
+ if (vrm10Instance == null)
+ {
+ gltfInstance.Dispose();
+ return default;
+ }
+
+ if (showMeshes)
+ {
+ gltfInstance.ShowMeshes();
+ }
+ return vrm10Instance;
+ }
+ }
+ }
+}
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Utility.cs.meta b/Assets/VRM10/Runtime/IO/Vrm10.cs.meta
similarity index 100%
rename from Assets/VRM10/Runtime/IO/Vrm10Utility.cs.meta
rename to Assets/VRM10/Runtime/IO/Vrm10.cs.meta
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Utility.cs b/Assets/VRM10/Runtime/IO/Vrm10Utility.cs
deleted file mode 100644
index 9f86ab2d3..000000000
--- a/Assets/VRM10/Runtime/IO/Vrm10Utility.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System.Threading.Tasks;
-using UniGLTF;
-using UnityEngine;
-using VRMShaders;
-
-namespace UniVRM10
-{
- public static class Vrm10Utility
- {
- public delegate void MetaCallback(Texture2D thumbnail, UniGLTF.Extensions.VRMC_vrm.Meta meta1, Migration.Vrm0Meta meta0);
- public static async Task LoadPathAsync(string path,
- bool doMigrate,
- bool doNormalize,
- IAwaitCaller awaitCaller = null,
- IMaterialDescriptorGenerator materialGenerator = null,
- MetaCallback metaCallback = null
- )
- {
- return await LoadBytesAsync(path, System.IO.File.ReadAllBytes(path), doMigrate, doNormalize, awaitCaller, materialGenerator, metaCallback);
- }
-
- public static async Task LoadBytesAsync(string path, byte[] bytes,
- bool doMigrate,
- bool doNormalize,
- IAwaitCaller awaitCaller = null,
- IMaterialDescriptorGenerator materialGenerator = null,
- MetaCallback metaCallback = null
- )
- {
- // 1st parse as vrm1
- using (var data = new GlbLowLevelParser(path, bytes).Parse())
- {
- var vrm1Data = Vrm10Data.Parse(data);
- if (vrm1Data != null)
- {
- // successfully parsed vrm-1.0
- using (var loader = new Vrm10Importer(vrm1Data, materialGenerator: materialGenerator, doNormalize: doNormalize))
- {
- if (metaCallback != null)
- {
- var thumbnail = await loader.LoadVrmThumbnailAsync();
- metaCallback(thumbnail, vrm1Data.VrmExtension.Meta, null);
- }
- var instance = await loader.LoadAsync(awaitCaller);
- return instance;
- }
- }
-
- if (!doMigrate)
- {
- return default;
- }
-
- // try migration...
- MigrationData migration;
- using (var migrated = Vrm10Data.Migrate(data, out vrm1Data, out migration))
- {
- if (vrm1Data != null)
- {
- // successfully migrated from vrm-0.x
- using (var loader = new Vrm10Importer(vrm1Data, materialGenerator: materialGenerator, doNormalize: doNormalize))
- {
- if (metaCallback != null)
- {
- var thumbnail = await loader.LoadVrmThumbnailAsync();
- metaCallback(thumbnail, vrm1Data.VrmExtension.Meta, null);
- }
- var instance = await loader.LoadAsync(awaitCaller);
- return instance;
- }
- }
- }
-
- // fail to migrate...
- if (migration != null)
- {
- Debug.LogWarning(migration.Message);
- }
- return default;
- }
- }
- }
-}
diff --git a/Assets/VRM10/Runtime/Scenes/Sample.cs b/Assets/VRM10/Runtime/Scenes/Sample.cs
index c5c35bbab..6fc1b47b4 100644
--- a/Assets/VRM10/Runtime/Scenes/Sample.cs
+++ b/Assets/VRM10/Runtime/Scenes/Sample.cs
@@ -22,12 +22,12 @@ namespace UniVRM10.Sample
async void Run()
{
var src = new FileInfo(m_vrmPath);
- var instance = await Vrm10Utility.LoadPathAsync(m_vrmPath, true, true);
+ var instance = await Vrm10.LoadPathAsync(m_vrmPath, true, true);
var exportedBytes = Vrm10Exporter.Export(instance.gameObject);
// Import 1.0
- var vrm10 = await Vrm10Utility.LoadBytesAsync("tmp.vrm", exportedBytes, false, true);
+ var vrm10 = await Vrm10.LoadBytesAsync(exportedBytes, false, true);
var pos = vrm10.transform.position;
pos.x += 1.5f;
vrm10.transform.position = pos;
diff --git a/Assets/VRM10/Runtime/Scenes/SampleScene.unity b/Assets/VRM10/Runtime/Scenes/SampleScene.unity
index ecb42cea9..af58e6cbd 100644
--- a/Assets/VRM10/Runtime/Scenes/SampleScene.unity
+++ b/Assets/VRM10/Runtime/Scenes/SampleScene.unity
@@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 705507994}
- m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
+ m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
@@ -325,8 +325,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d2dd74f31dd71684da8aa80eaa66390e, type: 3}
m_Name:
m_EditorClassIdentifier:
- m_vrmPath: ../UniVRM_1_0/Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm
- m_rightHandToLeftHand: 1
+ m_vrmPath: Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm
--- !u!4 &1706915413
Transform:
m_ObjectHideFlags: 0
diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs
index 62044094e..d60deb448 100644
--- a/Assets/VRM10/Tests/MigrationTests.cs
+++ b/Assets/VRM10/Tests/MigrationTests.cs
@@ -198,7 +198,7 @@ namespace UniVRM10
{
try
{
- Vrm10Utility.LoadPathAsync(gltf.FullName, true, false).Wait();
+ Vrm10.LoadPathAsync(gltf.FullName, true, false).Wait();
}
catch (UnNormalizedException)
{
diff --git a/Assets/VRM10/Tests/TestAsset.cs b/Assets/VRM10/Tests/TestAsset.cs
index 9b536d66e..2ee9fe5bf 100644
--- a/Assets/VRM10/Tests/TestAsset.cs
+++ b/Assets/VRM10/Tests/TestAsset.cs
@@ -16,7 +16,7 @@ namespace UniVRM10
public static Vrm10Instance LoadAlicia()
{
- var task = Vrm10Utility.LoadPathAsync(AliciaPath, true, true);
+ var task = Vrm10.LoadPathAsync(AliciaPath, true, true);
task.Wait();
var instance = task.Result;
diff --git a/Assets/VRM10_Samples/VRM10FirstPersonSample/VRM10RuntimeLoader.cs b/Assets/VRM10_Samples/VRM10FirstPersonSample/VRM10RuntimeLoader.cs
index f10c429ae..b2c30e826 100644
--- a/Assets/VRM10_Samples/VRM10FirstPersonSample/VRM10RuntimeLoader.cs
+++ b/Assets/VRM10_Samples/VRM10FirstPersonSample/VRM10RuntimeLoader.cs
@@ -82,17 +82,14 @@ namespace UniVRM10.FirstPersonSample
}
m_target = humanPoseTransfer;
SetupTarget(m_target);
-
- instance.ShowMeshes();
}
- async Task LoadAsync(string path)
+ async Task LoadAsync(string path)
{
- var instance = await Vrm10Utility.LoadPathAsync(path, true, true);
+ var instance = await Vrm10.LoadPathAsync(path);
// VR用 FirstPerson 設定
- var controller = instance.GetComponent();
- await controller.Vrm.FirstPerson.SetupAsync(controller.gameObject);
+ await instance.Vrm.FirstPerson.SetupAsync(instance.gameObject);
return instance;
}
diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
index 89f606eb3..77f191a0a 100644
--- a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
+++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
@@ -415,16 +415,23 @@ namespace UniVRM10.VRM10Viewer
}
Debug.LogFormat("{0}", path);
- var instance = await Vrm10Utility.LoadPathAsync(path, true, m_useNormalization.isOn,
- awaitCaller: new RuntimeOnlyAwaitCaller(),
- materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn),
- metaCallback: m_texts.UpdateMeta);
- if (instance == null)
+ var vrm10Instance = await Vrm10.LoadPathAsync(path,
+ canLoadVrm0X: true,
+ normalizeTransform: m_useNormalization.isOn,
+ showMeshes: false,
+ awaitCaller: new RuntimeOnlyAwaitCaller(),
+ materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn),
+ vrmMetaInformationCallback: m_texts.UpdateMeta);
+ if (vrm10Instance != null)
+ {
+ SetModel(vrm10Instance.GetComponent());
+ }
+ else
{
// fallback to gltf
- instance = await GltfUtility.LoadAsync(path, awaitCaller: new RuntimeOnlyAwaitCaller());
+ var instance = await GltfUtility.LoadAsync(path, awaitCaller: new RuntimeOnlyAwaitCaller());
+ SetModel(instance);
}
- SetModel(instance);
}
void SetModel(RuntimeGltfInstance instance)