300 lines
7.9 KiB
C#
300 lines
7.9 KiB
C#
|
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>
|
|||
|
/// <returns></returns>
|
|||
|
IEnumerator ProcessOnMainThread(bool isLinear);
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
public class AssetTextureLoader : ITextureLoader
|
|||
|
{
|
|||
|
public Texture2D Texture
|
|||
|
{
|
|||
|
private set;
|
|||
|
get;
|
|||
|
}
|
|||
|
|
|||
|
private string m_textureName;
|
|||
|
UnityPath m_assetPath;
|
|||
|
|
|||
|
public AssetTextureLoader(UnityPath assetPath, string textureName)
|
|||
|
{
|
|||
|
m_assetPath = assetPath;
|
|||
|
m_textureName = textureName;
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public void ProcessOnAnyThread(glTF gltf, IStorage storage)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public IEnumerator ProcessOnMainThread(bool isLinear)
|
|||
|
{
|
|||
|
//
|
|||
|
// 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.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);
|
|||
|
}
|
|||
|
|
|||
|
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)
|
|||
|
{
|
|||
|
//
|
|||
|
// 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);
|
|||
|
}
|
|||
|
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)
|
|||
|
{
|
|||
|
// 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);
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|