CopyTool.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using UnityEditor.U2D.Layout;
  6. using UnityEngine.U2D;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. internal interface ICopyToolStringStore
  10. {
  11. string stringStore
  12. {
  13. get;
  14. set;
  15. }
  16. }
  17. internal class SystemCopyBufferStringStore : ICopyToolStringStore
  18. {
  19. public string stringStore
  20. {
  21. get { return EditorGUIUtility.systemCopyBuffer; }
  22. set { EditorGUIUtility.systemCopyBuffer = value; }
  23. }
  24. }
  25. internal class CopyTool : MeshToolWrapper
  26. {
  27. public class NewBonesStore
  28. {
  29. public BoneCache[] newBones;
  30. public Dictionary<string, string> newBoneNameDict;
  31. public NewBonesStore()
  32. {
  33. newBones = null;
  34. newBoneNameDict = new Dictionary<string, string>();
  35. }
  36. public void MapAllExistingBones()
  37. {
  38. foreach (var bone in newBones)
  39. newBoneNameDict.Add(bone.name, bone.name);
  40. }
  41. }
  42. private ICopyToolStringStore m_CopyToolStringStore;
  43. private CopyToolView m_CopyToolView;
  44. public float pixelsPerUnit
  45. {
  46. private get;
  47. set;
  48. }
  49. public ICopyToolStringStore copyToolStringStore
  50. {
  51. set { m_CopyToolStringStore = value; }
  52. }
  53. internal override void OnCreate()
  54. {
  55. m_CopyToolView = new CopyToolView();
  56. m_CopyToolView.onPasteActivated += OnPasteActivated;
  57. m_CopyToolStringStore = new SystemCopyBufferStringStore();
  58. disableMeshEditor = true;
  59. }
  60. public override void Initialize(LayoutOverlay layout)
  61. {
  62. m_CopyToolView.Initialize(layout);
  63. }
  64. protected override void OnActivate()
  65. {
  66. base.OnActivate();
  67. m_CopyToolView.Show();
  68. }
  69. protected override void OnDeactivate()
  70. {
  71. base.OnDeactivate();
  72. m_CopyToolView.Hide();
  73. }
  74. private void CopyMeshFromSpriteCache(SpriteCache sprite, SkinningCopySpriteData skinningSpriteData)
  75. {
  76. if (meshTool == null)
  77. return;
  78. meshTool.SetupSprite(sprite);
  79. skinningSpriteData.vertices = meshTool.mesh.vertices;
  80. skinningSpriteData.indices = meshTool.mesh.indices;
  81. skinningSpriteData.edges = meshTool.mesh.edges;
  82. skinningSpriteData.boneWeightNames = new List<string>();
  83. foreach (var bone in meshTool.mesh.bones)
  84. {
  85. skinningSpriteData.boneWeightNames.Add(bone.name);
  86. }
  87. }
  88. public void OnCopyActivated()
  89. {
  90. SkinningCopyData skinningCopyData = null;
  91. var selectedSprite = skinningCache.selectedSprite;
  92. if (selectedSprite == null)
  93. {
  94. var sprites = skinningCache.GetSprites();
  95. if(!skinningCache.character || sprites.Length > 1)
  96. skinningCopyData = CopyAll();
  97. else if(sprites.Length == 1)
  98. skinningCopyData = CopySingle(sprites[0]);
  99. }
  100. else
  101. {
  102. skinningCopyData = CopySingle(selectedSprite);
  103. }
  104. if (skinningCopyData != null)
  105. m_CopyToolStringStore.stringStore = SkinningCopyUtility.SerializeSkinningCopyDataToString(skinningCopyData);
  106. skinningCache.events.copy.Invoke();
  107. }
  108. SkinningCopyData CopyAll()
  109. {
  110. var skinningCopyData = new SkinningCopyData();
  111. skinningCopyData.pixelsPerUnit = pixelsPerUnit;
  112. var sprites = skinningCache.GetSprites();
  113. foreach (var sprite in sprites)
  114. {
  115. var skinningSpriteData = new SkinningCopySpriteData();
  116. skinningSpriteData.spriteName = sprite.name;
  117. var skeleton = skinningCache.GetEffectiveSkeleton(sprite);
  118. if (skeleton != null && skeleton.BoneCount > 0)
  119. {
  120. if (skinningCache.hasCharacter)
  121. {
  122. // Order doesn't matter for character bones
  123. skinningSpriteData.spriteBones = skeleton.bones.ToSpriteBone(Matrix4x4.identity).Select(x => new SpriteBoneCopyData()
  124. {
  125. spriteBone = x,
  126. order = -1
  127. }).ToList();
  128. }
  129. else
  130. {
  131. skinningSpriteData.spriteBones = new List<SpriteBoneCopyData>();
  132. var bones = skeleton.bones.FindRoots();
  133. foreach (var bone in bones)
  134. GetSpriteBoneDataRecursively(skinningSpriteData.spriteBones, bone, skeleton.bones.ToList());
  135. }
  136. }
  137. if (meshTool != null)
  138. {
  139. CopyMeshFromSpriteCache(sprite, skinningSpriteData);
  140. }
  141. skinningCopyData.copyData.Add(skinningSpriteData);
  142. }
  143. if (meshTool != null)
  144. {
  145. meshTool.SetupSprite(null);
  146. }
  147. return skinningCopyData;
  148. }
  149. SkinningCopyData CopySingle(SpriteCache sprite)
  150. {
  151. var skinningCopyData = new SkinningCopyData();
  152. skinningCopyData.pixelsPerUnit = pixelsPerUnit;
  153. // Mesh
  154. var skinningSpriteData = new SkinningCopySpriteData();
  155. skinningSpriteData.spriteName = sprite.name;
  156. skinningCopyData.copyData.Add(skinningSpriteData);
  157. CopyMeshFromSpriteCache(sprite, skinningSpriteData);
  158. // Bones
  159. var rootBones = new List<BoneCache>();
  160. BoneCache[] boneCache = null;
  161. if (skinningCache.hasCharacter)
  162. {
  163. var characterPart = skinningCache.GetCharacterPart(sprite);
  164. if (characterPart != null && characterPart.bones != null)
  165. {
  166. boneCache = characterPart.bones;
  167. var bones = characterPart.bones.FindRoots();
  168. foreach (var bone in bones)
  169. rootBones.Add(bone);
  170. }
  171. }
  172. else
  173. {
  174. var skeleton = skinningCache.GetEffectiveSkeleton(sprite);
  175. if (skeleton != null && skeleton.BoneCount > 0)
  176. {
  177. boneCache = skeleton.bones;
  178. var bones = boneCache.FindRoots();
  179. foreach (var bone in bones)
  180. rootBones.Add(bone);
  181. }
  182. }
  183. if (rootBones.Count > 0)
  184. {
  185. skinningSpriteData.spriteBones = new List<SpriteBoneCopyData>();
  186. foreach (var rootBone in rootBones)
  187. {
  188. var rootBoneIndex = skinningSpriteData.spriteBones.Count;
  189. GetSpriteBoneDataRecursively(skinningSpriteData.spriteBones, rootBone, boneCache.ToList());
  190. if (skinningCache.hasCharacter)
  191. {
  192. // Offset the bones based on the currently selected Sprite in Character mode
  193. var characterPart = sprite.GetCharacterPart();
  194. if (characterPart != null)
  195. {
  196. var offset = characterPart.position;
  197. var rootSpriteBone = skinningSpriteData.spriteBones[rootBoneIndex];
  198. rootSpriteBone.spriteBone.position = rootSpriteBone.spriteBone.position - offset;
  199. skinningSpriteData.spriteBones[rootBoneIndex] = rootSpriteBone;
  200. }
  201. }
  202. }
  203. }
  204. return skinningCopyData;
  205. }
  206. private void GetSpriteBoneDataRecursively(List<SpriteBoneCopyData> bones, BoneCache rootBone, List<BoneCache> boneCache)
  207. {
  208. AppendSpriteBoneDataRecursively(bones, rootBone, -1, boneCache);
  209. }
  210. private void AppendSpriteBoneDataRecursively(List<SpriteBoneCopyData> spriteBones, BoneCache bone, int parentIndex, List<BoneCache> boneCache)
  211. {
  212. int currentParentIndex = spriteBones.Count;
  213. var boneCopyData = new SpriteBoneCopyData()
  214. {
  215. spriteBone = new SpriteBone()
  216. {
  217. name = bone.name,
  218. parentId = parentIndex
  219. },
  220. order = boneCache.FindIndex(x => x == bone)
  221. };
  222. if (boneCopyData.order < 0)
  223. {
  224. boneCopyData.order = boneCache.Count;
  225. boneCache.Add(bone);
  226. }
  227. if (parentIndex == -1 && bone.parentBone != null)
  228. {
  229. boneCopyData.spriteBone.position = bone.position;
  230. boneCopyData.spriteBone.rotation = bone.rotation;
  231. }
  232. else
  233. {
  234. boneCopyData.spriteBone.position = bone.localPosition;
  235. boneCopyData.spriteBone.rotation = bone.localRotation;
  236. }
  237. boneCopyData.spriteBone.position = new Vector3(boneCopyData.spriteBone.position.x, boneCopyData.spriteBone.position.y, bone.depth);
  238. boneCopyData.spriteBone.length = bone.localLength;
  239. spriteBones.Add(boneCopyData);
  240. foreach (var child in bone)
  241. {
  242. var childBone = child as BoneCache;
  243. if (childBone != null)
  244. AppendSpriteBoneDataRecursively(spriteBones, childBone, currentParentIndex, boneCache);
  245. }
  246. }
  247. public void OnPasteActivated(bool bone, bool mesh, bool flipX, bool flipY)
  248. {
  249. var copyBuffer = m_CopyToolStringStore.stringStore;
  250. if (!SkinningCopyUtility.CanDeserializeStringToSkinningCopyData(copyBuffer))
  251. {
  252. Debug.LogError(TextContent.copyError1);
  253. return;
  254. }
  255. var skinningCopyData = SkinningCopyUtility.DeserializeStringToSkinningCopyData(copyBuffer);
  256. if (skinningCopyData == null || skinningCopyData.copyData.Count == 0)
  257. {
  258. Debug.LogError(TextContent.copyError2);
  259. return;
  260. }
  261. var scale = 1f;
  262. if (skinningCopyData.pixelsPerUnit > 0f)
  263. scale = pixelsPerUnit / skinningCopyData.pixelsPerUnit;
  264. var sprites = skinningCache.GetSprites();
  265. var copyMultiple = skinningCopyData.copyData.Count > 1;
  266. if (copyMultiple && skinningCopyData.copyData.Count != sprites.Length && mesh)
  267. {
  268. Debug.LogError(String.Format(TextContent.copyError3, sprites.Length, skinningCopyData.copyData.Count));
  269. return;
  270. }
  271. using (skinningCache.UndoScope(TextContent.pasteData))
  272. {
  273. NewBonesStore newBonesStore = null;
  274. if (bone && copyMultiple && skinningCache.hasCharacter)
  275. {
  276. newBonesStore = new NewBonesStore();
  277. var skinningSpriteData = skinningCopyData.copyData[0];
  278. newBonesStore.newBones = skinningCache.CreateBoneCacheFromSpriteBones(skinningSpriteData.spriteBones.Select(y => y.spriteBone).ToArray(), scale);
  279. if (flipX || flipY)
  280. {
  281. var characterRect = new Rect(Vector2.zero, skinningCache.character.dimension);
  282. var newPositions = new Vector3[newBonesStore.newBones.Length];
  283. var newRotations = new Quaternion[newBonesStore.newBones.Length];
  284. for (var i = 0; i < newBonesStore.newBones.Length; ++i)
  285. {
  286. newPositions[i] = GetFlippedBonePosition(newBonesStore.newBones[i], Vector2.zero, characterRect, flipX, flipY);
  287. newRotations[i] = GetFlippedBoneRotation(newBonesStore.newBones[i], flipX, flipY);
  288. }
  289. for (var i = 0; i < newBonesStore.newBones.Length; ++i)
  290. {
  291. newBonesStore.newBones[i].position = newPositions[i];
  292. newBonesStore.newBones[i].rotation = newRotations[i];
  293. }
  294. }
  295. newBonesStore.MapAllExistingBones();
  296. var skeleton = skinningCache.character.skeleton;
  297. skeleton.SetBones(newBonesStore.newBones);
  298. skinningCache.events.skeletonTopologyChanged.Invoke(skeleton);
  299. }
  300. foreach (var skinningSpriteData in skinningCopyData.copyData)
  301. {
  302. SpriteCache sprite = null;
  303. if (skinningCache.selectedSprite != null && skinningCopyData.copyData.Count == 1)
  304. {
  305. sprite = skinningCache.selectedSprite;
  306. }
  307. if (sprite == null && !string.IsNullOrEmpty(skinningSpriteData.spriteName))
  308. {
  309. sprite = sprites.FirstOrDefault(x => x.name == skinningSpriteData.spriteName);
  310. }
  311. if (sprite == null)
  312. continue;
  313. if (bone && (!skinningCache.hasCharacter || !copyMultiple))
  314. {
  315. var spriteBones = new SpriteBone[skinningSpriteData.spriteBones.Count];
  316. for (int i = 0; i < skinningSpriteData.spriteBones.Count; ++i)
  317. {
  318. var order = skinningSpriteData.spriteBones[i].order;
  319. spriteBones[order] = skinningSpriteData.spriteBones[i].spriteBone;
  320. var parentId = spriteBones[order].parentId;
  321. if (parentId >= 0)
  322. {
  323. spriteBones[order].parentId = skinningSpriteData.spriteBones[parentId].order;
  324. }
  325. }
  326. newBonesStore = PasteSkeletonBones(sprite, spriteBones.ToList(), flipX, flipY, scale);
  327. }
  328. if (mesh && meshTool != null)
  329. {
  330. PasteMesh(sprite, skinningSpriteData, flipX, flipY, scale, newBonesStore);
  331. }
  332. }
  333. if (newBonesStore != null && newBonesStore.newBones != null)
  334. {
  335. skinningCache.skeletonSelection.elements = newBonesStore.newBones;
  336. skinningCache.events.boneSelectionChanged.Invoke();
  337. }
  338. }
  339. skinningCache.events.paste.Invoke(bone, mesh, flipX, flipY);
  340. }
  341. private Vector3 GetFlippedBonePosition(BoneCache bone, Vector2 startPosition, Rect spriteRect
  342. , bool flipX, bool flipY)
  343. {
  344. Vector3 position = startPosition;
  345. if (flipX)
  346. {
  347. position.x += spriteRect.width - bone.position.x;
  348. }
  349. else
  350. {
  351. position.x += bone.position.x;
  352. }
  353. if (flipY)
  354. {
  355. position.y += spriteRect.height - bone.position.y;
  356. }
  357. else
  358. {
  359. position.y += bone.position.y;
  360. }
  361. position.z = bone.position.z;
  362. return position;
  363. }
  364. private Quaternion GetFlippedBoneRotation(BoneCache bone, bool flipX, bool flipY)
  365. {
  366. var euler = bone.rotation.eulerAngles;
  367. if (flipX)
  368. {
  369. if (euler.z <= 180)
  370. {
  371. euler.z = 180 - euler.z;
  372. }
  373. else
  374. {
  375. euler.z = 540 - euler.z;
  376. }
  377. }
  378. if (flipY)
  379. {
  380. euler.z = 360 - euler.z;
  381. }
  382. return Quaternion.Euler(euler);
  383. }
  384. void SetBonePositionAndRotation(BoneCache[] boneCache, TransformCache bone, Vector3[] position, Quaternion[] rotation)
  385. {
  386. var index = Array.FindIndex(boneCache, x => x == bone);
  387. if (index >= 0)
  388. {
  389. bone.position = position[index];
  390. bone.rotation = rotation[index];
  391. }
  392. foreach (var child in bone.children)
  393. {
  394. SetBonePositionAndRotation(boneCache, child, position, rotation);
  395. }
  396. }
  397. public NewBonesStore PasteSkeletonBones(SpriteCache sprite, List<SpriteBone> spriteBones, bool flipX, bool flipY, float scale = 1.0f)
  398. {
  399. NewBonesStore newBonesStore = new NewBonesStore();
  400. newBonesStore.newBones = skinningCache.CreateBoneCacheFromSpriteBones(spriteBones.ToArray(), scale);
  401. if (newBonesStore.newBones.Length == 0)
  402. return null;
  403. if (sprite == null || (skinningCache.mode == SkinningMode.SpriteSheet && skinningCache.hasCharacter))
  404. return null;
  405. var spriteRect = sprite.textureRect;
  406. var skeleton = skinningCache.GetEffectiveSkeleton(sprite);
  407. var rectPosition = spriteRect.position;
  408. if (skinningCache.mode == SkinningMode.Character)
  409. {
  410. var characterPart = sprite.GetCharacterPart();
  411. if (characterPart == null)
  412. return null;
  413. rectPosition = characterPart.position;
  414. }
  415. var newPositions = new Vector3[newBonesStore.newBones.Length];
  416. var newRotations = new Quaternion[newBonesStore.newBones.Length];
  417. for (var i = 0; i < newBonesStore.newBones.Length; ++i)
  418. {
  419. newPositions[i] = GetFlippedBonePosition(newBonesStore.newBones[i], rectPosition, spriteRect, flipX, flipY);
  420. newRotations[i] = GetFlippedBoneRotation(newBonesStore.newBones[i], flipX, flipY);
  421. }
  422. for (var i = 0; i < newBonesStore.newBones.Length; ++i)
  423. {
  424. if(newBonesStore.newBones[i].parent == null)
  425. SetBonePositionAndRotation(newBonesStore.newBones, newBonesStore.newBones[i], newPositions, newRotations);
  426. }
  427. if (skinningCache.mode == SkinningMode.SpriteSheet)
  428. {
  429. newBonesStore.MapAllExistingBones();
  430. skeleton.SetBones(newBonesStore.newBones);
  431. }
  432. else
  433. {
  434. var existingBoneNames = skeleton.bones.Select(x => x.name).ToList();
  435. skeleton.AddBones(newBonesStore.newBones);
  436. var bones = skeleton.bones;
  437. // Update names of all newly pasted bones
  438. foreach (var bone in newBonesStore.newBones)
  439. {
  440. if (existingBoneNames.Contains(bone.name))
  441. {
  442. var oldBoneName = bone.name;
  443. bone.name = SkeletonController.AutoBoneName(bone.parentBone, bones);
  444. existingBoneNames.Add(bone.name);
  445. newBonesStore.newBoneNameDict.Add(oldBoneName, bone.name);
  446. }
  447. else
  448. {
  449. newBonesStore.newBoneNameDict.Add(bone.name, bone.name);
  450. }
  451. }
  452. skeleton.SetDefaultPose();
  453. }
  454. skinningCache.events.skeletonTopologyChanged.Invoke(skeleton);
  455. return newBonesStore;
  456. }
  457. public void PasteMesh(SpriteCache sprite, SkinningCopySpriteData skinningSpriteData, bool flipX, bool flipY, float scale, NewBonesStore newBonesStore)
  458. {
  459. if (sprite == null)
  460. return;
  461. meshTool.SetupSprite(sprite);
  462. meshTool.mesh.vertices = skinningSpriteData.vertices;
  463. if (!Mathf.Approximately(scale, 1f) || flipX || flipY)
  464. {
  465. var spriteRect = sprite.textureRect;
  466. foreach (var vertex in meshTool.mesh.vertices)
  467. {
  468. var position = vertex.position;
  469. if (!Mathf.Approximately(scale, 1f))
  470. position = position * scale;
  471. if (flipX)
  472. position.x = spriteRect.width - vertex.position.x;
  473. if (flipY)
  474. position.y = spriteRect.height - vertex.position.y;
  475. vertex.position = position;
  476. }
  477. }
  478. meshTool.mesh.indices = skinningSpriteData.indices;
  479. meshTool.mesh.edges = skinningSpriteData.edges;
  480. int[] copyBoneToNewBones = new int[skinningSpriteData.boneWeightNames.Count];
  481. BoneCache[] setBones = null;
  482. if (newBonesStore != null && newBonesStore.newBones != null)
  483. {
  484. // Update bone weights with new bone indices
  485. var setBonesList = new List<BoneCache>();
  486. copyBoneToNewBones = new int[skinningSpriteData.boneWeightNames.Count];
  487. int index = 0;
  488. for (int i = 0; i < skinningSpriteData.boneWeightNames.Count; ++i)
  489. {
  490. string oldBoneName = skinningSpriteData.boneWeightNames[i];
  491. string newBoneName;
  492. newBonesStore.newBoneNameDict.TryGetValue(oldBoneName, out newBoneName);
  493. var newBone = newBonesStore.newBones.FirstOrDefault(bone => bone.name == newBoneName);
  494. copyBoneToNewBones[i] = -1;
  495. if (newBone == null)
  496. continue;
  497. for (int j = 0; j < skinningSpriteData.spriteBones.Count; ++j)
  498. {
  499. if (skinningSpriteData.spriteBones[j].spriteBone.name == oldBoneName)
  500. {
  501. copyBoneToNewBones[i] = index++;
  502. setBonesList.Add(newBone);
  503. break;
  504. }
  505. }
  506. }
  507. setBones = setBonesList.ToArray();
  508. }
  509. else
  510. {
  511. // Attempt to link weights based on existing bone names
  512. var skeleton = skinningCache.GetEffectiveSkeleton(sprite);
  513. var characterBones = new List<BoneCache>();
  514. for (int i = 0; i < skinningSpriteData.boneWeightNames.Count; ++i)
  515. {
  516. copyBoneToNewBones[i] = -1;
  517. var boneName = skinningSpriteData.boneWeightNames[i];
  518. for (int j = 0; j < skeleton.bones.Length; ++j)
  519. {
  520. if (skeleton.bones[j].name == boneName)
  521. {
  522. copyBoneToNewBones[i] = characterBones.Count;
  523. characterBones.Add(skeleton.bones[j]);
  524. break;
  525. }
  526. }
  527. }
  528. setBones = characterBones.ToArray();
  529. }
  530. // Remap new bone indexes from copied bone indexes
  531. foreach (var vertex in meshTool.mesh.vertices)
  532. {
  533. var editableBoneWeight = vertex.editableBoneWeight;
  534. for (var i = 0; i < editableBoneWeight.Count; ++i)
  535. {
  536. if (!editableBoneWeight[i].enabled)
  537. continue;
  538. if (copyBoneToNewBones.Length > editableBoneWeight[i].boneIndex)
  539. {
  540. var boneIndex = copyBoneToNewBones[editableBoneWeight[i].boneIndex];
  541. if (boneIndex != -1)
  542. editableBoneWeight[i].boneIndex = boneIndex;
  543. }
  544. }
  545. }
  546. // Update associated bones for mesh
  547. meshTool.mesh.SetCompatibleBoneSet(setBones);
  548. meshTool.mesh.bones = setBones; // Fixes weights for bones that do not exist
  549. // Update associated bones for character
  550. if (skinningCache.hasCharacter)
  551. {
  552. var characterPart = sprite.GetCharacterPart();
  553. if (characterPart != null)
  554. {
  555. characterPart.bones = setBones;
  556. skinningCache.events.characterPartChanged.Invoke(characterPart);
  557. }
  558. }
  559. meshTool.UpdateMesh();
  560. }
  561. }
  562. internal class CopyToolView
  563. {
  564. private PastePanel m_PastePanel;
  565. public event Action<bool, bool, bool, bool> onPasteActivated = (bone, mesh, flipX, flipY) => {};
  566. public void Show()
  567. {
  568. m_PastePanel.SetHiddenFromLayout(false);
  569. }
  570. public void Hide()
  571. {
  572. m_PastePanel.SetHiddenFromLayout(true);
  573. }
  574. public void Initialize(LayoutOverlay layoutOverlay)
  575. {
  576. m_PastePanel = PastePanel.GenerateFromUXML();
  577. BindElements();
  578. layoutOverlay.rightOverlay.Add(m_PastePanel);
  579. m_PastePanel.SetHiddenFromLayout(true);
  580. }
  581. void BindElements()
  582. {
  583. m_PastePanel.onPasteActivated += OnPasteActivated;
  584. }
  585. void OnPasteActivated(bool bone, bool mesh, bool flipX, bool flipY)
  586. {
  587. onPasteActivated(bone, mesh, flipX, flipY);
  588. }
  589. }
  590. }