No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TextureImporterDataProvider.cs 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace UnityEditor.U2D.Sprites
  6. {
  7. internal class TextureImporterDataProviderFactory :
  8. ISpriteDataProviderFactory<Texture2D>,
  9. ISpriteDataProviderFactory<Sprite>,
  10. ISpriteDataProviderFactory<TextureImporter>,
  11. ISpriteDataProviderFactory<GameObject>
  12. {
  13. public ISpriteEditorDataProvider CreateDataProvider(Texture2D obj)
  14. {
  15. var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(obj)) as TextureImporter;
  16. if (ti != null)
  17. return new TextureImporterDataProvider(ti);
  18. return null;
  19. }
  20. public ISpriteEditorDataProvider CreateDataProvider(Sprite obj)
  21. {
  22. var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(obj)) as TextureImporter;
  23. if (ti != null)
  24. return new TextureImporterDataProvider(ti);
  25. return null;
  26. }
  27. public ISpriteEditorDataProvider CreateDataProvider(GameObject obj)
  28. {
  29. var spriteRenderer = obj.GetComponent<SpriteRenderer>();
  30. if (spriteRenderer != null && spriteRenderer.sprite != null)
  31. {
  32. var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spriteRenderer.sprite)) as TextureImporter;
  33. if (ti != null)
  34. return new TextureImporterDataProvider(ti);
  35. }
  36. return null;
  37. }
  38. public ISpriteEditorDataProvider CreateDataProvider(TextureImporter obj)
  39. {
  40. return new TextureImporterDataProvider(obj);
  41. }
  42. [SpriteEditorAssetPathProviderAttribute]
  43. static string GetAssetPathFromSpriteRenderer(UnityEngine.Object obj)
  44. {
  45. var go = obj as GameObject;
  46. if (go != null)
  47. {
  48. var spriteRenderer = go.GetComponent<SpriteRenderer>();
  49. if (spriteRenderer != null && spriteRenderer.sprite != null)
  50. return AssetDatabase.GetAssetPath(spriteRenderer.sprite);
  51. }
  52. return null;
  53. }
  54. [SpriteObjectProvider]
  55. static Sprite GetSpriteObjectFromSpriteRenderer(UnityEngine.Object obj)
  56. {
  57. var go = obj as GameObject;
  58. if (go != null)
  59. {
  60. var spriteRenderer = go.GetComponent<SpriteRenderer>();
  61. if (spriteRenderer != null)
  62. return spriteRenderer.sprite;
  63. }
  64. return null;
  65. }
  66. }
  67. internal class TextureImporterDataProvider : ISpriteEditorDataProvider, ISpriteNameFileIdDataProvider
  68. {
  69. TextureImporter m_TextureImporter;
  70. SpriteNameFileIdPairExt[] m_NameFileIdPairs;
  71. List<SpriteDataExt> m_SpritesMultiple;
  72. SpriteDataExt m_SpriteSingle;
  73. Dictionary<string, string> m_CustomMetadata;
  74. SpriteImportMode m_SpriteImportMode = SpriteImportMode.None;
  75. SecondarySpriteTexture[] m_SecondaryTextureDataTransfer;
  76. SerializedObject m_CachedSerializedObject;
  77. internal TextureImporterDataProvider(TextureImporter importer)
  78. {
  79. m_TextureImporter = importer;
  80. if (m_TextureImporter != null)
  81. {
  82. m_SpriteImportMode = m_TextureImporter.spriteImportMode;
  83. m_CachedSerializedObject = new SerializedObject(m_TextureImporter);
  84. }
  85. }
  86. public Dictionary<string, string> customMetadata => m_CustomMetadata;
  87. float ISpriteEditorDataProvider.pixelsPerUnit
  88. {
  89. get { return m_TextureImporter.spritePixelsPerUnit; }
  90. }
  91. UnityEngine.Object ISpriteEditorDataProvider.targetObject
  92. {
  93. get { return m_TextureImporter; }
  94. }
  95. public SpriteImportMode spriteImportMode
  96. {
  97. get { return m_SpriteImportMode; }
  98. }
  99. SpriteRect[] ISpriteEditorDataProvider.GetSpriteRects()
  100. {
  101. return spriteImportMode == SpriteImportMode.Multiple ? m_SpritesMultiple.Select(x => new SpriteDataExt(x) as SpriteRect).ToArray() : new[] { new SpriteDataExt(m_SpriteSingle) };
  102. }
  103. public SerializedObject GetSerializedObject()
  104. {
  105. m_CachedSerializedObject?.UpdateIfRequiredOrScript();
  106. return m_CachedSerializedObject;
  107. }
  108. public string assetPath
  109. {
  110. get { return m_TextureImporter.assetPath; }
  111. }
  112. public void GetWidthAndHeight(ref int width, ref int height)
  113. {
  114. m_TextureImporter.GetWidthAndHeight(ref width, ref height);
  115. }
  116. void ISpriteEditorDataProvider.SetSpriteRects(SpriteRect[] spriteRects)
  117. {
  118. if (spriteImportMode != SpriteImportMode.Multiple && spriteImportMode != SpriteImportMode.None && spriteRects.Length == 1)
  119. {
  120. m_SpriteSingle.CopyFromSpriteRect(spriteRects[0]);
  121. }
  122. else if (spriteImportMode == SpriteImportMode.Multiple)
  123. {
  124. Dictionary<GUID, SpriteRect> newSprites = new Dictionary<GUID, SpriteRect>();
  125. foreach (var newSprite in spriteRects)
  126. {
  127. newSprites.Add(newSprite.spriteID, newSprite);
  128. }
  129. HashSet<long> internalIdUsed = new HashSet<long>();
  130. for (int i = m_SpritesMultiple.Count - 1; i >= 0; --i)
  131. {
  132. var spriteID = m_SpritesMultiple[i].spriteID;
  133. if (newSprites.TryGetValue(spriteID, out SpriteRect smd))
  134. {
  135. m_SpritesMultiple[i].CopyFromSpriteRect(smd);
  136. internalIdUsed.Add(m_SpritesMultiple[i].internalID);
  137. newSprites.Remove(spriteID);
  138. }
  139. else
  140. {
  141. m_SpritesMultiple.RemoveAt(i);
  142. }
  143. }
  144. // Add new ones
  145. var nameIdTable = GetSerializedNameFileIdTable(GetSerializedObject());
  146. // First pass map by id
  147. var values = newSprites.Values.ToArray();
  148. foreach (var newSprite in values)
  149. {
  150. var newSpriteRect = new SpriteDataExt(newSprite);
  151. var nameIdPair = nameIdTable.FirstOrDefault(x => x.GetFileGUID() == newSprite.spriteID);
  152. if (nameIdPair != null && !internalIdUsed.Contains(nameIdPair.internalID))
  153. {
  154. newSpriteRect.internalID = nameIdPair.internalID;
  155. internalIdUsed.Add(nameIdPair.internalID);
  156. m_SpritesMultiple.Add(newSpriteRect);
  157. newSprites.Remove(newSprite.spriteID);
  158. }
  159. }
  160. //Second pass map by name
  161. foreach (var newSprite in newSprites.Values)
  162. {
  163. var newSpriteRect = new SpriteDataExt(newSprite);
  164. var nameIdPair = nameIdTable.FirstOrDefault(x => x.name == newSprite.name);
  165. if (nameIdPair != null && !internalIdUsed.Contains(nameIdPair.internalID))
  166. newSpriteRect.internalID = nameIdPair.internalID;
  167. internalIdUsed.Add(newSpriteRect.internalID);
  168. m_SpritesMultiple.Add(newSpriteRect);
  169. }
  170. }
  171. }
  172. IEnumerable<SpriteNameFileIdPair> ISpriteNameFileIdDataProvider.GetNameFileIdPairs()
  173. {
  174. return m_NameFileIdPairs.ToArray<SpriteNameFileIdPair>();
  175. }
  176. void ISpriteNameFileIdDataProvider.SetNameFileIdPairs(IEnumerable<SpriteNameFileIdPair> pairs)
  177. {
  178. var newFileIdPair = new SpriteNameFileIdPairExt[pairs.Count()];
  179. var count = 0;
  180. foreach (var pair in pairs)
  181. {
  182. var guid = pair.GetFileGUID();
  183. var internalId = (long)guid.GetHashCode();
  184. //check if guid is in current name id table
  185. var idPair = m_NameFileIdPairs.FirstOrDefault(x => x.GetFileGUID() == guid);
  186. if (idPair != null)
  187. internalId = idPair.internalID;
  188. else
  189. {
  190. // check if guid is in current sprite list
  191. var sr = m_SpritesMultiple.FirstOrDefault(x => x.spriteID == guid);
  192. if (sr != null)
  193. internalId = sr.internalID;
  194. }
  195. newFileIdPair[count] = new SpriteNameFileIdPairExt(pair.name, guid, internalId);
  196. count++;
  197. }
  198. m_NameFileIdPairs = newFileIdPair;
  199. }
  200. internal SpriteRect GetSpriteData(GUID guid)
  201. {
  202. return spriteImportMode == SpriteImportMode.Multiple ? m_SpritesMultiple.FirstOrDefault(x => x.spriteID == guid) : m_SpriteSingle;
  203. }
  204. internal int GetSpriteDataIndex(GUID guid)
  205. {
  206. switch (spriteImportMode)
  207. {
  208. case SpriteImportMode.Single:
  209. case SpriteImportMode.Polygon:
  210. return 0;
  211. case SpriteImportMode.Multiple:
  212. {
  213. return m_SpritesMultiple.FindIndex(x => x.spriteID == guid);
  214. }
  215. default:
  216. throw new InvalidOperationException(string.Format("Sprite with GUID {0} not found", guid));
  217. }
  218. }
  219. void ISpriteEditorDataProvider.Apply()
  220. {
  221. var so = GetSerializedObject();
  222. m_SpriteSingle.Apply(so);
  223. var spriteSheet = so.FindProperty("m_SpriteSheet");
  224. var spriteSheetSprites = spriteSheet.FindPropertyRelative("m_Sprites");
  225. Dictionary<GUID, SpriteDataExt> newSprites = new Dictionary<GUID, SpriteDataExt>();
  226. foreach (var newSprite in m_SpritesMultiple)
  227. {
  228. newSprites.Add(newSprite.spriteID, newSprite);
  229. }
  230. if (spriteSheetSprites.arraySize > 0)
  231. {
  232. var validateCurrent = spriteSheetSprites.GetArrayElementAtIndex(0);
  233. for (int i = 0; i < spriteSheetSprites.arraySize; ++i)
  234. {
  235. var guid = SpriteRect.GetSpriteIDFromSerializedProperty(validateCurrent);
  236. // find the GUID in our sprite list and apply to it;
  237. if (newSprites.TryGetValue(guid, out SpriteDataExt smd))
  238. {
  239. smd.Apply(validateCurrent);
  240. newSprites.Remove(guid);
  241. validateCurrent.Next(false);
  242. }
  243. else// we can't find it, it is already deleted
  244. {
  245. spriteSheetSprites.DeleteArrayElementAtIndex(i);
  246. --i;
  247. }
  248. }
  249. }
  250. // Add new ones
  251. int newCount = newSprites.Count();
  252. if (newCount > 0)
  253. {
  254. var idx = spriteSheetSprites.arraySize;
  255. spriteSheetSprites.arraySize += newCount;
  256. var addCurrent = spriteSheetSprites.GetArrayElementAtIndex(idx);
  257. foreach (var newSprite in newSprites.Values)
  258. {
  259. newSprite.Apply(addCurrent);
  260. addCurrent.Next(false);
  261. }
  262. }
  263. var noOfPairs = m_NameFileIdPairs.Length;
  264. var pairsSo = spriteSheet.FindPropertyRelative("m_NameFileIdTable");
  265. pairsSo.arraySize = noOfPairs;
  266. if (noOfPairs > 0)
  267. {
  268. var element = pairsSo.GetArrayElementAtIndex(0);
  269. foreach (var pair in m_NameFileIdPairs)
  270. {
  271. pair.Apply(element);
  272. element.Next(false);
  273. }
  274. }
  275. SpriteSecondaryTextureDataTransfer.Apply(so, m_SecondaryTextureDataTransfer);
  276. SpriteCustomDataTransfer.Apply(spriteSheet, m_CustomMetadata);
  277. so.ApplyModifiedPropertiesWithoutUndo();
  278. }
  279. void ISpriteEditorDataProvider.InitSpriteEditorDataProvider()
  280. {
  281. var so = GetSerializedObject();
  282. var spriteSheet = so.FindProperty("m_SpriteSheet");
  283. var spriteSheetSprites = spriteSheet.FindPropertyRelative("m_Sprites");
  284. m_SpritesMultiple = new List<SpriteDataExt>();
  285. m_SpriteSingle = new SpriteDataExt(so);
  286. if (spriteSheetSprites.arraySize > 0)
  287. {
  288. var sp = spriteSheetSprites.GetArrayElementAtIndex(0);
  289. for (var i = 0; i < spriteSheetSprites.arraySize; ++i)
  290. {
  291. var data = new SpriteDataExt(sp);
  292. m_SpritesMultiple.Add(data);
  293. sp.Next(false);
  294. }
  295. }
  296. m_SecondaryTextureDataTransfer = SpriteSecondaryTextureDataTransfer.Load(so);
  297. m_CustomMetadata = SpriteCustomDataTransfer.Load(spriteSheet);
  298. m_NameFileIdPairs = GetSerializedNameFileIdTable(so);
  299. }
  300. SpriteNameFileIdPairExt[] GetSerializedNameFileIdTable(SerializedObject so)
  301. {
  302. var nameFileIdTableSo = so.FindProperty("m_SpriteSheet.m_NameFileIdTable");
  303. var arraySize = nameFileIdTableSo.arraySize;
  304. var nameFileIdPairs = new SpriteNameFileIdPairExt[arraySize];
  305. if (nameFileIdPairs.Length > 0)
  306. {
  307. var sp = nameFileIdTableSo.GetArrayElementAtIndex(0);
  308. for (var i = 0; i < nameFileIdTableSo.arraySize; ++i)
  309. {
  310. var spriteNameFileId = SpriteNameFileIdPairExt.GetValue(sp);
  311. // check if this internal nid is already in one of the sprite.
  312. // We don't check name as changing internal id can cause reference to be lost
  313. var spriteRect = m_SpritesMultiple.FirstOrDefault(x => x.internalID == spriteNameFileId.internalID);
  314. if (spriteRect != null)
  315. spriteNameFileId.SetFileGUID(spriteRect.spriteID);
  316. nameFileIdPairs[i] = spriteNameFileId;
  317. sp.Next(false);
  318. }
  319. }
  320. return nameFileIdPairs;
  321. }
  322. T ISpriteEditorDataProvider.GetDataProvider<T>()
  323. {
  324. if (typeof(T) == typeof(ISpriteBoneDataProvider))
  325. {
  326. return new SpriteBoneDataTransfer(this) as T;
  327. }
  328. if (typeof(T) == typeof(ISpriteMeshDataProvider))
  329. {
  330. return new SpriteMeshDataTransfer(this) as T;
  331. }
  332. if (typeof(T) == typeof(ISpriteOutlineDataProvider))
  333. {
  334. return new SpriteOutlineDataTransfer(this) as T;
  335. }
  336. if (typeof(T) == typeof(ISpritePhysicsOutlineDataProvider))
  337. {
  338. return new SpritePhysicsOutlineDataTransfer(this) as T;
  339. }
  340. if (typeof(T) == typeof(ITextureDataProvider))
  341. {
  342. return new SpriteTextureDataTransfer(this) as T;
  343. }
  344. if (typeof(T) == typeof(ISecondaryTextureDataProvider))
  345. {
  346. return new SpriteSecondaryTextureDataTransfer(this) as T;
  347. }
  348. if (typeof(T) == typeof(ISpriteCustomDataProvider))
  349. {
  350. return new SpriteCustomDataTransfer(this) as T;
  351. }
  352. else
  353. return this as T;
  354. }
  355. bool ISpriteEditorDataProvider.HasDataProvider(Type type)
  356. {
  357. if (type == typeof(ISpriteBoneDataProvider) ||
  358. type == typeof(ISpriteMeshDataProvider) ||
  359. type == typeof(ISpriteOutlineDataProvider) ||
  360. type == typeof(ISpritePhysicsOutlineDataProvider) ||
  361. type == typeof(ITextureDataProvider) ||
  362. type == typeof(ISecondaryTextureDataProvider) ||
  363. type == typeof(ISpriteCustomDataProvider))
  364. {
  365. return true;
  366. }
  367. else
  368. return type.IsAssignableFrom(GetType());
  369. }
  370. public override bool Equals(object a)
  371. {
  372. return this == (a as TextureImporterDataProvider);
  373. }
  374. public override int GetHashCode()
  375. {
  376. return base.GetHashCode();
  377. }
  378. public static bool operator!=(TextureImporterDataProvider t1, TextureImporterDataProvider t2)
  379. {
  380. return !(t1 == t2);
  381. }
  382. public static bool operator==(TextureImporterDataProvider t1, TextureImporterDataProvider t2)
  383. {
  384. if (ReferenceEquals(null, t1) && (!ReferenceEquals(null, t2) && t2.m_TextureImporter == null) ||
  385. ReferenceEquals(null, t2) && (!ReferenceEquals(null, t1) && t1.m_TextureImporter == null))
  386. return true;
  387. if (!ReferenceEquals(null, t1) && !ReferenceEquals(null, t2))
  388. {
  389. if (t1.m_TextureImporter == null && t2.m_TextureImporter == null ||
  390. t1.m_TextureImporter == t2.m_TextureImporter)
  391. return true;
  392. }
  393. if (ReferenceEquals(t1, t2))
  394. return true;
  395. return false;
  396. }
  397. public SecondarySpriteTexture[] secondaryTextures
  398. {
  399. get { return m_SecondaryTextureDataTransfer; }
  400. set { m_SecondaryTextureDataTransfer = value; }
  401. }
  402. }
  403. }