ImageWebARMenu.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using UnityEngine;
  7. using UnityEditor;
  8. namespace Imagine.WebAR.Editor
  9. {
  10. public class ImageWebARMenu
  11. {
  12. [MenuItem("Assets/Imagine WebAR/Create/Image Target", false, 1010)]
  13. public static void CreateImageTarget()
  14. {
  15. if(Selection.activeObject == null || !(Selection.activeObject is Texture2D)){
  16. EditorUtility.DisplayDialog("No Image Selected", "Please select an image in your project first", "OK");
  17. return;
  18. }
  19. var texture = (Texture2D)Selection.activeObject;
  20. var texturePath = AssetDatabase.GetAssetPath(texture);
  21. Debug.Log(texture.name + ": " + texture.width + "x" + texture.height);
  22. var savePath = EditorUtility.SaveFilePanel("Save Imagetarget Prefab", texturePath, texture.name, "prefab");
  23. var id = Path.GetFileNameWithoutExtension(savePath);
  24. Debug.Log(savePath);
  25. var go = CreateMesh(texture);
  26. go.name = id;
  27. Selection.activeGameObject = go;
  28. var mat = new Material(Shader.Find("Unlit/Texture"));
  29. mat.mainTexture = texture;
  30. var matDir = Application.dataPath + "/Imagine/ImageTracker/Imagetargets/Materials/";
  31. if (!Directory.Exists(matDir))
  32. {
  33. Directory.CreateDirectory(matDir);
  34. }
  35. AssetDatabase.CreateAsset(mat, "Assets/Imagine/ImageTracker/Imagetargets/Materials/" + id + " Material.mat");
  36. var mesh = go.GetComponent<MeshFilter>().sharedMesh;
  37. var meshDir = Application.dataPath + "/Imagine/ImageTracker/Imagetargets/Meshes/";
  38. if (!Directory.Exists(meshDir))
  39. {
  40. Directory.CreateDirectory(meshDir);
  41. }
  42. AssetDatabase.CreateAsset(mesh, "Assets/Imagine/ImageTracker/Imagetargets/Meshes/" + id + " Mesh.asset");
  43. var renderer = go.AddComponent<MeshRenderer>();
  44. renderer.material = mat;
  45. PrefabUtility.SaveAsPrefabAsset(go, savePath);
  46. PrefabUtility.SaveAsPrefabAssetAndConnect(go, savePath, InteractionMode.AutomatedAction);
  47. ImageTrackerGlobalSettings.Instance.imageTargetInfos.Add(new ImageTargetInfo()
  48. {
  49. id = id,
  50. texture = texture
  51. });
  52. EditorUtility.SetDirty(ImageTrackerGlobalSettings.Instance);
  53. var tracker = GameObject.FindObjectOfType<ImageTracker>();
  54. if (tracker != null)
  55. {
  56. var so = new SerializedObject(tracker);
  57. var sp = so.FindProperty("imageTargets");
  58. go.transform.position = new Vector3((sp.arraySize), 0, 0);
  59. go.transform.parent = tracker.transform;
  60. sp.arraySize++;
  61. so.ApplyModifiedProperties();
  62. var obj = sp.GetArrayElementAtIndex(sp.arraySize - 1);
  63. obj.FindPropertyRelative("id").stringValue = id;
  64. obj.FindPropertyRelative("transform").objectReferenceValue = go.transform;
  65. so.ApplyModifiedProperties();
  66. }
  67. }
  68. // [MenuItem("Assets/Imagine WebAR/Create/Image Target", true)]
  69. // static bool ValidateCreateImageTarget()
  70. // {
  71. // var asset = Selection.activeObject;
  72. // return (asset != null && asset is Texture2D);
  73. // }
  74. static GameObject CreateMesh(Texture2D texture)
  75. {
  76. var go = new GameObject();
  77. MeshFilter filter = go.AddComponent<MeshFilter>();
  78. Mesh mesh = new Mesh();
  79. filter.mesh = mesh;
  80. mesh.Clear();
  81. int resX = 2;
  82. int resY = 2;
  83. int actualWidth = 0;
  84. int actualHeight = 0;
  85. GetActualTextureSize(texture, ref actualWidth, ref actualHeight);
  86. if (actualWidth <= 0 || actualWidth <= 0)
  87. {
  88. EditorUtility.DisplayDialog("Failed to create Imagetarget", "Texture width and/or height cannot be zero", "Ok");
  89. throw new System.ArgumentException("Texture width and / or height cannot be zero");
  90. }
  91. float maxSide = Mathf.Max(actualWidth, actualHeight);
  92. float width = (float)actualWidth / maxSide;
  93. float height = (float)actualHeight / maxSide;
  94. Debug.Log("Mesh size = " + height + "x" + width);
  95. Vector3[] vertices = new Vector3[resX * resY];
  96. for (int y = 0; y < resY; y++)
  97. {
  98. float yPos = ((float)y / (resY - 1) - .5f) * height;
  99. for (int x = 0; x < resX; x++)
  100. {
  101. float xPos = ((float)x / (resX - 1) - .5f) * width;
  102. vertices[x + y * resX] = new Vector3(xPos, yPos, 0f);
  103. }
  104. }
  105. Vector3[] normals = new Vector3[vertices.Length];
  106. for (int n = 0; n < normals.Length; n++)
  107. normals[n] = Vector3.up;
  108. Vector2[] uvs = new Vector2[vertices.Length];
  109. for (int v = 0; v < resY; v++)
  110. {
  111. for (int u = 0; u < resX; u++)
  112. {
  113. uvs[u + v * resX] = new Vector2((float)u / (resX - 1), (float)v / (resY - 1));
  114. }
  115. }
  116. int nbFaces = (resX - 1) * (resY - 1);
  117. int[] triangles = new int[nbFaces * 6];
  118. int t = 0;
  119. for (int face = 0; face < nbFaces; face++)
  120. {
  121. int i = face % (resX - 1) + (face / (resY - 1) * resX);
  122. triangles[t++] = i + resX;
  123. triangles[t++] = i + 1;
  124. triangles[t++] = i;
  125. triangles[t++] = i + resX;
  126. triangles[t++] = i + resX + 1;
  127. triangles[t++] = i + 1;
  128. }
  129. mesh.vertices = vertices;
  130. mesh.normals = normals;
  131. mesh.uv = uvs;
  132. mesh.triangles = triangles;
  133. mesh.RecalculateBounds();
  134. return go;
  135. }
  136. private delegate void GetWidthAndHeight(TextureImporter importer, ref int width, ref int height);
  137. private static GetWidthAndHeight getWidthAndHeightDelegate;
  138. public static void GetActualTextureSize(Texture2D texture, ref int width, ref int height)
  139. {
  140. if (texture == null)
  141. throw new System.NullReferenceException();
  142. var path = AssetDatabase.GetAssetPath(texture);
  143. if (string.IsNullOrEmpty(path))
  144. throw new System.Exception("Texture2D is not an asset texture.");
  145. var importer = AssetImporter.GetAtPath(path) as TextureImporter;
  146. if (importer == null)
  147. throw new System.Exception("Failed to get Texture importer for " + path);
  148. if (getWidthAndHeightDelegate == null)
  149. {
  150. var method = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
  151. getWidthAndHeightDelegate = System.Delegate.CreateDelegate(typeof(GetWidthAndHeight), null, method) as GetWidthAndHeight;
  152. }
  153. getWidthAndHeightDelegate(importer, ref width, ref height);
  154. }
  155. [MenuItem("Assets/Imagine WebAR/Create/Image Tracker", false, 1100)]
  156. public static void CreateImageTracker()
  157. {
  158. GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Imagine/ImageTracker/Prefabs/ImageTracker.prefab");
  159. GameObject gameObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
  160. PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
  161. Selection.activeGameObject = gameObject;
  162. gameObject.name = "ImageTracker";
  163. }
  164. [MenuItem("Assets/Imagine WebAR/Create/AR Camera", false, 1120)]
  165. public static void CreateImageTrackerCamera()
  166. {
  167. GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Imagine/Common/Prefabs/ARCamera.prefab");
  168. GameObject gameObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
  169. PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
  170. Selection.activeGameObject = gameObject;
  171. gameObject.name = "ARCamera";
  172. }
  173. [MenuItem("Assets/Imagine WebAR/Update Plugin to URP", false, 1200)]
  174. public static void SetURP()
  175. {
  176. if (EditorUtility.DisplayDialog(
  177. "Update Imagine WebAR Plugin to URP",
  178. "Please make sure that the Universal RP package is already installed before doing this step.",
  179. "Proceed",
  180. "Cancel"))
  181. {
  182. string[] files = Directory.GetFiles(Application.dataPath + "/Imagine/ImageTracker/Demos/Materials", "*.mat", SearchOption.TopDirectoryOnly);
  183. foreach (var file in files)
  184. {
  185. var path = file.Replace(Application.dataPath, "Assets");
  186. var mat = AssetDatabase.LoadAssetAtPath<Material>(path);
  187. if (mat.shader.name == "Standard")
  188. {
  189. mat.shader = Shader.Find("Universal Render Pipeline/Lit");
  190. }
  191. else if (mat.shader.name == "Imagine/ARShadow")
  192. {
  193. mat.shader = Shader.Find("Imagine/ARShadowURP");
  194. }
  195. }
  196. AddDefineSymbol("IMAGINE_URP");
  197. EditorUtility.DisplayDialog("Completed", "Imagine WebAR Plugin is now set to URP. \n\nSome URP features such as HDR and Post-Processing may be partially/fully unsupported.", "Ok");
  198. }
  199. }
  200. [MenuItem("Assets/Imagine WebAR/Roll-back Plugin to Built-In RP", false, 1201)]
  201. public static void SetBuiltInRP ()
  202. {
  203. if (EditorUtility.DisplayDialog(
  204. "Roll-back Imagine WebAR Plugin to Built-In RP",
  205. "Plese confirm.",
  206. "Proceed",
  207. "Cancel"))
  208. {
  209. string[] files = Directory.GetFiles(Application.dataPath + "/Imagine/ImageTracker/Demos/Materials", "*.mat", SearchOption.TopDirectoryOnly);
  210. foreach (var file in files)
  211. {
  212. var path = file.Replace(Application.dataPath, "Assets");
  213. var mat = AssetDatabase.LoadAssetAtPath<Material>(path);
  214. if (mat.shader.name == "Universal Render Pipeline/Lit" || mat.shader.name == "Hidden/InternalErrorShader")
  215. {
  216. mat.shader = Shader.Find("Standard");
  217. }
  218. else if (mat.shader.name == "Imagine/ARShadowURP")
  219. {
  220. mat.shader = Shader.Find("Imagine/ARShadow");
  221. }
  222. }
  223. RemoveDefineSymbol("IMAGINE_URP");
  224. EditorUtility.DisplayDialog("Completed", "Imagine WebAR Plugin is now set to Built-In RP. Some edited materials may still require manual shader change","Ok");
  225. }
  226. }
  227. public static void AddDefineSymbol(string symbol)
  228. {
  229. string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
  230. List<string> allDefines = definesString.Split(';').ToList();
  231. if (!allDefines.Contains(symbol))
  232. allDefines.Add(symbol);
  233. PlayerSettings.SetScriptingDefineSymbolsForGroup(
  234. EditorUserBuildSettings.selectedBuildTargetGroup,
  235. string.Join(";", allDefines.ToArray()));
  236. AssetDatabase.RefreshSettings();
  237. }
  238. public static void RemoveDefineSymbol(string symbol)
  239. {
  240. string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
  241. List<string> allDefines = definesString.Split(';').ToList();
  242. allDefines.RemoveAll(s => s == symbol);
  243. PlayerSettings.SetScriptingDefineSymbolsForGroup(
  244. EditorUserBuildSettings.selectedBuildTargetGroup,
  245. string.Join(";", allDefines.ToArray()));
  246. AssetDatabase.RefreshSettings();
  247. }
  248. }
  249. }