123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor.U2D.Layout;
- using UnityEditor.U2D.Common;
-
- namespace UnityEditor.U2D.Animation
- {
- internal class SpriteBoneInfluenceToolController
- {
- SkinningEvents m_Events;
- ISpriteBoneInfluenceToolModel m_Model;
- public SpriteBoneInfluenceToolController(ISpriteBoneInfluenceToolModel model, SkinningEvents events)
- {
- m_Events = events;
- m_Model = model;
- }
-
- public void Activate()
- {
- m_Events.selectedSpriteChanged.AddListener(OnSpriteSelectionChanged);
- m_Events.boneSelectionChanged.AddListener(OnBoneSelectionChanged);
- m_Events.boneNameChanged.AddListener(OnBoneNameChanged);
- m_Events.skeletonTopologyChanged.AddListener(OnSkeletonTopologyChanged);
- m_Events.meshChanged.AddListener(OnMeshChanged);
- m_Events.skinningModeChanged.AddListener(OnSkinningModeChanged);
-
- ShowHideView(true);
- }
-
- public void Deactivate()
- {
- m_Events.selectedSpriteChanged.RemoveListener(OnSpriteSelectionChanged);
- m_Events.boneSelectionChanged.RemoveListener(OnBoneSelectionChanged);
- m_Events.boneNameChanged.RemoveListener(OnBoneNameChanged);
- m_Events.skeletonTopologyChanged.RemoveListener(OnSkeletonTopologyChanged);
- m_Events.meshChanged.RemoveListener(OnMeshChanged);
- m_Events.skinningModeChanged.RemoveListener(OnSkinningModeChanged);
-
- ShowHideView(false);
- }
-
- void OnMeshChanged(MeshCache mesh)
- {
- if (m_Model.view.visible)
- {
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- UpdateAddRemoveButtons();
- }
- }
-
- void OnSpriteSelectionChanged(SpriteCache sprite)
- {
- if (m_Model.view.visible)
- {
- UpdateSelectedSpriteBoneInfluence();
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- UpdateAddRemoveButtons();
- SetViewHeaderText();
- }
- }
-
- void OnBoneSelectionChanged()
- {
- if (m_Model.view.visible)
- {
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- UpdateAddRemoveButtons();
- }
- }
-
- void OnBoneNameChanged(BoneCache bone)
- {
- if (m_Model.view.visible)
- {
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- }
- }
-
- void OnSkeletonTopologyChanged(SkeletonCache skeleton)
- {
- if (m_Model.view.visible)
- {
- UpdateSelectedSpriteBoneInfluence();
-
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- }
- }
-
- void UpdateAddRemoveButtons()
- {
- m_Model.view.ToggleAddButton(ShouldEnableAddButton());
- m_Model.view.ToggleRemoveButton(InCharacterMode());
- }
-
- public void OnViewCreated()
- {
- m_Model.view.onAddElement += AddSelectedBoneInfluenceToSprite;
- m_Model.view.onRemoveElement += RemoveSelectedBoneInfluenceFromSprite;
- m_Model.view.onReordered += OnReorderBoneInfluenceFromSprite;
- m_Model.view.onSelectionChanged += SelectedBonesFromList;
-
- ShowHideView(false);
- }
-
- void OnSkinningModeChanged(SkinningMode skinningMode)
- {
- UpdateAddRemoveButtons();
- }
-
- void AddSelectedBoneInfluenceToSprite()
- {
- var character = m_Model.characterSkeleton;
-
- if (character == null)
- return;
-
- var characterPart = m_Model.GetSpriteCharacterPart(m_Model.selectedSprite);
- var selectedBones = m_Model.selectedBones;
- var characterBones = characterPart.bones.ToList();
-
- foreach (var bone in selectedBones)
- {
- if (!characterBones.Contains(bone))
- characterBones.Add(bone as BoneCache);
- }
-
- using (m_Model.UndoScope(TextContent.addBoneInfluence))
- {
- characterPart.bones = characterBones.ToArray();
- m_Events.characterPartChanged.Invoke(characterPart);
-
- UpdateSelectedSpriteBoneInfluence();
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- UpdateAddRemoveButtons();
- }
- }
-
- void RemoveSelectedBoneInfluenceFromSprite()
- {
- var character = m_Model.characterSkeleton;
-
- if (character == null)
- return;
-
- var characterPart = m_Model.GetSpriteCharacterPart(m_Model.selectedSprite);
- var selectedBones = m_Model.selectedBones;
- var characterBones = characterPart.bones.ToList();
-
- characterBones.RemoveAll(b => selectedBones.Contains(b));
-
- using (m_Model.UndoScope(TextContent.removeBoneInfluence))
- {
- characterPart.bones = characterBones.ToArray();
- m_Events.characterPartChanged.Invoke(characterPart);
-
- characterPart.sprite.SmoothFill();
- m_Events.meshChanged.Invoke(characterPart.sprite.GetMesh());
-
- UpdateSelectedSpriteBoneInfluence();
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- UpdateAddRemoveButtons();
- }
- }
-
- void OnReorderBoneInfluenceFromSprite(IEnumerable<TransformCache> transformCache)
- {
- var boneCache = transformCache.Cast<BoneCache>();
-
- var character = m_Model.characterSkeleton;
-
- if (character != null)
- {
- var characterPart = m_Model.GetSpriteCharacterPart(m_Model.selectedSprite);
- using (m_Model.UndoScope(TextContent.reorderBoneInfluence))
- {
- characterPart.bones = boneCache.ToArray();
- m_Events.characterPartChanged.Invoke(characterPart);
-
- UpdateSelectedSpriteBoneInfluence();
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- }
- }
- else
- {
- using (m_Model.UndoScope(TextContent.reorderBoneInfluence))
- {
- m_Model.selectedSprite.GetSkeleton().ReorderBones(boneCache);
- m_Events.skeletonTopologyChanged.Invoke(m_Model.selectedSprite.GetSkeleton());
- }
- }
- }
-
- void SelectedBonesFromList(IEnumerable<object> selectedBones)
- {
- using (m_Model.UndoScope(TextContent.boneSelection))
- {
- m_Model.selectedBones = selectedBones.Cast<BoneCache>();
- m_Events.boneSelectionChanged.Invoke();
- }
- }
-
- private void ShowHideView(bool show)
- {
- m_Model.view.SetHiddenFromLayout(!show);
- if (show)
- {
- UpdateSelectedSpriteBoneInfluence();
- m_Model.view.UpdateList(m_Model.selectionInfluencedBones);
- m_Model.view.UpdateSelection(m_Model.selectedBones);
- m_Model.view.listLabelText = TextContent.boneInfluences;
- m_Model.view.SetTooltips(TextContent.addBoneInfluenceTooltip, TextContent.removeBoneInfluenceTooltip);
- UpdateAddRemoveButtons();
- SetViewHeaderText();
- }
- }
-
- void SetViewHeaderText()
- {
- var headerText = m_Model.selectedSprite != null ? m_Model.selectedSprite.name : TextContent.noSpriteSelected;
- m_Model.view.headerText = headerText;
- }
-
- void UpdateSelectedSpriteBoneInfluence()
- {
- var selectedSpriteInfluences = new List<TransformCache>();
- var selectedSprite = m_Model.selectedSprite;
-
- if (selectedSprite != null)
- {
- if (m_Model.hasCharacter)
- {
- var characterPart = m_Model.GetSpriteCharacterPart(selectedSprite);
- selectedSpriteInfluences = characterPart.bones.Cast<TransformCache>().ToList();
- }
- else
- {
- selectedSpriteInfluences = selectedSprite.GetSkeleton().bones.Cast<TransformCache>().ToList();
- }
- }
-
- m_Model.selectionInfluencedBones = selectedSpriteInfluences;
- }
-
- public bool ShouldEnableAddButton()
- {
- if (InCharacterMode())
- {
- var hasSelectedSprite = m_Model.selectedSprite != null;
- var selectedBones = m_Model.selectedBones;
- return hasSelectedSprite && selectedBones.FirstOrDefault(x => !m_Model.selectionInfluencedBones.Contains(x)) != null;
- }
- return false;
- }
-
- private bool InCharacterMode()
- {
- return m_Model.hasCharacter && m_Model.skinningMode == SkinningMode.Character;
- }
- }
-
- internal interface ISpriteBoneInfluenceToolModel
- {
- IInfluenceWindow view { get; }
- IEnumerable<BoneCache> selectedBones { get; set; }
- List<TransformCache> selectionInfluencedBones { get; set; }
- SpriteCache selectedSprite { get; }
- bool hasCharacter { get; }
- SkinningMode skinningMode { get; }
- SkeletonCache characterSkeleton { get; }
- UndoScope UndoScope(string description);
- CharacterPartCache GetSpriteCharacterPart(SpriteCache sprite);
- }
-
- internal class SpriteBoneInfluenceTool : BaseTool, ISpriteBoneInfluenceToolModel
- {
- private SpriteBoneInfluenceToolController m_Controller;
- private MeshPreviewBehaviour m_MeshPreviewBehaviour = new MeshPreviewBehaviour();
- private InfluenceWindow m_View;
-
- public SkeletonTool skeletonTool { set; private get; }
- public override IMeshPreviewBehaviour previewBehaviour => m_MeshPreviewBehaviour;
-
- internal override void OnCreate()
- {
- m_Controller = new SpriteBoneInfluenceToolController(this, skinningCache.events);
- }
-
- IInfluenceWindow ISpriteBoneInfluenceToolModel.view => m_View;
-
- IEnumerable<BoneCache> ISpriteBoneInfluenceToolModel.selectedBones
- {
- get => skinningCache.skeletonSelection.elements;
- set => skinningCache.skeletonSelection.elements = value.ToArray();
- }
-
- List<TransformCache> ISpriteBoneInfluenceToolModel.selectionInfluencedBones { get; set; }
-
- SpriteCache ISpriteBoneInfluenceToolModel.selectedSprite => skinningCache.selectedSprite;
- bool ISpriteBoneInfluenceToolModel.hasCharacter => skinningCache.hasCharacter;
- SkinningMode ISpriteBoneInfluenceToolModel.skinningMode => skinningCache.mode;
- SkeletonCache ISpriteBoneInfluenceToolModel.characterSkeleton => skinningCache.character != null ? skinningCache.character.skeleton : null;
-
- UndoScope ISpriteBoneInfluenceToolModel.UndoScope(string description) { return skinningCache.UndoScope(description); }
-
- protected override void OnActivate()
- {
- m_Controller.Activate();
- if (skeletonTool != null)
- skeletonTool.Activate();
- }
-
- protected override void OnDeactivate()
- {
- m_Controller.Deactivate();
- if (skeletonTool != null)
- skeletonTool.Deactivate();
- }
-
- public override void Initialize(LayoutOverlay layout)
- {
- if (m_View == null)
- {
- m_View = InfluenceWindow.CreateFromUxml();
- m_View.SetListReorderable(true);
- m_View.SetAllowMultiselect(true);
- m_View.LocalizeTextInChildren();
- m_Controller.OnViewCreated();
- }
-
- layout.rightOverlay.Add(m_View);
- }
-
- protected override void OnGUI()
- {
- m_MeshPreviewBehaviour.showWeightMap = true;
- m_MeshPreviewBehaviour.overlaySelected = true;
- m_MeshPreviewBehaviour.drawWireframe = true;
-
- skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
- skeletonTool.mode = SkeletonMode.EditPose;
- skeletonTool.editBindPose = false;
- skeletonTool.DoGUI();
- }
-
- public CharacterPartCache GetSpriteCharacterPart(SpriteCache sprite)
- {
- return sprite.GetCharacterPart();
- }
- }
- }
|