mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-26 00:29:19 -05:00
Merge pull request #1196 from ousttrue/fix10/oldmeta_when_migrate
[1.0] RuntimeLoad と meta 取得 を実装
This commit is contained in:
commit
a2307b42b8
|
|
@ -52,7 +52,7 @@ namespace UniGLTF
|
|||
//
|
||||
// Parse(parse glb, parser gltf json)
|
||||
//
|
||||
var data = new AmbiguousGltfFileParser(scriptedImporter.assetPath).Parse();
|
||||
var data = new AutoGltfFileParser(scriptedImporter.assetPath).Parse();
|
||||
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace UniGLTF
|
|||
base.OnEnable();
|
||||
|
||||
m_importer = target as GltfScriptedImporter;
|
||||
m_data = new AmbiguousGltfFileParser(m_importer.assetPath).Parse();
|
||||
m_data = new AutoGltfFileParser(m_importer.assetPath).Parse();
|
||||
|
||||
var materialGenerator = new GltfMaterialDescriptorGenerator();
|
||||
var materialKeys = m_data.GLTF.materials.Select((_, i) => materialGenerator.Get(m_data, i).SubAssetKey);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace UniGLTF
|
|||
base.OnEnable();
|
||||
|
||||
m_importer = target as ZipArchivedGltfScriptedImporter;
|
||||
m_data = new AmbiguousGltfFileParser(m_importer.assetPath).Parse();
|
||||
m_data = new AutoGltfFileParser(m_importer.assetPath).Parse();
|
||||
|
||||
var materialGenerator = new GltfMaterialDescriptorGenerator();
|
||||
var materialKeys = m_data.GLTF.materials.Select((_, i) => materialGenerator.Get(m_data, i).SubAssetKey);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace UniGLTF
|
|||
{
|
||||
if (awaitCaller == null)
|
||||
{
|
||||
awaitCaller = new TaskCaller();
|
||||
awaitCaller = new ImmediateCaller();
|
||||
}
|
||||
|
||||
if (MeasureTime == null)
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3a36dcb5732b467598919c0ed66f0c5a
|
||||
timeCreated: 1624802689
|
||||
|
|
@ -3,14 +3,15 @@
|
|||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Ambiguous file parser.
|
||||
/// Auto detection file parser.
|
||||
/// Determine parsing method from the file extension.
|
||||
/// Detects `gltf`` zip`, others as` glb`
|
||||
/// </summary>
|
||||
public sealed class AmbiguousGltfFileParser
|
||||
public sealed class AutoGltfFileParser
|
||||
{
|
||||
private readonly string _path;
|
||||
|
||||
public AmbiguousGltfFileParser(string path)
|
||||
public AutoGltfFileParser(string path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bc9d157827565c84f9ad41c907fd12e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -81,7 +81,7 @@ namespace UniGLTF
|
|||
GltfData data = null;
|
||||
try
|
||||
{
|
||||
data = new AmbiguousGltfFileParser(gltf.FullName).Parse();
|
||||
data = new AutoGltfFileParser(gltf.FullName).Parse();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -127,7 +127,7 @@ namespace UniGLTF
|
|||
GltfData data = null;
|
||||
try
|
||||
{
|
||||
data = new AmbiguousGltfFileParser(gltf.FullName).Parse();
|
||||
data = new AutoGltfFileParser(gltf.FullName).Parse();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -205,7 +205,7 @@ namespace UniGLTF
|
|||
|
||||
{
|
||||
var path = Path.Combine(root.FullName, "DamagedHelmet/glTF-Binary/DamagedHelmet.glb");
|
||||
var data = new AmbiguousGltfFileParser(path).Parse();
|
||||
var data = new AutoGltfFileParser(path).Parse();
|
||||
|
||||
var matDesc = new GltfMaterialDescriptorGenerator().Get(data, 0);
|
||||
Assert.AreEqual("Standard", matDesc.ShaderName);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ namespace VRM
|
|||
|
||||
private void OnDisable()
|
||||
{
|
||||
Debug.Log("StopCoroutine");
|
||||
if (m_coroutine != null)
|
||||
{
|
||||
StopCoroutine(m_coroutine);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ namespace VRM.SimpleViewer
|
|||
|
||||
private void OnDisable()
|
||||
{
|
||||
Debug.Log("StopCoroutine");
|
||||
StopCoroutine(m_coroutine);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ namespace VRM.SimpleViewer
|
|||
|
||||
public async Task UpdateMetaAsync(VRMImporterContext context)
|
||||
{
|
||||
var meta = await context.ReadMetaAsync(new TaskCaller(), true);
|
||||
var meta = await context.ReadMetaAsync(new ImmediateCaller(), true);
|
||||
|
||||
m_textModelTitle.text = meta.Title;
|
||||
m_textModelVersion.text = meta.Version;
|
||||
|
|
@ -183,38 +183,115 @@ namespace VRM.SimpleViewer
|
|||
m_target = GameObject.FindObjectOfType<TargetMover>().gameObject;
|
||||
}
|
||||
|
||||
HumanPoseTransfer m_loaded;
|
||||
VRMBlendShapeProxy m_proxy;
|
||||
|
||||
AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
bool EnableLipSyncValue
|
||||
class Loaded : IDisposable
|
||||
{
|
||||
set
|
||||
RuntimeGltfInstance _instance;
|
||||
HumanPoseTransfer _pose;
|
||||
VRMBlendShapeProxy m_proxy;
|
||||
|
||||
Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
public bool EnableBlinkValue
|
||||
{
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
set
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
public bool EnableLipSyncValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Loaded(RuntimeGltfInstance instance, HumanPoseTransfer src, Transform lookAtTarget)
|
||||
{
|
||||
_instance = instance;
|
||||
|
||||
var lookAt = instance.GetComponent<VRMLookAtHead>();
|
||||
if (lookAt != null)
|
||||
{
|
||||
_pose = _instance.gameObject.AddComponent<HumanPoseTransfer>();
|
||||
_pose.Source = src;
|
||||
_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_lipSync = instance.gameObject.AddComponent<AIUEO>();
|
||||
m_blink = instance.gameObject.AddComponent<Blinker>();
|
||||
|
||||
lookAt.Target = lookAtTarget;
|
||||
lookAt.UpdateType = UpdateType.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
|
||||
var animation = instance.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
|
||||
m_proxy = instance.GetComponent<VRMBlendShapeProxy>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Destroy game object. not RuntimeGltfInstance
|
||||
GameObject.Destroy(_instance.gameObject);
|
||||
}
|
||||
|
||||
public void EnableBvh(HumanPoseTransfer src)
|
||||
{
|
||||
if (_pose != null)
|
||||
{
|
||||
_pose.Source = src;
|
||||
_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableTPose(HumanPoseClip pose)
|
||||
{
|
||||
if (_pose != null)
|
||||
{
|
||||
_pose.PoseClip = pose;
|
||||
_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnResetClicked()
|
||||
{
|
||||
if (_pose != null)
|
||||
{
|
||||
foreach (var spring in _pose.GetComponentsInChildren<VRMSpringBone>())
|
||||
{
|
||||
spring.Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (m_proxy != null)
|
||||
{
|
||||
m_proxy.Apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded m_loaded;
|
||||
|
||||
|
||||
Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
bool EnableBlinkValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
|
@ -222,7 +299,7 @@ namespace VRM.SimpleViewer
|
|||
VRMVersion.MAJOR, VRMVersion.MINOR);
|
||||
m_open.onClick.AddListener(OnOpenClicked);
|
||||
|
||||
m_reset.onClick.AddListener(OnResetClicked);
|
||||
m_reset.onClick.AddListener(() => m_loaded.OnResetClicked());
|
||||
|
||||
// load initial bvh
|
||||
if (m_motion != null)
|
||||
|
|
@ -249,49 +326,18 @@ namespace VRM.SimpleViewer
|
|||
|
||||
private void Update()
|
||||
{
|
||||
EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (Root != null) Root.SetActive(!Root.activeSelf);
|
||||
}
|
||||
|
||||
m_ui.UpdateToggle(EnableBvh, EnableTPose);
|
||||
m_ui.UpdateToggle(() => m_loaded?.EnableBvh(m_src), () => m_loaded?.EnableTPose(m_pose));
|
||||
|
||||
if (m_proxy != null)
|
||||
{
|
||||
m_proxy.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
void EnableBvh()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableTPose()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.PoseClip = m_pose;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
}
|
||||
|
||||
void OnResetClicked()
|
||||
{
|
||||
if (m_loaded == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var spring in m_loaded.GetComponentsInChildren<VRMSpringBone>())
|
||||
{
|
||||
spring.Setup();
|
||||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -357,109 +403,61 @@ namespace VRM.SimpleViewer
|
|||
}
|
||||
|
||||
Debug.LogFormat("{0}", path);
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
|
||||
GltfData data;
|
||||
try
|
||||
{
|
||||
case ".vrm":
|
||||
{
|
||||
var data = new GlbFileParser(path).Parse();
|
||||
var vrm = new VRMData(data);
|
||||
using (var context = new VRMImporterContext(vrm, materialGenerator: GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm.VrmExtension)))
|
||||
{
|
||||
await m_texts.UpdateMetaAsync(context);
|
||||
var loaded = await context.LoadAsync();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
data = new AutoGltfFileParser(path).Parse();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarningFormat("parse error: {0}", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
case ".glb":
|
||||
{
|
||||
var data = new GlbFileParser(path).Parse();
|
||||
|
||||
var context = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn));
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
break;
|
||||
}
|
||||
|
||||
case ".gltf":
|
||||
{
|
||||
var data = new GltfFileWithResourceFilesParser(path).Parse();
|
||||
|
||||
var context = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn));
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
break;
|
||||
}
|
||||
case ".zip":
|
||||
{
|
||||
var data = new ZipArchivedGltfFileParser(path).Parse();
|
||||
|
||||
var context = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn));
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug.LogWarningFormat("unknown file type: {0}", path);
|
||||
break;
|
||||
try
|
||||
{
|
||||
var vrm = new VRMData(data);
|
||||
using (var loader = new VRMImporterContext(vrm, materialGenerator: GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm.VrmExtension)))
|
||||
{
|
||||
await m_texts.UpdateMetaAsync(loader);
|
||||
var instance = await loader.LoadAsync();
|
||||
SetModel(instance);
|
||||
}
|
||||
}
|
||||
catch (NotVrm0Exception)
|
||||
{
|
||||
using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var instance = await loader.LoadAsync();
|
||||
SetModel(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetModel(GameObject go)
|
||||
void SetModel(RuntimeGltfInstance instance)
|
||||
{
|
||||
// cleanup
|
||||
var loaded = m_loaded;
|
||||
m_loaded = null;
|
||||
|
||||
if (loaded != null)
|
||||
if (m_loaded != null)
|
||||
{
|
||||
Debug.LogFormat("destroy {0}", loaded);
|
||||
GameObject.Destroy(loaded.gameObject);
|
||||
m_loaded.Dispose();
|
||||
m_loaded = null;
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
var lookAt = go.GetComponent<VRMLookAtHead>();
|
||||
if (lookAt != null)
|
||||
{
|
||||
m_loaded = go.AddComponent<HumanPoseTransfer>();
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
instance.EnableUpdateWhenOffscreen();
|
||||
instance.ShowMeshes();
|
||||
|
||||
m_lipSync = go.AddComponent<AIUEO>();
|
||||
m_blink = go.AddComponent<Blinker>();
|
||||
|
||||
lookAt.Target = m_target.transform;
|
||||
lookAt.UpdateType = UpdateType.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
}
|
||||
|
||||
var animation = go.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
|
||||
m_proxy = go.GetComponent<VRMBlendShapeProxy>();
|
||||
}
|
||||
m_loaded = new Loaded(instance, m_src, m_target.transform);
|
||||
}
|
||||
|
||||
void SetMotion(HumanPoseTransfer src)
|
||||
{
|
||||
m_src = src;
|
||||
src.GetComponent<Renderer>().enabled = false;
|
||||
|
||||
EnableBvh();
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.EnableBvh(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UniJSON;
|
||||
|
|
@ -17,15 +18,17 @@ namespace UniVRM10
|
|||
{
|
||||
public GltfData Data { get; }
|
||||
public UniGLTF.Extensions.VRMC_vrm.VRMC_vrm VrmExtension { get; }
|
||||
public readonly Migration.Vrm0Meta OriginalMetaBeforeMigration;
|
||||
public readonly Vrm10FileType FileType;
|
||||
public readonly String Message;
|
||||
|
||||
public Vrm10Data(GltfData data, VRMC_vrm vrm, Vrm10FileType fileType, string message)
|
||||
public Vrm10Data(GltfData data, VRMC_vrm vrm, Vrm10FileType fileType, string message, Migration.Vrm0Meta oldMeta = null)
|
||||
{
|
||||
Data = data;
|
||||
VrmExtension = vrm;
|
||||
FileType = fileType;
|
||||
Message = message;
|
||||
OriginalMetaBeforeMigration = oldMeta;
|
||||
}
|
||||
|
||||
public static bool TryParseOrMigrate(string path, bool doMigrate, out Vrm10Data result)
|
||||
|
|
@ -33,19 +36,24 @@ namespace UniVRM10
|
|||
return TryParseOrMigrate(path, File.ReadAllBytes(path), doMigrate, out result);
|
||||
}
|
||||
|
||||
public static bool TryParseOrMigrate(string path, byte[] bytes, bool doMigrate, out Vrm10Data result)
|
||||
{
|
||||
var data = new GlbLowLevelParser(path, bytes).Parse();
|
||||
return TryParseOrMigrate(data, doMigrate, out result);
|
||||
}
|
||||
|
||||
/// <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 Vrm10Data result)
|
||||
public static bool TryParseOrMigrate(GltfData data, bool doMigrate, out Vrm10Data result)
|
||||
{
|
||||
//
|
||||
// Parse(parse glb, parser gltf json)
|
||||
//
|
||||
{
|
||||
var data = new GlbLowLevelParser(path, bytes).Parse();
|
||||
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(data.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
|
||||
{
|
||||
// success
|
||||
|
|
@ -56,10 +64,11 @@ namespace UniVRM10
|
|||
|
||||
// try migrateion
|
||||
byte[] migrated = default;
|
||||
Migration.Vrm0Meta oldMeta = default;
|
||||
try
|
||||
{
|
||||
var glb = UniGLTF.Glb.Parse(bytes);
|
||||
var json = glb.Json.Bytes.ParseAsJson();
|
||||
var json = data.Json.ParseAsJson();
|
||||
var bin = data.Chunks.First(x => x.ChunkType == GlbChunkType.BIN);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -86,12 +95,14 @@ namespace UniVRM10
|
|||
return false;
|
||||
}
|
||||
|
||||
migrated = MigrationVrm.Migrate(json, glb.Binary.Bytes);
|
||||
migrated = MigrationVrm.Migrate(json, bin.Bytes);
|
||||
if (migrated == null)
|
||||
{
|
||||
result = new Vrm10Data(default, default, Vrm10FileType.Vrm0, "vrm0: cannot migrate");
|
||||
return false;
|
||||
}
|
||||
|
||||
oldMeta = Migration.Vrm0Meta.FromJsonBytes(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -100,11 +111,15 @@ namespace UniVRM10
|
|||
}
|
||||
|
||||
{
|
||||
var data = new GlbLowLevelParser(path, migrated).Parse();
|
||||
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(data.GLTF.extensions, out VRMC_vrm vrm))
|
||||
var migratedData = new GlbLowLevelParser(data.TargetPath, migrated).Parse();
|
||||
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(migratedData.GLTF.extensions, out VRMC_vrm vrm))
|
||||
{
|
||||
// success
|
||||
result = new Vrm10Data(data, vrm, Vrm10FileType.Vrm0, "vrm0: migrated");
|
||||
if (oldMeta == null)
|
||||
{
|
||||
throw new NullReferenceException("oldMeta");
|
||||
}
|
||||
result = new Vrm10Data(migratedData, vrm, Vrm10FileType.Vrm0, "vrm0: migrated", oldMeta);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,24 @@ namespace UniVRM10
|
|||
return clip;
|
||||
}
|
||||
|
||||
public async Task<Texture2D> LoadVrmThumbnailAsync(IAwaitCaller awaitCaller = null)
|
||||
{
|
||||
if (awaitCaller == null)
|
||||
{
|
||||
awaitCaller = new ImmediateCaller();
|
||||
}
|
||||
|
||||
if (Vrm10TextureDescriptorGenerator.TryGetMetaThumbnailTextureImportParam(Data, m_vrm.VrmExtension, out (SubAssetKey, VRMShaders.TextureDescriptor Param) kv))
|
||||
{
|
||||
var texture = await TextureFactory.GetTextureAsync(kv.Param, awaitCaller);
|
||||
return texture as Texture2D;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async Task<VRM10Object> LoadVrmAsync(IAwaitCaller awaitCaller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrmExtension)
|
||||
{
|
||||
if (m_externalMap.TryGetValue(VRM10Object.SubAssetKey, out UnityEngine.Object obj) && obj is VRM10Object vrm)
|
||||
|
|
@ -347,13 +365,11 @@ namespace UniVRM10
|
|||
{
|
||||
meta.Authors.AddRange(src.Authors);
|
||||
}
|
||||
if (Vrm10TextureDescriptorGenerator.TryGetMetaThumbnailTextureImportParam(Data, vrmExtension, out (SubAssetKey, VRMShaders.TextureDescriptor Param) kv))
|
||||
|
||||
var tex2D = await LoadVrmThumbnailAsync(awaitCaller);
|
||||
if (tex2D != null)
|
||||
{
|
||||
var texture = await TextureFactory.GetTextureAsync(kv.Param, awaitCaller);
|
||||
if (texture is Texture2D tex2D)
|
||||
{
|
||||
meta.Thumbnail = tex2D;
|
||||
}
|
||||
meta.Thumbnail = tex2D;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
109
Assets/VRM10/Runtime/Migration/Vrm10Meta.cs
Normal file
109
Assets/VRM10/Runtime/Migration/Vrm10Meta.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
using System;
|
||||
using UniJSON;
|
||||
|
||||
namespace UniVRM10.Migration
|
||||
{
|
||||
public enum AllowedUser
|
||||
{
|
||||
OnlyAuthor,
|
||||
ExplicitlyLicensedPerson,
|
||||
Everyone,
|
||||
}
|
||||
|
||||
public enum LicenseType
|
||||
{
|
||||
Redistribution_Prohibited,
|
||||
CC0,
|
||||
CC_BY,
|
||||
CC_BY_NC,
|
||||
CC_BY_SA,
|
||||
CC_BY_NC_SA,
|
||||
CC_BY_ND,
|
||||
CC_BY_NC_ND,
|
||||
Other
|
||||
}
|
||||
|
||||
public enum UssageLicense
|
||||
{
|
||||
Disallow,
|
||||
Allow,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VRM0.X version meta. This class has meta before migrate.
|
||||
/// </summary>
|
||||
public class Vrm0Meta
|
||||
{
|
||||
public string title;
|
||||
public string version;
|
||||
public string author;
|
||||
public string contactInformation;
|
||||
public string reference;
|
||||
public int texture = -1;
|
||||
public AllowedUser allowedUser = AllowedUser.OnlyAuthor;
|
||||
public bool violentUsage = false;
|
||||
public bool sexualUsage = false;
|
||||
public bool commercialUsage = false;
|
||||
public string otherPermissionUrl;
|
||||
public LicenseType licenseType = LicenseType.Redistribution_Prohibited;
|
||||
public string otherLicenseUrl;
|
||||
|
||||
public static Vrm0Meta FromJsonBytes(UniJSON.JsonNode glTF)
|
||||
{
|
||||
var oldMeta = new Vrm0Meta();
|
||||
var extensions = glTF["extensions"];
|
||||
var vrm = extensions["VRM"];
|
||||
var meta = vrm["meta"];
|
||||
foreach (var kv in meta.ObjectItems())
|
||||
{
|
||||
var key = kv.Key.GetString();
|
||||
switch (key)
|
||||
{
|
||||
case "title":
|
||||
oldMeta.title = kv.Value.GetString();
|
||||
break;
|
||||
case "version":
|
||||
oldMeta.version = kv.Value.GetString();
|
||||
break;
|
||||
case "author":
|
||||
oldMeta.author = kv.Value.GetString();
|
||||
break;
|
||||
case "contactInformation":
|
||||
oldMeta.contactInformation = kv.Value.GetString();
|
||||
break;
|
||||
case "reference":
|
||||
oldMeta.reference = kv.Value.GetString();
|
||||
break;
|
||||
case "texture":
|
||||
oldMeta.texture = kv.Value.GetInt32();
|
||||
break;
|
||||
case "allowedUserName":
|
||||
oldMeta.allowedUser = (AllowedUser)Enum.Parse(typeof(AllowedUser), kv.Value.GetString(), true);
|
||||
break;
|
||||
case "violentUssageName":
|
||||
oldMeta.violentUsage = kv.Value.GetString() == "Allow";
|
||||
break;
|
||||
case "sexualUssageName":
|
||||
oldMeta.sexualUsage = kv.Value.GetString() == "Allow";
|
||||
break;
|
||||
case "commercialUssageName":
|
||||
oldMeta.commercialUsage = kv.Value.GetString() == "Allow";
|
||||
break;
|
||||
case "otherPermissionUrl":
|
||||
oldMeta.otherPermissionUrl = kv.Value.GetString();
|
||||
break;
|
||||
case "licenseName":
|
||||
oldMeta.licenseType = (LicenseType)Enum.Parse(typeof(LicenseType), kv.Value.GetString(), true);
|
||||
break;
|
||||
case "otherLicenseUrl":
|
||||
oldMeta.otherLicenseUrl = kv.Value.GetString();
|
||||
break;
|
||||
default:
|
||||
UnityEngine.Debug.Log($"{key}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return oldMeta;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/Migration/Vrm10Meta.cs.meta
Normal file
11
Assets/VRM10/Runtime/Migration/Vrm10Meta.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 57e782f0f79ef4d4abcd4f1c5438e9e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -5,7 +5,7 @@ using UniGLTF;
|
|||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using VRMShaders;
|
||||
|
||||
namespace UniVRM10.VRM10Viewer
|
||||
{
|
||||
|
|
@ -93,7 +93,31 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_textDistributionOther.text = "";
|
||||
}
|
||||
|
||||
public void UpdateMeta(VRM10ObjectMeta meta)
|
||||
public void UpdateMeta(Migration.Vrm0Meta meta, Texture2D thumbnail)
|
||||
{
|
||||
if (meta == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_textModelTitle.text = meta.title;
|
||||
m_textModelVersion.text = meta.version;
|
||||
m_textModelAuthor.text = meta.author;
|
||||
m_textModelContact.text = meta.contactInformation;
|
||||
m_textModelReference.text = meta.reference;
|
||||
m_textPermissionAllowed.text = meta.allowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.violentUsage.ToString();
|
||||
m_textPermissionSexual.text = meta.sexualUsage.ToString();
|
||||
m_textPermissionCommercial.text = meta.commercialUsage.ToString();
|
||||
m_textPermissionOther.text = meta.otherPermissionUrl;
|
||||
|
||||
// m_textDistributionLicense.text = meta.ModificationLicense.ToString();
|
||||
m_textDistributionOther.text = meta.otherLicenseUrl;
|
||||
|
||||
m_thumbnail.texture = thumbnail;
|
||||
}
|
||||
|
||||
public void UpdateMeta(UniGLTF.Extensions.VRMC_vrm.Meta meta, Texture2D thumbnail)
|
||||
{
|
||||
if (meta == null)
|
||||
{
|
||||
|
|
@ -108,16 +132,16 @@ namespace UniVRM10.VRM10Viewer
|
|||
{
|
||||
m_textModelReference.text = meta.References[0];
|
||||
}
|
||||
m_textPermissionAllowed.text = meta.AllowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.ViolentUsage.ToString();
|
||||
m_textPermissionSexual.text = meta.SexualUsage.ToString();
|
||||
// m_textPermissionAllowed.text = meta.AllowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.AllowExcessivelyViolentUsage.ToString();
|
||||
m_textPermissionSexual.text = meta.AllowExcessivelySexualUsage.ToString();
|
||||
m_textPermissionCommercial.text = meta.CommercialUsage.ToString();
|
||||
m_textPermissionOther.text = meta.OtherPermissionUrl;
|
||||
// m_textPermissionOther.text = meta.OtherPermissionUrl;
|
||||
|
||||
m_textDistributionLicense.text = meta.ModificationLicense.ToString();
|
||||
// m_textDistributionLicense.text = meta.ModificationLicense.ToString();
|
||||
m_textDistributionOther.text = meta.OtherLicenseUrl;
|
||||
|
||||
m_thumbnail.texture = meta.Thumbnail;
|
||||
m_thumbnail.texture = thumbnail;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
|
|
@ -182,53 +206,113 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_target = GameObject.FindObjectOfType<VRM10TargetMover>().gameObject;
|
||||
}
|
||||
|
||||
HumanPoseTransfer m_loaded;
|
||||
VRM10Controller m_controller;
|
||||
|
||||
VRM10AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
bool EnableLipSyncValue
|
||||
class Loaded : IDisposable
|
||||
{
|
||||
set
|
||||
RuntimeGltfInstance m_instance;
|
||||
HumanPoseTransfer m_pose;
|
||||
VRM10Controller m_controller;
|
||||
|
||||
VRM10AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
public bool EnableLipSyncValue
|
||||
{
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
set
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VRM10AutoExpression m_autoExpression;
|
||||
bool m_enableAutoExpressionValue;
|
||||
bool EnableAutoExpressionValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_enableAutoExpressionValue == value) return;
|
||||
m_enableAutoExpressionValue = value;
|
||||
if (m_autoExpression != null)
|
||||
{
|
||||
m_autoExpression.enabled = m_enableAutoExpressionValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VRM10Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
bool EnableBlinkValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VRM10AutoExpression m_autoExpression;
|
||||
bool m_enableAutoExpressionValue;
|
||||
public bool EnableAutoExpressionValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_enableAutoExpressionValue == value) return;
|
||||
m_enableAutoExpressionValue = value;
|
||||
if (m_autoExpression != null)
|
||||
{
|
||||
m_autoExpression.enabled = m_enableAutoExpressionValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VRM10Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
public bool EnableBlinkValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Loaded(RuntimeGltfInstance instance, HumanPoseTransfer src, Transform lookAtTarget)
|
||||
{
|
||||
m_instance = instance;
|
||||
|
||||
m_controller = instance.GetComponent<VRM10Controller>();
|
||||
if (m_controller != null)
|
||||
{
|
||||
// VRM
|
||||
m_controller.UpdateType = VRM10Controller.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
{
|
||||
m_pose = instance.gameObject.AddComponent<HumanPoseTransfer>();
|
||||
m_pose.Source = src;
|
||||
m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_lipSync = instance.gameObject.AddComponent<VRM10AIUEO>();
|
||||
m_blink = instance.gameObject.AddComponent<VRM10Blinker>();
|
||||
m_autoExpression = instance.gameObject.AddComponent<VRM10AutoExpression>();
|
||||
|
||||
m_controller.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze;
|
||||
m_controller.Gaze = lookAtTarget;
|
||||
}
|
||||
}
|
||||
|
||||
var animation = instance.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
// GLTF animation
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// destroy GameObject
|
||||
GameObject.Destroy(m_instance.gameObject);
|
||||
}
|
||||
|
||||
public void EnableBvh(HumanPoseTransfer src)
|
||||
{
|
||||
if (m_pose != null)
|
||||
{
|
||||
m_pose.Source = src;
|
||||
m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableTPose(HumanPoseClip pose)
|
||||
{
|
||||
if (m_pose != null)
|
||||
{
|
||||
m_pose.PoseClip = pose;
|
||||
m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded m_loaded;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
|
@ -261,39 +345,19 @@ namespace UniVRM10.VRM10Viewer
|
|||
|
||||
private void Update()
|
||||
{
|
||||
EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (Root != null) Root.SetActive(!Root.activeSelf);
|
||||
}
|
||||
|
||||
m_ui.UpdateToggle(EnableBvh, EnableTPose);
|
||||
|
||||
// if (m_controller != null)
|
||||
// {
|
||||
// m_controller.Expression.Apply();
|
||||
// }
|
||||
}
|
||||
|
||||
void EnableBvh()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableTPose()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.PoseClip = m_pose;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
m_ui.UpdateToggle(() => m_loaded?.EnableBvh(m_src), () => m_loaded?.EnableTPose(m_pose));
|
||||
}
|
||||
|
||||
void OnOpenClicked()
|
||||
|
|
@ -350,7 +414,7 @@ namespace UniVRM10.VRM10Viewer
|
|||
}
|
||||
}
|
||||
|
||||
void LoadModel(string path)
|
||||
async void LoadModel(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
|
|
@ -358,115 +422,63 @@ namespace UniVRM10.VRM10Viewer
|
|||
}
|
||||
|
||||
Debug.LogFormat("{0}", path);
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
GltfData data;
|
||||
try
|
||||
{
|
||||
case ".vrm":
|
||||
data = new AutoGltfFileParser(path).Parse();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Vrm10Data.TryParseOrMigrate(data, doMigrate: true, out Vrm10Data vrm))
|
||||
{
|
||||
// vrm
|
||||
using (var loader = new Vrm10Importer(vrm, materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
// migrate しても thumbnail は同じ
|
||||
var thumbnail = await loader.LoadVrmThumbnailAsync();
|
||||
|
||||
if (vrm.OriginalMetaBeforeMigration != null)
|
||||
{
|
||||
if (!Vrm10Data.TryParseOrMigrate(path, doMigrate: true, out Vrm10Data result))
|
||||
{
|
||||
Debug.LogError(result.Message);
|
||||
return;
|
||||
}
|
||||
using (var loader = new Vrm10Importer(result, materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
// migrated from vrm-0.x. use OldMeta
|
||||
m_texts.UpdateMeta(vrm.OriginalMetaBeforeMigration, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load vrm-1.0. use newMeta
|
||||
m_texts.UpdateMeta(vrm.VrmExtension.Meta, thumbnail);
|
||||
}
|
||||
|
||||
case ".glb":
|
||||
{
|
||||
var data = new GlbFileParser(path).Parse();
|
||||
|
||||
using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ".gltf":
|
||||
{
|
||||
var data = new GltfFileWithResourceFilesParser(path).Parse();
|
||||
|
||||
using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ".zip":
|
||||
{
|
||||
var data = new ZipArchivedGltfFileParser(path).Parse();
|
||||
|
||||
using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug.LogWarningFormat("unknown file type: {0}", path);
|
||||
break;
|
||||
var instance = await loader.LoadAsync();
|
||||
SetModel(instance);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// gltf
|
||||
using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
var instance = await loader.LoadAsync();
|
||||
SetModel(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetModel(GameObject go)
|
||||
void SetModel(RuntimeGltfInstance instance)
|
||||
{
|
||||
// cleanup
|
||||
var loaded = m_loaded;
|
||||
m_loaded = null;
|
||||
|
||||
if (loaded != null)
|
||||
if (m_loaded != null)
|
||||
{
|
||||
Debug.LogFormat("destroy {0}", loaded);
|
||||
GameObject.Destroy(loaded.gameObject);
|
||||
m_loaded.Dispose();
|
||||
m_loaded = null;
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
m_controller = go.GetComponent<VRM10Controller>();
|
||||
if (m_controller != null)
|
||||
{
|
||||
|
||||
m_texts.UpdateMeta(m_controller.Vrm.Meta);
|
||||
|
||||
m_controller.UpdateType = VRM10Controller.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
{
|
||||
m_loaded = go.AddComponent<HumanPoseTransfer>();
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_lipSync = go.AddComponent<VRM10AIUEO>();
|
||||
m_blink = go.AddComponent<VRM10Blinker>();
|
||||
m_autoExpression = go.AddComponent<VRM10AutoExpression>();
|
||||
|
||||
m_controller.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze;
|
||||
m_controller.Gaze = m_target.transform;
|
||||
}
|
||||
}
|
||||
|
||||
var animation = go.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
}
|
||||
instance.ShowMeshes();
|
||||
instance.EnableUpdateWhenOffscreen();
|
||||
m_loaded = new Loaded(instance, m_src, m_target.transform);
|
||||
}
|
||||
|
||||
void SetMotion(HumanPoseTransfer src)
|
||||
|
|
@ -474,7 +486,10 @@ namespace UniVRM10.VRM10Viewer
|
|||
m_src = src;
|
||||
src.GetComponent<Renderer>().enabled = false;
|
||||
|
||||
EnableBvh();
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.EnableBvh(m_src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,5 +254,12 @@ namespace UniVRM10
|
|||
Assert.AreEqual(VALUE.y, springBone.Colliders[colliderIndex].Shape.Sphere.Offset[1]);
|
||||
Assert.AreEqual(VALUE.z, springBone.Colliders[colliderIndex].Shape.Sphere.Offset[2]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MigrateMeta()
|
||||
{
|
||||
Assert.True(Vrm10Data.TryParseOrMigrate(AliciaPath, true, out Vrm10Data vrm));
|
||||
var a = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,28 +54,4 @@ namespace VRMShaders
|
|||
return Task.FromResult(action());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 非同期実行
|
||||
/// </summary>
|
||||
public sealed class TaskCaller : IAwaitCaller
|
||||
{
|
||||
public Task NextFrame()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
// Thread.Sleep(10);
|
||||
});
|
||||
}
|
||||
|
||||
public Task Run(Action action)
|
||||
{
|
||||
return Task.Run(action);
|
||||
}
|
||||
|
||||
public Task<T> Run<T>(Func<T> action)
|
||||
{
|
||||
return Task.Run(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
docfx/articles/en/gltf/0_36_update.md
Normal file
32
docfx/articles/en/gltf/0_36_update.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# v0.36
|
||||
|
||||
## Changed Storage Position of Texture Name
|
||||
|
||||
Conforming to the GLTF specification.
|
||||
|
||||
```json
|
||||
json.images[i].extra.name
|
||||
```
|
||||
|
||||
After the change
|
||||
|
||||
```json
|
||||
json.images[i].name
|
||||
```
|
||||
|
||||
## Changed Storage Position BlendShape Name
|
||||
|
||||
Conforming to the GLTF specification.
|
||||
|
||||
* `extras` is not allowed in target
|
||||
* https://github.com/KhronosGroup/glTF/issues/1036#issuecomment-314078356
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].targets[k].extra.name
|
||||
```
|
||||
|
||||
After the change
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].extras.targetNames[k]
|
||||
```
|
||||
|
|
@ -58,14 +58,8 @@ See `SimpleViewer` sample.
|
|||
```cs
|
||||
GltfData Load(string path)
|
||||
{
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch(ext)
|
||||
{
|
||||
case ".glb": return new GlbFileParser(path).Parse();
|
||||
case ".gltf": return new GltfFileWithResourceFilesParser(path).Parse();
|
||||
case ".zip": return new ZipArchivedGltfFileParser(path).Parse();
|
||||
default: throw new Exception($"unknown: {ext}");
|
||||
}
|
||||
// Detect type by file extension automatically
|
||||
return new AutoGltfFileParser(path).Parse();
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,10 @@
|
|||
# Version
|
||||
|
||||
| version | |
|
||||
|---------|---------------------------------------|
|
||||
| v0.82.1 | Material replacement when(for URP) |
|
||||
| v0.82.0 | Material replacement when(for URP) |
|
||||
| v0.77 | Reorganize ImporterContext |
|
||||
| v0.68 | Reorganize ImporterContext |
|
||||
| v0.63.2 | Update gltf extensions implementation |
|
||||
| v0.56 | Update BlendShapeKey spec |
|
||||
|
||||
[Rework BlendShapeKey's Interface](https://github.com/vrm-c/UniVRM/wiki/ReleaseNote-v0.56.0%28en%29#reworks-blendshapekeys-interface)
|
||||
|
||||
## v0.36
|
||||
|
||||
### Changed Storage Position of Texture Name
|
||||
|
||||
Conforming to the GLTF specification.
|
||||
|
||||
```json
|
||||
json.images[i].extra.name
|
||||
```
|
||||
|
||||
After the change
|
||||
|
||||
```json
|
||||
json.images[i].name
|
||||
```
|
||||
|
||||
### Changed Storage Position BlendShape Name
|
||||
|
||||
Conforming to the GLTF specification.
|
||||
|
||||
* `extras` is not allowed in target
|
||||
* https://github.com/KhronosGroup/glTF/issues/1036#issuecomment-314078356
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].targets[k].extra.name
|
||||
```
|
||||
|
||||
After the change
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].extras.targetNames[k]
|
||||
```
|
||||
| version | |
|
||||
|---------|-----------------------------------------------------|
|
||||
| v0.82.1 | `materialGenerator(for URP)` argument and `VrmData` |
|
||||
| v0.79 | `GltfData` |
|
||||
| v0.77 | `RuntimeGltfInstance` |
|
||||
| v0.68 | `GltfParser` |
|
||||
| v0.63.2 | Update gltf extensions implementation |
|
||||
| v0.56 | Update BlendShapeKey spec |
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
href: gltf/0_82_glb_import.md
|
||||
- name: glTF extensions implementation(0.63.2)
|
||||
href: gltf/how_to_impl_extension.md
|
||||
- name: GltfUpdate(0.36)
|
||||
href: gltf/0_36_update.md
|
||||
|
||||
- name: VRM
|
||||
items:
|
||||
|
|
@ -37,7 +39,7 @@
|
|||
- name: VRM-1.0(β)
|
||||
items:
|
||||
- name: 🚧Samples/VRM10Viewer
|
||||
- name: 🚧RuntimeImport
|
||||
- name: RuntimeImport
|
||||
href: vrm1/vrm1_runtime_load.md
|
||||
- name: 🚧Humanoid
|
||||
href: vrm1/vrm1_get_humanoid.md
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ tags: ["api"]
|
|||
## Environment
|
||||
UniVRM v0.58.0
|
||||
|
||||
[Rework BlendShapeKey's Interface](https://github.com/vrm-c/UniVRM/wiki/ReleaseNote-v0.56.0%28en%29#reworks-blendshapekeys-interface)
|
||||
|
||||
## Methods
|
||||
|
||||
* [Recommended] `SetValues`
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ Below step is needed.
|
|||
1. Load a `RuntimeGltfInstance` from `VRMData`.
|
||||
1. Use the `RuntimeGltfInstance`
|
||||
|
||||
See `Assets\VRM\Samples\SimpleViewer\ViewerUI.cs`
|
||||
|
||||
# 1. Get `GltfData`
|
||||
|
||||
```cs
|
||||
|
|
|
|||
|
|
@ -1,19 +1,44 @@
|
|||
---
|
||||
title: 🚧Runtime ロード
|
||||
weight: 10
|
||||
---
|
||||
# RuntimeLoad
|
||||
|
||||
VRM-1.0 を使うアプリケーションは、 `VRM-0.x` の資産もロードしたいはずです。
|
||||
`VRM-1.0` can load `VRM-0.x`.
|
||||
In that case, incompatible migrated meta properties are not allowed.
|
||||
Therefore, we provide an API that allows you to access the original meta before migration.
|
||||
|
||||
`VRM-1.0` と `VRM-0.X` の meta の非互換に [Metaの自動的なマイグレーションは禁止する方針](https://github.com/vrm-c/vrm-specification/issues/181) となりました。
|
||||
See `Assets\VRM10\Samples\VRM10Viewer\VRM10ViewerUI.cs`.
|
||||
|
||||
## VRM-0.X を VRM-1.0 コンポーネントに対してロードする
|
||||
```cs
|
||||
async Task<RuntimeGltfInstance> LoadAsync(string path)
|
||||
{
|
||||
GltfData data = new GltfZipOrGlbFileParser(path).Parse();
|
||||
|
||||
`UniVRM-1.0` では、
|
||||
`VRM-0.X` のライセンスを保持したまま、`VRM-1.0` のコンポーネントにロードする機能を提供します(予定)。
|
||||
// The doMigrate argument allows you to load that older version of the vrm.
|
||||
if (Vrm10Data.TryParseOrMigrate(data, doMigrate: true, out Vrm10Data vrm))
|
||||
{
|
||||
// vrm
|
||||
using (var loader = new Vrm10Importer(vrm,
|
||||
materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
// It has been migrated, but it is the same thumbnail
|
||||
var thumbnail = await loader.LoadVrmThumbnailAsync();
|
||||
|
||||
アプリケーションは、この方法でロードしたモデルは、`VRM-0.X` ライセンスとして扱ってください。
|
||||
if (vrm.OldMeta != null)
|
||||
{
|
||||
// migrated from vrm-0.x. use OldMeta
|
||||
UpdateMeta(vrm.OldMeta, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load vrm-1.0. use newMeta
|
||||
UpdateMeta(vrm.VrmExtension.Meta, thumbnail);
|
||||
}
|
||||
|
||||
## RuntimeLoad 例
|
||||
|
||||
`vrm-0.x` と `vrm-1.0` 両方をロードしてライセンスを取得する例。
|
||||
// load model
|
||||
RuntimeGltfInstance instance = await loader.LoadAsync();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw new Exception("not vrm");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
36
docfx/articles/ja/gltf/0_36_update.md
Normal file
36
docfx/articles/ja/gltf/0_36_update.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# v0.36
|
||||
|
||||
## テクスチャ名の格納位置の修正
|
||||
|
||||
GLTFの仕様に準拠しました。
|
||||
|
||||
* extraはextrasの間違い
|
||||
* imageはnameを持っていた
|
||||
|
||||
```json
|
||||
json.images[i].extra.name
|
||||
```
|
||||
|
||||
変更後
|
||||
|
||||
```json
|
||||
json.images[i].name
|
||||
```
|
||||
|
||||
## ブレンドシェイプ名の格納位置の修正
|
||||
|
||||
GLTFの仕様に準拠しました。
|
||||
|
||||
* extraはextrasの間違い
|
||||
* targetにextrasは不許可
|
||||
* https://github.com/KhronosGroup/glTF/issues/1036#issuecomment-314078356
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].targets[k].extra.name
|
||||
```
|
||||
|
||||
変更後
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].extras.targetNames[k]
|
||||
```
|
||||
|
|
@ -58,14 +58,8 @@ GltfData Load(string path)
|
|||
```cs
|
||||
GltfData Load(string path)
|
||||
{
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch(ext)
|
||||
{
|
||||
case ".glb": return new GlbFileParser(path).Parse();
|
||||
case ".gltf": return new GltfFileWithResourceFilesParser(path).Parse();
|
||||
case ".zip": return new ZipArchivedGltfFileParser(path).Parse();
|
||||
default: throw new Exception($"unknown: {ext}");
|
||||
}
|
||||
// ファイル拡張子で自動判定します
|
||||
return new AutoGltfFileParser(path).Parse();
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +1,10 @@
|
|||
# Version
|
||||
|
||||
| version | |
|
||||
|---------|-------------------------------------|
|
||||
| v0.82.1 | Import時のMaterial差し替え(URP対応) |
|
||||
| v0.82.0 | Import時のMaterial差し替え(URP対応) |
|
||||
| v0.77 | ImporterContext の整理 |
|
||||
| v0.68 | ImporterContext の整理 |
|
||||
| v0.63.2 | gltf の extension の実装方法を変更 |
|
||||
| v0.56 | BlendShapeKey の仕様変更 |
|
||||
|
||||
[BlendShapeKeyのインタフェースを厳格化、整理](https://github.com/vrm-c/UniVRM/wiki/ReleaseNote-v0.56.0%28ja%29#blendshapekey%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%82%92%E5%8E%B3%E6%A0%BC%E5%8C%96%E6%95%B4%E7%90%86)
|
||||
|
||||
## v0.36
|
||||
|
||||
### テクスチャ名の格納位置の修正
|
||||
|
||||
GLTFの仕様に準拠しました。
|
||||
|
||||
* extraはextrasの間違い
|
||||
* imageはnameを持っていた
|
||||
|
||||
```json
|
||||
json.images[i].extra.name
|
||||
```
|
||||
|
||||
変更後
|
||||
|
||||
```json
|
||||
json.images[i].name
|
||||
```
|
||||
|
||||
### ブレンドシェイプ名の格納位置の修正
|
||||
|
||||
GLTFの仕様に準拠しました。
|
||||
|
||||
* extraはextrasの間違い
|
||||
* targetにextrasは不許可
|
||||
* https://github.com/KhronosGroup/glTF/issues/1036#issuecomment-314078356
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].targets[k].extra.name
|
||||
```
|
||||
|
||||
変更後
|
||||
|
||||
```json
|
||||
json.meshes[i].primitives[j].extras.targetNames[k]
|
||||
```
|
||||
| version | |
|
||||
|---------|-------------------------------------------------|
|
||||
| v0.82.1 | `materialGenerator(URP対応)` 引き数と `VrmData` |
|
||||
| v0.79 | `GltfData` |
|
||||
| v0.77 | `RuntimeGltfInstance` |
|
||||
| v0.68 | `GltfParser` |
|
||||
| v0.63.2 | gltf の extension の実装方法を変更 |
|
||||
| v0.56 | BlendShapeKey の仕様変更 |
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
href: gltf/0_82_glb_import.md
|
||||
- name: glTF拡張の実装(0.63.2)
|
||||
href: gltf/how_to_impl_extension.md
|
||||
- name: GltfUpdate(0.36)
|
||||
href: gltf/0_36_update.md
|
||||
|
||||
- name: VRM
|
||||
items:
|
||||
|
|
@ -37,7 +39,7 @@
|
|||
- name: VRM-1.0(β)
|
||||
items:
|
||||
- name: 🚧Samples/VRM10Viewer
|
||||
- name: 🚧RuntimeImport
|
||||
- name: RuntimeImport
|
||||
href: vrm1/vrm1_runtime_load.md
|
||||
- name: 🚧Humanoid
|
||||
href: vrm1/vrm1_get_humanoid.md
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ tags: ["api"]
|
|||
## 環境
|
||||
UniVRM v0.58.0
|
||||
|
||||
[BlendShapeKeyのインタフェースを厳格化、整理](https://github.com/vrm-c/UniVRM/wiki/ReleaseNote-v0.56.0%28ja%29#blendshapekey%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%82%92%E5%8E%B3%E6%A0%BC%E5%8C%96%E6%95%B4%E7%90%86)
|
||||
|
||||
## 使用するメソッド
|
||||
|
||||
* [推奨] `SetValues`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
* `Version 0.82.0` `0.82.1` 以降を使ってください。
|
||||
* `Version 0.82.0` は `0.82.1` 以降を使ってください。
|
||||
* `Version 0.82.1~`
|
||||
|
||||
以下の手順で import します。
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
1. `VrmData` から `RuntimeGltfInstance` をロードする。
|
||||
1. `RuntimeGltfInstance` を使う。
|
||||
|
||||
サンプルの `Assets\VRM\Samples\SimpleViewer\ViewerUI.cs` も参照してください。
|
||||
|
||||
# 1. `GltfData` を得る
|
||||
|
||||
```cs
|
||||
|
|
|
|||
|
|
@ -1,19 +1,44 @@
|
|||
---
|
||||
title: 🚧Runtime ロード
|
||||
weight: 10
|
||||
---
|
||||
# RuntimeLoad
|
||||
|
||||
VRM-1.0 を使うアプリケーションは、 `VRM-0.x` の資産もロードしたいはずです。
|
||||
`VRM-1.0` は、 `VRM-0.x` もロードできます。
|
||||
その場合、あたらしい meta への変換が発生し互換性の無い部分はすべて `不許可` の値になります。
|
||||
このため、変換前のライセンスにアクセスする API を提供します。
|
||||
|
||||
`VRM-1.0` と `VRM-0.X` の meta の非互換に [Metaの自動的なマイグレーションは禁止する方針](https://github.com/vrm-c/vrm-specification/issues/181) となりました。
|
||||
サンプルの `Assets\VRM10\Samples\VRM10Viewer\VRM10ViewerUI.cs` も参照してください。
|
||||
|
||||
## VRM-0.X を VRM-1.0 コンポーネントに対してロードする
|
||||
```cs
|
||||
async Task<RuntimeGltfInstance> LoadAsync(string path)
|
||||
{
|
||||
GltfData data = new GltfZipOrGlbFileParser(path).Parse();
|
||||
|
||||
`UniVRM-1.0` では、
|
||||
`VRM-0.X` のライセンスを保持したまま、`VRM-1.0` のコンポーネントにロードする機能を提供します(予定)。
|
||||
// doMigrate: true で旧バージョンの vrm をロードできます。
|
||||
if (Vrm10Data.TryParseOrMigrate(data, doMigrate: true, out Vrm10Data vrm))
|
||||
{
|
||||
// vrm
|
||||
using (var loader = new Vrm10Importer(vrm,
|
||||
materialGenerator: GetVrmMaterialDescriptorGenerator(m_useUrpMaterial.isOn)))
|
||||
{
|
||||
// migrate しても thumbnail は同じ
|
||||
var thumbnail = await loader.LoadVrmThumbnailAsync();
|
||||
|
||||
アプリケーションは、この方法でロードしたモデルは、`VRM-0.X` ライセンスとして扱ってください。
|
||||
if (vrm.OldMeta != null)
|
||||
{
|
||||
// migrated from vrm-0.x. use OldMeta
|
||||
UpdateMeta(vrm.OldMeta, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load vrm-1.0. use newMeta
|
||||
UpdateMeta(vrm.VrmExtension.Meta, thumbnail);
|
||||
}
|
||||
|
||||
## RuntimeLoad 例
|
||||
|
||||
`vrm-0.x` と `vrm-1.0` 両方をロードしてライセンスを取得する例。
|
||||
// モデルをロード
|
||||
RuntimeGltfInstance instance = await loader.LoadAsync();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw new Exception("not vrm");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user