mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-16 08:02:57 -05:00
Merge pull request #744 from ousttrue/feature/refactor_textureitem
Feature/refactor textureitem
This commit is contained in:
commit
df8e554be9
|
|
@ -3,8 +3,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace
|
||||
DepthFirstScheduler
|
||||
namespace DepthFirstScheduler
|
||||
{
|
||||
public static class IEnumeratorExtensions
|
||||
{
|
||||
|
|
|
|||
58
Assets/UniGLTF/Runtime/Extensions/TaskExtensions.cs
Normal file
58
Assets/UniGLTF/Runtime/Extensions/TaskExtensions.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f49a88d3a0e6eb24e91af983452f59f6
|
||||
guid: 54481e2d4da20ec4fa15376518f2e938
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader.meta
Normal file
8
Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a4bd2e8f388fb204186d743f337ddb83
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09cdeb503b1e8234faf528b6ae134e7a
|
||||
timeCreated: 1519799583
|
||||
licenseType: Free
|
||||
guid: 748452d292d79304da4c271f584ab985
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ffd8b31d371e024593b9aff2cf2495b
|
||||
timeCreated: 1540300073
|
||||
licenseType: Free
|
||||
guid: 405597f56d6540347bbecb1203aba033
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c541795ac7ae51d468dfff535e5333cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4d6069f2bfbfc0c4c9276e8a5f8b0789
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b91b7b42ddfd6284a9303a0901fccaa3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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をシーンオブジェクトに変換していく
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user