AssetViewerBase.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. #pragma warning disable 649
  2. using System;
  3. using System.IO;
  4. using TriLibCore.General;
  5. using TriLibCore.Utils;
  6. using UnityEngine;
  7. using UnityEngine.Networking;
  8. using UnityEngine.UI;
  9. namespace TriLibCore.Samples
  10. {
  11. /// <summary>Represents a base class used in TriLib samples.</summary>
  12. public class AssetViewerBase : AbstractInputSystem
  13. {
  14. /// <summary>Gets the Asset Viewer Singleton instance.</summary>
  15. public static AssetViewerBase Instance { get; private set; }
  16. /// <summary>
  17. /// Model/skybox loading bar. (Used on platforms with async capabilities)
  18. /// </summary>
  19. [SerializeField]
  20. private RectTransform _loadingBar;
  21. /// <summary>
  22. /// Help box wrapper.
  23. /// </summary>
  24. [SerializeField]
  25. private GameObject _helpWrapper;
  26. /// <summary>
  27. /// Loading screen wrapper. (Used on platforms without async capabilities)
  28. /// </summary>
  29. [SerializeField]
  30. private GameObject _loadingWrapper;
  31. /// <summary>
  32. /// Model URL loading dialog.
  33. /// </summary>
  34. [SerializeField]
  35. private GameObject _modelUrlDialog;
  36. /// <summary>
  37. /// Model URL loading Input Field.
  38. /// </summary>
  39. [SerializeField]
  40. private InputField _modelUrl;
  41. /// <summary>
  42. /// Animation playback slider.
  43. /// </summary>
  44. [SerializeField]
  45. protected Slider PlaybackSlider;
  46. /// <summary>
  47. /// Animation playback time.
  48. /// </summary>
  49. [SerializeField]
  50. protected Text PlaybackTime;
  51. /// <summary>
  52. /// Animation selector.
  53. /// </summary>
  54. [SerializeField]
  55. protected Dropdown PlaybackAnimation;
  56. /// <summary>
  57. /// Play button.
  58. /// </summary>
  59. [SerializeField]
  60. protected Selectable Play;
  61. /// <summary>
  62. /// Stop button.
  63. /// </summary>
  64. [SerializeField]
  65. protected Selectable Stop;
  66. /// <summary>
  67. /// Options used in this sample.
  68. /// </summary>
  69. protected AssetLoaderOptions AssetLoaderOptions;
  70. /// <summary>
  71. /// Current camera pitch and yaw angles.
  72. /// </summary>
  73. public Vector2 CameraAngle;
  74. /// <summary>
  75. /// Loaded game object.
  76. /// </summary>
  77. public GameObject RootGameObject { get; protected set; }
  78. /// <summary>
  79. /// Mouse input multiplier.
  80. /// Higher values will make the mouse movement more sensible.
  81. /// </summary>
  82. protected const float InputMultiplierRatio = 0.1f;
  83. /// <summary>
  84. /// Maximum camera pitch and light pitch (rotation around local X-axis).
  85. /// </summary>
  86. protected const float MaxPitch = 80f;
  87. /// <summary>
  88. /// The AssetLoaderFilePicker instance created for this viewer.
  89. /// </summary>
  90. protected AssetLoaderFilePicker FilePickerAssetLoader;
  91. /// <summary>
  92. /// Holds the peak memory used to load the model.
  93. /// </summary>
  94. protected long PeakMemory;
  95. /// <summary>
  96. /// A flag representing if the model is loading or not.
  97. /// </summary>
  98. private bool _loading;
  99. /// <summary>Updates the Camera based on mouse Input.</summary>
  100. protected void UpdateCamera()
  101. {
  102. CameraAngle.x = Mathf.Repeat(CameraAngle.x + GetAxis("Mouse X"), 360f);
  103. CameraAngle.y = Mathf.Clamp(CameraAngle.y + GetAxis("Mouse Y"), -MaxPitch, MaxPitch);
  104. }
  105. /// <summary>
  106. /// Shows the help box.
  107. /// </summary>
  108. public void ShowHelp()
  109. {
  110. _helpWrapper.SetActive(true);
  111. }
  112. /// <summary>
  113. /// Hides the help box.
  114. /// </summary>
  115. public void HideHelp()
  116. {
  117. _helpWrapper.SetActive(false);
  118. }
  119. /// <summary>
  120. /// Shows the model URL dialog.
  121. /// </summary>
  122. public void ShowModelUrlDialog()
  123. {
  124. _modelUrlDialog.SetActive(true);
  125. _modelUrl.Select();
  126. _modelUrl.ActivateInputField();
  127. }
  128. /// <summary>
  129. /// Hides the model URL dialog.
  130. /// </summary>
  131. public void HideModelUrlDialog()
  132. {
  133. _modelUrlDialog.SetActive(false);
  134. _modelUrl.text = null;
  135. }
  136. /// <summary>
  137. /// Shows the file picker for loading a model from local file-system.
  138. /// </summary>
  139. protected void LoadModelFromFile(GameObject wrapperGameObject = null, Action<AssetLoaderContext> onMaterialsLoad = null)
  140. {
  141. SetLoading(false);
  142. FilePickerAssetLoader = AssetLoaderFilePicker.Create();
  143. FilePickerAssetLoader.LoadModelFromFilePickerAsync("Select a File", OnLoad, onMaterialsLoad ?? OnMaterialsLoad, OnProgress, OnBeginLoadModel, OnError, wrapperGameObject ?? gameObject, AssetLoaderOptions);
  144. }
  145. /// <summary>
  146. /// Loads a model from a URL.
  147. /// </summary>
  148. protected void LoadModelFromURL(UnityWebRequest request, string fileExtension, GameObject wrapperGameObject = null, object customData = null, Action<AssetLoaderContext> onMaterialsLoad = null)
  149. {
  150. if (string.IsNullOrWhiteSpace(fileExtension))
  151. {
  152. throw new Exception("TriLib could not determine the given model extension.");
  153. }
  154. HideModelUrlDialog();
  155. SetLoading(true);
  156. OnBeginLoadModel(true);
  157. fileExtension = fileExtension.ToLowerInvariant();
  158. var isZipFile = fileExtension == "zip" || fileExtension == ".zip";
  159. AssetDownloader.LoadModelFromUri(request, OnLoad, onMaterialsLoad ?? OnMaterialsLoad, OnProgress, OnError, wrapperGameObject, AssetLoaderOptions, customData, isZipFile ? null : fileExtension, isZipFile);
  160. }
  161. /// <summary>
  162. /// Shows the URL selector for loading a model from network.
  163. /// </summary>
  164. protected void LoadModelFromURLWithDialogValues()
  165. {
  166. if (string.IsNullOrWhiteSpace(_modelUrl.text))
  167. {
  168. return;
  169. }
  170. var request = AssetDownloader.CreateWebRequest(_modelUrl.text.Trim());
  171. var fileExtension = FileUtils.GetFileExtension(request.uri.Segments[request.uri.Segments.Length - 1], false);
  172. try
  173. {
  174. LoadModelFromURL(request, fileExtension);
  175. }
  176. catch (Exception e)
  177. {
  178. HideModelUrlDialog();
  179. OnError(new ContextualizedError<object>(e, null));
  180. }
  181. }
  182. /// <summary>Event triggered when the user selects a file or cancels the Model selection dialog.</summary>
  183. /// <param name="hasFiles">If any file has been selected, this value is <c>true</c>, otherwise it is <c>false</c>.</param>
  184. protected virtual void OnBeginLoadModel(bool hasFiles)
  185. {
  186. if (hasFiles)
  187. {
  188. if (RootGameObject != null)
  189. {
  190. Destroy(RootGameObject);
  191. }
  192. SetLoading(true);
  193. }
  194. }
  195. /// <summary>
  196. /// Enables/disables the loading flag.
  197. /// </summary>
  198. /// <param name="value">The new loading flag.</param>
  199. protected void SetLoading(bool value)
  200. {
  201. var selectables = FindObjectsOfType<Selectable>();
  202. for (var i = 0; i < selectables.Length; i++)
  203. {
  204. var button = selectables[i];
  205. button.interactable = !value;
  206. }
  207. //#if (UNITY_WEBGL && !TRILIB_ENABLE_WEBGL_THREADS) || (UNITY_WSA && !TRILIB_ENABLE_UWP_THREADS) || TRILIB_FORCE_SYNC
  208. //
  209. //#else
  210. _loadingWrapper.gameObject.SetActive(value);
  211. _loadingBar.gameObject.SetActive(value);
  212. //#endif
  213. _loading = value;
  214. }
  215. /// <summary>
  216. /// Gets a flag indicating whether the model is loading or not.
  217. /// </summary>
  218. /// <returns>The loading flag.</returns>
  219. protected bool IsLoading()
  220. {
  221. return _loading;
  222. }
  223. /// <summary>Checks if the Dispatcher instance exists and stores this class instance as the Singleton.</summary>
  224. protected virtual void Start()
  225. {
  226. Dispatcher.CheckInstance();
  227. PasteManager.CheckInstance();
  228. Instance = this;
  229. }
  230. /// <summary>Event that is triggered when the Model loading progress changes.</summary>
  231. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the Model loading data.</param>
  232. /// <param name="value">The loading progress, ranging from 0 to 1.</param>
  233. protected virtual void OnProgress(AssetLoaderContext assetLoaderContext, float value)
  234. {
  235. _loadingBar.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, Screen.width * value);
  236. }
  237. /// <summary>Event that is triggered when any error occurs.</summary>
  238. /// <param name="contextualizedError">The Contextualized Error that has occurred.</param>
  239. protected virtual void OnError(IContextualizedError contextualizedError)
  240. {
  241. Debug.LogError(contextualizedError);
  242. RootGameObject = null;
  243. SetLoading(false);
  244. }
  245. /// <summary>Event that is triggered when the Model Meshes and hierarchy are loaded.</summary>
  246. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the Model loading data.</param>
  247. protected virtual void OnLoad(AssetLoaderContext assetLoaderContext)
  248. {
  249. }
  250. /// <summary>Event is triggered when the Model (including Textures and Materials) has been fully loaded.</summary>
  251. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the Model loading data.</param>
  252. protected virtual void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
  253. {
  254. SetLoading(false);
  255. }
  256. /// <summary>
  257. /// Plays the selected animation.
  258. /// </summary>
  259. public virtual void PlayAnimation()
  260. {
  261. }
  262. /// <summary>Stops playing the selected animation.</summary>
  263. public virtual void StopAnimation()
  264. {
  265. }
  266. /// <summary>Switches to the animation selected on the Dropdown.</summary>
  267. /// <param name="index">The selected Animation index.</param>
  268. public virtual void PlaybackAnimationChanged(int index)
  269. {
  270. }
  271. /// <summary>
  272. /// Event triggered when the animation slider value has been changed by the user.
  273. /// </summary>
  274. /// <param name="value">The Animation playback normalized position.</param>
  275. public virtual void PlaybackSliderChanged(float value)
  276. {
  277. }
  278. }
  279. }