Skip to content

Commit

Permalink
IVRM0SpringBoneRuntime
Browse files Browse the repository at this point in the history
  • Loading branch information
ousttrue committed Sep 19, 2024
1 parent 7b284bb commit ee3ce66
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 21 deletions.
10 changes: 7 additions & 3 deletions Assets/VRM/Runtime/IO/VRMImporterContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ public VRM.glTF_VRM_extensions VRM
}
}

IVRM0SpringBoneRuntime _springBoneRuntime;

public VRMImporterContext(
VRMData data,
IReadOnlyDictionary<SubAssetKey, Object> 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
Expand Down Expand Up @@ -57,8 +61,8 @@ protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func<str

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();

Expand Down
7 changes: 5 additions & 2 deletions Assets/VRM/Runtime/IO/VrmUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public static async Task<RuntimeGltfInstance> LoadBytesAsync(string path,
MaterialGeneratorCallback materialGeneratorCallback = null,
MetaCallback metaCallback = null,
ITextureDeserializer textureDeserializer = null,
bool loadAnimation = false
bool loadAnimation = false,
IVRM0SpringBoneRuntime springboneRuntime = null
)
{
if (bytes == null)
Expand Down Expand Up @@ -102,7 +103,9 @@ public static async Task<RuntimeGltfInstance> LoadBytesAsync(string path,
vrm,
textureDeserializer: textureDeserializer,
materialGenerator: materialGen,
settings: importerContextSettings))
settings: importerContextSettings,
springboneRuntime: springboneRuntime
))
{
if (metaCallback != null)
{
Expand Down
11 changes: 11 additions & 0 deletions Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using UniGLTF;
using UnityEngine;

namespace VRM
{
public interface IVRM0SpringBoneRuntime
{
public Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller);
}
}
11 changes: 11 additions & 0 deletions Assets/VRM/Runtime/SpringBone/IVRM0SpringBoneRuntime.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Threading.Tasks;
using UniGLTF;
using UniGLTF.SpringBoneJobs;
using UnityEngine;

namespace VRM
{
/// <summary>
/// FastSpringbone(job + singleton) で動作します。
///
/// VRMSpringBone.m_updateType = Manual
///
/// により、各VRMSpringBoneの自力Updateは停止します。
/// FastSpringBoneService に登録します。
/// FastSpringBoneService.LateUpdate[DefaultExecutionOrder(11000)] で動作します。
/// </summary>
public class FastSpringboneRuntime : IVRM0SpringBoneRuntime
{
public async Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller)
{
// default update の停止
foreach (VRMSpringBone sb in vrm.GetComponentsInChildren<VRMSpringBone>())
{
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<FastSpringBoneDisposer>()
.AddAction(() =>
{
SpringBoneJobs.FastSpringBoneService.Instance.BufferCombiner.Unregister(buffer);
buffer.Dispose();
})
;
}
}
}
11 changes: 11 additions & 0 deletions Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneRuntime.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Threading.Tasks;
using UniGLTF;
using UnityEngine;

namespace VRM
{
/// <summary>
/// デフォルトの VRMSPringBone 実装です。
///
/// VRMSpringBone.m_updateType = LateUpdate
///
/// により、各VRMSpringBoneが自力で LateUpdate に動作します。
/// </summary>
public class VRMSpringBoneDefaultRuntime : IVRM0SpringBoneRuntime
{
public async Task InitializeAsync(GameObject vrm, IAwaitCaller awaitCaller)
{
foreach (VRMSpringBone sb in vrm.GetComponentsInChildren<VRMSpringBone>())
{
sb.m_updateType = VRMSpringBone.SpringBoneUpdateType.LateUpdate;
}
await awaitCaller.NextFrame();
}
}
}
11 changes: 11 additions & 0 deletions Assets/VRM/Runtime/SpringBone/VRMSpringBoneDefaultRuntime.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 14 additions & 16 deletions Assets/VRM_Samples/SimpleViewer/ViewerUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using UniGLTF;
using UniGLTF.SpringBoneJobs;
using UniHumanoid;
using Unity.Collections;
using UnityEngine;
using UnityEngine.UI;

Expand Down Expand Up @@ -267,6 +268,13 @@ public static bool TryGetFirstLoadable(out string cmd)
}
}

private void Awake()
{
#if DEBUG
NativeLeakDetection.Mode = NativeLeakDetectionMode.EnabledWithStackTrace;
#endif
}

private void Start()
{
m_version.text = string.Format("VRMViewer {0}.{1}",
Expand Down Expand Up @@ -382,23 +390,13 @@ public async Task LoadBytesAsync(string path, byte[] bytes)
}

// 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<FastSpringBoneDisposer>()
.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();
Expand Down

0 comments on commit ee3ce66

Please sign in to comment.