TextureItem to MaterialFactory.GetTextureAsync

This commit is contained in:
ousttrue
2021-02-12 20:32:05 +09:00
parent c26ea50e6a
commit 153ec536e6
18 changed files with 257 additions and 422 deletions

View File

@@ -105,14 +105,9 @@ namespace UniGLTF
#endregion
MaterialFactory m_materialFactory = new MaterialFactory();
MaterialFactory m_materialFactory;
public MaterialFactory MaterialFactory => m_materialFactory;
public ImporterContext(MaterialImporter materialImporter)
{
m_materialFactory.MaterialImporter = materialImporter;
}
public ImporterContext()
{
}
@@ -267,12 +262,13 @@ namespace UniGLTF
Json = json;
Storage = storage;
GLTF = GltfDeserializer.Deserialize(json.ParseAsJson());
if (GLTF.asset.version != "2.0")
{
throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version);
}
m_materialFactory = new MaterialFactory(GLTF, Storage);
// Version Compatibility
RestoreOlderVersionValues();
@@ -501,10 +497,9 @@ namespace UniGLTF
Schedulable.Create()
.AddTask(Scheduler.ThreadPool, () =>
{
m_materialFactory.Prepare(GLTF);
// root task. do nothing
})
.ContinueWithCoroutine(Scheduler.MainThread, () => m_materialFactory.TexturesProcessOnMainThread(GLTF, Storage))
.ContinueWithCoroutine(Scheduler.MainThread, () => m_materialFactory.LoadMaterials(GLTF))
.ContinueWithCoroutine(Scheduler.MainThread, () => m_materialFactory.LoadMaterials())
.OnExecute(Scheduler.ThreadPool, parent =>
{
// UniGLTF does not support draco
@@ -695,16 +690,10 @@ namespace UniGLTF
protected virtual IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
HashSet<Texture2D> textures = new HashSet<Texture2D>();
foreach (var x in MaterialFactory.GetTextures().SelectMany(y => y.GetTexturesForSaveAssets()))
foreach (var x in MaterialFactory.ObjectsForSubAsset())
{
if (!textures.Contains(x))
{
textures.Add(x);
}
yield return x;
}
foreach (var x in textures) { yield return x; }
foreach (var x in MaterialFactory.GetMaterials()) { yield return x.GetOrCreate(MaterialFactory.GetTexture); }
foreach (var x in Meshes) { yield return x.Mesh; }
foreach (var x in AnimationClips) { yield return x; }
}
@@ -895,7 +884,8 @@ namespace UniGLTF
AssetDatabase.Refresh();
}
m_materialFactory.CreateTextureItems(GLTF, prefabParentDir);
// texture will load from assets
m_materialFactory.ImageBaseDir = prefabParentDir;
}
#endregion
#endif

View File

@@ -634,10 +634,11 @@ namespace UniGLTF
mesh.RecalculateTangents();
}
// 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい
var result = new MeshWithMaterials
{
Mesh = mesh,
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreate(ctx.GetTexture)).ToArray()
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreateAsync(ctx.GetTextureAsync).Result).ToArray()
};
if (meshContext.BlendShapes.Count > 0)
@@ -662,10 +663,11 @@ namespace UniGLTF
yield return null;
}
// 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい
var result = new MeshWithMaterials
{
Mesh = mesh,
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreate(ctx.GetTexture)).ToArray()
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreateAsync(ctx.GetTextureAsync).Result).ToArray()
};
yield return null;

View File

