-
Notifications
You must be signed in to change notification settings - Fork 439
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #744 from ousttrue/feature/refactor_textureitem
Feature/refactor textureitem
- Loading branch information
Showing
36 changed files
with
988 additions
and
1,105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
.../MaterialFacotry/MaterialItemBase.cs.meta → ...Runtime/Extensions/TaskExtensions.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
175 changes: 175 additions & 0 deletions
175
Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
} |
File renamed without changes.
Oops, something went wrong.