DynamicLibrary.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using QFramework;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. using Unity.Jobs;
  7. using UnityEditor;
  8. using UnityEngine;
  9. using UnityEngine.XR.ARFoundation;
  10. using UnityEngine.XR.ARSubsystems;
  11. namespace UnityEngine.XR.ARFoundation.Samples
  12. {
  13. /// <summary>
  14. /// Adds images to the reference library at runtime.
  15. /// </summary>
  16. [RequireComponent(typeof(ARTrackedImageManager))]
  17. public class DynamicLibrary : MonoSingleton<DynamicLibrary>
  18. {
  19. [Serializable]
  20. public class ImageData
  21. {
  22. [SerializeField, Tooltip("The source texture for the image. Must be marked as readable.")]
  23. Texture2D m_Texture;
  24. public Texture2D texture
  25. {
  26. get => m_Texture;
  27. set => m_Texture = value;
  28. }
  29. [SerializeField, Tooltip("The name for this image.")]
  30. string m_Name;
  31. public string name
  32. {
  33. get => m_Name;
  34. set => m_Name = value;
  35. }
  36. [SerializeField, Tooltip("The width, in meters, of the image in the real world.")]
  37. float m_Width;
  38. public float width
  39. {
  40. get => m_Width;
  41. set => m_Width = value;
  42. }
  43. public AddReferenceImageJobState jobState { get; set; }
  44. }
  45. [SerializeField, Tooltip("The set of images to add to the image library at runtime")]
  46. ImageData[] m_Images;
  47. /// <summary>
  48. /// The set of images to add to the image library at runtime
  49. /// </summary>
  50. public ImageData[] images
  51. {
  52. get => m_Images;
  53. set => m_Images = value;
  54. }
  55. enum State
  56. {
  57. NoImagesAdded,
  58. AddImagesRequested,
  59. AddingImages,
  60. Done,
  61. Error
  62. }
  63. State m_State;
  64. string m_ErrorMessage = "";
  65. StringBuilder m_StringBuilder = new StringBuilder();
  66. private void Start()
  67. {
  68. //var pathName = Application.persistentDataPath + "/3.jpg";
  69. //Debug.Log(pathName);
  70. //var bytes = ReadFile(pathName);
  71. //int width = Screen.width;
  72. //int height = Screen.height;
  73. //Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
  74. //texture.LoadImage(bytes);
  75. //texture = SettingTexture(texture);
  76. //ImageData data = new ImageData();
  77. //data.texture = texture;
  78. //data.name = "3Test";
  79. //data.width = 0.5f;
  80. //m_Images[0] = data;
  81. manager = GetComponent<ARTrackedImageManager>();
  82. }
  83. public void AddImageTracked(List<string> list_SavePath)
  84. {
  85. m_Images = new ImageData[list_SavePath.Count];
  86. for (int i = 0; i < list_SavePath.Count; i++)
  87. {
  88. int width = Screen.width;
  89. int height = Screen.height;
  90. var bytes = ReadFile(list_SavePath[i]);
  91. Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
  92. texture.LoadImage(bytes);
  93. texture = SettingTexture(texture);
  94. ImageData data = new ImageData();
  95. data.texture = texture;
  96. data.name = i.ToString();
  97. data.width = 0.5f;
  98. m_Images[i] = data;
  99. }
  100. m_State = State.AddImagesRequested;
  101. }
  102. public void AddImageTracked(List<string> list_SavePath,Dictionary<string,Sprite>dicImageTracked)
  103. {
  104. m_Images = new ImageData[list_SavePath.Count];
  105. Debug.Log(list_SavePath.Count +" "+ dicImageTracked.Count);
  106. for (int i = 0; i < list_SavePath.Count; i++)
  107. {
  108. Debug.Log("SavePath "+list_SavePath[i]);
  109. }
  110. foreach (var item in dicImageTracked)
  111. {
  112. Debug.Log(item.Key);
  113. }
  114. for (int i = 0; i < list_SavePath.Count; i++)
  115. {
  116. if (dicImageTracked.ContainsKey(list_SavePath[i]))
  117. {
  118. int width = dicImageTracked[list_SavePath[i]].texture.width;
  119. int height = dicImageTracked[list_SavePath[i]].texture.height;
  120. var bytes = dicImageTracked[list_SavePath[i]].texture.EncodeToPNG();
  121. Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
  122. texture.LoadImage(bytes);
  123. texture = SettingTexture(texture);
  124. ImageData data = new ImageData();
  125. data.texture = texture;
  126. data.name = i.ToString();
  127. data.width = 0.5f;
  128. m_Images[i] = data;
  129. }
  130. else
  131. Debug.LogError("Image Not SavePath");
  132. }
  133. m_State = State.AddImagesRequested;
  134. }
  135. byte[] ReadFile(string filePath)
  136. {
  137. var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  138. fs.Seek(0, SeekOrigin.Begin);
  139. var binary = new byte[fs.Length];
  140. fs.Read(binary, 0, binary.Length);
  141. fs.Close();
  142. return binary;
  143. }
  144. void OnGUI()
  145. {
  146. var fontSize = 50;
  147. GUI.skin.button.fontSize = fontSize;
  148. GUI.skin.label.fontSize = fontSize;
  149. float margin = 100;
  150. GUILayout.BeginArea(new Rect(margin, margin, Screen.width - margin * 2, Screen.height - margin * 2));
  151. switch (m_State)
  152. {
  153. case State.NoImagesAdded:
  154. {
  155. //if (GUILayout.Button("Add images" + manager.trackables.count))
  156. //{
  157. // m_State = State.AddImagesRequested;
  158. //}
  159. break;
  160. }
  161. case State.AddingImages:
  162. {
  163. m_StringBuilder.Clear();
  164. m_StringBuilder.AppendLine("Add image status:");
  165. foreach (var image in m_Images)
  166. {
  167. m_StringBuilder.AppendLine($"\t{image.name}: {(image.jobState.status.ToString())}");
  168. }
  169. // GUILayout.Label(m_StringBuilder.ToString());
  170. break;
  171. }
  172. case State.Done:
  173. {
  174. // GUILayout.Label("All images added " + manager.trackables.count);
  175. break;
  176. }
  177. case State.Error:
  178. {
  179. GUILayout.Label(m_ErrorMessage);
  180. break;
  181. }
  182. }
  183. GUILayout.EndArea();
  184. }
  185. void SetError(string errorMessage)
  186. {
  187. m_State = State.Error;
  188. m_ErrorMessage = $"Error: {errorMessage}";
  189. }
  190. ARTrackedImageManager manager;
  191. void Update()
  192. {
  193. switch (m_State)
  194. {
  195. case State.AddImagesRequested:
  196. {
  197. if (m_Images == null)
  198. {
  199. SetError("No images to add.");
  200. break;
  201. }
  202. manager = GetComponent<ARTrackedImageManager>();
  203. if (manager == null)
  204. {
  205. SetError($"No {nameof(ARTrackedImageManager)} available.");
  206. break;
  207. }
  208. // You can either add raw image bytes or use the extension method (used below) which accepts
  209. // a texture. To use a texture, however, its import settings must have enabled read/write
  210. // access to the texture.
  211. for (int i = 0; i < m_Images.Length; i++)
  212. {
  213. if (!m_Images[i].texture.isReadable)
  214. {
  215. Texture2D tex = SettingTexture(m_Images[i].texture);
  216. m_Images[i].texture = tex;
  217. }
  218. }
  219. foreach (var image in m_Images)
  220. {
  221. if (!image.texture.isReadable)
  222. {
  223. SetError($"Image {image.name} must be readable to be added to the image library.");
  224. break;
  225. }
  226. // else
  227. // Debug.LogError(" IsReadable = true "+image.name);
  228. }
  229. if (manager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)
  230. {
  231. try
  232. {
  233. foreach (var image in m_Images)
  234. {
  235. // Note: You do not need to do anything with the returned JobHandle, but it can be
  236. // useful if you want to know when the image has been added to the library since it may
  237. // take several frames.
  238. image.jobState = mutableLibrary.ScheduleAddImageWithValidationJob(image.texture, image.name, image.width);
  239. }
  240. m_State = State.AddingImages;
  241. }
  242. catch (InvalidOperationException e)
  243. {
  244. SetError($"ScheduleAddImageJob threw exception: {e.Message}");
  245. }
  246. }
  247. else
  248. {
  249. SetError($"The reference image library is not mutable.");
  250. }
  251. break;
  252. }
  253. case State.AddingImages:
  254. {
  255. // Check for completion
  256. var done = true;
  257. foreach (var image in m_Images)
  258. {
  259. if (!image.jobState.jobHandle.IsCompleted)
  260. {
  261. done = false;
  262. break;
  263. }
  264. }
  265. if (done)
  266. {
  267. m_State = State.Done;
  268. GameManager.Instance.finish = true;
  269. }
  270. break;
  271. }
  272. }
  273. }
  274. Texture2D SettingTexture( Texture2D texture)
  275. {
  276. //TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));
  277. //ti.isReadable = true;
  278. //AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(texture));
  279. Texture2D tex = new Texture2D(texture.width, texture.height, TextureFormat.RGB24,false);
  280. byte[] data = texture.EncodeToPNG();
  281. tex.LoadImage(data);
  282. Debug.Log(tex.isReadable);
  283. return tex;
  284. }
  285. }
  286. }