PaletteManager.cs 93 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378
  1. /*
  2. Copyright (c) 2020 Omar Duarte
  3. Unauthorized copying of this file, via any medium is strictly prohibited.
  4. Writen by Omar Duarte, 2020.
  5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  9. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  10. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  11. THE SOFTWARE.
  12. */
  13. using System.Linq;
  14. using UnityEngine;
  15. namespace PluginMaster
  16. {
  17. #region BRUSH SETTINGS
  18. [System.Serializable]
  19. public class BrushSettings : ISerializationCallbackReceiver
  20. {
  21. [SerializeField] private long _id = -1;
  22. [SerializeField] private float _surfaceDistance = 0f;
  23. [SerializeField] private bool _randomSurfaceDistance = false;
  24. [SerializeField] private RandomUtils.Range _randomSurfaceDistanceRange = new RandomUtils.Range(-0.005f, 0.005f);
  25. [SerializeField] protected bool _embedInSurface = false;
  26. [SerializeField] protected bool _embedAtPivotHeight = true;
  27. [SerializeField] protected Vector3 _localPositionOffset = Vector3.zero;
  28. [SerializeField] private bool _rotateToTheSurface = true;
  29. [SerializeField] private Vector3 _eulerOffset = Vector3.zero;
  30. [SerializeField] private bool _addRandomRotation = false;
  31. [SerializeField] private float _rotationFactor = 90;
  32. [SerializeField] private bool _rotateInMultiples = false;
  33. [SerializeField]
  34. private RandomUtils.Range3 _randomEulerOffset = new RandomUtils.Range3(Vector3.zero, Vector3.zero);
  35. [SerializeField] private bool _alwaysOrientUp = false;
  36. [SerializeField] private bool _separateScaleAxes = false;
  37. [SerializeField] private Vector3 _scaleMultiplier = Vector3.one;
  38. [SerializeField] private bool _randomScaleMultiplier = false;
  39. [SerializeField]
  40. private RandomUtils.Range3 _randomScaleMultiplierRange = new RandomUtils.Range3(Vector3.one, Vector3.one);
  41. public enum FlipAction { NONE, FLIP, RANDOM }
  42. [SerializeField] private FlipAction _flipX = FlipAction.NONE;
  43. [SerializeField] private FlipAction _flipY = FlipAction.NONE;
  44. [SerializeField] private ThumbnailSettings _thumbnailSettings = new ThumbnailSettings();
  45. [field: System.NonSerialized] private Texture2D _thumbnail = null;
  46. public System.Action OnDataChangedAction;
  47. public static System.Action OnBrushSettingsChanged;
  48. protected virtual void OnDataChanged()
  49. {
  50. if (OnDataChangedAction != null) OnDataChangedAction();
  51. if (OnBrushSettingsChanged != null) OnBrushSettingsChanged();
  52. }
  53. public long id => _id;
  54. public virtual float surfaceDistance
  55. {
  56. get => _surfaceDistance;
  57. set
  58. {
  59. if (_surfaceDistance == value) return;
  60. _surfaceDistance = value;
  61. OnDataChanged();
  62. }
  63. }
  64. public virtual bool randomSurfaceDistance
  65. {
  66. get => _randomSurfaceDistance;
  67. set
  68. {
  69. if (_randomSurfaceDistance == value) return;
  70. _randomSurfaceDistance = value;
  71. OnDataChanged();
  72. }
  73. }
  74. public virtual RandomUtils.Range randomSurfaceDistanceRange
  75. {
  76. get => _randomSurfaceDistanceRange;
  77. set
  78. {
  79. if (_randomSurfaceDistanceRange == value) return;
  80. _randomSurfaceDistanceRange = value;
  81. OnDataChanged();
  82. }
  83. }
  84. public virtual bool embedInSurface
  85. {
  86. get => _embedInSurface;
  87. set
  88. {
  89. if (_embedInSurface == value) return;
  90. _embedInSurface = value;
  91. OnDataChanged();
  92. }
  93. }
  94. public virtual bool embedAtPivotHeight
  95. {
  96. get => _embedAtPivotHeight;
  97. set
  98. {
  99. if (_embedAtPivotHeight == value) return;
  100. _embedAtPivotHeight = value;
  101. OnDataChanged();
  102. }
  103. }
  104. public virtual void UpdateBottomVertices() { }
  105. public virtual Vector3 localPositionOffset
  106. {
  107. get => _localPositionOffset;
  108. set
  109. {
  110. if (_localPositionOffset == value) return;
  111. _localPositionOffset = value;
  112. OnDataChanged();
  113. }
  114. }
  115. public virtual bool rotateToTheSurface
  116. {
  117. get => _rotateToTheSurface;
  118. set
  119. {
  120. if (_rotateToTheSurface == value) return;
  121. _rotateToTheSurface = value;
  122. OnDataChanged();
  123. }
  124. }
  125. public virtual Vector3 eulerOffset
  126. {
  127. get => _eulerOffset;
  128. set
  129. {
  130. if (_eulerOffset == value) return;
  131. _eulerOffset = value;
  132. _randomEulerOffset.v1 = _randomEulerOffset.v2 = Vector3.zero;
  133. OnDataChanged();
  134. }
  135. }
  136. public virtual bool addRandomRotation
  137. {
  138. get => _addRandomRotation;
  139. set
  140. {
  141. if (_addRandomRotation == value) return;
  142. _addRandomRotation = value;
  143. OnDataChanged();
  144. }
  145. }
  146. public virtual float rotationFactor
  147. {
  148. get => _rotationFactor;
  149. set
  150. {
  151. value = Mathf.Max(value, 0f);
  152. if (_rotationFactor == value) return;
  153. _rotationFactor = value;
  154. OnDataChanged();
  155. }
  156. }
  157. public virtual bool rotateInMultiples
  158. {
  159. get => _rotateInMultiples;
  160. set
  161. {
  162. if (_rotateInMultiples == value) return;
  163. _rotateInMultiples = value;
  164. OnDataChanged();
  165. }
  166. }
  167. public virtual RandomUtils.Range3 randomEulerOffset
  168. {
  169. get => _randomEulerOffset;
  170. set
  171. {
  172. if (_randomEulerOffset == value) return;
  173. _randomEulerOffset = value;
  174. _eulerOffset = Vector3.zero;
  175. OnDataChanged();
  176. }
  177. }
  178. public virtual bool alwaysOrientUp
  179. {
  180. get => rotateToTheSurface ? _alwaysOrientUp : false;
  181. set
  182. {
  183. if (_alwaysOrientUp == value) return;
  184. _alwaysOrientUp = value;
  185. OnDataChanged();
  186. }
  187. }
  188. public virtual bool separateScaleAxes
  189. {
  190. get => _separateScaleAxes;
  191. set
  192. {
  193. if (_separateScaleAxes == value) return;
  194. _separateScaleAxes = value;
  195. OnDataChanged();
  196. }
  197. }
  198. public virtual Vector3 scaleMultiplier
  199. {
  200. get => _scaleMultiplier;
  201. set
  202. {
  203. if (Mathf.Approximately(value.x, 0) && Mathf.Approximately(value.y, 0) && Mathf.Approximately(value.z, 0))
  204. return;
  205. if (_scaleMultiplier == value) return;
  206. _scaleMultiplier = value;
  207. _randomScaleMultiplierRange.v1 = _randomScaleMultiplierRange.v2 = Vector3.one;
  208. OnDataChanged();
  209. }
  210. }
  211. public virtual RandomUtils.Range3 randomScaleMultiplierRange
  212. {
  213. get => _randomScaleMultiplierRange;
  214. set
  215. {
  216. if (_randomScaleMultiplierRange == value) return;
  217. _randomScaleMultiplierRange = value;
  218. _scaleMultiplier = Vector3.one;
  219. OnDataChanged();
  220. }
  221. }
  222. public virtual bool randomScaleMultiplier
  223. {
  224. get => _randomScaleMultiplier;
  225. set
  226. {
  227. if (_randomScaleMultiplier == value) return;
  228. _randomScaleMultiplier = value;
  229. _randomScaleMultiplierRange.v1 = _randomScaleMultiplierRange.v2 = _scaleMultiplier = Vector3.one;
  230. OnDataChanged();
  231. }
  232. }
  233. public virtual bool isAsset2D { get; set; }
  234. public virtual FlipAction flipX
  235. {
  236. get => _flipX;
  237. set
  238. {
  239. if (_flipX == value) return;
  240. _flipX = value;
  241. OnDataChanged();
  242. }
  243. }
  244. public virtual FlipAction flipY
  245. {
  246. get => _flipY;
  247. set
  248. {
  249. if (_flipY == value) return;
  250. _flipY = value;
  251. OnDataChanged();
  252. }
  253. }
  254. public virtual Vector3 maxScaleMultiplier
  255. => randomScaleMultiplier ? randomScaleMultiplierRange.max : scaleMultiplier;
  256. public virtual Vector3 minScaleMultiplier
  257. => randomScaleMultiplier ? randomScaleMultiplierRange.min : scaleMultiplier;
  258. public Vector3 GetAdditionalAngle()
  259. {
  260. if (addRandomRotation)
  261. {
  262. var randomAngle = randomEulerOffset.randomVector;
  263. if (rotateInMultiples)
  264. {
  265. randomAngle = new Vector3(
  266. Mathf.Round(randomAngle.x / rotationFactor) * rotationFactor,
  267. Mathf.Round(randomAngle.y / rotationFactor) * rotationFactor,
  268. Mathf.Round(randomAngle.z / rotationFactor) * rotationFactor);
  269. }
  270. return randomAngle;
  271. }
  272. return eulerOffset;
  273. }
  274. public Vector3 GetScaleMultiplier()
  275. {
  276. var scale = randomScaleMultiplier ? randomScaleMultiplierRange.randomVector : scaleMultiplier;
  277. if (!separateScaleAxes) scale.z = scale.y = scale.x;
  278. return scale;
  279. }
  280. public bool GetFlipX() => flipX == FlipAction.NONE ? false : flipX == FlipAction.FLIP ? true : Random.value > 0.5;
  281. public bool GetFlipY() => flipY == FlipAction.NONE ? false : flipY == FlipAction.FLIP ? true : Random.value > 0.5;
  282. public float GetSurfaceDistance() => randomSurfaceDistance ? randomSurfaceDistanceRange.randomValue : surfaceDistance;
  283. public virtual string thumbnailPath { get; }
  284. public virtual ThumbnailSettings thumbnailSettings
  285. {
  286. get => _thumbnailSettings;
  287. set => _thumbnailSettings.Copy(value);
  288. }
  289. public Texture2D thumbnail
  290. {
  291. get
  292. {
  293. if (_thumbnail == null) LoadThumbnailFromFile();
  294. if (_thumbnail == null) UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  295. return _thumbnail;
  296. }
  297. }
  298. public void LoadThumbnailFromFile()
  299. {
  300. var filePath = thumbnailPath;
  301. if (filePath != null)
  302. {
  303. if (System.IO.File.Exists(filePath))
  304. {
  305. var fileData = System.IO.File.ReadAllBytes(filePath);
  306. _thumbnail = new Texture2D(ThumbnailUtils.SIZE, ThumbnailUtils.SIZE);
  307. _thumbnail.LoadImage(fileData);
  308. }
  309. else
  310. {
  311. _thumbnailSettings.useCustomImage = false;
  312. UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  313. }
  314. }
  315. }
  316. public Texture2D thumbnailTexture
  317. {
  318. get
  319. {
  320. if (_thumbnail == null) _thumbnail = new Texture2D(ThumbnailUtils.SIZE, ThumbnailUtils.SIZE);
  321. return _thumbnail;
  322. }
  323. }
  324. public void SetCustomThumbnailTexture(Texture2D customThumbnailTexture, bool savePng)
  325. {
  326. _thumbnail = customThumbnailTexture;
  327. if (savePng) ThumbnailUtils.SavePngResource(_thumbnail, thumbnailPath);
  328. }
  329. public void UpdateThumbnail(bool updateItemThumbnails, bool savePng)
  330. => ThumbnailUtils.UpdateThumbnail(brushItem: this, updateItemThumbnails, savePng);
  331. public virtual BrushSettings Clone()
  332. {
  333. var clone = new BrushSettings();
  334. clone.Copy(this);
  335. clone._thumbnail = _thumbnail;
  336. return clone;
  337. }
  338. public virtual void Copy(BrushSettings other)
  339. {
  340. _surfaceDistance = other._surfaceDistance;
  341. _randomSurfaceDistance = other._randomSurfaceDistance;
  342. _randomSurfaceDistanceRange = other._randomSurfaceDistanceRange;
  343. _embedInSurface = other._embedInSurface;
  344. _embedAtPivotHeight = other._embedAtPivotHeight;
  345. _localPositionOffset = other._localPositionOffset;
  346. _rotateToTheSurface = other._rotateToTheSurface;
  347. _addRandomRotation = other._addRandomRotation;
  348. _eulerOffset = other._eulerOffset;
  349. _randomEulerOffset = new RandomUtils.Range3(other._randomEulerOffset);
  350. _randomScaleMultiplier = other._randomScaleMultiplier;
  351. _alwaysOrientUp = other._alwaysOrientUp;
  352. _separateScaleAxes = other._separateScaleAxes;
  353. _scaleMultiplier = other._scaleMultiplier;
  354. _randomScaleMultiplierRange = new RandomUtils.Range3(other._randomScaleMultiplierRange);
  355. _thumbnailSettings.Copy(other._thumbnailSettings);
  356. _rotationFactor = other._rotationFactor;
  357. _rotateInMultiples = other._rotateInMultiples;
  358. _flipX = other._flipX;
  359. _flipY = other._flipY;
  360. }
  361. public void Reset()
  362. {
  363. _surfaceDistance = 0f;
  364. _randomSurfaceDistance = false;
  365. _randomSurfaceDistanceRange = new RandomUtils.Range(-0.005f, 0.005f);
  366. _embedInSurface = false;
  367. _embedAtPivotHeight = true;
  368. _localPositionOffset = Vector3.zero;
  369. _rotateToTheSurface = true;
  370. _addRandomRotation = false;
  371. _eulerOffset = Vector3.zero;
  372. _randomEulerOffset = new RandomUtils.Range3(Vector3.zero, Vector3.zero);
  373. _randomScaleMultiplier = false;
  374. _alwaysOrientUp = false;
  375. _separateScaleAxes = false;
  376. _scaleMultiplier = Vector3.one;
  377. _randomScaleMultiplierRange = new RandomUtils.Range3(Vector3.one, Vector3.one);
  378. _thumbnailSettings = new ThumbnailSettings();
  379. _rotationFactor = 90;
  380. _rotateInMultiples = false;
  381. _flipX = FlipAction.NONE;
  382. _flipY = FlipAction.NONE;
  383. }
  384. private static long _prevId = 0;
  385. protected void SetId()
  386. {
  387. _id = System.DateTime.Now.Ticks;
  388. if (_id <= _prevId) _id = _prevId + 1;
  389. _prevId = _id;
  390. }
  391. public BrushSettings() { }
  392. public BrushSettings(BrushSettings other) => Copy(other);
  393. public virtual void OnBeforeSerialize() { }
  394. public virtual void OnAfterDeserialize() { }
  395. public override int GetHashCode()
  396. {
  397. int hashCode = 917907199;
  398. hashCode = hashCode * -1521134295 + _id.GetHashCode();
  399. hashCode = hashCode * -1521134295 + _surfaceDistance.GetHashCode();
  400. hashCode = hashCode * -1521134295 + _randomSurfaceDistance.GetHashCode();
  401. hashCode = hashCode * -1521134295 + _randomSurfaceDistanceRange.GetHashCode();
  402. hashCode = hashCode * -1521134295 + _embedInSurface.GetHashCode();
  403. hashCode = hashCode * -1521134295 + _embedAtPivotHeight.GetHashCode();
  404. hashCode = hashCode * -1521134295 + _localPositionOffset.GetHashCode();
  405. hashCode = hashCode * -1521134295 + _rotateToTheSurface.GetHashCode();
  406. hashCode = hashCode * -1521134295 + _eulerOffset.GetHashCode();
  407. hashCode = hashCode * -1521134295 + _addRandomRotation.GetHashCode();
  408. hashCode = hashCode * -1521134295 + _rotationFactor.GetHashCode();
  409. hashCode = hashCode * -1521134295 + _rotateInMultiples.GetHashCode();
  410. hashCode = hashCode * -1521134295 + _randomEulerOffset.GetHashCode();
  411. hashCode = hashCode * -1521134295 + _alwaysOrientUp.GetHashCode();
  412. hashCode = hashCode * -1521134295 + _separateScaleAxes.GetHashCode();
  413. hashCode = hashCode * -1521134295 + _scaleMultiplier.GetHashCode();
  414. hashCode = hashCode * -1521134295 + _randomScaleMultiplier.GetHashCode();
  415. hashCode = hashCode * -1521134295 + _randomScaleMultiplier.GetHashCode();
  416. hashCode = hashCode * -1521134295 + _flipX.GetHashCode();
  417. hashCode = hashCode * -1521134295 + _flipY.GetHashCode();
  418. hashCode = hashCode * -1521134295 + _thumbnailSettings.GetHashCode();
  419. return hashCode;
  420. }
  421. }
  422. public static class SelectionUtils
  423. {
  424. public static void Swap<T>(int fromIdx, int toIdx, ref int[] selection, System.Collections.Generic.List<T> list)
  425. {
  426. if (fromIdx == toIdx) return;
  427. var newOrder = new System.Collections.Generic.List<T>();
  428. var newSelection = selection.ToArray();
  429. for (int idx = 0; idx <= list.Count; ++idx)
  430. {
  431. if (idx == toIdx)
  432. {
  433. System.Array.Sort(selection);
  434. int newSelectionIdx = 0;
  435. foreach (var selectionIdx in selection)
  436. {
  437. newOrder.Add(list[selectionIdx]);
  438. newSelection[newSelectionIdx++] = newOrder.Count - 1;
  439. }
  440. if (idx < list.Count && !selection.Contains(idx)) newOrder.Add(list[idx]);
  441. }
  442. else if (selection.Contains(idx)) continue;
  443. else if (idx < list.Count) newOrder.Add(list[idx]);
  444. }
  445. selection = newSelection;
  446. list.Clear();
  447. list.AddRange(newOrder);
  448. PWBCore.staticData.Save();
  449. }
  450. }
  451. [System.Serializable]
  452. public class ThumbnailSettings
  453. {
  454. [SerializeField] private Color _backgroudColor = Color.gray;
  455. [SerializeField] private Vector2 _lightEuler = new Vector2(130, -165);
  456. [SerializeField] private Color _lightColor = Color.white;
  457. [SerializeField] private float _lightIntensity = 1;
  458. [SerializeField] private float _zoom = 1;
  459. [SerializeField] private Vector3 _targetEuler = new Vector3(0, 125, 0);
  460. [SerializeField] private Vector2 _targetOffset = Vector2.zero;
  461. [SerializeField] private bool _useCustomImage = false;
  462. public Color backgroudColor { get => _backgroudColor; set => _backgroudColor = value; }
  463. public Vector2 lightEuler { get => _lightEuler; set => _lightEuler = value; }
  464. public Color lightColor { get => _lightColor; set => _lightColor = value; }
  465. public float lightIntensity { get => _lightIntensity; set => _lightIntensity = value; }
  466. public float zoom { get => _zoom; set => _zoom = value; }
  467. public Vector3 targetEuler { get => _targetEuler; set => _targetEuler = value; }
  468. public Vector2 targetOffset { get => _targetOffset; set => _targetOffset = value; }
  469. public bool useCustomImage { get => _useCustomImage; set => _useCustomImage = value; }
  470. public ThumbnailSettings() { }
  471. private static ThumbnailSettings _defaultTAsset2DThumbnailSettings = null;
  472. public static ThumbnailSettings GetDefaultTAsset2DThumbnailSettings()
  473. {
  474. if (_defaultTAsset2DThumbnailSettings == null)
  475. {
  476. _defaultTAsset2DThumbnailSettings = new ThumbnailSettings();
  477. _defaultTAsset2DThumbnailSettings.targetEuler = new Vector3(17.5f, 0f, 0f);
  478. _defaultTAsset2DThumbnailSettings.zoom = 1.47f;
  479. _defaultTAsset2DThumbnailSettings.targetOffset = new Vector2(0f, -0.06f);
  480. }
  481. return _defaultTAsset2DThumbnailSettings;
  482. }
  483. public ThumbnailSettings(Color backgroudColor, Vector3 lightEuler, Color lightColor, float lightIntensity,
  484. float zoom, Vector3 targetEuler, Vector2 targetOffset, bool useCustomImage)
  485. {
  486. _backgroudColor = backgroudColor;
  487. _lightEuler = lightEuler;
  488. _lightColor = lightColor;
  489. _lightIntensity = lightIntensity;
  490. _zoom = zoom;
  491. _targetEuler = targetEuler;
  492. _targetOffset = targetOffset;
  493. _useCustomImage = useCustomImage;
  494. }
  495. public ThumbnailSettings(ThumbnailSettings other) => Copy(other);
  496. public void Copy(ThumbnailSettings other)
  497. {
  498. _backgroudColor = other._backgroudColor;
  499. _lightEuler = other._lightEuler;
  500. _lightColor = other._lightColor;
  501. _lightIntensity = other._lightIntensity;
  502. _zoom = other._zoom;
  503. _targetEuler = other._targetEuler;
  504. _targetOffset = other._targetOffset;
  505. _useCustomImage = other._useCustomImage;
  506. }
  507. public ThumbnailSettings Clone()
  508. {
  509. var clone = new ThumbnailSettings();
  510. clone.Copy(this);
  511. return clone;
  512. }
  513. public override int GetHashCode()
  514. {
  515. int hashCode = 917907199;
  516. hashCode = hashCode * -1521134295 + _backgroudColor.GetHashCode();
  517. hashCode = hashCode * -1521134295 + _lightEuler.GetHashCode();
  518. hashCode = hashCode * -1521134295 + _lightColor.GetHashCode();
  519. hashCode = hashCode * -1521134295 + _lightIntensity.GetHashCode();
  520. hashCode = hashCode * -1521134295 + _zoom.GetHashCode();
  521. hashCode = hashCode * -1521134295 + _targetEuler.GetHashCode();
  522. hashCode = hashCode * -1521134295 + _targetOffset.GetHashCode();
  523. hashCode = hashCode * -1521134295 + _useCustomImage.GetHashCode();
  524. return hashCode;
  525. }
  526. }
  527. [System.Serializable]
  528. public class MultibrushItemSettings : BrushSettings
  529. {
  530. [SerializeField] private bool _overwriteSettings = false;
  531. [SerializeField] private string _guid = string.Empty;
  532. [SerializeField] private string _prefabPath = string.Empty;
  533. [SerializeField] private float _frequency = 1;
  534. [SerializeField] private long _parentId = -1;
  535. [SerializeField] private bool _overwriteThumbnailSettings = false;
  536. [SerializeField] private bool _includeInThumbnail = true;
  537. [SerializeField] private bool _isAsset2D = false;
  538. private Vector3[] _bottomVertices = null;
  539. private float _bottomMagnitude = 0;
  540. private float _height = 1f;
  541. private Vector3 _size = Vector3.zero;
  542. private GameObject _prefab = null;
  543. private System.Collections.Generic.Dictionary<Vector3, (Vector3[] vertices, float magnitude)>
  544. _furthestVerticesInDirection = new System.Collections.Generic.Dictionary<Vector3,
  545. (Vector3[] vertices, float magnitude)>();
  546. private System.Collections.Generic.List<Vector3> _directionList = new System.Collections.Generic.List<Vector3>();
  547. [System.NonSerialized] private MultibrushSettings _parentSettings = null;
  548. public MultibrushSettings parentSettings
  549. {
  550. get
  551. {
  552. if (_parentSettings == null) _parentSettings = PaletteManager.GetBrushById(_parentId);
  553. return _parentSettings;
  554. }
  555. set
  556. {
  557. if (value == null)
  558. {
  559. _parentId = -1;
  560. _parentSettings = null;
  561. return;
  562. }
  563. _parentSettings = value;
  564. _parentId = value.id;
  565. }
  566. }
  567. protected override void OnDataChanged()
  568. {
  569. base.OnDataChanged();
  570. SavePalette();
  571. }
  572. private void SavePalette()
  573. {
  574. if (parentSettings == null) return;
  575. parentSettings.SavePalette();
  576. }
  577. public MultibrushItemSettings(GameObject prefab, MultibrushSettings parentSettings) : base()
  578. {
  579. SetId();
  580. _prefab = prefab;
  581. _parentId = parentSettings.id;
  582. _parentSettings = parentSettings;
  583. UnityEditor.AssetDatabase.TryGetGUIDAndLocalFileIdentifier(_prefab, out _guid, out long localId);
  584. if (_prefab == null) return;
  585. _prefabPath = UnityEditor.AssetDatabase.GetAssetPath(_prefab);
  586. _bottomVertices = BoundsUtils.GetBottomVertices(prefab.transform);
  587. _height = BoundsUtils.GetBoundsRecursive(prefab.transform, prefab.transform.rotation).size.y;
  588. _size = BoundsUtils.GetBoundsRecursive(prefab.transform).size;
  589. _bottomMagnitude = BoundsUtils.GetBottomMagnitude(prefab.transform);
  590. UpdateAssetType();
  591. if (isAsset2D) thumbnailSettings.Copy(ThumbnailSettings.GetDefaultTAsset2DThumbnailSettings());
  592. UpdateThumbnail(updateItemThumbnails: false, savePng: true);
  593. }
  594. public void InitializeParentSettings(MultibrushSettings parentSettings)
  595. {
  596. _parentId = parentSettings.id;
  597. _parentSettings = parentSettings;
  598. this.parentSettings.UpdateTotalFrequency();
  599. }
  600. public override string thumbnailPath
  601. {
  602. get
  603. {
  604. if (parentSettings == null) return null;
  605. var parentPath = parentSettings.thumbnailPath;
  606. if (parentPath == null) return null;
  607. var path = parentPath.Insert(parentPath.Length - 4, "_" + id.ToString("X"));
  608. return path;
  609. }
  610. }
  611. public bool overwriteSettings
  612. {
  613. get => _overwriteSettings;
  614. set
  615. {
  616. if (_overwriteSettings == value) return;
  617. _overwriteSettings = value;
  618. SavePalette();
  619. }
  620. }
  621. public float frequency
  622. {
  623. get => _frequency;
  624. set
  625. {
  626. value = Mathf.Max(value, 0);
  627. if (_frequency == value) return;
  628. _frequency = value;
  629. if (parentSettings != null) parentSettings.UpdateTotalFrequency();
  630. OnDataChanged();
  631. }
  632. }
  633. public GameObject prefab
  634. {
  635. get
  636. {
  637. if (_prefab == null)
  638. _prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>
  639. (UnityEditor.AssetDatabase.GUIDToAssetPath(_guid));
  640. if (_prefab == null)
  641. {
  642. _prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(_prefabPath);
  643. if (_prefab != null)
  644. UnityEditor.AssetDatabase.TryGetGUIDAndLocalFileIdentifier(_prefab, out _guid, out long localId);
  645. }
  646. else _prefabPath = UnityEditor.AssetDatabase.GetAssetPath(_prefab);
  647. return _prefab;
  648. }
  649. }
  650. public string prefabPath => _prefabPath;
  651. public override float surfaceDistance
  652. => _overwriteSettings || parentSettings == null ? base.surfaceDistance : parentSettings.surfaceDistance;
  653. public override bool randomSurfaceDistance
  654. => _overwriteSettings || parentSettings == null
  655. ? base.randomSurfaceDistance : parentSettings.randomSurfaceDistance;
  656. public override RandomUtils.Range randomSurfaceDistanceRange
  657. => _overwriteSettings || parentSettings == null
  658. ? base.randomSurfaceDistanceRange : parentSettings.randomSurfaceDistanceRange;
  659. public override bool embedInSurface
  660. {
  661. get => _overwriteSettings || parentSettings == null ? base.embedInSurface
  662. : parentSettings.embedInSurface;
  663. set
  664. {
  665. if (_embedInSurface == value) return;
  666. _embedInSurface = value;
  667. if (_embedInSurface) UpdateBottomVertices();
  668. }
  669. }
  670. public override bool embedAtPivotHeight
  671. {
  672. get => _overwriteSettings || parentSettings == null ? base.embedAtPivotHeight : parentSettings.embedAtPivotHeight;
  673. set
  674. {
  675. if (_embedAtPivotHeight == value) return;
  676. _embedAtPivotHeight = value;
  677. }
  678. }
  679. public override Vector3 localPositionOffset
  680. => _overwriteSettings || parentSettings == null ? base.localPositionOffset : parentSettings.localPositionOffset;
  681. public override bool rotateToTheSurface
  682. => _overwriteSettings || parentSettings == null ? base.rotateToTheSurface : parentSettings.rotateToTheSurface;
  683. public override Vector3 eulerOffset
  684. => _overwriteSettings || parentSettings == null ? base.eulerOffset : parentSettings.eulerOffset;
  685. public override bool addRandomRotation
  686. => _overwriteSettings || parentSettings == null ? base.addRandomRotation : parentSettings.addRandomRotation;
  687. public override RandomUtils.Range3 randomEulerOffset
  688. => _overwriteSettings || parentSettings == null ? base.randomEulerOffset : parentSettings.randomEulerOffset;
  689. public override float rotationFactor
  690. => _overwriteSettings || parentSettings == null ? base.rotationFactor : parentSettings.rotationFactor;
  691. public override bool rotateInMultiples
  692. => _overwriteSettings || parentSettings == null ? base.rotateInMultiples : parentSettings.rotateInMultiples;
  693. public override bool alwaysOrientUp
  694. => _overwriteSettings || parentSettings == null ? base.alwaysOrientUp : parentSettings.alwaysOrientUp;
  695. public override bool separateScaleAxes
  696. => _overwriteSettings || parentSettings == null ? base.separateScaleAxes : parentSettings.separateScaleAxes;
  697. public override Vector3 scaleMultiplier
  698. => _overwriteSettings || parentSettings == null ? base.scaleMultiplier : parentSettings.scaleMultiplier;
  699. public override RandomUtils.Range3 randomScaleMultiplierRange
  700. => _overwriteSettings || parentSettings == null ? base.randomScaleMultiplierRange
  701. : parentSettings.randomScaleMultiplierRange;
  702. public override bool randomScaleMultiplier
  703. => _overwriteSettings || parentSettings == null ? base.randomScaleMultiplier
  704. : parentSettings.randomScaleMultiplier;
  705. public override FlipAction flipX
  706. => _overwriteSettings || parentSettings == null ? base.flipX : parentSettings.flipX;
  707. public override FlipAction flipY
  708. => _overwriteSettings || parentSettings == null ? base.flipY : parentSettings.flipY;
  709. public override Vector3 maxScaleMultiplier
  710. => _overwriteSettings || parentSettings == null ? base.maxScaleMultiplier
  711. : randomScaleMultiplier ? randomScaleMultiplierRange.max : scaleMultiplier;
  712. public override Vector3 minScaleMultiplier
  713. => _overwriteSettings || parentSettings == null ? base.minScaleMultiplier
  714. : randomScaleMultiplier ? randomScaleMultiplierRange.min : scaleMultiplier;
  715. public virtual bool overwriteThumbnailSettings
  716. {
  717. get => _overwriteThumbnailSettings;
  718. set
  719. {
  720. if (_overwriteThumbnailSettings == value) return;
  721. _overwriteThumbnailSettings = value;
  722. }
  723. }
  724. public override ThumbnailSettings thumbnailSettings
  725. {
  726. get => _overwriteThumbnailSettings || parentSettings == null
  727. ? base.thumbnailSettings : parentSettings.thumbnailSettings;
  728. set => base.thumbnailSettings = value;
  729. }
  730. public bool includeInThumbnail
  731. {
  732. get => _includeInThumbnail;
  733. set
  734. {
  735. if (_includeInThumbnail == value) return;
  736. _includeInThumbnail = value;
  737. }
  738. }
  739. public override bool isAsset2D { get => _isAsset2D; set => _isAsset2D = value; }
  740. public void UpdateAssetType() => _isAsset2D = Utils2D.Is2DAsset(prefab);
  741. public override void Copy(BrushSettings other)
  742. {
  743. if (other is MultibrushItemSettings)
  744. {
  745. var otherItemSettings = other as MultibrushItemSettings;
  746. _overwriteSettings = otherItemSettings._overwriteSettings;
  747. _frequency = otherItemSettings._frequency;
  748. _overwriteThumbnailSettings = otherItemSettings._overwriteThumbnailSettings;
  749. _includeInThumbnail = otherItemSettings._includeInThumbnail;
  750. _isAsset2D = otherItemSettings._isAsset2D;
  751. }
  752. base.Copy(other);
  753. }
  754. public MultibrushItemSettings() : base() { }
  755. public MultibrushItemSettings(MultibrushItemSettings other) : base() => Copy(other);
  756. public override BrushSettings Clone()
  757. {
  758. var clone = new MultibrushItemSettings();
  759. clone._prefab = _prefab;
  760. clone._guid = _guid;
  761. if (parentSettings != null)
  762. {
  763. clone._parentId = parentSettings.id;
  764. clone._parentSettings = parentSettings;
  765. }
  766. clone._bottomVertices = bottomVertices == null ? null : bottomVertices.ToArray();
  767. clone._bottomMagnitude = bottomMagnitude;
  768. clone._height = height;
  769. clone.Copy(this);
  770. clone.SetId();
  771. clone.SetCustomThumbnailTexture(thumbnail, savePng: false);
  772. clone._furthestVerticesInDirection = new System.Collections.Generic.Dictionary<Vector3,
  773. (Vector3[] vertices, float magnitude)>(_furthestVerticesInDirection);
  774. clone._directionList = new System.Collections.Generic.List<Vector3>(_directionList);
  775. return clone;
  776. }
  777. public override void OnBeforeSerialize()
  778. {
  779. base.OnBeforeSerialize();
  780. _prefabPath = UnityEditor.AssetDatabase.GetAssetPath(_prefab);
  781. }
  782. public override void OnAfterDeserialize()
  783. {
  784. base.OnAfterDeserialize();
  785. _prefab = null;
  786. }
  787. public Vector3[] bottomVertices
  788. {
  789. get
  790. {
  791. if (_bottomVertices == null) UpdateBottomVertices();
  792. return _bottomVertices;
  793. }
  794. }
  795. public float bottomMagnitude
  796. {
  797. get
  798. {
  799. if (prefab == null) return 0f;
  800. if (_bottomMagnitude == 0) _bottomMagnitude = BoundsUtils.GetBottomMagnitude(prefab.transform);
  801. return _bottomMagnitude;
  802. }
  803. }
  804. public float height => _height;
  805. public Vector3 size
  806. {
  807. get
  808. {
  809. if (prefab == null) return Vector3.zero;
  810. if (_size == Vector3.zero) _size = BoundsUtils.GetBoundsRecursive(prefab.transform).size;
  811. return _size;
  812. }
  813. }
  814. public override void UpdateBottomVertices()
  815. {
  816. base.UpdateBottomVertices();
  817. if (prefab == null) return;
  818. _bottomVertices = BoundsUtils.GetBottomVertices(prefab.transform);
  819. _height = BoundsUtils.GetBoundsRecursive(prefab.transform, prefab.transform.rotation).size.y;
  820. _size = BoundsUtils.GetBoundsRecursive(prefab.transform).size;
  821. _bottomMagnitude = BoundsUtils.GetBottomMagnitude(prefab.transform);
  822. }
  823. public Vector3[] GetFurthestVerticesInDirection(Vector3 direction, out float magnitude)
  824. {
  825. var vertices = BoundsUtils.GetFurthestVertices(prefab.transform, direction, out magnitude);
  826. return vertices;
  827. }
  828. private void AddFurthestVertices(Vector3 direction)
  829. {
  830. if (prefab == null) return;
  831. if (_furthestVerticesInDirection.ContainsKey(direction)) return;
  832. float magnitude;
  833. var vertices = BoundsUtils.GetFurthestVertices(prefab.transform, direction, out magnitude);
  834. _furthestVerticesInDirection.Add(direction, (vertices, magnitude));
  835. _directionList.Insert(0, direction);
  836. const int maxListCount = 8;
  837. if (_directionList.Count > maxListCount)
  838. {
  839. if (_furthestVerticesInDirection.ContainsKey(_directionList[maxListCount]))
  840. _furthestVerticesInDirection.Remove(_directionList[maxListCount]);
  841. _directionList.RemoveAt(maxListCount);
  842. }
  843. }
  844. public override int GetHashCode()
  845. {
  846. var hashCode = base.GetHashCode();
  847. hashCode = hashCode * -1521134295 + _overwriteSettings.GetHashCode();
  848. hashCode = hashCode * -1521134295 + _guid.GetHashCode();
  849. hashCode = hashCode * -1521134295 + _prefabPath.GetHashCode();
  850. hashCode = hashCode * -1521134295 + _frequency.GetHashCode();
  851. hashCode = hashCode * -1521134295 + _parentId.GetHashCode();
  852. hashCode = hashCode * -1521134295 + _embedAtPivotHeight.GetHashCode();
  853. hashCode = hashCode * -1521134295 + _overwriteThumbnailSettings.GetHashCode();
  854. hashCode = hashCode * -1521134295 + _includeInThumbnail.GetHashCode();
  855. hashCode = hashCode * -1521134295 + _isAsset2D.GetHashCode();
  856. return hashCode;
  857. }
  858. }
  859. [System.Serializable]
  860. public class MultibrushSettings : BrushSettings
  861. {
  862. public enum FrequencyMode { RANDOM, PATTERN }
  863. [SerializeField] private string _name = null;
  864. [SerializeField]
  865. private System.Collections.Generic.List<MultibrushItemSettings> _items
  866. = new System.Collections.Generic.List<MultibrushItemSettings>();
  867. [SerializeField] private FrequencyMode _frequencyMode = FrequencyMode.RANDOM;
  868. [SerializeField] private string _pattern = "1...";
  869. [SerializeField] private bool _restartPatternForEachStroke = true;
  870. [field: System.NonSerialized] private float _totalFrequency = -1;
  871. [field: System.NonSerialized] private PatternMachine _patternMachine = null;
  872. [field: System.NonSerialized] private PaletteData _palette = null;
  873. public string name
  874. {
  875. get => _name;
  876. set
  877. {
  878. if (_name == value) return;
  879. _name = value;
  880. OnDataChanged();
  881. }
  882. }
  883. public FrequencyMode frequencyMode
  884. {
  885. get => _frequencyMode;
  886. set
  887. {
  888. if (_frequencyMode == value) return;
  889. _frequencyMode = value;
  890. OnDataChanged();
  891. }
  892. }
  893. public string pattern
  894. {
  895. get => _pattern;
  896. set
  897. {
  898. if (_pattern == value) return;
  899. _pattern = value;
  900. OnDataChanged();
  901. }
  902. }
  903. public PatternMachine patternMachine
  904. {
  905. get
  906. {
  907. if (_patternMachine == null)
  908. {
  909. if (PatternMachine.Validate(_pattern, _items.Count,
  910. out PatternMachine.Token[] tokens, out PatternMachine.Token[] endTokens)
  911. == PatternMachine.ValidationResult.VALID) _patternMachine = new PatternMachine(tokens, endTokens);
  912. }
  913. return _patternMachine;
  914. }
  915. set
  916. {
  917. _patternMachine = value;
  918. OnDataChanged();
  919. }
  920. }
  921. public bool restartPatternForEachStroke
  922. {
  923. get => _restartPatternForEachStroke;
  924. set
  925. {
  926. if (_restartPatternForEachStroke == value) return;
  927. _restartPatternForEachStroke = value;
  928. OnDataChanged();
  929. }
  930. }
  931. public PaletteData palette
  932. {
  933. get
  934. {
  935. if (_palette == null) _palette = PaletteManager.GetPalette(this);
  936. return _palette;
  937. }
  938. set => _palette = value;
  939. }
  940. public override bool isAsset2D
  941. {
  942. get => _items.Exists(i => i.isAsset2D);
  943. set
  944. {
  945. foreach (var item in _items) item.isAsset2D = value;
  946. }
  947. }
  948. protected override void OnDataChanged()
  949. {
  950. base.OnDataChanged();
  951. SavePalette();
  952. }
  953. public void SavePalette()
  954. {
  955. if (palette != null) palette.Save();
  956. }
  957. public MultibrushSettings(GameObject prefab, PaletteData palette) : base()
  958. {
  959. SetId();
  960. this.palette = palette;
  961. _items.Add(new MultibrushItemSettings(prefab, this));
  962. _name = prefab.name;
  963. Copy(palette.brushCreationSettings.defaultBrushSettings);
  964. thumbnailSettings.Copy(palette.brushCreationSettings.defaultThumbnailSettings);
  965. if (isAsset2D) thumbnailSettings.Copy(ThumbnailSettings.GetDefaultTAsset2DThumbnailSettings());
  966. UpdateThumbnail(updateItemThumbnails: false, savePng: true);
  967. }
  968. public override string thumbnailPath
  969. => palette == null ? null : palette.thumbnailsFolderPath + "/" + id.ToString("X") + ".png";
  970. public void AddItem(MultibrushItemSettings item)
  971. {
  972. _items.Add(item);
  973. OnItemCountChange();
  974. }
  975. private void RemoveFromPalette()
  976. {
  977. if (palette != null) palette.RemoveBrush(this);
  978. }
  979. public void RemoveItemAt(int index)
  980. {
  981. _items.RemoveAt(index);
  982. OnItemCountChange();
  983. if (_items.Count == 0) RemoveFromPalette();
  984. }
  985. public void RemoveItem(MultibrushItemSettings item)
  986. {
  987. if (!_items.Contains(item)) return;
  988. _items.Remove(item);
  989. OnItemCountChange();
  990. if (_items.Count == 0) RemoveFromPalette();
  991. }
  992. public MultibrushItemSettings GetItemAt(int index)
  993. {
  994. if (index >= _items.Count) return null;
  995. return _items[index];
  996. }
  997. public bool ItemExist(long itemId) => _items.Exists(i => i.id == itemId);
  998. public MultibrushItemSettings GetItemById(long itemId)
  999. {
  1000. var items = _items.Where(i => i.id == itemId).ToArray();
  1001. if (items.Length == 0) return null;
  1002. return items[0];
  1003. }
  1004. public void InsertItemAt(MultibrushItemSettings item, int index)
  1005. {
  1006. _items.Insert(index, item);
  1007. OnItemCountChange();
  1008. }
  1009. private void OnItemCountChange()
  1010. {
  1011. UpdateTotalFrequency();
  1012. UpdatePatternMachine();
  1013. PWBCore.staticData.SaveAndUpdateVersion();
  1014. BrushstrokeManager.UpdateBrushstroke();
  1015. SavePalette();
  1016. UpdateThumbnail(updateItemThumbnails: false, savePng: true);
  1017. if (_palette != null) _palette.ClearObjectQuery();
  1018. }
  1019. public void Swap(int fromIdx, int toIdx, ref int[] selection)
  1020. => SelectionUtils.Swap<MultibrushItemSettings>(fromIdx, toIdx, ref selection, _items);
  1021. public MultibrushItemSettings[] items => _items.ToArray();
  1022. public int itemCount => _items.Count;
  1023. public int notNullItemCount => _items.Where(i => i.prefab != null).Count();
  1024. public bool containMissingPrefabs
  1025. {
  1026. get
  1027. {
  1028. foreach (var item in _items)
  1029. if (item.prefab == null) return true;
  1030. return false;
  1031. }
  1032. }
  1033. public bool allPrefabMissing
  1034. {
  1035. get
  1036. {
  1037. foreach (var item in _items)
  1038. if (item.prefab != null) return false;
  1039. return true;
  1040. }
  1041. }
  1042. public void UpdateTotalFrequency()
  1043. {
  1044. _totalFrequency = 0;
  1045. foreach (var item in _items) _totalFrequency += item.frequency;
  1046. }
  1047. public float totalFrequency
  1048. {
  1049. get
  1050. {
  1051. if (_totalFrequency == -1) UpdateTotalFrequency();
  1052. return _totalFrequency;
  1053. }
  1054. }
  1055. private int GetNextItemIndex()
  1056. {
  1057. if (frequencyMode == FrequencyMode.RANDOM)
  1058. {
  1059. if (_items.Count == 1) return 0;
  1060. var rand = UnityEngine.Random.Range(0f, totalFrequency);
  1061. float sum = 0;
  1062. for (int i = 0; i < _items.Count; ++i)
  1063. {
  1064. sum += _items[i].frequency;
  1065. if (rand <= sum) return i;
  1066. }
  1067. return -1;
  1068. }
  1069. if (_patternMachine == null)
  1070. {
  1071. if (PatternMachine.Validate(_pattern, _items.Count,
  1072. out PatternMachine.Token[] tokens, out PatternMachine.Token[] endTokens)
  1073. == PatternMachine.ValidationResult.VALID) _patternMachine = new PatternMachine(tokens, endTokens);
  1074. }
  1075. var result = _patternMachine == null ? -2 : _patternMachine.nextIndex - 1;
  1076. return result;
  1077. }
  1078. private int _currentItemIndex = 0;
  1079. public int nextItemIndex
  1080. {
  1081. get
  1082. {
  1083. _currentItemIndex = GetNextItemIndex();
  1084. return _currentItemIndex;
  1085. }
  1086. }
  1087. public int currentItemIndex
  1088. {
  1089. get
  1090. {
  1091. return _currentItemIndex;
  1092. }
  1093. }
  1094. public void ResetCurrentItemIndex()
  1095. {
  1096. if (frequencyMode == FrequencyMode.RANDOM) return;
  1097. if (_patternMachine == null)
  1098. {
  1099. if (PatternMachine.Validate(_pattern, _items.Count,
  1100. out PatternMachine.Token[] tokens, out PatternMachine.Token[] endTokens)
  1101. == PatternMachine.ValidationResult.VALID) _patternMachine = new PatternMachine(tokens, endTokens);
  1102. return;
  1103. }
  1104. _patternMachine.Reset();
  1105. _currentItemIndex = _patternMachine.nextIndex - 1;
  1106. }
  1107. public void SetNextItemIndex()
  1108. {
  1109. _currentItemIndex = GetNextItemIndex();
  1110. }
  1111. public int GetPatternTokenIndex()
  1112. {
  1113. if (frequencyMode == FrequencyMode.RANDOM | _patternMachine == null) return 0;
  1114. return _patternMachine.tokenIndex;
  1115. }
  1116. public void SetPatternTokenIndex(int value)
  1117. {
  1118. if (frequencyMode == FrequencyMode.RANDOM | _patternMachine == null) return;
  1119. _patternMachine.SetTokenIndex(value);
  1120. }
  1121. private void UpdatePatternMachine()
  1122. {
  1123. if (PatternMachine.Validate(_pattern, _items.Count,
  1124. out PatternMachine.Token[] tokens, out PatternMachine.Token[] endTokens)
  1125. != PatternMachine.ValidationResult.VALID)
  1126. _patternMachine = null;
  1127. }
  1128. public override void Copy(BrushSettings other)
  1129. {
  1130. if (other is MultibrushSettings)
  1131. {
  1132. var otherMulti = other as MultibrushSettings;
  1133. _items.Clear();
  1134. foreach (var item in otherMulti._items)
  1135. {
  1136. var clone = item.Clone() as MultibrushItemSettings;
  1137. clone.parentSettings = this;
  1138. _items.Add(clone);
  1139. }
  1140. _name = otherMulti._name;
  1141. _frequencyMode = otherMulti._frequencyMode;
  1142. _pattern = otherMulti._pattern;
  1143. _restartPatternForEachStroke = otherMulti._restartPatternForEachStroke;
  1144. _totalFrequency = otherMulti._totalFrequency;
  1145. }
  1146. base.Copy(other);
  1147. }
  1148. private MultibrushSettings() : base() { }
  1149. public override BrushSettings Clone()
  1150. {
  1151. var clone = new MultibrushSettings();
  1152. clone.Copy(this);
  1153. clone.SetId();
  1154. clone.palette = _palette;
  1155. clone.SetCustomThumbnailTexture(thumbnail, savePng: false);
  1156. return clone;
  1157. }
  1158. public MultibrushSettings CloneAndChangePalette(PaletteData palette)
  1159. {
  1160. var clone = new MultibrushSettings();
  1161. clone.Copy(this);
  1162. clone.SetId();
  1163. clone.palette = palette;
  1164. return clone;
  1165. }
  1166. public BrushSettings CloneMainSettings()
  1167. {
  1168. var clone = new BrushSettings();
  1169. clone.Copy(this);
  1170. return clone;
  1171. }
  1172. public void Duplicate(int index)
  1173. {
  1174. var original = _items[index];
  1175. var clone = original.Clone();
  1176. if (clone.thumbnailSettings.useCustomImage)
  1177. {
  1178. clone.thumbnailSettings.useCustomImage = false;
  1179. clone.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1180. clone.thumbnailSettings.useCustomImage = true;
  1181. var thumbnailClone = new Texture2D(original.thumbnail.width, original.thumbnail.height);
  1182. thumbnailClone.SetPixels(original.thumbnail.GetPixels());
  1183. thumbnailClone.Apply();
  1184. clone.SetCustomThumbnailTexture(thumbnailClone, savePng: true);
  1185. }
  1186. else clone.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1187. _items.Insert(index, clone as MultibrushItemSettings);
  1188. OnItemCountChange();
  1189. }
  1190. public override void UpdateBottomVertices()
  1191. {
  1192. foreach (var item in _items) item.UpdateBottomVertices();
  1193. }
  1194. public override bool embedInSurface
  1195. {
  1196. get => _embedInSurface;
  1197. set
  1198. {
  1199. if (_embedInSurface == value) return;
  1200. _embedInSurface = value;
  1201. if (_embedInSurface) UpdateBottomVertices();
  1202. }
  1203. }
  1204. public bool ContainsPrefab(int prefabId)
  1205. => _items.Exists(item => item.prefab != null && item.prefab.GetInstanceID() == prefabId);
  1206. public bool ContainsPrefabPath(string path) => _items.Exists(item => item.prefabPath == path);
  1207. public bool ContainsSceneObject(GameObject obj)
  1208. {
  1209. if (obj == null) return false;
  1210. var outermostPrefab = UnityEditor.PrefabUtility.GetOutermostPrefabInstanceRoot(obj);
  1211. if (outermostPrefab == null) return false;
  1212. var prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(outermostPrefab);
  1213. if (prefab == null) return false;
  1214. return ContainsPrefab(prefab.GetInstanceID());
  1215. }
  1216. public Vector3 minBrushSize
  1217. {
  1218. get
  1219. {
  1220. var min = Vector3.one * float.MaxValue;
  1221. foreach (var item in _items)
  1222. min = Vector3.Min(min, item.size);
  1223. return min;
  1224. }
  1225. }
  1226. public float minBrushMagnitude
  1227. {
  1228. get
  1229. {
  1230. var min = minBrushSize;
  1231. return Mathf.Min(min.x, min.y, min.z);
  1232. }
  1233. }
  1234. public Vector3 maxBrushSize
  1235. {
  1236. get
  1237. {
  1238. var max = Vector3.one * float.MinValue;
  1239. foreach (var item in _items)
  1240. max = Vector3.Max(max, item.size);
  1241. max = Vector3.Scale(max, maxScaleMultiplier);
  1242. return max;
  1243. }
  1244. }
  1245. public float maxBrushMagnitude
  1246. {
  1247. get
  1248. {
  1249. var max = maxBrushSize;
  1250. return Mathf.Min(max.x, max.y, max.z);
  1251. }
  1252. }
  1253. public void UpdateAssetTypes()
  1254. {
  1255. foreach (var item in _items) item.UpdateAssetType();
  1256. }
  1257. public void Cleanup()
  1258. {
  1259. foreach (var item in items) if (item.prefab == null) RemoveItem(item);
  1260. }
  1261. public override int GetHashCode()
  1262. {
  1263. int hashCode = 917907199;
  1264. hashCode = hashCode * -1521134295 + _name.GetHashCode();
  1265. hashCode = hashCode * -1521134295 + _frequencyMode.GetHashCode();
  1266. hashCode = hashCode * -1521134295 + _pattern.GetHashCode();
  1267. hashCode = hashCode * -1521134295 + _restartPatternForEachStroke.GetHashCode();
  1268. foreach (var item in _items) hashCode = hashCode * -1521134295 + item.GetHashCode();
  1269. return hashCode;
  1270. }
  1271. }
  1272. [System.Serializable]
  1273. public class BrushCreationSettings
  1274. {
  1275. [SerializeField] private bool _includeSubfolders = true;
  1276. [SerializeField] private bool _addLabelsToDroppedPrefabs = false;
  1277. [SerializeField] private string _labelsCSV = null;
  1278. private string[] _labels = null;
  1279. [SerializeField] private BrushSettings _defaultBrushSettings = new BrushSettings();
  1280. [SerializeField] private ThumbnailSettings _defaultThumbnailSettings = new ThumbnailSettings();
  1281. public bool includeSubfolders
  1282. {
  1283. get => _includeSubfolders;
  1284. set
  1285. {
  1286. if (_includeSubfolders == value) return;
  1287. _includeSubfolders = value;
  1288. }
  1289. }
  1290. public bool addLabelsToDroppedPrefabs
  1291. {
  1292. get => _addLabelsToDroppedPrefabs;
  1293. set
  1294. {
  1295. if (_addLabelsToDroppedPrefabs == value) return;
  1296. _addLabelsToDroppedPrefabs = value;
  1297. }
  1298. }
  1299. private void SplitCSV() => _labels = _labelsCSV.Replace(", ", ",").Split(',');
  1300. public string[] labels
  1301. {
  1302. get
  1303. {
  1304. if (_labels == null || (_labels.Length == 0 && _labelsCSV != null && _labelsCSV != string.Empty))
  1305. SplitCSV();
  1306. return _labels;
  1307. }
  1308. }
  1309. public string labelsCSV
  1310. {
  1311. get => _labelsCSV;
  1312. set
  1313. {
  1314. if (_labelsCSV == value) return;
  1315. if (value == string.Empty)
  1316. {
  1317. _labelsCSV = string.Empty;
  1318. _labels = new string[0];
  1319. return;
  1320. }
  1321. var trimmed = System.Text.RegularExpressions.Regex.Replace(value.Trim(), "[( *, +)]+", ", ");
  1322. if (trimmed.Last() == ' ') trimmed = trimmed.Substring(0, trimmed.Length - 2);
  1323. if (trimmed.First() == ',') trimmed = trimmed.Substring(1);
  1324. if (_labelsCSV == trimmed) return;
  1325. _labelsCSV = trimmed;
  1326. SplitCSV();
  1327. }
  1328. }
  1329. public BrushSettings defaultBrushSettings => _defaultBrushSettings;
  1330. public void FactoryResetDefaultBrushSettings() => _defaultBrushSettings = new BrushSettings();
  1331. public ThumbnailSettings defaultThumbnailSettings => _defaultThumbnailSettings;
  1332. public void FactoryResetDefaultThumbnailSettings() => _defaultThumbnailSettings = new ThumbnailSettings();
  1333. public BrushCreationSettings Clone()
  1334. {
  1335. var clone = new BrushCreationSettings();
  1336. clone.Copy(this);
  1337. return clone;
  1338. }
  1339. public void Copy(BrushCreationSettings other)
  1340. {
  1341. _includeSubfolders = other._includeSubfolders;
  1342. _addLabelsToDroppedPrefabs = other._addLabelsToDroppedPrefabs;
  1343. _labelsCSV = other._labelsCSV;
  1344. if (other._labels != null)
  1345. {
  1346. _labels = new string[other._labels.Length];
  1347. System.Array.Copy(other._labels, _labels, other._labels.Length);
  1348. }
  1349. _defaultBrushSettings.Copy(other._defaultBrushSettings);
  1350. _defaultThumbnailSettings.Copy(other._defaultThumbnailSettings);
  1351. }
  1352. public override int GetHashCode()
  1353. {
  1354. int hashCode = 917907199;
  1355. hashCode = hashCode * -1521134295 + _includeSubfolders.GetHashCode();
  1356. hashCode = hashCode * -1521134295 + _addLabelsToDroppedPrefabs.GetHashCode();
  1357. hashCode = hashCode * -1521134295 + _defaultBrushSettings.GetHashCode();
  1358. hashCode = hashCode * -1521134295 + _defaultThumbnailSettings.GetHashCode();
  1359. return hashCode;
  1360. }
  1361. }
  1362. public class BrushInputData
  1363. {
  1364. public readonly int index;
  1365. public readonly Rect rect;
  1366. public readonly EventType eventType;
  1367. public readonly bool control;
  1368. public readonly bool shift;
  1369. public readonly float mouseX;
  1370. public BrushInputData(int index, Rect rect, EventType eventType, bool control, bool shift, float mouseX)
  1371. {
  1372. this.index = index;
  1373. this.rect = rect;
  1374. this.eventType = eventType;
  1375. this.control = !shift && control;
  1376. this.shift = shift;
  1377. this.mouseX = mouseX;
  1378. }
  1379. }
  1380. #endregion
  1381. #region PALETTE DATA & MANAGER
  1382. [System.Serializable]
  1383. public class PaletteData : ISerializationCallbackReceiver
  1384. {
  1385. [SerializeField] private string _version = PWBData.VERSION;
  1386. [SerializeField] private string _name = null;
  1387. [SerializeField] private long _id = -1;
  1388. [SerializeField]
  1389. private System.Collections.Generic.List<MultibrushSettings> _brushes
  1390. = new System.Collections.Generic.List<MultibrushSettings>();
  1391. [SerializeField] BrushCreationSettings _brushCreationSettings = new BrushCreationSettings();
  1392. [SerializeField] private int _hashCode = 0;
  1393. private string _filePath = null;
  1394. private bool _saving = false;
  1395. public PaletteData(string name, long id) => (_name, _id) = (name, id);
  1396. public string name
  1397. {
  1398. get => _name;
  1399. set
  1400. {
  1401. if (_name == value) return;
  1402. _name = value;
  1403. Save();
  1404. }
  1405. }
  1406. public long id => _id;
  1407. public MultibrushSettings[] brushes => _brushes.Where(b => !b.allPrefabMissing).ToArray();
  1408. public int brushCount => _brushes.Count;
  1409. public BrushCreationSettings brushCreationSettings => _brushCreationSettings;
  1410. public string filePath
  1411. {
  1412. get
  1413. {
  1414. void SetFilePath() => _filePath = PWBData.palettesDirectory + "/"
  1415. + GetFileNameFromData(this, includeExtension: true);
  1416. if (_filePath == null) SetFilePath();
  1417. else if (!System.IO.File.Exists(_filePath)) SetFilePath();
  1418. return _filePath;
  1419. }
  1420. set => _filePath = value;
  1421. }
  1422. public string thumbnailsFolderPath
  1423. {
  1424. get
  1425. {
  1426. var path = PWBData.palettesDirectory + (PWBCore.staticData.createThumbnailsFolder ? "/Thumbnails/" : "/")
  1427. + GetFileNameFromData(this, includeExtension: false);
  1428. if (!System.IO.Directory.Exists(path)) System.IO.Directory.CreateDirectory(path);
  1429. return path;
  1430. }
  1431. }
  1432. public string version { get => _version; set => _version = value; }
  1433. public bool saving => _saving;
  1434. public void StopSaving() => _saving = false;
  1435. public static string GetFileNameFromData(PaletteData data, bool includeExtension)
  1436. => "PWB_" + data._id.ToString("X") + (includeExtension ? ".txt" : "");
  1437. public MultibrushSettings GetBrush(int idx)
  1438. {
  1439. if (idx < 0 || idx >= _brushes.Count) return null;
  1440. if (_brushes[idx].allPrefabMissing) return null;
  1441. return _brushes[idx];
  1442. }
  1443. public void UpdateAllThumbnails()
  1444. {
  1445. foreach (var brush in _brushes) brush.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1446. }
  1447. public void AddBrush(MultibrushSettings brush)
  1448. {
  1449. _brushes.Add(brush);
  1450. brush.palette = this;
  1451. PWBCore.staticData.SaveAndUpdateVersion();
  1452. Save();
  1453. ClearObjectQuery();
  1454. }
  1455. public void RemoveBrushAt(int idx)
  1456. {
  1457. _brushes.RemoveAt(idx);
  1458. PWBCore.staticData.SaveAndUpdateVersion();
  1459. BrushstrokeManager.UpdateBrushstroke();
  1460. Save();
  1461. ClearObjectQuery();
  1462. }
  1463. public void RemoveBrush(MultibrushSettings brush)
  1464. {
  1465. _brushes.Remove(brush);
  1466. PWBCore.staticData.SaveAndUpdateVersion();
  1467. BrushstrokeManager.UpdateBrushstroke();
  1468. PrefabPalette.OnChangeRepaint();
  1469. Save();
  1470. ClearObjectQuery();
  1471. }
  1472. public void InsertBrushAt(MultibrushSettings brush, int idx)
  1473. {
  1474. _brushes.Insert(idx, brush);
  1475. brush.palette = this;
  1476. PWBCore.staticData.SaveAndUpdateVersion();
  1477. Save();
  1478. ClearObjectQuery();
  1479. }
  1480. public void Swap(int fromIdx, int toIdx, ref int[] selection)
  1481. => SelectionUtils.Swap(fromIdx, toIdx, ref selection, _brushes);
  1482. public void AscendingSort()
  1483. {
  1484. _brushes.Sort(delegate (MultibrushSettings x, MultibrushSettings y) { return x.name.CompareTo(y.name); });
  1485. PaletteManager.ClearSelection();
  1486. PWBCore.staticData.SaveAndUpdateVersion();
  1487. PrefabPalette.OnChangeRepaint();
  1488. }
  1489. public void DescendingSort()
  1490. {
  1491. _brushes.Sort(delegate (MultibrushSettings x, MultibrushSettings y) { return y.name.CompareTo(x.name); });
  1492. PaletteManager.ClearSelection();
  1493. PWBCore.staticData.SaveAndUpdateVersion();
  1494. PrefabPalette.OnChangeRepaint();
  1495. }
  1496. public void DuplicateBrush(int index) => DuplicateBrushAt(index, index);
  1497. public void DuplicateBrushAt(int indexToDuplicate, int at)
  1498. {
  1499. var original = _brushes[indexToDuplicate];
  1500. var clone = original.Clone();
  1501. if (clone.thumbnailSettings.useCustomImage)
  1502. {
  1503. clone.thumbnailSettings.useCustomImage = false;
  1504. clone.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1505. clone.thumbnailSettings.useCustomImage = true;
  1506. var thumbnailClone = new Texture2D(original.thumbnail.width, original.thumbnail.height);
  1507. thumbnailClone.SetPixels(original.thumbnail.GetPixels());
  1508. thumbnailClone.Apply();
  1509. clone.SetCustomThumbnailTexture(thumbnailClone, savePng: true);
  1510. }
  1511. else clone.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1512. _brushes.Insert(at, clone as MultibrushSettings);
  1513. PWBCore.staticData.SaveAndUpdateVersion();
  1514. Save();
  1515. }
  1516. public System.Collections.Generic.SortedDictionary<int, bool> _objectQuery
  1517. = new System.Collections.Generic.SortedDictionary<int, bool>();
  1518. public void ClearObjectQuery()
  1519. {
  1520. if (_objectQuery != null) _objectQuery.Clear();
  1521. else _objectQuery = new System.Collections.Generic.SortedDictionary<int, bool>();
  1522. }
  1523. public bool ContainsSceneObject(GameObject obj)
  1524. {
  1525. if (obj == null) return false;
  1526. var objId = obj.GetInstanceID();
  1527. if (_objectQuery == null) _objectQuery = new System.Collections.Generic.SortedDictionary<int, bool>();
  1528. if (_objectQuery.ContainsKey(objId)) return _objectQuery[objId];
  1529. _objectQuery.Add(objId, false);
  1530. var outermostPrefab = UnityEditor.PrefabUtility.GetOutermostPrefabInstanceRoot(obj);
  1531. if (outermostPrefab == null) return false;
  1532. var prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(outermostPrefab);
  1533. if (prefab == null) return false;
  1534. _objectQuery[objId] = _brushes.Exists(brush => brush.ContainsPrefab(prefab.GetInstanceID()));
  1535. return _objectQuery[objId];
  1536. }
  1537. public bool ContainsPrefab(GameObject prefab)
  1538. {
  1539. if (prefab == null) return false;
  1540. return _brushes.Exists(brush => brush.ContainsPrefab(prefab.GetInstanceID()));
  1541. }
  1542. public bool ContainsPrefabPath(string path) => _brushes.Exists(brush => brush.ContainsPrefabPath(path));
  1543. public int FindBrushIdx(GameObject obj)
  1544. {
  1545. if (obj == null) return -1;
  1546. var outermostPrefab = UnityEditor.PrefabUtility.GetOutermostPrefabInstanceRoot(obj);
  1547. if (outermostPrefab == null) return -1;
  1548. var prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(outermostPrefab);
  1549. if (prefab == null) return -1;
  1550. var idx = _brushes.FindIndex(brush => brush.ContainsPrefab(prefab.GetInstanceID()) && brush.itemCount == 1);
  1551. if (idx == -1) idx = _brushes.FindIndex(brush => brush.ContainsPrefab(prefab.GetInstanceID()));
  1552. return idx;
  1553. }
  1554. public bool ContainsBrush(MultibrushSettings brush)
  1555. => _brushes.Contains(brush) || _brushes.Exists(b => b.id == brush.id);
  1556. public static System.Action OnPaletteSaved;
  1557. public string Save()
  1558. {
  1559. _saving = true;
  1560. var jsonString = JsonUtility.ToJson(this, true);
  1561. var fileExist = System.IO.File.Exists(filePath);
  1562. System.IO.File.WriteAllText(filePath, jsonString);
  1563. if (!fileExist) PWBCore.AssetDatabaseRefresh();
  1564. if (OnPaletteSaved != null) OnPaletteSaved();
  1565. return filePath;
  1566. }
  1567. public void Copy(PaletteData other)
  1568. {
  1569. _brushes.Clear();
  1570. var otherBrushes = other.brushes.ToArray();
  1571. var cloneBrushes = otherBrushes.Select(b => b.CloneAndChangePalette(this)).ToArray();
  1572. _brushes.AddRange(cloneBrushes);
  1573. _name = other.name;
  1574. _brushCreationSettings.Copy(other._brushCreationSettings);
  1575. }
  1576. public void ReloadFromFile()
  1577. {
  1578. var fileText = System.IO.File.ReadAllText(_filePath);
  1579. if (string.IsNullOrEmpty(fileText)) return;
  1580. var paletteData = JsonUtility.FromJson<PaletteData>(fileText);
  1581. if (paletteData == null) return;
  1582. Copy(paletteData);
  1583. ClearObjectQuery();
  1584. }
  1585. public void Cleanup()
  1586. {
  1587. foreach (var brush in _brushes.ToArray()) brush.Cleanup();
  1588. Save();
  1589. ClearObjectQuery();
  1590. }
  1591. public int hashCode => _hashCode;
  1592. public override int GetHashCode()
  1593. {
  1594. int hashCode = 917907199;
  1595. hashCode = hashCode * -1521134295 + _version.GetHashCode();
  1596. hashCode = hashCode * -1521134295 + _name.GetHashCode();
  1597. hashCode = hashCode * -1521134295 + _id.GetHashCode();
  1598. foreach (var brush in _brushes) hashCode = hashCode * -1521134295 + brush.GetHashCode();
  1599. hashCode = hashCode * -1521134295 + _brushCreationSettings.GetHashCode();
  1600. return hashCode;
  1601. }
  1602. public void ResetHashCode()
  1603. {
  1604. _hashCode = GetHashCode();
  1605. }
  1606. void ISerializationCallbackReceiver.OnBeforeSerialize()
  1607. {
  1608. _hashCode = GetHashCode();
  1609. }
  1610. void ISerializationCallbackReceiver.OnAfterDeserialize()
  1611. {
  1612. }
  1613. }
  1614. [System.Serializable]
  1615. public struct BasicPaletteData
  1616. {
  1617. [SerializeField] private int _hashCode;
  1618. [SerializeField] private string _name;
  1619. [SerializeField] private long _id;
  1620. public int hashCode => _hashCode;
  1621. public string name => _name;
  1622. public long id => _id;
  1623. }
  1624. [System.Serializable]
  1625. public class PaletteManager : ISerializationCallbackReceiver
  1626. {
  1627. private System.Collections.Generic.List<PaletteData> _paletteDataList
  1628. = new System.Collections.Generic.List<PaletteData>()
  1629. { new PaletteData("Palette", System.DateTime.Now.ToBinary()) };
  1630. public static PaletteData[] paletteData => instance.paletteDataList.ToArray();
  1631. public static bool addingPalettes { get; set; }
  1632. [SerializeField] private int _selectedPaletteIdx = 0;
  1633. [SerializeField] private int _selectedBrushIdx = -1;
  1634. [SerializeField] private bool _showBrushName = false;
  1635. [SerializeField] private bool _viewList = false;
  1636. [SerializeField] private bool _showTabsInMultipleRows = false;
  1637. private System.Collections.Generic.HashSet<int> _idxSelection = new System.Collections.Generic.HashSet<int>();
  1638. public static System.Action OnBrushSelectionChanged;
  1639. public static System.Action OnSelectionChanged;
  1640. public static System.Action OnPaletteChanged;
  1641. private bool _pickingBrushes = false;
  1642. private int _movingBrushesFromIdx = -1;
  1643. public static bool movingBrushes => instance._movingBrushesFromIdx >= 0;
  1644. private System.Collections.Generic.List<MultibrushSettings> _brushesToMove
  1645. = new System.Collections.Generic.List<MultibrushSettings>();
  1646. [SerializeField] private int _iconSize = PrefabPalette.DEFAULT_ICON_SIZE;
  1647. public System.Collections.Generic.List<PaletteData> paletteDataList
  1648. {
  1649. get
  1650. {
  1651. if (_paletteDataList.Count == 0)
  1652. {
  1653. AddPalette(new PaletteData("Palette", System.DateTime.Now.ToBinary()), save: true);
  1654. _selectedPaletteIdx = 0;
  1655. _selectedBrushIdx = -1;
  1656. }
  1657. return _paletteDataList;
  1658. }
  1659. }
  1660. private static PaletteManager _instance = null;
  1661. private PaletteManager() { }
  1662. public static PaletteManager instance
  1663. {
  1664. get
  1665. {
  1666. if (_instance == null) _instance = new PaletteManager();
  1667. return _instance;
  1668. }
  1669. }
  1670. private static bool _loadPaletteFilesPending = false;
  1671. public static void SetLoadPaletteFilesPending() => _loadPaletteFilesPending = true;
  1672. public static bool loadPaletteFilesPending => _loadPaletteFilesPending;
  1673. public void LoadPaletteFiles(bool deleteUnusedThumbnails)
  1674. {
  1675. _loadPaletteFilesPending = false;
  1676. var txtPaths = System.IO.Directory.GetFiles(PWBData.palettesDirectory, "*.txt");
  1677. if (txtPaths.Length == 0)
  1678. {
  1679. if (_paletteDataList.Count == 0)
  1680. _paletteDataList = new System.Collections.Generic.List<PaletteData>()
  1681. { new PaletteData("Palette", System.DateTime.Now.ToBinary()) };
  1682. _paletteDataList[0].filePath = _paletteDataList[0].Save();
  1683. }
  1684. bool clearList = true;
  1685. foreach (var path in txtPaths)
  1686. {
  1687. var fileText = System.IO.File.ReadAllText(path);
  1688. if (string.IsNullOrEmpty(fileText)) continue;
  1689. try
  1690. {
  1691. var basicPaletteDataFromFile = JsonUtility.FromJson<BasicPaletteData>(fileText);
  1692. if (_paletteDataList.Count > 0)
  1693. {
  1694. var sameHash = _paletteDataList.Where(p => p.GetHashCode() == basicPaletteDataFromFile.hashCode);
  1695. if (sameHash.Count() > 0)
  1696. {
  1697. clearList = false;
  1698. continue;
  1699. }
  1700. var sameId = _paletteDataList.Where(p => p.id == basicPaletteDataFromFile.id);
  1701. if (sameId.Count() > 0)
  1702. {
  1703. var currentData = sameId.First();
  1704. currentData.Save();
  1705. clearList = false;
  1706. continue;
  1707. }
  1708. }
  1709. var paletteData = JsonUtility.FromJson<PaletteData>(fileText);
  1710. if (paletteData == null) continue;
  1711. if (clearList)
  1712. {
  1713. _paletteDataList.Clear();
  1714. clearList = false;
  1715. }
  1716. paletteData.filePath = path;
  1717. AddPalette(paletteData, save: false);
  1718. }
  1719. catch
  1720. {
  1721. Debug.LogWarning("PWB found a corrupted palette file at: " + path);
  1722. }
  1723. }
  1724. if (deleteUnusedThumbnails) ThumbnailUtils.DeleteUnusedThumbnails();
  1725. }
  1726. public static void Clear()
  1727. {
  1728. ClearPaletteList();
  1729. instance.paletteDataList.Add(new PaletteData("Palette", System.DateTime.Now.ToBinary()));
  1730. instance._selectedPaletteIdx = 0;
  1731. instance._selectedBrushIdx = -1;
  1732. instance._idxSelection.Clear();
  1733. instance._pickingBrushes = false;
  1734. }
  1735. public static bool showBrushName
  1736. {
  1737. get => instance._showBrushName;
  1738. set
  1739. {
  1740. if (instance._showBrushName == value) return;
  1741. instance._showBrushName = value;
  1742. PWBCore.staticData.SaveAndUpdateVersion();
  1743. }
  1744. }
  1745. public static bool viewList
  1746. {
  1747. get => instance._viewList;
  1748. set
  1749. {
  1750. if (instance._viewList == value) return;
  1751. instance._viewList = value;
  1752. PWBCore.staticData.SaveAndUpdateVersion();
  1753. }
  1754. }
  1755. public static bool showTabsInMultipleRows
  1756. {
  1757. get => instance._showTabsInMultipleRows;
  1758. set
  1759. {
  1760. if (instance._showTabsInMultipleRows == value) return;
  1761. instance._showTabsInMultipleRows = value;
  1762. PWBCore.staticData.SaveAndUpdateVersion();
  1763. }
  1764. }
  1765. public static void ClearPaletteList() => instance._paletteDataList.Clear();
  1766. public static void AddPalette(PaletteData palette, bool save)
  1767. {
  1768. addingPalettes = true;
  1769. if (instance._paletteDataList.Exists(p => p.id == palette.id)) return;
  1770. instance._paletteDataList.Add(palette);
  1771. if (save)
  1772. {
  1773. palette.filePath = PWBData.palettesDirectory + "/"
  1774. + PaletteData.GetFileNameFromData(palette, includeExtension: true);
  1775. palette.Save();
  1776. }
  1777. }
  1778. public static void DuplicatePalette(int paletteIdx)
  1779. {
  1780. var palette = instance._paletteDataList[paletteIdx];
  1781. var cloneId = System.DateTime.Now.ToBinary();
  1782. var cloneName = palette.name + " Copy";
  1783. var clone = new PaletteData(cloneName, cloneId);
  1784. clone.Copy(palette);
  1785. clone.name = cloneName;
  1786. AddPalette(clone, save: true);
  1787. clone.UpdateAllThumbnails();
  1788. }
  1789. public static void RemovePaletteAt(int paletteIdx)
  1790. {
  1791. var filePath = instance._paletteDataList[paletteIdx].filePath;
  1792. var thumbnailFolderPath = instance._paletteDataList[paletteIdx].thumbnailsFolderPath;
  1793. instance._paletteDataList.RemoveAt(paletteIdx);
  1794. var metapath = filePath + ".meta";
  1795. if (System.IO.File.Exists(metapath)) System.IO.File.Delete(metapath);
  1796. if (System.IO.File.Exists(filePath)) System.IO.File.Delete(filePath);
  1797. metapath = thumbnailFolderPath + ".meta";
  1798. if (System.IO.File.Exists(metapath)) System.IO.File.Delete(metapath);
  1799. if (System.IO.Directory.Exists(thumbnailFolderPath))
  1800. System.IO.Directory.Delete(thumbnailFolderPath, true);
  1801. PWBCore.AssetDatabaseRefresh();
  1802. }
  1803. public static void SwapPalette(int from, int to)
  1804. {
  1805. if (from == to) return;
  1806. instance.paletteDataList.Insert(to, instance.paletteDataList[from]);
  1807. var removeIdx = from;
  1808. if (from > to) ++removeIdx;
  1809. instance.paletteDataList.RemoveAt(removeIdx);
  1810. }
  1811. public static void SelectNextPalette()
  1812. {
  1813. if (PrefabPalette.instance == null) return;
  1814. if (paletteCount <= 1) return;
  1815. instance._idxSelection.Clear();
  1816. var idsDic = paletteData.Select((palette, index) => new { palette, index })
  1817. .ToDictionary(item => item.index, item => item.palette);
  1818. var sortedDic = PWBCore.staticData.selectTheNextPaletteInAlphabeticalOrder
  1819. ? (from item in idsDic orderby item.Value.name ascending select item)
  1820. .ToDictionary(pair => pair.Key, pair => pair.Value.id)
  1821. : idsDic.ToDictionary(pair => pair.Key, pair => pair.Value.id);
  1822. var selectedId = selectedPalette.id;
  1823. int sortedIdx = -1;
  1824. var stop = false;
  1825. foreach (var idx in sortedDic.Keys)
  1826. {
  1827. if (sortedIdx == -1) sortedIdx = idx;
  1828. if (stop)
  1829. {
  1830. sortedIdx = idx;
  1831. break;
  1832. }
  1833. stop = sortedDic[idx] == selectedId;
  1834. }
  1835. PrefabPalette.instance.SelectPalette(sortedIdx);
  1836. selectedBrushIdx = 0;
  1837. AddToSelection(selectedBrushIdx);
  1838. PrefabPalette.instance.FrameSelectedBrush();
  1839. PrefabPalette.RepainWindow();
  1840. }
  1841. public static void SelectPreviousPalette()
  1842. {
  1843. if (PrefabPalette.instance == null) return;
  1844. if (paletteCount <= 1) return;
  1845. instance._idxSelection.Clear();
  1846. var idsDic = paletteData.Select((palette, index) => new { palette, index })
  1847. .ToDictionary(item => item.index, item => item.palette);
  1848. var sortedDic = PWBCore.staticData.selectTheNextPaletteInAlphabeticalOrder
  1849. ? (from item in idsDic orderby item.Value.name descending select item)
  1850. .ToDictionary(pair => pair.Key, pair => pair.Value.id)
  1851. : (from item in idsDic orderby item.Key descending select item)
  1852. .ToDictionary(pair => pair.Key, pair => pair.Value.id);
  1853. var selectedId = selectedPalette.id;
  1854. int sortedIdx = -1;
  1855. var stop = false;
  1856. foreach (var idx in sortedDic.Keys)
  1857. {
  1858. if (sortedIdx == -1) sortedIdx = idx;
  1859. if (stop)
  1860. {
  1861. sortedIdx = idx;
  1862. break;
  1863. }
  1864. stop = sortedDic[idx] == selectedId;
  1865. }
  1866. PrefabPalette.instance.SelectPalette(sortedIdx);
  1867. selectedBrushIdx = 0;
  1868. AddToSelection(selectedBrushIdx);
  1869. PrefabPalette.instance.FrameSelectedBrush();
  1870. PrefabPalette.RepainWindow();
  1871. }
  1872. public static string[] paletteNames => instance.paletteDataList.Select(p => p.name).ToArray();
  1873. public static long[] paletteIds => instance.paletteDataList.Select(p => p.id).ToArray();
  1874. public static int selectedPaletteIdx
  1875. {
  1876. get
  1877. {
  1878. instance._selectedPaletteIdx = Mathf.Clamp(instance._selectedPaletteIdx, 0,
  1879. Mathf.Max(instance.paletteDataList.Count - 1, 0));
  1880. return instance._selectedPaletteIdx;
  1881. }
  1882. set
  1883. {
  1884. value = Mathf.Max(value, 0);
  1885. if (instance._selectedPaletteIdx == value) return;
  1886. instance._selectedPaletteIdx = value;
  1887. if (OnPaletteChanged != null) OnPaletteChanged();
  1888. }
  1889. }
  1890. public static int selectedBrushIdx
  1891. {
  1892. get => instance._selectedBrushIdx;
  1893. set
  1894. {
  1895. if (instance._selectedBrushIdx == value) return;
  1896. instance._selectedBrushIdx = value;
  1897. if (selectedBrush != null)
  1898. {
  1899. selectedBrush.UpdateBottomVertices();
  1900. selectedBrush.UpdateAssetTypes();
  1901. }
  1902. else instance._selectedBrushIdx = -1;
  1903. if (PWBCore.staticData.openBrushPropertiesWhenABrushIsSelected && instance._selectedBrushIdx >= 0)
  1904. BrushProperties.ShowWindow();
  1905. BrushstrokeManager.UpdateBrushstroke(true);
  1906. if (ToolManager.tool == ToolManager.PaintTool.PIN) PWBIO.ResetPinValues();
  1907. if (OnBrushSelectionChanged != null) OnBrushSelectionChanged();
  1908. }
  1909. }
  1910. public static bool pickingBrushes
  1911. {
  1912. get => instance._pickingBrushes;
  1913. set
  1914. {
  1915. if (instance._pickingBrushes == value) return;
  1916. instance._pickingBrushes = value;
  1917. if (instance._pickingBrushes)
  1918. {
  1919. PWBCore.UpdateTempColliders();
  1920. PWBIO.repaint = true;
  1921. UnityEditor.SceneView.RepaintAll();
  1922. }
  1923. PrefabPalette.RepainWindow();
  1924. }
  1925. }
  1926. public static int iconSize
  1927. {
  1928. get => instance._iconSize;
  1929. set
  1930. {
  1931. if (instance._iconSize == value) return;
  1932. instance._iconSize = value;
  1933. PWBCore.staticData.SaveAndUpdateVersion();
  1934. }
  1935. }
  1936. public static void SelectBrush(int idx)
  1937. {
  1938. if (PrefabPalette.instance == null) return;
  1939. if (selectedPalette.brushCount == 0) return;
  1940. if (!PrefabPalette.instance.FilteredBrushListContains(idx)) return;
  1941. instance._idxSelection.Clear();
  1942. selectedBrushIdx = idx;
  1943. if (selectedBrush != null)
  1944. {
  1945. selectedBrush.UpdateBottomVertices();
  1946. selectedBrush.UpdateAssetTypes();
  1947. }
  1948. AddToSelection(selectedBrushIdx);
  1949. PrefabPalette.instance.FrameSelectedBrush();
  1950. PrefabPalette.RepainWindow();
  1951. }
  1952. public static void SelectNextBrush()
  1953. {
  1954. if (PrefabPalette.instance == null) return;
  1955. if (selectedPalette.brushCount <= 1) return;
  1956. instance._idxSelection.Clear();
  1957. int selectedIdx = instance._selectedBrushIdx;
  1958. int count = 0;
  1959. do
  1960. {
  1961. selectedIdx = (selectedIdx + 1) % selectedPalette.brushCount;
  1962. if (++count > selectedPalette.brushCount) return;
  1963. }
  1964. while (!PrefabPalette.instance.FilteredBrushListContains(selectedIdx));
  1965. selectedBrushIdx = selectedIdx;
  1966. if (selectedBrush != null)
  1967. {
  1968. selectedBrush.UpdateBottomVertices();
  1969. selectedBrush.UpdateAssetTypes();
  1970. }
  1971. AddToSelection(selectedBrushIdx);
  1972. PrefabPalette.instance.FrameSelectedBrush();
  1973. }
  1974. public static void SelectPreviousBrush()
  1975. {
  1976. if (PrefabPalette.instance == null) return;
  1977. if (selectedPalette.brushCount <= 1) return;
  1978. instance._idxSelection.Clear();
  1979. int selectedIdx = instance._selectedBrushIdx;
  1980. int count = 0;
  1981. do
  1982. {
  1983. selectedIdx = (selectedIdx == 0 ? selectedPalette.brushCount : selectedIdx) - 1;
  1984. if (++count > selectedPalette.brushCount) return;
  1985. }
  1986. while (!PrefabPalette.instance.FilteredBrushListContains(selectedIdx));
  1987. selectedBrushIdx = selectedIdx;
  1988. if (selectedBrush != null)
  1989. {
  1990. selectedBrush.UpdateBottomVertices();
  1991. selectedBrush.UpdateAssetTypes();
  1992. }
  1993. AddToSelection(selectedBrushIdx);
  1994. PrefabPalette.instance.FrameSelectedBrush();
  1995. }
  1996. public static MultibrushSettings selectedBrush
  1997. => instance._selectedBrushIdx < 0 ? null : selectedPalette.GetBrush(instance._selectedBrushIdx);
  1998. public static PaletteData selectedPalette => instance.paletteDataList[selectedPaletteIdx];
  1999. public static int paletteCount => instance.paletteDataList.Count;
  2000. public static MultibrushSettings GetBrushById(long id)
  2001. {
  2002. foreach (var palette in instance.paletteDataList)
  2003. foreach (var brush in palette.brushes)
  2004. if (brush.id == id) return brush;
  2005. return null;
  2006. }
  2007. public static MultibrushSettings GetBrushByThumbnail(string thumbnailPath)
  2008. {
  2009. foreach (var palette in instance.paletteDataList)
  2010. foreach (var brush in palette.brushes)
  2011. if (brush.thumbnailPath == thumbnailPath) return brush;
  2012. return null;
  2013. }
  2014. public static MultibrushSettings GetBrushByItemId(long id)
  2015. {
  2016. foreach (var palette in instance.paletteDataList)
  2017. foreach (var brush in palette.brushes)
  2018. foreach (var item in brush.items)
  2019. if (item.id == id) return brush;
  2020. return null;
  2021. }
  2022. public static bool BrushExist(long id) => instance.paletteDataList.Exists(b => b.id == id);
  2023. public static int GetBrushIdx(long id)
  2024. {
  2025. var palette = selectedPalette;
  2026. var brushes = palette.brushes;
  2027. for (int i = 0; i < brushes.Length; ++i)
  2028. if (brushes[i].id == id) return i;
  2029. return -1;
  2030. }
  2031. public static int[] idxSelection
  2032. {
  2033. get => instance._idxSelection.ToArray();
  2034. set
  2035. {
  2036. instance._idxSelection = new System.Collections.Generic.HashSet<int>(value);
  2037. if (OnSelectionChanged != null) OnSelectionChanged();
  2038. }
  2039. }
  2040. public static int selectionCount
  2041. {
  2042. get
  2043. {
  2044. if (instance._idxSelection.Count == 0 && instance._selectedBrushIdx > 0 && selectedBrush != null)
  2045. {
  2046. instance._idxSelection.Add(instance._selectedBrushIdx);
  2047. if (OnSelectionChanged != null) OnSelectionChanged();
  2048. }
  2049. return instance._idxSelection.Count;
  2050. }
  2051. }
  2052. public static void AddToSelection(int index)
  2053. {
  2054. instance._idxSelection.Add(index);
  2055. if (OnSelectionChanged != null) OnSelectionChanged();
  2056. }
  2057. public static bool SelectionContains(int index) => instance._idxSelection.Contains(index);
  2058. public static void RemoveFromSelection(int index)
  2059. {
  2060. instance._idxSelection.Remove(index);
  2061. if (OnSelectionChanged != null) OnSelectionChanged();
  2062. }
  2063. public static void ClearSelection(bool updateBrushProperties = true)
  2064. {
  2065. selectedBrushIdx = -1;
  2066. instance._idxSelection.Clear();
  2067. if (!updateBrushProperties) return;
  2068. if (OnSelectionChanged != null) OnSelectionChanged();
  2069. BrushProperties.RepaintWindow();
  2070. }
  2071. public static void SelectBrushesToMove()
  2072. {
  2073. instance._movingBrushesFromIdx = selectedPaletteIdx;
  2074. instance._brushesToMove.Clear();
  2075. foreach (var idx in instance._idxSelection) instance._brushesToMove.Add(selectedPalette.GetBrush(idx));
  2076. }
  2077. public static void MoveBrushesToAnotherPalette(int paletteIdx, bool removeFromSource)
  2078. {
  2079. if (instance._movingBrushesFromIdx < 0 || instance._movingBrushesFromIdx >= paletteCount) return;
  2080. if (paletteIdx < 0 || paletteIdx >= paletteCount) return;
  2081. if (instance._movingBrushesFromIdx != paletteIdx)
  2082. {
  2083. var sourcePalette = paletteData[instance._movingBrushesFromIdx];
  2084. var destinationPalette = paletteData[paletteIdx];
  2085. foreach (var brush in instance._brushesToMove)
  2086. {
  2087. destinationPalette.AddBrush(brush);
  2088. if (removeFromSource) sourcePalette.RemoveBrush(brush);
  2089. }
  2090. }
  2091. instance._brushesToMove.Clear();
  2092. instance._movingBrushesFromIdx = -1;
  2093. }
  2094. public static void MoveBrushesToSelectedPalette() => MoveBrushesToAnotherPalette(selectedPaletteIdx, true);
  2095. public static void PasteBrushesToSelectedPalette() => MoveBrushesToAnotherPalette(selectedPaletteIdx, false);
  2096. public static void UpdateSelectedThumbnails()
  2097. {
  2098. foreach (var idx in instance._idxSelection)
  2099. selectedPalette.GetBrush(idx).UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  2100. }
  2101. public static void UpdateAllThumbnails()
  2102. {
  2103. var palettes = instance.paletteDataList.ToArray();
  2104. foreach (var palette in palettes) palette.UpdateAllThumbnails();
  2105. }
  2106. public static PaletteData GetPalette(MultibrushSettings brush)
  2107. {
  2108. foreach (var palette in instance.paletteDataList)
  2109. if (palette.ContainsBrush(brush)) return palette;
  2110. return null;
  2111. }
  2112. public static PaletteData GetPalette(long id)
  2113. {
  2114. foreach (var palette in instance.paletteDataList)
  2115. if (palette.id == id) return palette;
  2116. return null;
  2117. }
  2118. public static string[] GetPaletteThumbnailFolderPaths()
  2119. {
  2120. var paths = new string[instance.paletteDataList.Count];
  2121. for (int i = 0; i < paths.Length; ++i) paths[i] = instance.paletteDataList[i].thumbnailsFolderPath;
  2122. return paths;
  2123. }
  2124. public static void Cleanup()
  2125. {
  2126. foreach (var palette in instance.paletteDataList.ToArray()) palette.Cleanup();
  2127. }
  2128. public void OnBeforeSerialize() { }
  2129. public void OnAfterDeserialize() { }
  2130. private static bool _savePending = false;
  2131. public static bool savePending => _savePending;
  2132. public static void SetSavePending() => _savePending = true;
  2133. private static void SavePalettes()
  2134. {
  2135. foreach (var palette in instance.paletteDataList) palette.Save();
  2136. }
  2137. public static void SaveIfPending()
  2138. {
  2139. if (_savePending) SavePalettes();
  2140. _savePending = false;
  2141. }
  2142. #region CLIPBOARD
  2143. private static BrushSettings _clipboardSettings = null;
  2144. private static ThumbnailSettings _clipboardThumbnailSettings = null;
  2145. public enum Trit { FALSE, TRUE, SAME }
  2146. private static Trit _clipboardOverwriteThumbnailSettings = Trit.FALSE;
  2147. public static BrushSettings clipboardSetting { get => _clipboardSettings; set => _clipboardSettings = value; }
  2148. public static ThumbnailSettings clipboardThumbnailSettings
  2149. { get => _clipboardThumbnailSettings; set => _clipboardThumbnailSettings = value; }
  2150. public static Trit clipboardOverwriteThumbnailSettings
  2151. { get => _clipboardOverwriteThumbnailSettings; set => _clipboardOverwriteThumbnailSettings = value; }
  2152. #endregion
  2153. }
  2154. public class PaletteAssetPostprocessor : UnityEditor.AssetPostprocessor
  2155. {
  2156. static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets,
  2157. string[] movedAssets, string[] movedFromAssetPaths)
  2158. {
  2159. bool repaintPalette = false;
  2160. foreach (var path in importedAssets)
  2161. {
  2162. if (PaletteManager.selectedPalette.ContainsPrefabPath(path))
  2163. {
  2164. repaintPalette = true;
  2165. break;
  2166. }
  2167. }
  2168. foreach (var path in deletedAssets)
  2169. {
  2170. if (PaletteManager.selectedPalette.ContainsPrefabPath(path))
  2171. {
  2172. PaletteManager.Cleanup();
  2173. PaletteManager.ClearSelection();
  2174. repaintPalette = true;
  2175. break;
  2176. }
  2177. }
  2178. if (repaintPalette) PrefabPalette.OnChangeRepaint();
  2179. }
  2180. }
  2181. #endregion
  2182. }