Merge pull request #744 from ousttrue/feature/refactor_textureitem

Feature/refactor textureitem
This commit is contained in:
ousttrue 2021-02-15 17:13:30 +09:00 committed by GitHub
commit df8e554be9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 988 additions and 1105 deletions

View File

@ -3,8 +3,7 @@ using System.Collections;
using System.Collections.Generic;
namespace
DepthFirstScheduler
namespace DepthFirstScheduler
{
public static class IEnumeratorExtensions
{

View File

@ -0,0 +1,58 @@
using System;
using System.Collections;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace UniGLTF
{
/// <summary>
/// work around
///
/// https://forum.unity.com/threads/async-await-in-editor-script.481276/
///
/// https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Scripting/UnitySynchronizationContext.cs
///
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public static class TaskExtensions
{
delegate void ExecFunc();
static ExecFunc s_exec;
static void Invoke()
{
if (s_exec == null)
{
var context = SynchronizationContext.Current;
var t = context.GetType();
var execMethod = t.GetMethod("Exec", BindingFlags.NonPublic | BindingFlags.Instance);
var exec = execMethod.CreateDelegate(typeof(ExecFunc), context);
s_exec = (ExecFunc)exec;
}
s_exec();
}
public static IEnumerable AsIEnumerator(this Task task)
{
while (!task.IsCompleted)
{
yield return null;
#if UNITY_EDITOR
if (!UnityEngine.Application.isPlaying)
{
Invoke();
}
#endif
}
if (task.IsFaulted)
{
throw task.Exception;
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f49a88d3a0e6eb24e91af983452f59f6
guid: 54481e2d4da20ec4fa15376518f2e938
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -105,13 +105,11 @@ namespace UniGLTF
#endregion
MaterialFactory m_materialFactory = new MaterialFactory();
MaterialFactory m_materialFactory;
public MaterialFactory MaterialFactory => m_materialFactory;
public ImporterContext(MaterialImporter materialImporter)
{
m_materialFactory.MaterialImporter = materialImporter;
}
TextureFactory m_textureFactory;
public TextureFactory TextureFactory => m_textureFactory;
public ImporterContext()
{
@ -267,12 +265,14 @@ 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_textureFactory = new TextureFactory(GLTF, Storage);
m_materialFactory = new MaterialFactory(GLTF, Storage);
// Version Compatibility
RestoreOlderVersionValues();
@ -501,11 +501,15 @@ namespace UniGLTF
Schedulable.Create()
.AddTask(Scheduler.ThreadPool, () =>
{
m_materialFactory.Prepare(GLTF);
// root task. do nothing
})
.ContinueWithCoroutine(Scheduler.MainThread, () =>
{
using (MeasureTime("LoadMaterials"))
{
return m_materialFactory.LoadMaterials(m_textureFactory.GetTextureAsync);
}
})
.ContinueWithCoroutine(Scheduler.ThreadPool, () => m_materialFactory.TexturesProcessOnAnyThread(GLTF, Storage))
.ContinueWithCoroutine(Scheduler.MainThread, () => m_materialFactory.TexturesProcessOnMainThread(GLTF))
.ContinueWithCoroutine(Scheduler.MainThread, () => m_materialFactory.LoadMaterials(GLTF))
.OnExecute(Scheduler.ThreadPool, parent =>
{
// UniGLTF does not support draco
@ -696,16 +700,14 @@ 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 TextureFactory.ObjectsForSubAsset())
{
if (!textures.Contains(x))
{
textures.Add(x);
}
yield return x;
}
foreach (var x in MaterialFactory.ObjectsForSubAsset())
{
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; }
}
@ -896,7 +898,8 @@ namespace UniGLTF
AssetDatabase.Refresh();
}
m_materialFactory.CreateTextureItems(GLTF, prefabParentDir);
// texture will load from assets
m_textureFactory.ImageBaseDir = prefabParentDir;
}
#endregion
#endif
@ -939,10 +942,16 @@ namespace UniGLTF
if (Root != null) GameObject.Destroy(Root);
// Remove resources. materials, textures meshes etc...
foreach (var o in ObjectsForSubAsset())
foreach (var x in Meshes)
{
UnityEngine.Object.DestroyImmediate(o, true);
UnityEngine.Object.DestroyImmediate(x.Mesh, true);
}
foreach (var x in AnimationClips)
{
UnityEngine.Object.DestroyImmediate(x, true);
}
MaterialFactory.Dispose();
TextureFactory.Dispose();
}
#if UNITY_EDITOR

View File

@ -0,0 +1,175 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
public class MaterialFactory : IDisposable
{
glTF m_gltf;
IStorage m_storage;
public MaterialFactory(glTF gltf, IStorage storage)
{
m_gltf = gltf;
m_storage = storage;
}
public delegate Task<Material> CreateMaterialAsyncFunc(glTF glTF, int i, GetTextureAsyncFunc getTexture);
CreateMaterialAsyncFunc m_createMaterialAsync;
public CreateMaterialAsyncFunc CreateMaterialAsync
{
set
{
m_createMaterialAsync = value;
}
get
{
if (m_createMaterialAsync == null)
{
m_createMaterialAsync = MaterialFactory.DefaultCreateMaterialAsync;
}
return m_createMaterialAsync;
}
}
List<Material> m_materials = new List<Material>();
public IReadOnlyList<Material> Materials => m_materials;
public void Dispose()
{
foreach (var x in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(x, true);
}
}
public IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var x in m_materials)
{
yield return x;
}
}
public void AddMaterial(Material material)
{
var originalName = material.name;
int j = 2;
while (m_materials.Any(x => x.name == material.name))
{
material.name = string.Format("{0}({1})", originalName, j++);
}
m_materials.Add(material);
}
public Material GetMaterial(int index)
{
if (index < 0) return null;
if (index >= m_materials.Count) return null;
return m_materials[index];
}
public IEnumerator LoadMaterials(GetTextureAsyncFunc getTexture)
{
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
{
var task = CreateMaterialAsync(m_gltf, 0, getTexture);
foreach (var x in task.AsIEnumerator())
{
yield return x;
}
AddMaterial(task.Result);
}
else
{
for (int i = 0; i < m_gltf.materials.Count; ++i)
{
var task = CreateMaterialAsync(m_gltf, i, getTexture);
foreach (var x in task.AsIEnumerator())
{
yield return null;
}
AddMaterial(task.Result);
}
}
yield return null;
}
public static Material CreateMaterial(int index, glTFMaterial src, string shaderName)
{
var material = new Material(Shader.Find(shaderName));
#if UNITY_EDITOR
// textureImporter.SaveAndReimport(); may destroy this material
material.hideFlags = HideFlags.DontUnloadUnusedAsset;
#endif
material.name = (src == null || string.IsNullOrEmpty(src.name))
? string.Format("material_{0:00}", index)
: src.name
;
return material;
}
public static void SetTextureOffsetAndScale(Material material, glTFTextureInfo textureInfo, string propertyName)
{
if (glTF_KHR_texture_transform.TryGet(textureInfo, out glTF_KHR_texture_transform textureTransform))
{
Vector2 offset = new Vector2(0, 0);
Vector2 scale = new Vector2(1, 1);
if (textureTransform.offset != null && textureTransform.offset.Length == 2)
{
offset = new Vector2(textureTransform.offset[0], textureTransform.offset[1]);
}
if (textureTransform.scale != null && textureTransform.scale.Length == 2)
{
scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]);
}
offset.y = (offset.y + scale.y - 1.0f) * -1.0f;
material.SetTextureOffset(propertyName, offset);
material.SetTextureScale(propertyName, scale);
}
}
public static Task<Material> DefaultCreateMaterialAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i < 0 || i >= gltf.materials.Count)
{
UnityEngine.Debug.LogWarning("glTFMaterial is empty");
return PBRMaterialItem.CreateAsync(i, null, getTexture);
}
var x = gltf.materials[i];
if (glTF_KHR_materials_unlit.IsEnable(x))
{
var hasVertexColor = gltf.MaterialHasVertexColor(i);
return UnlitMaterialItem.CreateAsync(i, x, getTexture, hasVertexColor);
}
return PBRMaterialItem.CreateAsync(i, x, getTexture);
}
/// <summary>
/// for unittest
/// </summary>
/// <param name="i"></param>
/// <param name="material"></param>
/// <param name="getTexture"></param>
/// <returns></returns>
public static Material CreateMaterialForTest(int i, glTFMaterial material)
{
var gltf = new glTF
{
materials = new System.Collections.Generic.List<glTFMaterial> { material },
};
var task = DefaultCreateMaterialAsync(gltf, i, null);
return task.Result;
}
}
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
@ -29,7 +30,7 @@ namespace UniGLTF
/// _SrcBlend
/// _DstBlend
/// _ZWrite
public class PBRMaterialItem : MaterialItemBase
public static class PBRMaterialItem
{
public const string ShaderName = "Standard";
@ -41,51 +42,44 @@ namespace UniGLTF
Transparent
}
public PBRMaterialItem(int i, glTFMaterial src) : base(i, src)
{
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
public static async Task<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture)
{
if (getTexture == null)
{
getTexture = _ => null;
getTexture = _ => Task.FromResult<Texture2D>(null);
}
var material = CreateMaterial(ShaderName);
var material = MaterialFactory.CreateMaterial(i, src, ShaderName);
// PBR material
if (m_src != null)
if (src != null)
{
if (m_src.pbrMetallicRoughness != null)
if (src.pbrMetallicRoughness != null)
{
if (m_src.pbrMetallicRoughness.baseColorFactor != null && m_src.pbrMetallicRoughness.baseColorFactor.Length == 4)
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
var color = m_src.pbrMetallicRoughness.baseColorFactor;
var color = src.pbrMetallicRoughness.baseColorFactor;
material.color = (new Color(color[0], color[1], color[2], color[3])).gamma;
}
if (m_src.pbrMetallicRoughness.baseColorTexture != null && m_src.pbrMetallicRoughness.baseColorTexture.index != -1)
if (src.pbrMetallicRoughness.baseColorTexture != null && 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(src.pbrMetallicRoughness.baseColorTexture.index));
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
}
if (m_src.pbrMetallicRoughness.metallicRoughnessTexture != null && m_src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
{
material.EnableKeyword("_METALLICGLOSSMAP");
var texture = getTexture(m_src.pbrMetallicRoughness.metallicRoughnessTexture.index);
var texture = await getTexture(GetTextureParam.CreateMetallic(
src.pbrMetallicRoughness.metallicRoughnessTexture.index,
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);
@ -93,71 +87,69 @@ namespace UniGLTF
material.SetFloat("_GlossMapScale", 1.0f);
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap");
MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap");
}
else
{
material.SetFloat("_Metallic", m_src.pbrMetallicRoughness.metallicFactor);
material.SetFloat("_Glossiness", 1.0f - m_src.pbrMetallicRoughness.roughnessFactor);
material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor);
material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
}
}
if (m_src.normalTexture != null && m_src.normalTexture.index != -1)
if (src.normalTexture != null && src.normalTexture.index != -1)
{
material.EnableKeyword("_NORMALMAP");
var texture = getTexture(m_src.normalTexture.index);
var texture = await getTexture(GetTextureParam.CreateNormal(src.normalTexture.index));
if (texture != null)
{
var prop = "_BumpMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
material.SetFloat("_BumpScale", m_src.normalTexture.scale);
material.SetTexture(GetTextureParam.NORMAL_PROP, texture);
material.SetFloat("_BumpScale", src.normalTexture.scale);
}
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.normalTexture, "_BumpMap");
MaterialFactory.SetTextureOffsetAndScale(material, src.normalTexture, "_BumpMap");
}
if (m_src.occlusionTexture != null && m_src.occlusionTexture.index != -1)
if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
{
var texture = getTexture(m_src.occlusionTexture.index);
var texture = await getTexture(GetTextureParam.CreateOcclusion(src.occlusionTexture.index));
if (texture != null)
{
var prop = "_OcclusionMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
material.SetFloat("_OcclusionStrength", m_src.occlusionTexture.strength);
material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture);
material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength);
}
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.occlusionTexture, "_OcclusionMap");
MaterialFactory.SetTextureOffsetAndScale(material, src.occlusionTexture, "_OcclusionMap");
}
if (m_src.emissiveFactor != null
|| (m_src.emissiveTexture != null && m_src.emissiveTexture.index != -1))
if (src.emissiveFactor != null
|| (src.emissiveTexture != null && src.emissiveTexture.index != -1))
{
material.EnableKeyword("_EMISSION");
material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
if (m_src.emissiveFactor != null && m_src.emissiveFactor.Length == 3)
if (src.emissiveFactor != null && src.emissiveFactor.Length == 3)
{
material.SetColor("_EmissionColor", new Color(m_src.emissiveFactor[0], m_src.emissiveFactor[1], m_src.emissiveFactor[2]));
material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2]));
}
if (m_src.emissiveTexture != null && m_src.emissiveTexture.index != -1)
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
var texture = getTexture(m_src.emissiveTexture.index);
var texture = await getTexture(GetTextureParam.Create(src.emissiveTexture.index));
if (texture != null)
{
material.SetTexture("_EmissionMap", texture.Texture);
material.SetTexture("_EmissionMap", texture);
}
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.emissiveTexture, "_EmissionMap");
MaterialFactory.SetTextureOffsetAndScale(material, src.emissiveTexture, "_EmissionMap");
}
}
BlendMode blendMode = BlendMode.Opaque;
// https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
switch (m_src.alphaMode)
switch (src.alphaMode)
{
case "BLEND":
blendMode = BlendMode.Fade;
@ -177,7 +169,7 @@ namespace UniGLTF
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.SetFloat("_Cutoff", m_src.alphaCutoff);
material.SetFloat("_Cutoff", src.alphaCutoff);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");

View File

@ -1,60 +1,50 @@
using UnityEngine;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
public class UnlitMaterialItem : MaterialItemBase
public static class UnlitMaterialItem
{
public const string ShaderName = "UniGLTF/UniUnlit";
bool m_hasVertexColor;
public UnlitMaterialItem(int i, glTFMaterial src, bool hasVertexColor) : base(i, src)
{
m_hasVertexColor = hasVertexColor;
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
public static async Task<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture, bool hasVertexColor)
{
if (getTexture == null)
{
getTexture = _ => null;
getTexture = _ => Task.FromResult<Texture2D>(null);
}
var material = CreateMaterial(ShaderName);
var material = MaterialFactory.CreateMaterial(i, src, ShaderName);
// texture
if (m_src.pbrMetallicRoughness.baseColorTexture != null)
if (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(src.pbrMetallicRoughness.baseColorTexture.index));
// Texture Offset and Scale
SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
}
// color
if (m_src.pbrMetallicRoughness.baseColorFactor != null && m_src.pbrMetallicRoughness.baseColorFactor.Length == 4)
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
var color = m_src.pbrMetallicRoughness.baseColorFactor;
var color = src.pbrMetallicRoughness.baseColorFactor;
material.color = (new Color(color[0], color[1], color[2], color[3])).gamma;
}
//renderMode
if (m_src.alphaMode == "OPAQUE")
if (src.alphaMode == "OPAQUE")
{
UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque);
}
else if (m_src.alphaMode == "BLEND")
else if (src.alphaMode == "BLEND")
{
UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent);
}
else if (m_src.alphaMode == "MASK")
else if (src.alphaMode == "MASK")
{
UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout);
material.SetFloat("_Cutoff", m_src.alphaCutoff);
material.SetFloat("_Cutoff", src.alphaCutoff);
}
else
{
@ -63,7 +53,7 @@ namespace UniGLTF
}
// culling
if (m_src.doubleSided)
if (src.doubleSided)
{
UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off);
}
@ -73,7 +63,7 @@ namespace UniGLTF
}
// VColor
if (m_hasVertexColor)
if (hasVertexColor)
{
UniUnlit.Utils.SetVColBlendMode(material, UniUnlit.UniUnlitVertexColorBlendOp.Multiply);
}

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)).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)).ToArray()
};
yield return null;

