| | 1 | | using Cysharp.Threading.Tasks; |
| | 2 | | using System; |
| | 3 | | using System.Collections.Generic; |
| | 4 | | using System.Threading.Tasks; |
| | 5 | | using GLTFast.Loading; |
| | 6 | | using MainScripts.DCL.Controllers.AssetManager; |
| | 7 | | using UnityEngine; |
| | 8 | | using UnityEngine.Networking; |
| | 9 | |
|
| | 10 | | namespace DCL.GLTFast.Wrappers |
| | 11 | | { |
| | 12 | | /// <summary> |
| | 13 | | /// With this class we replace all of GLTFast web requests with our own |
| | 14 | | /// </summary> |
| | 15 | | internal class GltFastDownloadProvider : IDownloadProvider, IDisposable |
| | 16 | | { |
| | 17 | | public delegate bool AssetIdConverter(string uri, out string id); |
| | 18 | |
|
| | 19 | | private readonly IWebRequestController webRequestController; |
| | 20 | | private readonly AssetIdConverter fileToUrl; |
| | 21 | | private readonly AssetPromiseKeeper_Texture texturePromiseKeeper; |
| | 22 | |
|
| 103 | 23 | | private List<IDisposable> disposables = new (); |
| | 24 | | private string baseUrl; |
| | 25 | | private bool isDisposed; |
| | 26 | |
|
| 103 | 27 | | public GltFastDownloadProvider(string baseUrl, IWebRequestController webRequestController, AssetIdConverter file |
| | 28 | | { |
| 103 | 29 | | this.baseUrl = baseUrl; |
| 103 | 30 | | this.webRequestController = webRequestController; |
| 103 | 31 | | this.fileToUrl = fileToUrl; |
| 103 | 32 | | this.texturePromiseKeeper = texturePromiseKeeper; |
| 103 | 33 | | } |
| | 34 | |
|
| | 35 | | public async Task<IDownload> RequestAsync(Uri uri) |
| | 36 | | { |
| 100 | 37 | | if (isDisposed) |
| 0 | 38 | | return null; |
| | 39 | |
|
| 100 | 40 | | string finalUrl = GetFinalUrl(uri, false); |
| | 41 | |
|
| 298 | 42 | | var asyncOp = await webRequestController.GetAsync( |
| | 43 | | url: finalUrl, |
| | 44 | | downloadHandler: new DownloadHandlerBuffer(), |
| | 45 | | timeout: 30, |
| | 46 | | requestAttemps: 3); |
| | 47 | |
|
| 100 | 48 | | GltfDownloaderWrapper wrapper = new GltfDownloaderWrapper(asyncOp); |
| 100 | 49 | | disposables.Add(wrapper); |
| | 50 | |
|
| 100 | 51 | | if (!wrapper.Success) { Debug.LogError($"<color=Red>[GLTFast WebRequest Failed]</color> {asyncOp.url} {async |
| | 52 | |
|
| 100 | 53 | | return wrapper; |
| 100 | 54 | | } |
| | 55 | |
|
| | 56 | | private string GetFinalUrl(Uri uri, bool isTexture) |
| | 57 | | { |
| 134 | 58 | | string fileName = uri.OriginalString; |
| | 59 | |
|
| 134 | 60 | | if (string.IsNullOrEmpty(baseUrl)) |
| 94 | 61 | | return fileName; |
| | 62 | |
|
| 40 | 63 | | fileName = fileName.Replace(baseUrl, ""); |
| | 64 | |
|
| 40 | 65 | | if (fileName.StartsWith("file://")) |
| 1 | 66 | | return fileName; |
| | 67 | |
|
| | 68 | | // this can return false and the url is valid, only happens with asset with hash as a name ( mostly gltf ) |
| 39 | 69 | | if (fileToUrl(fileName, out string finalUrl)) |
| 3 | 70 | | return finalUrl; |
| | 71 | |
|
| 36 | 72 | | if (isTexture) |
| 0 | 73 | | throw new Exception($"File not found in scene {finalUrl}"); |
| | 74 | |
|
| 36 | 75 | | return uri.OriginalString; |
| | 76 | | } |
| | 77 | |
|
| | 78 | | public async Task<ITextureDownload> RequestTextureAsync(Uri uri, bool nonReadable, bool forceLinear) |
| | 79 | | { |
| 34 | 80 | | if (isDisposed) |
| 0 | 81 | | return null; |
| | 82 | |
|
| 34 | 83 | | string finalUrl = GetFinalUrl(uri, true); |
| | 84 | |
|
| 34 | 85 | | var promise = new AssetPromise_Texture( |
| | 86 | | finalUrl, |
| | 87 | | storeTexAsNonReadable: nonReadable, |
| | 88 | | overrideMaxTextureSize: DataStore.i.textureConfig.gltfMaxSize.Get(), |
| | 89 | | overrideCompression: |
| | 90 | | #if UNITY_WEBGL |
| | 91 | | true |
| | 92 | | #else |
| | 93 | | false |
| | 94 | | #endif |
| | 95 | | , linear: forceLinear |
| | 96 | | ); |
| | 97 | |
|
| 34 | 98 | | var wrapper = new GLTFastTexturePromiseWrapper(texturePromiseKeeper, promise); |
| 34 | 99 | | disposables.Add(wrapper); |
| | 100 | |
|
| 34 | 101 | | Exception promiseException = null; |
| 34 | 102 | | promise.OnFailEvent += (_,e) => promiseException = e; |
| | 103 | |
|
| 34 | 104 | | texturePromiseKeeper.Keep(promise); |
| 102 | 105 | | await promise; |
| | 106 | |
|
| 34 | 107 | | if (!wrapper.Success) |
| | 108 | | { |
| 0 | 109 | | string errorMessage = promiseException != null ? promiseException.Message : wrapper.Error; |
| 0 | 110 | | Debug.LogError($"[GLTFast Texture WebRequest Failed] Error: {errorMessage} | url: " + finalUrl); |
| | 111 | | } |
| | 112 | |
|
| 34 | 113 | | return wrapper; |
| 34 | 114 | | } |
| | 115 | |
|
| | 116 | | public void Dispose() |
| | 117 | | { |
| 599 | 118 | | foreach (IDisposable disposable in disposables) { disposable.Dispose(); } |
| 103 | 119 | | disposables.Clear(); |
| 103 | 120 | | isDisposed = true; |
| 103 | 121 | | } |
| | 122 | | } |
| | 123 | | } |