holopy3/Assets/UniGLTF/Core/Scripts/IO/TextureItem.cs
Lena Biresch 490ef558ef CleanUp
2021-01-28 13:07:52 +01:00

300 lines
8.9 KiB
C#

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; }
}
public Texture2D ConvertTexture(string prop)
{
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().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)
{
m_textureIndex = index;
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
m_textureLoader = new UnityWebRequestTextureLoader(m_textureIndex);
#else
m_textureLoader = new TextureLoader(m_textureIndex);
#endif
}
#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);
TextureSamplerUtil.SetSampler(Texture, 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.Apply();
RenderTexture.active = null;
if (Application.isEditor)
{
GameObject.DestroyImmediate(renderTexture);
}
else
{
GameObject.Destroy(renderTexture);
}
return dst;
}
}
}