View File

@ -1,6 +1,7 @@
using System;
using System.Linq;
using UnityEngine;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
@ -20,7 +21,7 @@ namespace UniGLTF
public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial)
{
var copyTexture = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial);
var copyTexture = CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial);
if (colorConversion != null)
{
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
@ -45,6 +46,150 @@ namespace UniGLTF
texture.name = texture.name.Replace(extension, "");
}
}
struct ColorSpaceScope : IDisposable
{
bool m_sRGBWrite;
public ColorSpaceScope(RenderTextureReadWrite colorSpace)
{
m_sRGBWrite = GL.sRGBWrite;
switch (colorSpace)
{
case RenderTextureReadWrite.Linear:
GL.sRGBWrite = false;
break;
case RenderTextureReadWrite.sRGB:
default:
GL.sRGBWrite = true;
break;
}
}
public ColorSpaceScope(bool sRGBWrite)
{
m_sRGBWrite = GL.sRGBWrite;
GL.sRGBWrite = sRGBWrite;
}
public void Dispose()
{
GL.sRGBWrite = m_sRGBWrite;
}
}
#if UNITY_EDITOR && VRM_DEVELOP
[MenuItem("Assets/CopySRGBWrite", true)]
static bool CopySRGBWriteIsEnable()
{
return Selection.activeObject is Texture;
}
[MenuItem("Assets/CopySRGBWrite")]
static void CopySRGBWrite()
{
CopySRGBWrite(true);
}
[MenuItem("Assets/CopyNotSRGBWrite", true)]
static bool CopyNotSRGBWriteIsEnable()
{
return Selection.activeObject is Texture;
}
[MenuItem("Assets/CopyNotSRGBWrite")]
static void CopyNotSRGBWrite()
{
CopySRGBWrite(false);
}
static string AddPath(string path, string add)
{
return string.Format("{0}/{1}{2}{3}",
Path.GetDirectoryName(path),
Path.GetFileNameWithoutExtension(path),
add,
Path.GetExtension(path));
}
static void CopySRGBWrite(bool isSRGB)
{
var src = Selection.activeObject as Texture;
var texturePath = UnityPath.FromAsset(src);
var path = EditorUtility.SaveFilePanel("save prefab", "Assets",
Path.GetFileNameWithoutExtension(AddPath(texturePath.FullPath, ".sRGB")), "prefab");
var assetPath = UnityPath.FromFullpath(path);
if (!assetPath.IsUnderAssetsFolder)
{
return;
}
Debug.LogFormat("[CopySRGBWrite] {0} => {1}", texturePath, assetPath);
var renderTexture = new RenderTexture(src.width, src.height, 0,
RenderTextureFormat.ARGB32,
RenderTextureReadWrite.sRGB);
using (var scope = new ColorSpaceScope(isSRGB))
{
Graphics.Blit(src, renderTexture);
}
var dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false,
RenderTextureReadWrite.sRGB == RenderTextureReadWrite.Linear);
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
dst.Apply();
RenderTexture.active = null;
assetPath.CreateAsset(dst);
GameObject.DestroyImmediate(renderTexture);
}
#endif
public static Texture2D CopyTexture(Texture src, RenderTextureReadWrite colorSpace, Material material)
{
Texture2D dst = null;
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace);
using (var scope = new ColorSpaceScope(colorSpace))
{
if (material != null)
{
Graphics.Blit(src, renderTexture, material);
}
else
{
Graphics.Blit(src, renderTexture);
}
}
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear);
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
dst.name = src.name;
dst.anisoLevel = src.anisoLevel;
dst.filterMode = src.filterMode;
dst.mipMapBias = src.mipMapBias;
dst.wrapMode = src.wrapMode;
#if UNITY_2017_1_OR_NEWER
dst.wrapModeU = src.wrapModeU;
dst.wrapModeV = src.wrapModeV;
dst.wrapModeW = src.wrapModeW;
#endif
dst.Apply();
RenderTexture.active = null;
if (Application.isEditor)
{
GameObject.DestroyImmediate(renderTexture);
}
else
{
GameObject.Destroy(renderTexture);
}
return dst;
}
}
public class MetallicRoughnessConverter : ITextureConverter

