From ee3ce66034b6f5521f887c8458ca9a4997d4ce5d Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 19 Sep 2024 14:35:05 +0900 Subject: [PATCH] IVRM0SpringBoneRuntime --- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 10 +++-- Assets/VRM/Runtime/IO/VrmUtility.cs | 7 +++- .../SpringBone/IVRM0SpringBoneRuntime.cs | 11 +++++ .../SpringBone/IVRM0SpringBoneRuntime.cs.meta | 11 +++++ .../SpringBone/Jobs/FastSpringBoneRuntime.cs | 41 +++++++++++++++++++ .../Jobs/FastSpringBoneRuntime.cs.meta | 11 +++++ .../SpringBone/VRMSpringBoneDefaultRuntime.cs | 25 +++++++++++ .../VRMSpringBoneDefaultRuntime.cs.meta | 11 +++++ Assets/VRM_Samples/SimpleViewer/ViewerUI.cs | 30 +++++++------- 9 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs create mode 100644 Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs.meta create mode 100644 Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs create mode 100644 Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs.meta create mode 100644 Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs create mode 100644 Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs.meta diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index a3cc8f4af..db742f42c 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -20,16 +20,20 @@ namespace VRM } } + IVRM0SpringBoneRuntime _springBoneRuntime; + public VRMImporterContext( VRMData data, IReadOnlyDictionary externalObjectMap = null, ITextureDeserializer textureDeserializer = null, IMaterialDescriptorGenerator materialGenerator = null, - ImporterContextSettings settings = null) + ImporterContextSettings settings = null, + IVRM0SpringBoneRuntime springboneRuntime = null) : base(data.Data, externalObjectMap, textureDeserializer, materialGenerator ?? VrmMaterialDescriptorGeneratorUtility.GetValidVrmMaterialDescriptorGenerator(data.VrmExtension), settings ?? new ImporterContextSettings(false)) { _data = data; TextureDescriptorGenerator = new VrmTextureDescriptorGenerator(Data, VRM); + _springBoneRuntime = springboneRuntime ?? new VRMSpringBoneDefaultRuntime(); } #region OnLoad @@ -57,8 +61,8 @@ namespace VRM using (MeasureTime("VRM LoadSecondary")) { - VRMSpringUtility.LoadSecondary(Root.transform, TryGetNode, - VRM.secondaryAnimation); + VRMSpringUtility.LoadSecondary(Root.transform, TryGetNode, VRM.secondaryAnimation); + await _springBoneRuntime.InitializeAsync(Root, awaitCaller); } await awaitCaller.NextFrame(); diff --git a/Assets/VRM/Runtime/IO/VrmUtility.cs b/Assets/VRM/Runtime/IO/VrmUtility.cs index 8ba66c562..dfcd3ae4b 100644 --- a/Assets/VRM/Runtime/IO/VrmUtility.cs +++ b/Assets/VRM/Runtime/IO/VrmUtility.cs @@ -73,7 +73,8 @@ namespace VRM MaterialGeneratorCallback materialGeneratorCallback = null, MetaCallback metaCallback = null, ITextureDeserializer textureDeserializer = null, - bool loadAnimation = false + bool loadAnimation = false, + IVRM0SpringBoneRuntime springboneRuntime = null ) { if (bytes == null) @@ -102,7 +103,9 @@ namespace VRM vrm, textureDeserializer: textureDeserializer, materialGenerator: materialGen, - settings: importerContextSettings)) + settings: importerContextSettings, + springboneRuntime: springboneRuntime + )) { if (metaCallback != null) { diff --git a/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs b/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs new file mode 100644 index 000000000..814f90b1a --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using UniGLTF; +using UnityEngine; + +namespace VRM +{ + public interface IVRM0SpringBoneRuntime + { + public Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller); + } +} \ No newline at end of file diff --git a/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs.meta b/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs.meta new file mode 100644 index 000000000..50aa707a3 --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dde51548cb9bb7546b6a9824b8710315 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs new file mode 100644 index 000000000..79e9c23e7 --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using UniGLTF; +using UniGLTF.SpringBoneJobs; +using UnityEngine; + +namespace VRM +{ + /// + /// FastSpringbone(job + singleton) で動作します。 + /// + /// VRMSpringBone.m_updateType = Manual + /// + /// により、各VRMSpringBoneの自力Updateは停止します。 + /// FastSpringBoneService に登録します。 + /// FastSpringBoneService.LateUpdate[DefaultExecutionOrder(11000)] で動作します。 + /// + public class FastSpringboneRuntime : IVRM0SpringBoneRuntime + { + public async Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller) + { + // default update の停止 + foreach (VRMSpringBone sb in vrm.GetComponentsInChildren()) + { + sb.m_updateType = VRMSpringBone.SpringBoneUpdateType.Manual; + } + + // create + var buffer = await SpringBoneJobs.FastSpringBoneReplacer.MakeBufferAsync(vrm, awaitCaller); + SpringBoneJobs.FastSpringBoneService.Instance.BufferCombiner.Register(buffer); + + // disposer + var disposer = vrm.AddComponent() + .AddAction(() => + { + SpringBoneJobs.FastSpringBoneService.Instance.BufferCombiner.Unregister(buffer); + buffer.Dispose(); + }) + ; + } + } +} \ No newline at end of file diff --git a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs.meta b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs.meta new file mode 100644 index 000000000..45c4f4121 --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8315a3b319fd3f4a892def8ae68e812 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs b/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs new file mode 100644 index 000000000..8c805ee21 --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using UniGLTF; +using UnityEngine; + +namespace VRM +{ + /// + /// デフォルトの VRMSPringBone 実装です。 + /// + /// VRMSpringBone.m_updateType = LateUpdate + /// + /// により、各VRMSpringBoneが自力で LateUpdate に動作します。 + /// + public class VRMSpringBoneDefaultRuntime : IVRM0SpringBoneRuntime + { + public async Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller) + { + foreach (VRMSpringBone sb in vrm.GetComponentsInChildren()) + { + sb.m_updateType = VRMSpringBone.SpringBoneUpdateType.LateUpdate; + } + await awaitCaller.NextFrame(); + } + } +} \ No newline at end of file diff --git a/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs.meta b/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs.meta new file mode 100644 index 000000000..652689ebd --- /dev/null +++ b/Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08914ddaedc7d394ab58a879662341b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs b/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs index 2c5f2bdc8..1e40164ca 100644 --- a/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs +++ b/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using UniGLTF; using UniGLTF.SpringBoneJobs; using UniHumanoid; +using Unity.Collections; using UnityEngine; using UnityEngine.UI; @@ -267,6 +268,13 @@ namespace VRM.SimpleViewer } } + private void Awake() + { +#if DEBUG + NativeLeakDetection.Mode = NativeLeakDetectionMode.EnabledWithStackTrace; +#endif + } + private void Start() { m_version.text = string.Format("VRMViewer {0}.{1}", @@ -382,23 +390,13 @@ namespace VRM.SimpleViewer } // vrm - VrmUtility.MaterialGeneratorCallback materialCallback = (VRM.glTF_VRM_extensions vrm) => GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm); + VrmUtility.MaterialGeneratorCallback materialCallback = (glTF_VRM_extensions vrm) => GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm); VrmUtility.MetaCallback metaCallback = m_texts.UpdateMeta; - var instance = await VrmUtility.LoadBytesAsync(path, bytes, GetIAwaitCaller(m_useAsync.isOn), materialCallback, metaCallback, loadAnimation: m_loadAnimation.isOn); - - if (m_useFastSpringBone.isOn) - { - // job用バッファ作成 - var buffer = await SpringBoneJobs.FastSpringBoneReplacer.MakeBufferAsync(instance.Root); - - // 登録 - SpringBoneJobs.FastSpringBoneService.Instance.BufferCombiner.Register(buffer); - - // 削除登録 - instance.Root.AddComponent() - .AddAction(()=>{ SpringBoneJobs.FastSpringBoneService.Instance.BufferCombiner.Unregister(buffer);}) - .Add(buffer); - } + var instance = await VrmUtility.LoadBytesAsync(path, bytes, GetIAwaitCaller(m_useAsync.isOn), + materialCallback, metaCallback, + loadAnimation: m_loadAnimation.isOn, + springboneRuntime: m_useFastSpringBone.isOn ? new FastSpringboneRuntime() : new VRMSpringBoneDefaultRuntime() + ); instance.EnableUpdateWhenOffscreen(); instance.ShowMeshes();