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

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