View File

@ -66,7 +66,7 @@ namespace UniGLTF
#endif
// ToDo: may already exists
m_exportTextures[index] = TextureItem.CopyTexture(texture, readWrite, null);
m_exportTextures[index] = TextureConverter.CopyTexture(texture, readWrite, null);
return index;
}

View File

@ -52,7 +52,7 @@ namespace UniGLTF
{
foreach (var material in glTf.materials)
{
var textureInfo = material.GetTextures().FirstOrDefault(x => (x!=null) && x.index == textureIndex);
var textureInfo = material.GetTextures().FirstOrDefault(x => (x != null) && x.index == textureIndex);
if (textureInfo != null)
{
return textureInfo.TextureType;
@ -109,10 +109,10 @@ namespace UniGLTF
var getSizeMethod = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
if (textureImporter != null && getSizeMethod != null)
{
var args = new object[2] {0, 0};
var args = new object[2] { 0, 0 };
getSizeMethod.Invoke(textureImporter, args);
var originalWidth = (int) args[0];
var originalHeight = (int) args[1];
var originalWidth = (int)args[0];
var originalHeight = (int)args[1];
var originalSize = Mathf.Max(originalWidth, originalHeight);
var requiredMaxSize = textureImporter.maxTextureSize;
@ -122,12 +122,12 @@ namespace UniGLTF
{
return
(
TextureItem.CopyTexture(texture, GetColorSpace(textureType), null).EncodeToPNG(),
TextureConverter.CopyTexture(texture, GetColorSpace(textureType), null).EncodeToPNG(),
"image/png"
);
}
}
if (path.Extension == ".png")
{
return
@ -149,7 +149,7 @@ namespace UniGLTF
return
(
TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(),
TextureConverter.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(),
"image/png"
);
}

View File

@ -1,315 +0,0 @@
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
namespace UniGLTF
{
public 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
{
private 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.");
}
}
#if UNITY_EDITOR
/// <summary>
/// Texture from asset
/// </summary>
/// <param name="index"></param>
/// <param name="assetPath"></param>
/// <param name="textureName"></param>
public TextureItem(int index, UnityPath assetPath, string textureName)
{
m_textureIndex = index;
IsAsset = true;
m_textureLoader = new AssetTextureLoader(assetPath, textureName);
}
#endif
#region Process
ITextureLoader m_textureLoader;
public void Process(glTF gltf, IStorage storage)
{
ProcessOnAnyThread(gltf, storage);
ProcessOnMainThreadCoroutine(gltf).CoroutineToEnd();
}
public IEnumerator ProcessCoroutine(glTF gltf, IStorage storage)
{
ProcessOnAnyThread(gltf, storage);
yield return ProcessOnMainThreadCoroutine(gltf);
}
public void ProcessOnAnyThread(glTF gltf, IStorage storage)
{
m_textureLoader.ProcessOnAnyThread(gltf, storage);
}
public IEnumerator ProcessOnMainThreadCoroutine(glTF gltf)
{
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(isLinear, gltf.GetSamplerFromTextureIndex(m_textureIndex));
}
}
#endregion
struct ColorSpaceScope : IDisposable
{
bool m_sRGBWrite;
public ColorSpaceScope(RenderTextureReadWrite colorSpace)
{
m_sRGBWrite = GL.sRGBWrite;
switch (colorSpace)
{
case RenderTextureReadWrite.Linear:
GL.sRGBWrite = false;
break;
case RenderTextureReadWrite.sRGB:
default:
GL.sRGBWrite = true;
break;
}
}
public ColorSpaceScope(bool sRGBWrite)
{
m_sRGBWrite = GL.sRGBWrite;
GL.sRGBWrite = sRGBWrite;
}
public void Dispose()
{
GL.sRGBWrite = m_sRGBWrite;
}
}
#if UNITY_EDITOR && VRM_DEVELOP
[MenuItem("Assets/CopySRGBWrite", true)]
static bool CopySRGBWriteIsEnable()
{
return Selection.activeObject is Texture;
}
[MenuItem("Assets/CopySRGBWrite")]
static void CopySRGBWrite()
{
CopySRGBWrite(true);
}
[MenuItem("Assets/CopyNotSRGBWrite", true)]
static bool CopyNotSRGBWriteIsEnable()
{
return Selection.activeObject is Texture;
}
[MenuItem("Assets/CopyNotSRGBWrite")]
static void CopyNotSRGBWrite()
{
CopySRGBWrite(false);
}
static string AddPath(string path, string add)
{
return string.Format("{0}/{1}{2}{3}",
Path.GetDirectoryName(path),
Path.GetFileNameWithoutExtension(path),
add,
Path.GetExtension(path));
}
static void CopySRGBWrite(bool isSRGB)
{
var src = Selection.activeObject as Texture;
var texturePath = UnityPath.FromAsset(src);
var path = EditorUtility.SaveFilePanel("save prefab", "Assets",
Path.GetFileNameWithoutExtension(AddPath(texturePath.FullPath, ".sRGB")), "prefab");
var assetPath = UnityPath.FromFullpath(path);
if (!assetPath.IsUnderAssetsFolder)
{
return;
}
Debug.LogFormat("[CopySRGBWrite] {0} => {1}", texturePath, assetPath);
var renderTexture = new RenderTexture(src.width, src.height, 0,
RenderTextureFormat.ARGB32,
RenderTextureReadWrite.sRGB);
using (var scope = new ColorSpaceScope(isSRGB))
{
Graphics.Blit(src, renderTexture);
}
var dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false,
RenderTextureReadWrite.sRGB == RenderTextureReadWrite.Linear);
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
dst.Apply();
RenderTexture.active = null;
assetPath.CreateAsset(dst);
GameObject.DestroyImmediate(renderTexture);
}
#endif
public static Texture2D CopyTexture(Texture src, RenderTextureReadWrite colorSpace, Material material)
{
Texture2D dst = null;
var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace);
using (var scope = new ColorSpaceScope(colorSpace))
{
if (material != null)
{
Graphics.Blit(src, renderTexture, material);
}
else
{
Graphics.Blit(src, renderTexture);
}
}
dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear);
dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0);
dst.name = src.name;
dst.anisoLevel = src.anisoLevel;
dst.filterMode = src.filterMode;
dst.mipMapBias = src.mipMapBias;
dst.wrapMode = src.wrapMode;
#if UNITY_2017_1_OR_NEWER
dst.wrapModeU = src.wrapModeU;
dst.wrapModeV = src.wrapModeV;
dst.wrapModeW = src.wrapModeW;
#endif
dst.Apply();
RenderTexture.active = null;
if (Application.isEditor)
{
GameObject.DestroyImmediate(renderTexture);
}
else
{
GameObject.Destroy(renderTexture);
}
return dst;
}
}
}

