// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 using System; using System.Threading.Tasks; using Unity.Collections; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Profiling; namespace GLTFast.Loading { /// /// Default implementation /// public class DefaultDownloadProvider : IDownloadProvider { /// /// Sends a URI request and waits for its completion. /// /// URI to request /// Object representing the request public async Task Request(Uri url) { var req = new AwaitableDownload(url); await req.WaitAsync(); return req; } /// /// Sends a URI request to load a texture /// /// URI to request /// If true, resulting texture is not CPU readable (uses less memory) /// Object representing the request #pragma warning disable CS1998 public async Task RequestTexture(Uri url, bool nonReadable) { #pragma warning restore CS1998 #if UNITY_WEBREQUEST_TEXTURE var req = new AwaitableTextureDownload(url,nonReadable); await req.WaitAsync(); return req; #else return null; #endif } } /// /// Default implementation that loads URIs via /// public class AwaitableDownload : IDownload #if UNITY_2021_3_OR_NEWER ,INativeDownload #endif { const string k_MimeTypeGltfBinary = "model/gltf-binary"; const string k_MimeTypeGltf = "model/gltf+json"; /// /// that is used for the download /// protected UnityWebRequest m_Request; /// /// The download's /// protected UnityWebRequestAsyncOperation m_AsyncOperation; /// /// Empty constructor /// protected AwaitableDownload() { } /// /// Creates a download of a URI /// /// URI to request public AwaitableDownload(Uri url) { Init(url); } void Init(Uri url) { m_Request = UnityWebRequest.Get(url); m_AsyncOperation = m_Request.SendWebRequest(); } /// /// Waits until the URI request is completed. /// /// A task that represents the completion of the download public async Task WaitAsync() { while (!m_AsyncOperation.isDone) { await Task.Yield(); } } /// /// True if the download finished and was successful /// public bool Success => m_Request != null && m_Request.isDone && m_Request.result == UnityWebRequest.Result.Success; /// /// If the download failed, error description /// public string Error => m_Request == null ? "Request disposed" : m_Request.error; /// /// Downloaded data as byte array /// public byte[] Data { get { Profiler.BeginSample("AwaitableDownload.Data"); var result = m_Request?.downloadHandler.data; Profiler.EndSample(); return result; } } #if UNITY_2021_3_OR_NEWER /// public NativeArray.ReadOnly NativeData => m_Request?.downloadHandler.nativeData ?? default; #endif /// /// Downloaded data as string /// public string Text => m_Request?.downloadHandler.text; /// /// True if the requested download is a glTF-Binary file. /// False if it is a regular JSON-based glTF file. /// Null if the type could not be determined. /// public bool? IsBinary { get { if (Success) { string contentType = m_Request.GetResponseHeader("Content-Type"); if (contentType == k_MimeTypeGltfBinary) return true; if (contentType == k_MimeTypeGltf) return false; } #if UNITY_2021_3_OR_NEWER return GltfGlobals.IsGltfBinary(NativeData); #else return null; #endif } } /// /// Releases previously allocated resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases previously allocated resources. /// /// Indicates whether the method call comes from a Dispose method (its value is true) /// or from a finalizer (its value is false). protected virtual void Dispose(bool disposing) { if (disposing) { m_Request.Dispose(); m_Request = null; } } } #if UNITY_WEBREQUEST_TEXTURE /// /// Default implementation that loads /// texture URIs via . /// public class AwaitableTextureDownload : AwaitableDownload, ITextureDownload { /// /// Parameter-less constructor, required for inheritance. /// protected AwaitableTextureDownload() {} /// /// Default constructor. /// /// Texture URI to request /// If true, resulting texture is not CPU readable (uses less memory) public AwaitableTextureDownload(Uri url, bool nonReadable) { Init(url,nonReadable); } /// /// Generates the UnityWebRequest used for sending the request. /// /// Texture URI to request /// If true, resulting texture is not CPU readable (uses less memory) /// UnityWebRequest used for sending the request protected static UnityWebRequest CreateRequest(Uri url, bool nonReadable) { return UnityWebRequestTexture.GetTexture(url,nonReadable); } void Init(Uri url, bool nonReadable) { m_Request = CreateRequest(url,nonReadable); m_AsyncOperation = m_Request.SendWebRequest(); } /// public Texture2D Texture => (m_Request?.downloadHandler as DownloadHandlerTexture )?.texture; } #endif }