GLTFImage.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Newtonsoft.Json;
  8. using UnityEngine;
  9. using UnityEngine.Networking;
  10. using UnityEngine.Scripting;
  11. namespace Siccity.GLTFUtility {
  12. // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#image
  13. [Preserve] public class GLTFImage {
  14. /// <summary>
  15. /// The uri of the image.
  16. /// Relative paths are relative to the .gltf file.
  17. /// Instead of referencing an external file, the uri can also be a data-uri.
  18. /// The image format must be jpg or png.
  19. /// </summary>
  20. public string uri;
  21. /// <summary> Either "image/jpeg" or "image/png" </summary>
  22. public string mimeType;
  23. public int? bufferView;
  24. public string name;
  25. public class ImportResult {
  26. public byte[] bytes;
  27. public string path;
  28. public ImportResult(byte[] bytes, string path = null) {
  29. this.bytes = bytes;
  30. this.path = path;
  31. }
  32. public IEnumerator CreateTextureAsync(bool linear, Action<Texture2D> onFinish, Action<float> onProgress = null) {
  33. if (!string.IsNullOrEmpty(path)) {
  34. #if UNITY_EDITOR
  35. // Load textures from asset database if we can
  36. Texture2D assetTexture = UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D;
  37. if (assetTexture != null) {
  38. onFinish(assetTexture);
  39. if (onProgress != null) onProgress(1f);
  40. yield break;
  41. }
  42. #endif
  43. #if !UNITY_EDITOR && ( UNITY_ANDROID || UNITY_IOS )
  44. path = "File://" + path;
  45. #endif
  46. // TODO: Support linear/sRGB textures
  47. using(UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(path, true)) {
  48. UnityWebRequestAsyncOperation operation = uwr.SendWebRequest();
  49. float progress = 0;
  50. while (!operation.isDone) {
  51. if (progress != uwr.downloadProgress) {
  52. if (onProgress != null) onProgress(uwr.downloadProgress);
  53. }
  54. yield return null;
  55. }
  56. if (onProgress != null) onProgress(1f);
  57. #if UNITY_2020_2_OR_NEWER
  58. if(uwr.result == UnityWebRequest.Result.ConnectionError ||
  59. uwr.result == UnityWebRequest.Result.ProtocolError)
  60. #else
  61. if(uwr.isNetworkError || uwr.isHttpError)
  62. #endif
  63. {
  64. Debug.LogError("GLTFImage.cs ToTexture2D() ERROR: " + uwr.error);
  65. } else {
  66. Texture2D tex = DownloadHandlerTexture.GetContent(uwr);
  67. tex.name = Path.GetFileNameWithoutExtension(path);
  68. onFinish(tex);
  69. }
  70. uwr.Dispose();
  71. }
  72. } else {
  73. Texture2D tex = new Texture2D(2, 2, TextureFormat.ARGB32, true, linear);
  74. if (!tex.LoadImage(bytes)) {
  75. Debug.Log("mimeType not supported");
  76. yield break;
  77. } else onFinish(tex);
  78. }
  79. }
  80. }
  81. public class ImportTask : Importer.ImportTask<ImportResult[]> {
  82. public ImportTask(List<GLTFImage> images, string directoryRoot, GLTFBufferView.ImportTask bufferViewTask) : base(bufferViewTask) {
  83. task = new Task(() => {
  84. // No images
  85. if (images == null) return;
  86. Result = new ImportResult[images.Count];
  87. for (int i = 0; i < images.Count; i++) {
  88. string fullUri = directoryRoot + images[i].uri;
  89. if (!string.IsNullOrEmpty(images[i].uri)) {
  90. if (File.Exists(fullUri)) {
  91. // If the file is found at fullUri, read it
  92. byte[] bytes = File.ReadAllBytes(fullUri);
  93. Result[i] = new ImportResult(bytes, fullUri);
  94. } else if (images[i].uri.StartsWith("data:")) {
  95. // If the image is embedded, find its Base64 content and save as byte array
  96. string content = images[i].uri.Split(',').Last();
  97. byte[] imageBytes = Convert.FromBase64String(content);
  98. Result[i] = new ImportResult(imageBytes);
  99. }
  100. } else if (images[i].bufferView.HasValue && !string.IsNullOrEmpty(images[i].mimeType)) {
  101. GLTFBufferView.ImportResult view = bufferViewTask.Result[images[i].bufferView.Value];
  102. byte[] bytes = new byte[view.byteLength];
  103. view.stream.Position = view.byteOffset;
  104. view.stream.Read(bytes, 0, view.byteLength);
  105. Result[i] = new ImportResult(bytes);
  106. } else {
  107. Debug.Log("Couldn't find texture at " + fullUri);
  108. }
  109. }
  110. });
  111. }
  112. }
  113. }
  114. }