View File

@ -1,348 +0,0 @@
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
public interface ITextureLoader : IDisposable
{
Texture2D Texture { get; }
/// <summary>
/// Call from any thread
/// </summary>
/// <param name="gltf"></param>
/// <param name="storage"></param>
void ProcessOnAnyThread(glTF gltf, IStorage storage);
/// <summary>
/// Call from unity main thread
/// </summary>
/// <param name="isLinear"></param>
/// <param name="sampler"></param>
/// <returns></returns>
IEnumerator ProcessOnMainThread(bool isLinear, glTFTextureSampler sampler);
}
#if UNITY_EDITOR
public class AssetTextureLoader : ITextureLoader
{
public Texture2D Texture
{
private set;
get;
}
UnityPath m_assetPath;
public AssetTextureLoader(UnityPath assetPath, string _)
{
m_assetPath = assetPath;
}
public void Dispose()
{
}
public void ProcessOnAnyThread(glTF gltf, IStorage storage)
{
}
public IEnumerator ProcessOnMainThread(bool isLinear, glTFTextureSampler sampler)
{
//
// texture from assets
//
m_assetPath.ImportAsset();
var importer = m_assetPath.GetImporter<TextureImporter>();
if (importer == null)
{
Debug.LogWarningFormat("fail to get TextureImporter: {0}", m_assetPath);
}
importer.maxTextureSize = 8192;
importer.sRGBTexture = !isLinear;
importer.SaveAndReimport();
Texture = m_assetPath.LoadAsset<Texture2D>();
//Texture.name = m_textureName;
if (Texture == null)
{
Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath);
}
else
{
var maxSize = Mathf.Max(Texture.width, Texture.height);
importer.maxTextureSize
= maxSize > 4096 ? 8192 :
maxSize > 2048 ? 4096 :
maxSize > 1024 ? 2048 :
maxSize > 512 ? 1024 :
512;
importer.SaveAndReimport();
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
}
yield break;
}
}
#endif
public class TextureLoader : ITextureLoader
{
int m_textureIndex;
public TextureLoader(int textureIndex)
{
m_textureIndex = textureIndex;
}
public Texture2D Texture
{
private set;
get;
}
public void Dispose()
{
}
static Byte[] ToArray(ArraySegment<byte> bytes)
{
if (bytes.Array == null)
{
return new byte[] { };
}
else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length)
{
return bytes.Array;
}
else
{
Byte[] result = new byte[bytes.Count];
Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length);
return result;
}
}
Byte[] m_imageBytes;
string m_textureName;
public void ProcessOnAnyThread(glTF gltf, IStorage storage)
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex);
var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
m_imageBytes = ToArray(segments);
}
public IEnumerator ProcessOnMainThread(bool isLinear, glTFTextureSampler sampler)
{
//
// texture from image(png etc) bytes
//
Texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear);
Texture.name = m_textureName;
if (m_imageBytes != null)
{
Texture.LoadImage(m_imageBytes);
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
}
yield break;
}
}
public class UnityWebRequestTextureLoader : ITextureLoader
{
public Texture2D Texture
{
private set;
get;
}
int m_textureIndex;
public UnityWebRequestTextureLoader(int textureIndex)
{
m_textureIndex = textureIndex;
}
UnityWebRequest m_uwr;
public void Dispose()
{
if (m_uwr != null)
{
m_uwr.Dispose();
m_uwr = null;
}
}
ArraySegment<Byte> m_segments;
string m_textureName;
public void ProcessOnAnyThread(glTF gltf, IStorage storage)
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex);
m_segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
}
#if false
HttpHost m_http;
class HttpHost : IDisposable
{
TcpListener m_listener;
Socket m_connection;
public HttpHost(int port)
{
m_listener = new TcpListener(IPAddress.Loopback, port);
m_listener.Start();
m_listener.BeginAcceptSocket(OnAccepted, m_listener);
}
void OnAccepted(IAsyncResult ar)
{
var l = ar.AsyncState as TcpListener;
if (l == null) return;
m_connection = l.EndAcceptSocket(ar);
// 次の接続受付はしない
BeginRead(m_connection, new byte[8192]);
}
void BeginRead(Socket c, byte[] buffer)
{
AsyncCallback callback = ar =>
{
var s = ar.AsyncState as Socket;
if (s == null) return;
var size = s.EndReceive(ar);
if (size > 0)
{
OnRead(buffer, size);
}
BeginRead(s, buffer);
};
m_connection.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, m_connection);
}
List<Byte> m_buffer = new List<byte>();
void OnRead(byte[] buffer, int len)
{
m_buffer.AddRange(buffer.Take(len));
}
public string Url
{
get
{
}
}
public void Dispose()
{
if (m_connection != null)
{
m_connection.Dispose();
m_connection = null;
}
if(m_listener != null)
{
m_listener.Stop();
m_listener = null;
}
}
}
#endif
class Deleter : IDisposable
{
string m_path;
public Deleter(string path)
{
m_path = path;
}
public void Dispose()
{
if (File.Exists(m_path))
{
File.Delete(m_path);
}
}
}
public IEnumerator ProcessOnMainThread(bool isLinear, glTFTextureSampler sampler)
{
// tmp file
var tmp = Path.GetTempFileName();
using (var f = new FileStream(tmp, FileMode.Create))
{
f.Write(m_segments.Array, m_segments.Offset, m_segments.Count);
}
using (var d = new Deleter(tmp))
{
var url = "file:///" + tmp.Replace("\\", "/");
Debug.LogFormat("UnityWebRequest: {0}", url);
#if UNITY_2017_1_OR_NEWER
using (var m_uwr = UnityWebRequestTexture.GetTexture(url, true))
{
yield return m_uwr.SendWebRequest();
if (m_uwr.isNetworkError || m_uwr.isHttpError)
{
Debug.LogWarning(m_uwr.error);
}
else
{
// Get downloaded asset bundle
Texture = ((DownloadHandlerTexture)m_uwr.downloadHandler).texture;
Texture.name = m_textureName;
}
}
#elif UNITY_5
using (var m_uwr = new WWW(url))
{
yield return m_uwr;
// wait for request
while (!m_uwr.isDone)
{
yield return null;
}
if (!string.IsNullOrEmpty(m_uwr.error))
{
Debug.Log(m_uwr.error);
yield break;
}
// Get downloaded asset bundle
Texture = m_uwr.textureNonReadable;
Texture.name = m_textureName;
}
#else
#error Unsupported Unity version
#endif
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
}
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a4bd2e8f388fb204186d743f337ddb83
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
#if UNITY_EDITOR
public static class AssetTextureLoader
{
public static Task<Texture2D> LoadTaskAsync(UnityPath m_assetPath,
bool isLinear, glTFTextureSampler sampler)
{
//
// texture from assets
//
m_assetPath.ImportAsset();
var importer = m_assetPath.GetImporter<UnityEditor.TextureImporter>();
if (importer == null)
{
Debug.LogWarningFormat("fail to get TextureImporter: {0}", m_assetPath);
}
importer.maxTextureSize = 8192;
importer.sRGBTexture = !isLinear;
importer.SaveAndReimport();
var Texture = m_assetPath.LoadAsset<Texture2D>();
if (Texture == null)
{
Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath);
}
else
{
var maxSize = Mathf.Max(Texture.width, Texture.height);
importer.maxTextureSize
= maxSize > 4096 ? 8192 :
maxSize > 2048 ? 4096 :
maxSize > 1024 ? 2048 :
maxSize > 512 ? 1024 :
512;
importer.SaveAndReimport();
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
}
return Task.FromResult(Texture);
}
}
#endif
}