@@ -1,10 +1,6 @@
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System;
using DepthFirstScheduler;
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -12,135 +8,8 @@ using UnityEditor;
namespace UniGLTF
{
public class TextureItem
public static class TextureItem
{
private int m_textureIndex;
public Texture2D Texture
{
get
{
return m_textureLoader.Texture;
}
}
#region Texture converter
private Dictionary<string, Texture2D> m_converts = new Dictionary<string, Texture2D>();
public Dictionary<string, Texture2D> Converts
{
get { return m_converts; }
}
/// <summary>
///
/// </summary>
/// <param name="prop"></param>
/// <param name="smoothness">used only when converting MetallicRoughness maps</param>
/// <returns></returns>
public Texture2D ConvertTexture(string prop, float smoothnessOrRoughness = 1.0f)
{
var convertedTexture = Converts.FirstOrDefault(x => x.Key == prop);
if (convertedTexture.Value != null)
return convertedTexture.Value;
if (prop == "_BumpMap")
{
if (Application.isPlaying)
{
var converted = new NormalConverter().GetImportTexture(Texture);
m_converts.Add(prop, converted);
return converted;
}
else
{
#if UNITY_EDITOR
var textureAssetPath = AssetDatabase.GetAssetPath(Texture);
if (!string.IsNullOrEmpty(textureAssetPath))
{
TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
}
else
{
Debug.LogWarningFormat("no asset for {0}", Texture);
}
#endif
return Texture;
}
}
if (prop == "_MetallicGlossMap")
{
var converted = new MetallicRoughnessConverter(smoothnessOrRoughness).GetImportTexture(Texture);
m_converts.Add(prop, converted);
return converted;
}
if (prop == "_OcclusionMap")
{
var converted = new OcclusionConverter().GetImportTexture(Texture);
m_converts.Add(prop, converted);
return converted;
}
return null;
}
#endregion
public bool IsAsset
{
set;
get;
}
public IEnumerable<Texture2D> GetTexturesForSaveAssets()
{
if (!IsAsset)
{
yield return Texture;
}
if (m_converts.Any())
{
foreach (var texture in m_converts)
{
yield return texture.Value;
}
}
}
/// <summary>
/// Texture from buffer
/// </summary>
/// <param name="index"></param>
public TextureItem(int index, ITextureLoader textureLoader)
{
m_textureIndex = index;
m_textureLoader = textureLoader;
if (m_textureLoader == null)
{
throw new Exception("ITextureLoader is null.");
}
}
#region Process
ITextureLoader m_textureLoader;
// public void Process(glTF gltf, IStorage storage)
// {
// ProcessOnMainThreadCoroutine(gltf, storage).CoroutineToEnd();
// }
public IEnumerator ProcessOnMainThreadCoroutine(glTF gltf, IStorage storage)
{
using (m_textureLoader)
{
var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex);
var colorSpace = TextureIO.GetColorSpace(textureType);
var isLinear = colorSpace == RenderTextureReadWrite.Linear;
yield return m_textureLoader.ProcessOnMainThread(gltf, storage, isLinear, gltf.GetSamplerFromTextureIndex(m_textureIndex));
}
}
#endregion
struct ColorSpaceScope : IDisposable
{
bool m_sRGBWrite;

View File

@@ -1,19 +1,80 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
public delegate TextureItem GetTextureItemFunc(int i);
public struct GetTextureParam
{
public const string NORMAL_PROP = "_BumpMap";
public const string METALLIC_GLOSS_PROP = "_MetallicGlossMap";
public const string OCCLUSION_PROP = "_OcclusionMap";
public readonly string TextureType;
public readonly float MetallicFactor;
public readonly ushort? Index0;
public readonly ushort? Index1;
public readonly ushort? Index2;
public readonly ushort? Index3;
public readonly ushort? Index4;
public readonly ushort? Index5;
public GetTextureParam(string textureType, float metallicFactor, int i0, int i1, int i2, int i3, int i4, int i5)
{
TextureType = textureType;
MetallicFactor = metallicFactor;
Index0 = (ushort)i0;
Index1 = (ushort)i1;
Index2 = (ushort)i2;
Index3 = (ushort)i3;
Index4 = (ushort)i4;
Index5 = (ushort)i5;
}
public static GetTextureParam Create(int index)
{
return new GetTextureParam(default, default, index, default, default, default, default, default);
}
public static GetTextureParam CreateNormal(int index)
{
return new GetTextureParam(NORMAL_PROP, default, index, default, default, default, default, default);
}
public static GetTextureParam CreateMetallic(int index, float metallicFactor)
{
return new GetTextureParam(METALLIC_GLOSS_PROP, metallicFactor, index, default, default, default, default, default);
}
public static GetTextureParam CreateOcclusion(int index)
{
return new GetTextureParam(OCCLUSION_PROP, default, index, default, default, default, default, default);
}
}
public delegate Task<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
public delegate Shader GetShaderFunc();
public delegate MaterialItemBase MaterialImporter(int i, glTFMaterial x, bool hasVertexColor);
public class MaterialFactory : IDisposable
{
glTF m_gltf;
IStorage m_storage;
public MaterialFactory(glTF gltf, IStorage storage)
{
m_gltf = gltf;
m_storage = storage;
}
public UnityPath ImageBaseDir { get; set; }
MaterialImporter m_materialImporter;
public MaterialImporter MaterialImporter
{
@@ -31,22 +92,74 @@ namespace UniGLTF
}
}
List<TextureItem> m_textures = new List<TextureItem>();
public IList<TextureItem> GetTextures()
List<Texture2D> m_textuers = new List<Texture2D>();
Dictionary<GetTextureParam, Texture2D> m_textureCache = new Dictionary<GetTextureParam, Texture2D>();
/// <summary>
/// テクスチャーをロード、必要であれば変換して返す。
/// 同じものはキャッシュを返す
/// </summary>
/// <param name="texture_type">変換の有無を判断する: METALLIC_GLOSS_PROP</param>
/// <param name="roughnessFactor">METALLIC_GLOSS_PROPの追加パラメーター</param>
/// <param name="indices">gltf の texture index</param>
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(GetTextureParam param)
{
return m_textures;
}
public TextureItem GetTexture(int i)
{
if (i < 0 || i >= m_textures.Count)
if (m_textureCache.TryGetValue(param, out Texture2D texture))
{
return null;
return texture;
}
return m_textures[i];
}
public void AddTexture(TextureItem item)
{
m_textures.Add(item);
texture = await LoadTextureAsync(param.Index0.Value);
m_textureCache.Add(GetTextureParam.Create(param.Index0.Value), texture);
switch (param.TextureType)
{
case GetTextureParam.NORMAL_PROP:
{
if (Application.isPlaying)
{
var converted = new NormalConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
else
{
#if UNITY_EDITOR
var textureAssetPath = AssetDatabase.GetAssetPath(texture);
if (!string.IsNullOrEmpty(textureAssetPath))
{
TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
}
else
{
Debug.LogWarningFormat("no asset for {0}", texture);
}
#endif
m_textureCache.Add(param, texture);
return texture;
}
}
case GetTextureParam.METALLIC_GLOSS_PROP:
{
// Bake roughnessFactor values into a texture.
var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
case GetTextureParam.OCCLUSION_PROP:
{
var converted = new OcclusionConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
default:
return texture;
}
throw new NotImplementedException();
}
List<MaterialItemBase> m_materials = new List<MaterialItemBase>();
@@ -71,95 +184,28 @@ namespace UniGLTF
return m_materials[index];
}
public virtual ITextureLoader CreateTextureLoader(int index)
public virtual Task<Texture2D> LoadTextureAsync(int index)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return new UnityWebRequestTextureLoader(index);
return UnityWebRequestTextureLoader.LoadTextureAsync(index);
#else
return new GltfTextureLoader(index);
return GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index);
#endif
}
public void Prepare(UniGLTF.glTF gltf, UnityPath imageBaseDir = default(UnityPath))
{
if (m_textures.Count == 0)
{
//
// runtime
//
CreateTextureItems(gltf, imageBaseDir);
}
else
{
//
// already CreateTextures(by assetPostProcessor or editor menu)
//
}
}
public void CreateTextureItems(UniGLTF.glTF gltf, UnityPath imageBaseDir)
{
if (m_textures.Any())
{
return;
}
for (int i = 0; i < gltf.textures.Count; ++i)
{
TextureItem item = null;
#if UNITY_EDITOR
var image = gltf.GetImageFromTextureIndex(i);
if (imageBaseDir.IsUnderAssetsFolder
&& !string.IsNullOrEmpty(image.uri)
&& !image.uri.FastStartsWith("data:")
)
{
///
/// required SaveTexturesAsPng or SetTextureBaseDir
///
var assetPath = imageBaseDir.Child(image.uri);
var textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri);
item = new TextureItem(i, new AssetTextureLoader(assetPath, textureName))
{
IsAsset = true
};
}
else
#endif
{
item = new TextureItem(i, CreateTextureLoader(i));
}
AddTexture(item);
}
}
public IEnumerator TexturesProcessOnMainThread(glTF gltf, IStorage storage)
{
// using (MeasureTime("TexturesProcessOnMainThread"))
{
foreach (var x in GetTextures())
{
yield return x.ProcessOnMainThreadCoroutine(gltf, storage);
}
}
}
public IEnumerator LoadMaterials(glTF gltf)
public IEnumerator LoadMaterials()
{
// using (MeasureTime("LoadMaterials"))
{
if (gltf.materials == null || !gltf.materials.Any())
if (m_gltf.materials == null || !m_gltf.materials.Any())
{
AddMaterial(MaterialImporter(0, null, false));
}
else
{
for (int i = 0; i < gltf.materials.Count; ++i)
for (int i = 0; i < m_gltf.materials.Count; ++i)
{
AddMaterial(MaterialImporter(i, gltf.materials[i], gltf.MaterialHasVertexColor(i)));
AddMaterial(MaterialImporter(i, m_gltf.materials[i], m_gltf.MaterialHasVertexColor(i)));
}
}
}
@@ -184,7 +230,22 @@ namespace UniGLTF
public void Dispose()
{
throw new NotImplementedException();
foreach (var x in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(x, true);
}
}
public IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var kv in m_textureCache)
{
yield return kv.Value;
}
foreach (var x in m_materials)
{
yield return x.GetOrCreateAsync(GetTextureAsync).Result;
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using UnityEngine;
@@ -17,7 +18,12 @@ namespace UniGLTF
Name = src != null ? m_src.name : "";
}
public abstract Material GetOrCreate(GetTextureItemFunc getTexture);
public abstract Task<Material> GetOrCreateAsync(GetTextureAsyncFunc getTexture);
public Material GetOrCreateForTest()
{
return GetOrCreateAsync(null).Result;
}
protected Material CreateMaterial(string shaderName)
{

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
@@ -45,11 +46,11 @@ namespace UniGLTF
{
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
public override async Task<Material> GetOrCreateAsync(GetTextureAsyncFunc getTexture)
{
if (getTexture == null)
{
getTexture = _ => null;
getTexture = _ => Task.FromResult<Texture2D>(null);
}
var material = CreateMaterial(ShaderName);
@@ -67,11 +68,7 @@ namespace UniGLTF
if (m_src.pbrMetallicRoughness.baseColorTexture != null && m_src.pbrMetallicRoughness.baseColorTexture.index != -1)
{
var texture = getTexture(m_src.pbrMetallicRoughness.baseColorTexture.index);
if (texture != null)
{
material.mainTexture = texture.Texture;
}
material.mainTexture = await getTexture(GetTextureParam.Create(m_src.pbrMetallicRoughness.baseColorTexture.index));
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
@@ -80,12 +77,13 @@ namespace UniGLTF
if (m_src.pbrMetallicRoughness.metallicRoughnessTexture != null && m_src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
{
material.EnableKeyword("_METALLICGLOSSMAP");
var texture = getTexture(m_src.pbrMetallicRoughness.metallicRoughnessTexture.index);
var texture = await getTexture(GetTextureParam.CreateMetallic(
m_src.pbrMetallicRoughness.metallicRoughnessTexture.index,
m_src.pbrMetallicRoughness.metallicFactor));
if (texture != null)
{
var prop = "_MetallicGlossMap";
// Bake roughnessFactor values into a texture.
material.SetTexture(prop, texture.ConvertTexture(prop, m_src.pbrMetallicRoughness.roughnessFactor));
material.SetTexture(GetTextureParam.METALLIC_GLOSS_PROP, texture);
}
material.SetFloat("_Metallic", 1.0f);
@@ -105,11 +103,10 @@ namespace UniGLTF
if (m_src.normalTexture != null && m_src.normalTexture.index != -1)
{
material.EnableKeyword("_NORMALMAP");
var texture = getTexture(m_src.normalTexture.index);
var texture = await getTexture(GetTextureParam.CreateNormal(m_src.normalTexture.index));
if (texture != null)
{
var prop = "_BumpMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
material.SetTexture(GetTextureParam.NORMAL_PROP, texture);
material.SetFloat("_BumpScale", m_src.normalTexture.scale);
}
@@ -119,11 +116,10 @@ namespace UniGLTF
if (m_src.occlusionTexture != null && m_src.occlusionTexture.index != -1)
{
var texture = getTexture(m_src.occlusionTexture.index);
var texture = await getTexture(GetTextureParam.CreateOcclusion(m_src.occlusionTexture.index));
if (texture != null)
{
var prop = "_OcclusionMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture);
material.SetFloat("_OcclusionStrength", m_src.occlusionTexture.strength);
}
@@ -144,10 +140,10 @@ namespace UniGLTF
if (m_src.emissiveTexture != null && m_src.emissiveTexture.index != -1)
{
var texture = getTexture(m_src.emissiveTexture.index);
var texture = await getTexture(GetTextureParam.Create(m_src.emissiveTexture.index));
if (texture != null)
{
material.SetTexture("_EmissionMap", texture.Texture);
material.SetTexture("_EmissionMap", texture);
}
// Texture Offset and Scale

View File

@@ -1,29 +1,14 @@
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
#if UNITY_EDITOR
public class AssetTextureLoader : ITextureLoader
public static class AssetTextureLoader
{
public Texture2D Texture
{
private set;
get;
}
UnityPath m_assetPath;
public AssetTextureLoader(UnityPath assetPath, string _)
{
m_assetPath = assetPath;
}
public void Dispose()
{
}
public IEnumerator ProcessOnMainThread(glTF gltf, IStorage storage, bool isLinear, glTFTextureSampler sampler)
public static Task<Texture2D> LoadTaskAsync(UnityPath m_assetPath,
bool isLinear, glTFTextureSampler sampler)
{
//
// texture from assets
@@ -39,9 +24,8 @@ namespace UniGLTF
importer.SaveAndReimport();
Texture = m_assetPath.LoadAsset<Texture2D>();
var Texture = m_assetPath.LoadAsset<Texture2D>();
//Texture.name = m_textureName;
if (Texture == null)
{
Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath);
@@ -66,7 +50,7 @@ namespace UniGLTF
TextureSamplerUtil.SetSampler(Texture, sampler);
}
yield break;
return Task.FromResult(Texture);
}
}
#endif

View File

@@ -1,28 +1,11 @@
using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
public class GltfTextureLoader : ITextureLoader
public static class GltfTextureLoader
{
int m_textureIndex;
public GltfTextureLoader(int textureIndex)
{
m_textureIndex = textureIndex;
}
public Texture2D Texture
{
private set;
get;
}
public void Dispose()
{
}
static Byte[] ToArray(ArraySegment<byte> bytes)
{
if (bytes.Array == null)
@@ -41,36 +24,35 @@ namespace UniGLTF
}
}
string m_textureName;
public IEnumerator ProcessOnMainThread(glTF gltf, IStorage storage, bool isLinear, glTFTextureSampler sampler)
public static async Task<Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int index)
{
Byte[] imageBytes = default;
var task = Task.Run(() =>
string m_textureName = default;
var imageBytes = await Task.Run(() =>
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex);
var imageIndex = gltf.GetImageIndexFromTextureIndex(index);
var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
var m_imageBytes = ToArray(segments);
return ToArray(segments);
});
while (!task.IsCompleted)
{
yield break;
}
//
// texture from image(png etc) bytes
//
Texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear);
Texture.name = m_textureName;
var textureType = TextureIO.GetglTFTextureType(gltf, index);
var colorSpace = TextureIO.GetColorSpace(textureType);
var isLinear = colorSpace == RenderTextureReadWrite.Linear;
var sampler = gltf.GetSamplerFromTextureIndex(index);
var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear);
texture.name = m_textureName;
if (imageBytes != null)
{
Texture.LoadImage(imageBytes);
texture.LoadImage(imageBytes);
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
TextureSamplerUtil.SetSampler(texture, sampler);
}
yield break;
return texture;
}
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
public interface ITextureLoader : IDisposable
{
Texture2D Texture { get; }
/// <summary>
/// Call from unity main thread
/// </summary>
/// <param name="isLinear"></param>
/// <param name="sampler"></param>
/// <returns></returns>
IEnumerator ProcessOnMainThread(glTF gltf, IStorage storage, bool isLinear, glTFTextureSampler sampler);
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 4ffd8b31d371e024593b9aff2cf2495b
timeCreated: 1540300073
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -7,7 +7,7 @@ using UnityEngine.Networking;
namespace UniGLTF
{
public class UnityWebRequestTextureLoader : ITextureLoader
public class UnityWebRequestTextureLoader
{
public Texture2D Texture
{

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
@@ -13,11 +14,11 @@ namespace UniGLTF
m_hasVertexColor = hasVertexColor;
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
public override async Task<Material> GetOrCreateAsync(GetTextureAsyncFunc getTexture)
{
if (getTexture == null)
{
getTexture = _ => null;
getTexture = _ => Task.FromResult<Texture2D>(null);
}
var material = CreateMaterial(ShaderName);
@@ -25,11 +26,7 @@ namespace UniGLTF
// texture
if (m_src.pbrMetallicRoughness.baseColorTexture != null)
{
var texture = getTexture(m_src.pbrMetallicRoughness.baseColorTexture.index);
if (texture != null)
{
material.mainTexture = texture.Texture;
}
material.mainTexture = await getTexture(GetTextureParam.Create(m_src.pbrMetallicRoughness.baseColorTexture.index));
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex");

View File

@@ -32,7 +32,7 @@ namespace UniGLTF
var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureManager);
gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions = gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions.Deserialize();
var dstMaterial = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var dstMaterial = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual(dstMaterial.mainTextureOffset.x, offset.x, 0.3f);
Assert.AreEqual(dstMaterial.mainTextureOffset.y, offset.y, 0.2f);
@@ -80,7 +80,7 @@ namespace UniGLTF
Assert.IsTrue(glTF_KHR_materials_unlit.IsEnable(gltfMaterial));
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
}
@@ -99,7 +99,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -114,7 +114,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -130,7 +130,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -145,7 +145,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -160,7 +160,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -176,7 +176,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -191,7 +191,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -207,7 +207,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@@ -217,7 +217,7 @@ namespace UniGLTF
{
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreateForTest();
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
}
@@ -225,7 +225,7 @@ namespace UniGLTF
[Test]
public void MaterialImportTest()
{
var material = MaterialFactory.CreateMaterial(0, new glTFMaterial { }, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterial(0, new glTFMaterial { }, false).GetOrCreateForTest();
Assert.AreEqual("Standard", material.shader.name);
}

View File

@@ -29,7 +29,7 @@ namespace VRM.Samples
#region Load
void OnLoadClicked()
async void OnLoadClicked()
{
#if UNITY_STANDALONE_WIN
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
@@ -53,7 +53,7 @@ namespace VRM.Samples
// metaを取得(todo: thumbnailテクスチャのロード)
var meta = context.ReadMeta();
var meta = await context.ReadMetaAsync();
Debug.LogFormat("meta: title:{0}", meta.Title);
// ParseしたJSONをシーンオブジェクトに変換していく

View File

@@ -70,7 +70,7 @@ namespace VRM.Samples
m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked);
}
void LoadVRMClicked()
async void LoadVRMClicked()
{
#if UNITY_STANDALONE_WIN
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
@@ -94,7 +94,7 @@ namespace VRM.Samples
// metaを取得(todo: thumbnailテクスチャのロード)
var meta = context.ReadMeta();
var meta = await context.ReadMetaAsync();
Debug.LogFormat("meta: title:{0}", meta.Title);

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UniHumanoid;
using UnityEngine;
using UnityEngine.UI;
@@ -83,9 +84,9 @@ namespace VRM.Samples
m_textDistributionOther.text = "";
}
public void UpdateMeta(VRMImporterContext context)
public async Task UpdateMetaAsync(VRMImporterContext context)
{
var meta = context.ReadMeta(true);
var meta = await context.ReadMetaAsync(true);
m_textModelTitle.text = meta.Title;
m_textModelVersion.text = meta.Version;
@@ -211,7 +212,7 @@ namespace VRM.Samples
string[] cmds = System.Environment.GetCommandLineArgs();
if (cmds.Length > 1)
{
LoadModel(cmds[1]);
LoadModelAsync(cmds[1]);
}
m_texts.Start();
@@ -282,7 +283,7 @@ namespace VRM.Samples
case ".glb":
case ".vrm":
case ".zip":
LoadModel(path);
LoadModelAsync(path);
break;
case ".bvh":
@@ -291,7 +292,7 @@ namespace VRM.Samples
}
}
void LoadModel(string path)
async void LoadModelAsync(string path)
{
if (!File.Exists(path))
{
@@ -307,7 +308,7 @@ namespace VRM.Samples
var context = new VRMImporterContext();
var file = File.ReadAllBytes(path);
context.ParseGlb(file);
m_texts.UpdateMeta(context);
await m_texts.UpdateMetaAsync(context);
context.Load();
context.ShowMeshes();
context.EnableUpdateWhenOffscreen();

View File

@@ -6,7 +6,7 @@ using UnityEngine;
using System.IO;
using System.Collections;
using UniJSON;
using DepthFirstScheduler;
using System.Threading.Tasks;
namespace VRM
{
@@ -58,7 +58,11 @@ namespace VRM
using (MeasureTime("VRM LoadMeta"))
{
LoadMeta();
var task = LoadMetaAsync();
while (!task.IsCompleted)
{
yield return null;
}
}
yield return null;
@@ -87,9 +91,9 @@ namespace VRM
}
}
void LoadMeta()
async Task LoadMetaAsync()
{
var meta = ReadMeta();
var meta = await ReadMetaAsync();
var _meta = Root.AddComponent<VRMMeta>();
_meta.Meta = meta;
Meta = meta;
@@ -194,7 +198,9 @@ namespace VRM
}
}
var material = MaterialFactory.GetMaterials().FirstOrDefault(y => y.Name == x.materialName).GetOrCreate(MaterialFactory.GetTexture);
var material = MaterialFactory.GetMaterials()
.FirstOrDefault(y => y.Name == x.materialName)
.GetOrCreateAsync(MaterialFactory.GetTextureAsync).Result;
var propertyName = x.propertyName;
if (x.propertyName.FastEndsWith("_ST_S")
|| x.propertyName.FastEndsWith("_ST_T"))
@@ -293,7 +299,7 @@ namespace VRM
public BlendShapeAvatar BlendShapeAvatar;
public VRMMetaObject Meta;
public VRMMetaObject ReadMeta(bool createThumbnail = false)
public async Task<VRMMetaObject> ReadMetaAsync(bool createThumbnail = false)
{
var meta = ScriptableObject.CreateInstance<VRMMetaObject>();
meta.name = "Meta";
@@ -305,24 +311,7 @@ namespace VRM
meta.ContactInformation = gltfMeta.contactInformation;
meta.Reference = gltfMeta.reference;
meta.Title = gltfMeta.title;
var thumbnail = MaterialFactory.GetTexture(gltfMeta.texture);
if (thumbnail != null)
{
// ロード済み
meta.Thumbnail = thumbnail.Texture;
}
else if (createThumbnail)
{
// 作成する(先行ロード用)
if (gltfMeta.texture >= 0 && gltfMeta.texture < GLTF.textures.Count)
{
var t = new TextureItem(gltfMeta.texture, MaterialFactory.CreateTextureLoader(gltfMeta.texture));
t.ProcessOnMainThreadCoroutine(GLTF, Storage).CoroutineToEnd();
meta.Thumbnail = t.Texture;
}
}
meta.Thumbnail = await MaterialFactory.GetTextureAsync(GetTextureParam.Create(gltfMeta.texture));
meta.AllowedUser = gltfMeta.allowedUser;
meta.ViolentUssage = gltfMeta.violentUssage;
meta.SexualUssage = gltfMeta.sexualUssage;

View File

@@ -3,6 +3,7 @@ using UniGLTF;
using UnityEngine;
using System.Linq;
using System;
using System.Threading.Tasks;
namespace VRM
{
@@ -29,7 +30,7 @@ namespace VRM
m_vrmMaterial = vrmMaterial;
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
public override async Task<Material> GetOrCreateAsync(GetTextureAsyncFunc getTexture)
{
var item = m_vrmMaterial;
var shaderName = item.shader;
@@ -47,7 +48,7 @@ namespace VRM
{
Debug.LogWarningFormat("unknown shader {0}.", shaderName);
}
return MaterialFactory.CreateMaterial(m_index, m_src, m_hasVertexColor).GetOrCreate(getTexture);
return await MaterialFactory.CreateMaterial(m_index, m_src, m_hasVertexColor).GetOrCreateAsync(getTexture);
}
//
@@ -78,18 +79,10 @@ namespace VRM
}
foreach (var kv in item.textureProperties)
{
var texture = getTexture(kv.Value);
var texture = await getTexture(new GetTextureParam(kv.Key, default, kv.Value, default, default, default, default, default));
if (texture != null)
{
var converted = texture.ConvertTexture(kv.Key);
if (converted != null)
{
material.SetTexture(kv.Key, converted);
}
else
{
material.SetTexture(kv.Key, texture.Texture);
}
material.SetTexture(kv.Key, texture);
}
}
foreach (var kv in item.keywordMap)