mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-28 22:04:56 -05:00
not Generic
This commit is contained in:
141
Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs
Normal file
141
Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace UniGLTF.AltTask
|
||||
{
|
||||
public interface IAwaiter : INotifyCompletion
|
||||
{
|
||||
bool IsCompleted { get; }
|
||||
void GetResult();
|
||||
}
|
||||
|
||||
public interface IAwaitable
|
||||
{
|
||||
IAwaiter GetAwaiter();
|
||||
}
|
||||
|
||||
public struct AwaitableMethodBuilder
|
||||
{
|
||||
// https://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
|
||||
private AsyncTaskMethodBuilder _methodBuilder;
|
||||
|
||||
public static AwaitableMethodBuilder Create() =>
|
||||
new AwaitableMethodBuilder { _methodBuilder = AsyncTaskMethodBuilder.Create() };
|
||||
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
_methodBuilder.Start(ref stateMachine);
|
||||
}
|
||||
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
_methodBuilder.SetStateMachine(stateMachine);
|
||||
}
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
_methodBuilder.SetException(exception);
|
||||
}
|
||||
public void SetResult()
|
||||
{
|
||||
_methodBuilder.SetResult();
|
||||
}
|
||||
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
|
||||
}
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
|
||||
}
|
||||
|
||||
public Awaitable Task => new Awaitable(_methodBuilder.Task);
|
||||
}
|
||||
|
||||
[AsyncMethodBuilder(typeof(AwaitableMethodBuilder))]
|
||||
public struct Awaitable : IAwaitable
|
||||
{
|
||||
private Task _task;
|
||||
|
||||
public Awaitable(Task task)
|
||||
{
|
||||
_task = task;
|
||||
}
|
||||
|
||||
public bool IsCompleted => _task.IsCompleted;
|
||||
|
||||
public IAwaiter GetAwaiter()
|
||||
{
|
||||
return new Awaiter(this);
|
||||
}
|
||||
|
||||
public void ContinueWith(Action action)
|
||||
{
|
||||
_task.ContinueWith((Task, _) =>
|
||||
{
|
||||
action();
|
||||
}, null);
|
||||
}
|
||||
|
||||
public static Awaitable Delay()
|
||||
{
|
||||
var task = Task.FromResult<object>(default);
|
||||
return new Awaitable(task);
|
||||
}
|
||||
|
||||
public static Awaitable<T> Run<T>(Func<T> action)
|
||||
{
|
||||
return new Awaitable<T>(Task.Run(action));
|
||||
}
|
||||
|
||||
public static Awaitable Run<T>(Action action)
|
||||
{
|
||||
return new Awaitable(Task.Run(action));
|
||||
}
|
||||
|
||||
public static Awaitable<T> FromResult<T>(T result)
|
||||
{
|
||||
return new Awaitable<T>(Task.FromResult(result));
|
||||
}
|
||||
}
|
||||
|
||||
public class Awaiter : IAwaiter
|
||||
{
|
||||
Awaitable m_task;
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_task.IsCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
var context = TaskQueue.Current;
|
||||
this.m_task.ContinueWith(() =>
|
||||
{
|
||||
context.Post(_ => continuation(), null);
|
||||
});
|
||||
}
|
||||
|
||||
public Awaiter(Awaitable task)
|
||||
{
|
||||
m_task = task;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a5d6155408ca734297a104d9e590d1f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
@@ -98,19 +96,6 @@ namespace UniGLTF.AltTask
|
||||
}
|
||||
}
|
||||
|
||||
public static class Awaitable
|
||||
{
|
||||
public static Awaitable<T> Run<T>(Func<T> action)
|
||||
{
|
||||
return new Awaitable<T>(Task.Run(action));
|
||||
}
|
||||
|
||||
public static Awaitable<T> FromResult<T>(T result)
|
||||
{
|
||||
return new Awaitable<T>(Task.FromResult(result));
|
||||
}
|
||||
}
|
||||
|
||||
public class Awaiter<T> : IAwaiter<T>
|
||||
{
|
||||
Awaitable<T> m_task;
|
||||
@@ -142,6 +127,4 @@ namespace UniGLTF.AltTask
|
||||
m_task = task;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Unit { }
|
||||
}
|
||||
@@ -12,7 +12,7 @@ using UnityEditor;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
using Task = Awaitable<Unit>;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// GLTF importer
|
||||
@@ -355,13 +355,8 @@ namespace UniGLTF
|
||||
|
||||
public bool EnableLoadBalancing;
|
||||
|
||||
public virtual async Awaitable<Unit> LoadAsync(Func<Task> nextFrame = null)
|
||||
public virtual async Awaitable LoadAsync()
|
||||
{
|
||||
if (nextFrame == null)
|
||||
{
|
||||
nextFrame = () => Task.Delay();
|
||||
}
|
||||
|
||||
if (Root == null)
|
||||
{
|
||||
Root = new GameObject("_root_");
|
||||
@@ -384,7 +379,7 @@ namespace UniGLTF
|
||||
using (MeasureTime("ReadMesh"))
|
||||
{
|
||||
var x = meshImporter.ReadMesh(this, index);
|
||||
var y = await BuildMeshAsync(nextFrame, x, index);
|
||||
var y = await BuildMeshAsync(x, index);
|
||||
Meshes.Add(y);
|
||||
}
|
||||
}
|
||||
@@ -396,7 +391,7 @@ namespace UniGLTF
|
||||
Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform);
|
||||
}
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("BuildHierarchy"))
|
||||
{
|
||||
@@ -421,38 +416,35 @@ namespace UniGLTF
|
||||
t.SetParent(Root.transform, false);
|
||||
}
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("AnimationImporter"))
|
||||
{
|
||||
AnimationImporter.Import(this);
|
||||
}
|
||||
|
||||
await OnLoadModel(nextFrame);
|
||||
await OnLoadModel();
|
||||
|
||||
if (m_showSpeedLog)
|
||||
{
|
||||
Debug.Log(GetSpeedLog());
|
||||
}
|
||||
|
||||
return new Unit();
|
||||
}
|
||||
|
||||
protected virtual async Task OnLoadModel(Func<Task> nextFrame)
|
||||
protected virtual async Awaitable OnLoadModel()
|
||||
{
|
||||
Root.name = "GLTF";
|
||||
await nextFrame();
|
||||
return new Unit();
|
||||
await Awaitable.Delay();
|
||||
}
|
||||
|
||||
async Awaitable<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MeshImporter.MeshContext x, int i)
|
||||
async Awaitable<MeshWithMaterials> BuildMeshAsync(MeshImporter.MeshContext x, int i)
|
||||
{
|
||||
using (MeasureTime("BuildMesh"))
|
||||
{
|
||||
MeshWithMaterials meshWithMaterials;
|
||||
if (EnableLoadBalancing)
|
||||
{
|
||||
meshWithMaterials = await MeshImporter.BuildMeshAsync(nextFrame, MaterialFactory, x);
|
||||
meshWithMaterials = await MeshImporter.BuildMeshAsync(MaterialFactory, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace UniGLTF
|
||||
return m_materials[index];
|
||||
}
|
||||
|
||||
public async Awaitable<Unit> LoadMaterialsAsync(GetTextureAsyncFunc getTexture)
|
||||
public async Awaitable LoadMaterialsAsync(GetTextureAsyncFunc getTexture)
|
||||
{
|
||||
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
|
||||
{
|
||||
@@ -84,7 +84,6 @@ namespace UniGLTF
|
||||
AddMaterial(material);
|
||||
}
|
||||
}
|
||||
return new Unit();
|
||||
}
|
||||
|
||||
public static Material CreateMaterial(int index, glTFMaterial src, string shaderName)
|
||||
|
||||
@@ -8,7 +8,7 @@ using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
using Task = Awaitable<Unit>;
|
||||
|
||||
|
||||
public class MeshImporter
|
||||
{
|
||||
@@ -654,15 +654,15 @@ namespace UniGLTF
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Awaitable<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MaterialFactory ctx, MeshImporter.MeshContext meshContext)
|
||||
public static async Awaitable<MeshWithMaterials> BuildMeshAsync(MaterialFactory ctx, MeshImporter.MeshContext meshContext)
|
||||
{
|
||||
var (mesh, recalculateTangents) = _BuildMesh(meshContext);
|
||||
|
||||
if (recalculateTangents)
|
||||
{
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
mesh.RecalculateTangents();
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
}
|
||||
|
||||
// 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい
|
||||
@@ -672,7 +672,7 @@ namespace UniGLTF
|
||||
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x)).ToArray()
|
||||
};
|
||||
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
if (meshContext.BlendShapes.Count > 0)
|
||||
{
|
||||
var emptyVertices = new Vector3[mesh.vertexCount];
|
||||
|
||||
@@ -7,7 +7,7 @@ using UnityEngine;
|
||||
|
||||
namespace VRM.Samples
|
||||
{
|
||||
using Task = Awaitable<Unit>;
|
||||
|
||||
|
||||
public class VRMRuntimeLoader : MonoBehaviour
|
||||
{
|
||||
@@ -165,7 +165,7 @@ namespace VRM.Samples
|
||||
}
|
||||
|
||||
|
||||
async Task LoadAsync(VRMImporterContext context)
|
||||
async Awaitable LoadAsync(VRMImporterContext context)
|
||||
{
|
||||
#if true
|
||||
var now = Time.time;
|
||||
@@ -178,7 +178,6 @@ namespace VRM.Samples
|
||||
// ローカルファイルシステムからロードします
|
||||
VRMImporter.LoadVrmAsync(path, OnLoaded);
|
||||
#endif
|
||||
return new Unit();
|
||||
}
|
||||
|
||||
void LoadBVHClicked()
|
||||
|
||||
@@ -10,7 +10,7 @@ using UnityEngine.UI;
|
||||
|
||||
namespace VRM.Samples
|
||||
{
|
||||
using Task = Awaitable<Unit>;
|
||||
|
||||
|
||||
public class ViewerUI : MonoBehaviour
|
||||
{
|
||||
@@ -87,7 +87,7 @@ namespace VRM.Samples
|
||||
m_textDistributionOther.text = "";
|
||||
}
|
||||
|
||||
public async Task UpdateMetaAsync(VRMImporterContext context)
|
||||
public async Awaitable UpdateMetaAsync(VRMImporterContext context)
|
||||
{
|
||||
var meta = await context.ReadMetaAsync(true);
|
||||
|
||||
@@ -107,10 +107,9 @@ namespace VRM.Samples
|
||||
m_textDistributionOther.text = meta.OtherLicenseUrl;
|
||||
|
||||
m_thumbnail.texture = meta.Thumbnail;
|
||||
|
||||
return new Unit();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
TextFields m_texts = default;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ using UniGLTF.AltTask;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
using Task = Awaitable<Unit>;
|
||||
|
||||
|
||||
public class VRMImporterContext : ImporterContext
|
||||
{
|
||||
@@ -53,7 +53,7 @@ namespace VRM
|
||||
}
|
||||
|
||||
#region OnLoad
|
||||
protected override async Task OnLoadModel(Func<Task> nextFrame)
|
||||
protected override async Awaitable OnLoadModel()
|
||||
{
|
||||
Root.name = "VRM";
|
||||
|
||||
@@ -61,43 +61,39 @@ namespace VRM
|
||||
{
|
||||
await LoadMetaAsync();
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("VRM LoadHumanoid"))
|
||||
{
|
||||
LoadHumanoid();
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("VRM LoadBlendShapeMaster"))
|
||||
{
|
||||
LoadBlendShapeMaster();
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("VRM LoadSecondary"))
|
||||
{
|
||||
VRMSpringUtility.LoadSecondary(Root.transform, Nodes,
|
||||
VRM.secondaryAnimation);
|
||||
}
|
||||
await nextFrame();
|
||||
await Awaitable.Delay();
|
||||
|
||||
using (MeasureTime("VRM LoadFirstPerson"))
|
||||
{
|
||||
LoadFirstPerson();
|
||||
}
|
||||
|
||||
return new Unit();
|
||||
}
|
||||
|
||||
async Task LoadMetaAsync()
|
||||
async Awaitable LoadMetaAsync()
|
||||
{
|
||||
var meta = await ReadMetaAsync();
|
||||
var _meta = Root.AddComponent<VRMMeta>();
|
||||
_meta.Meta = meta;
|
||||
Meta = meta;
|
||||
|
||||
return new Unit();
|
||||
}
|
||||
|
||||
void LoadFirstPerson()
|
||||
|
||||
Reference in New Issue
Block a user