View File

@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 09cdeb503b1e8234faf528b6ae134e7a
timeCreated: 1519799583
licenseType: Free
guid: 748452d292d79304da4c271f584ab985
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,54 @@
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
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);
}
}
}

View File

@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: 4ffd8b31d371e024593b9aff2cf2495b
timeCreated: 1540300073
licenseType: Free
guid: 405597f56d6540347bbecb1203aba033
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

View File

@ -0,0 +1,59 @@
using System;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
{
public static class GltfTextureLoader
{
static Byte[] ToArray(ArraySegment<byte> bytes)
{
if (bytes.Array == null)
{
return new byte[] { };
}
else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length)
{
return bytes.Array;
}
else
{
Byte[] result = new byte[bytes.Count];
Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length);
return result;
}
}
public static async Task<Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int index)
{
string m_textureName = default;
var imageBytes = await Task.Run(() =>
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(index);
var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
return ToArray(segments);
});
//
// texture from image(png etc) bytes
//
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);
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(texture, sampler);
}
return texture;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c541795ac7ae51d468dfff535e5333cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace UniGLTF
{
public delegate Task<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
public class TextureFactory : IDisposable
{
glTF m_gltf;
IStorage m_storage;
public UnityPath ImageBaseDir { get; set; }
public TextureFactory(glTF gltf, IStorage storage)
{
m_gltf = gltf;
m_storage = storage;
}
List<Texture2D> m_textuers = new List<Texture2D>();
public void Dispose()
{
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;
}
}
Dictionary<GetTextureParam, Texture2D> m_textureCache = new Dictionary<GetTextureParam, Texture2D>();
public virtual Task<Texture2D> LoadTextureAsync(int index)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return UnityWebRequestTextureLoader.LoadTextureAsync(index);
#else
return GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index);
#endif
}
/// <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)
{
if (m_textureCache.TryGetValue(param, out Texture2D texture))
{
return texture;
}
{
var defaultParam = GetTextureParam.Create(param.Index0.Value);
if (!m_textureCache.TryGetValue(defaultParam, out texture))
{
texture = await LoadTextureAsync(param.Index0.Value);
m_textureCache.Add(defaultParam, 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();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d6069f2bfbfc0c4c9276e8a5f8b0789
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,119 @@
using System;
using System.Collections;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace UniGLTF
{
public class UnityWebRequestTextureLoader
{
public Texture2D Texture
{
private set;
get;
}
int m_textureIndex;
public UnityWebRequestTextureLoader(int textureIndex)
{
m_textureIndex = textureIndex;
}
UnityWebRequest m_uwr;
public void Dispose()
{
if (m_uwr != null)
{
m_uwr.Dispose();
m_uwr = null;
}
}
string m_textureName;
public void ProcessOnAnyThread()
{
}
class Deleter : IDisposable
{
string m_path;
public Deleter(string path)
{
m_path = path;
}
public void Dispose()
{
if (File.Exists(m_path))
{
File.Delete(m_path);
}
}
}
public IEnumerator ProcessOnMainThread(glTF gltf, IStorage storage, bool isLinear, glTFTextureSampler sampler)
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex);
var bytes = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
// tmp file
var tmp = Path.GetTempFileName();
using (var f = new FileStream(tmp, FileMode.Create))
{
f.Write(bytes.Array, bytes.Offset, bytes.Count);
}
using (var d = new Deleter(tmp))
{
var url = "file:///" + tmp.Replace("\\", "/");
Debug.LogFormat("UnityWebRequest: {0}", url);
#if UNITY_2017_1_OR_NEWER
using (var m_uwr = UnityWebRequestTexture.GetTexture(url, true))
{
yield return m_uwr.SendWebRequest();
if (m_uwr.isNetworkError || m_uwr.isHttpError)
{
Debug.LogWarning(m_uwr.error);
}
else
{
// Get downloaded asset bundle
Texture = ((DownloadHandlerTexture)m_uwr.downloadHandler).texture;
Texture.name = m_textureName;
}
}
#elif UNITY_5
using (var m_uwr = new WWW(url))
{
yield return m_uwr;
// wait for request
while (!m_uwr.isDone)
{
yield return null;
}
if (!string.IsNullOrEmpty(m_uwr.error))
{
Debug.Log(m_uwr.error);
yield break;
}
// Get downloaded asset bundle
Texture = m_uwr.textureNonReadable;
Texture.name = m_textureName;
}
#else
#error Unsupported Unity version
#endif
}
if (sampler != null)
{
TextureSamplerUtil.SetSampler(Texture, sampler);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b91b7b42ddfd6284a9303a0901fccaa3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,193 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace UniGLTF
{
public delegate TextureItem GetTextureItemFunc(int i);
public delegate Shader GetShaderFunc();
public delegate MaterialItemBase MaterialImporter(int i, glTFMaterial x, bool hasVertexColor);
public class MaterialFactory
{
MaterialImporter m_materialImporter;
public MaterialImporter MaterialImporter
{
set
{
m_materialImporter = value;
}
get
{
if (m_materialImporter == null)
{
m_materialImporter = CreateMaterial;
}
return m_materialImporter;
}
}
List<TextureItem> m_textures = new List<TextureItem>();
public IList<TextureItem> GetTextures()
{
return m_textures;
}
public TextureItem GetTexture(int i)
{
if (i < 0 || i >= m_textures.Count)
{
return null;
}
return m_textures[i];
}
public void AddTexture(TextureItem item)
{
m_textures.Add(item);
}
List<MaterialItemBase> m_materials = new List<MaterialItemBase>();
public void AddMaterial(MaterialItemBase material)
{
var originalName = material.Name;
int j = 2;
while (m_materials.Any(x => x.Name == material.Name))
{
material.Name = string.Format("{0}({1})", originalName, j++);
}
m_materials.Add(material);
}
public IList<MaterialItemBase> GetMaterials()
{
return m_materials;
}
public MaterialItemBase GetMaterial(int index)
{
if (index < 0) return null;
if (index >= m_materials.Count) return null;
return m_materials[index];
}
public virtual ITextureLoader CreateTextureLoader(int index)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return new UnityWebRequestTextureLoader(index);
#else
return new TextureLoader(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, assetPath, textureName);
}
else
#endif
{
item = new TextureItem(i, CreateTextureLoader(i));
}
AddTexture(item);
}
}
public IEnumerator TexturesProcessOnAnyThread(glTF gltf, IStorage storage)
{
// using (MeasureTime("TexturesProcessOnAnyThread"))
{
foreach (var x in GetTextures())
{
x.ProcessOnAnyThread(gltf, storage);
yield return null;
}
}
}
public IEnumerator TexturesProcessOnMainThread(glTF gltf)
{
// using (MeasureTime("TexturesProcessOnMainThread"))
{
foreach (var x in GetTextures())
{
yield return x.ProcessOnMainThreadCoroutine(gltf);
}
}
}
public IEnumerator LoadMaterials(glTF gltf)
{
// using (MeasureTime("LoadMaterials"))
{
if (gltf.materials == null || !gltf.materials.Any())
{
AddMaterial(MaterialImporter(0, null, false));
}
else
{
for (int i = 0; i < gltf.materials.Count; ++i)
{
AddMaterial(MaterialImporter(i, gltf.materials[i], gltf.MaterialHasVertexColor(i)));
}
}
}
yield return null;
}
public static MaterialItemBase CreateMaterial(int i, glTFMaterial x, bool hasVertexColor)
{
if (x == null)
{
UnityEngine.Debug.LogWarning("glTFMaterial is empty");
return new PBRMaterialItem(i, x);
}
if (glTF_KHR_materials_unlit.IsEnable(x))
{
return new UnlitMaterialItem(i, x, hasVertexColor);
}
return new PBRMaterialItem(i, x);
}
}
}

View File

@ -1,59 +0,0 @@
using UnityEngine;
namespace UniGLTF
{
public abstract class MaterialItemBase
{
protected int m_index;
protected glTFMaterial m_src;
public string Name { get; set; }
public MaterialItemBase(int i, glTFMaterial src)
{
m_index = i;
m_src = src;
Name = src != null ? m_src.name : "";
}
public abstract Material GetOrCreate(GetTextureItemFunc getTexture);
protected Material CreateMaterial(string shaderName)
{
var material = new Material(Shader.Find(shaderName));
#if UNITY_EDITOR
// textureImporter.SaveAndReimport(); may destroy this material
material.hideFlags = HideFlags.DontUnloadUnusedAsset;
#endif
material.name = (m_src == null || string.IsNullOrEmpty(m_src.name))
? string.Format("material_{0:00}", m_index)
: m_src.name
;
return material;
}
protected static void SetTextureOffsetAndScale(Material material, glTFTextureInfo textureInfo, string propertyName)
{
if (glTF_KHR_texture_transform.TryGet(textureInfo, out glTF_KHR_texture_transform textureTransform))
{
Vector2 offset = new Vector2(0, 0);
Vector2 scale = new Vector2(1, 1);
if (textureTransform.offset != null && textureTransform.offset.Length == 2)
{
offset = new Vector2(textureTransform.offset[0], textureTransform.offset[1]);
}
if (textureTransform.scale != null && textureTransform.scale.Length == 2)
{
scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]);
}
offset.y = (offset.y + scale.y - 1.0f) * -1.0f;
material.SetTextureOffset(propertyName, offset);
material.SetTextureScale(propertyName, scale);
}
}
}
}

View File

@ -3,6 +3,7 @@ using NUnit.Framework;
using UnityEngine;
using UniJSON;
using System.Linq;
using System.Threading.Tasks;
namespace UniGLTF
{
@ -32,7 +33,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.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual(dstMaterial.mainTextureOffset.x, offset.x, 0.3f);
Assert.AreEqual(dstMaterial.mainTextureOffset.y, offset.y, 0.2f);
@ -80,7 +81,7 @@ namespace UniGLTF
Assert.IsTrue(glTF_KHR_materials_unlit.IsEnable(gltfMaterial));
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
}
@ -99,7 +100,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -114,7 +115,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -130,7 +131,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -145,7 +146,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -160,7 +161,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -176,7 +177,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -191,7 +192,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -207,7 +208,7 @@ namespace UniGLTF
},
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
@ -217,7 +218,7 @@ namespace UniGLTF
{
extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(),
};
var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, gltfMaterial);
Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name);
}
}
@ -225,7 +226,7 @@ namespace UniGLTF
[Test]
public void MaterialImportTest()
{
var material = MaterialFactory.CreateMaterial(0, new glTFMaterial { }, false).GetOrCreate(null);
var material = MaterialFactory.CreateMaterialForTest(0, new glTFMaterial { });
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,6 +6,7 @@ using UnityEngine;
using System.IO;
using System.Collections;
using UniJSON;
using System.Threading.Tasks;
namespace VRM
{
@ -42,7 +43,7 @@ namespace VRM
{
VRM = vrm;
// override material importer
MaterialFactory.MaterialImporter = new VRMMaterialImporter(VRM.materialProperties).CreateMaterial;
MaterialFactory.CreateMaterialAsync = new VRMMaterialImporter(VRM.materialProperties).CreateMaterial;
}
else
{
@ -57,7 +58,11 @@ namespace VRM
using (MeasureTime("VRM LoadMeta"))
{
LoadMeta();
var task = LoadMetaAsync();
foreach (var x in task.AsIEnumerator())
{
yield return x;
}
}
yield return null;
@ -86,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;
@ -193,7 +198,8 @@ namespace VRM
}
}
var material = MaterialFactory.GetMaterials().FirstOrDefault(y => y.Name == x.materialName).GetOrCreate(MaterialFactory.GetTexture);
var material = MaterialFactory.Materials
.FirstOrDefault(y => y.name == x.materialName);
var propertyName = x.propertyName;
if (x.propertyName.FastEndsWith("_ST_S")
|| x.propertyName.FastEndsWith("_ST_T"))
@ -292,7 +298,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";
@ -304,24 +310,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.Process(GLTF, Storage);
meta.Thumbnail = t.Texture;
}
}
meta.Thumbnail = await TextureFactory.GetTextureAsync(GetTextureParam.Create(gltfMeta.texture));
meta.AllowedUser = gltfMeta.allowedUser;
meta.ViolentUssage = gltfMeta.violentUssage;
meta.SexualUssage = gltfMeta.sexualUssage;

View File

@ -3,10 +3,11 @@ using UniGLTF;
using UnityEngine;
using System.Linq;
using System;
using System.Threading.Tasks;
namespace VRM
{
public class MToonMaterialItem : MaterialItemBase
public static class MToonMaterialItem
{
static string[] VRM_SHADER_NAMES =
{
@ -20,18 +21,9 @@ namespace VRM
"VRM/UnlitTransparentZWrite",
};
glTF_VRM_Material m_vrmMaterial;
bool m_hasVertexColor;
public MToonMaterialItem(int i, glTFMaterial src, bool hasVertexColor, glTF_VRM_Material vrmMaterial) : base(i, src)
public static async Task<Material> CreateAsync(glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
{
m_hasVertexColor = hasVertexColor;
m_vrmMaterial = vrmMaterial;
}
public override Material GetOrCreate(GetTextureItemFunc getTexture)
{
var item = m_vrmMaterial;
var item = vrmMaterial;
var shaderName = item.shader;
var shader = Shader.Find(shaderName);
if (shader == null)
@ -47,7 +39,7 @@ namespace VRM
{
Debug.LogWarningFormat("unknown shader {0}.", shaderName);
}
return MaterialFactory.CreateMaterial(m_index, m_src, m_hasVertexColor).GetOrCreate(getTexture);
return await MaterialFactory.DefaultCreateMaterialAsync(gltf, m_index, getTexture);
}
//
@ -78,18 +70,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)
@ -127,15 +111,15 @@ namespace VRM
m_materials = materials;
}
public MaterialItemBase CreateMaterial(int i, glTFMaterial src, bool hasVertexColor)
public Task<Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i == 0 && m_materials.Count == 0)
{
// dummy
return new PBRMaterialItem(i, src);
return MaterialFactory.DefaultCreateMaterialAsync(gltf, i, getTexture);
}
return new MToonMaterialItem(i, src, hasVertexColor, m_materials[i]);
return MToonMaterialItem.CreateAsync(gltf, i, m_materials[i], getTexture);
}
}
}