123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- using UnityEngine;
- using UnityEditor.U2D.Layout;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace UnityEditor.U2D.Animation
- {
- internal enum WeightPainterMode
- {
- Brush,
- Slider
- }
- internal class WeightPainterTool : MeshToolWrapper
- {
- private WeightPainterPanel m_WeightPainterPanel;
- private WeightEditor m_WeightEditor = new WeightEditor();
- private Brush m_Brush = new Brush(new GUIWrapper());
- private ISelection<int> m_BrushSelection = new IndexedSelection();
- private CircleVertexSelector m_CircleVertexSelector = new CircleVertexSelector();
- public WeightPainterMode paintMode
- {
- get { return m_WeightPainterPanel.paintMode; }
- set { m_WeightPainterPanel.paintMode = value; }
- }
- public override int defaultControlID
- {
- get { return m_Brush.controlID; }
- }
- internal override void OnCreate()
- {
- m_WeightEditor.cacheUndo = skinningCache;
- m_Brush.onMove += (brush) =>
- {
- UpdateBrushSelection(brush);
- };
- m_Brush.onRepaint += (brush) =>
- {
- DrawBrush(brush);
- };
- m_Brush.onSize += (brush) =>
- {
- UpdateBrushSelection(brush);
- m_WeightPainterPanel.size = Mathf.RoundToInt(brush.size);
- };
- m_Brush.onStrokeBegin += (brush) =>
- {
- UpdateBrushSelection(brush);
- EditStart(m_BrushSelection, true);
- };
- m_Brush.onStrokeDelta += (brush) =>
- {
- if (m_BrushSelection.Count > 0)
- meshTool.UpdateWeights();
- };
- m_Brush.onStrokeStep += (brush) =>
- {
- UpdateBrushSelection(brush);
- var hardness = brush.hardness / 100f;
- if (EditorGUI.actionKey)
- hardness *= -1f;
- EditWeights(hardness, false);
- };
- m_Brush.onStrokeEnd += (brush) =>
- {
- EditEnd();
- };
- }
- public string panelTitle
- {
- set { m_WeightPainterPanel.title = value; }
- }
- protected override void OnActivate()
- {
- base.OnActivate();
- m_WeightPainterPanel.SetHiddenFromLayout(false);
- skinningCache.events.selectedSpriteChanged.AddListener(OnSelectedSpriteChanged);
- skinningCache.events.skinningModeChanged.AddListener(OnSkinningModeChanged);
- skinningCache.events.boneSelectionChanged.AddListener(OnBoneSelectionChanged);
- m_Brush.size = skinningCache.brushSize;
- m_Brush.hardness = skinningCache.brushHardness;
- m_Brush.step = skinningCache.brushStep;
- m_WeightPainterPanel.size = (int) m_Brush.size;
- m_WeightPainterPanel.hardness = (int) m_Brush.hardness;
- m_WeightPainterPanel.step = (int) m_Brush.step;
- UpdatePanel();
- }
- protected override void OnDeactivate()
- {
- base.OnDeactivate();
- skinningCache.events.selectedSpriteChanged.RemoveListener(OnSelectedSpriteChanged);
- skinningCache.events.skinningModeChanged.RemoveListener(OnSkinningModeChanged);
- skinningCache.events.boneSelectionChanged.RemoveListener(OnBoneSelectionChanged);
- m_WeightPainterPanel.SetHiddenFromLayout(true);
- }
- private void OnBoneSelectionChanged()
- {
- UpdateSelectedBone();
- }
- private void OnSelectedSpriteChanged(SpriteCache sprite)
- {
- UpdatePanel();
- }
- private void OnSkinningModeChanged(SkinningMode mode)
- {
- UpdatePanel();
- }
- private string[] GetSkeletonBonesNames()
- {
- var names = new List<string>() { WeightPainterPanel.kNone };
- var skeleton = skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite);
- if (skeleton != null)
- names.AddRange(GetUniqueBoneNames(skeleton.bones, skeleton));
- return names.ToArray();
- }
- private string[] GetMeshBoneNames()
- {
- var mesh = meshTool.mesh;
- var skeleton = skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite);
- if (mesh != null && skeleton != null)
- {
- var bones = meshTool.mesh.bones.ToSpriteSheetIfNeeded();
- return GetUniqueBoneNames(bones, skeleton);
- }
- return new string[0];
- }
- private string[] GetUniqueBoneNames(BoneCache[] bones, SkeletonCache skeleton)
- {
- return Array.ConvertAll(bones, b => skeleton.GetUniqueName(b));
- }
- private void UpdatePanel()
- {
- m_WeightPainterPanel.SetActive(skinningCache.selectedSprite != null);
- m_WeightPainterPanel.UpdateWeightInspector(meshTool.mesh, GetMeshBoneNames(), skinningCache.vertexSelection, skinningCache);
- m_WeightPainterPanel.UpdatePanel(GetSkeletonBonesNames());
- UpdateSelectedBone();
- }
- private void UpdateSelectedBone()
- {
- var boneName = WeightPainterPanel.kNone;
- var bone = skinningCache.skeletonSelection.activeElement.ToSpriteSheetIfNeeded();
- var skeleton = skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite);
- if (skeleton != null && skeleton.Contains(bone))
- boneName = skeleton.GetUniqueName(bone);
- m_WeightPainterPanel.SetBoneSelectionByName(boneName);
- }
- public override void Initialize(LayoutOverlay layout)
- {
- base.Initialize(layout);
- m_WeightPainterPanel = WeightPainterPanel.GenerateFromUXML();
- m_WeightPainterPanel.SetHiddenFromLayout(true);
- layout.rightOverlay.Add(m_WeightPainterPanel);
- m_WeightPainterPanel.sliderStarted += () =>
- {
- EditStart(skinningCache.vertexSelection, false);
- };
- m_WeightPainterPanel.sliderChanged += (value) =>
- {
- EditWeights(value, true);
- meshTool.UpdateWeights();
- };
- m_WeightPainterPanel.sliderEnded += () =>
- {
- EditEnd();
- };
- m_WeightPainterPanel.bonePopupChanged += (i) =>
- {
- var skeleton = skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite);
- if (skeleton != null)
- {
- BoneCache bone = null;
- if (i != -1)
- bone = skeleton.GetBone(i).ToCharacterIfNeeded();
- if(bone != skinningCache.skeletonSelection.activeElement)
- {
- using (skinningCache.UndoScope(TextContent.boneSelection))
- {
- skinningCache.skeletonSelection.activeElement = bone;
- InvokeBoneSelectionChanged();
- }
- }
- }
- };
- m_WeightPainterPanel.weightsChanged += () => meshTool.UpdateWeights();
- }
- internal void SetWeightPainterPanelTitle(string title)
- {
- m_WeightPainterPanel.title = title;
- }
- private void AssociateSelectedBoneToCharacterPart()
- {
- var mesh = meshTool.mesh;
- if (skinningCache.hasCharacter
- && skinningCache.mode == SkinningMode.Character
- && m_WeightPainterPanel.boneIndex != -1
- && mesh != null)
- {
- var skeleton = skinningCache.character.skeleton;
- Debug.Assert(skeleton != null);
- var bone = skeleton.GetBone(m_WeightPainterPanel.boneIndex);
- if (!mesh.ContainsBone(bone))
- {
- using (skinningCache.UndoScope(TextContent.addBoneInfluence))
- {
- var characterPart = mesh.sprite.GetCharacterPart();
- var characterBones = characterPart.bones.ToList();
- characterBones.Add(bone);
- characterPart.bones = characterBones.ToArray();
- skinningCache.events.characterPartChanged.Invoke(characterPart);
- m_WeightPainterPanel.UpdateWeightInspector(meshTool.mesh, GetMeshBoneNames(), skinningCache.vertexSelection, skinningCache);
- }
- }
- }
- }
-
- private void EditStart(ISelection<int> selection, bool relative)
- {
- AssociateSelectedBoneToCharacterPart();
- SetupWeightEditor(selection);
- if (m_WeightEditor.spriteMeshData != null)
- m_WeightEditor.OnEditStart(relative);
- }
- private void EditWeights(float hardness, bool emptySelectionEditsAll)
- {
- m_WeightEditor.emptySelectionEditsAll = emptySelectionEditsAll;
- if (m_WeightEditor.spriteMeshData != null)
- m_WeightEditor.DoEdit(hardness);
- }
- private void EditEnd()
- {
- if (m_WeightEditor.spriteMeshData != null)
- {
- m_WeightEditor.OnEditEnd();
- meshTool.UpdateWeights();
- }
- }
- private void InvokeBoneSelectionChanged()
- {
- skinningCache.events.boneSelectionChanged.RemoveListener(OnBoneSelectionChanged);
- skinningCache.events.boneSelectionChanged.Invoke();
- skinningCache.events.boneSelectionChanged.AddListener(OnBoneSelectionChanged);
- }
- private int ConvertBoneIndex(int index)
- {
- if (index != -1 && meshTool.mesh != null)
- {
- var skeleton = skinningCache.GetEffectiveSkeleton(meshTool.mesh.sprite);
- if (skeleton != null)
- {
- var bone = skeleton.GetBone(index).ToCharacterIfNeeded();
- index = Array.IndexOf(meshTool.mesh.bones, bone);
- }
- }
- return index;
- }
- private void SetupWeightEditor(ISelection<int> selection)
- {
- m_WeightEditor.spriteMeshData = meshTool.mesh;
- m_WeightEditor.mode = m_WeightPainterPanel.mode;
- m_WeightEditor.boneIndex = ConvertBoneIndex(m_WeightPainterPanel.boneIndex);
- m_WeightEditor.autoNormalize = m_WeightPainterPanel.normalize;
- m_WeightEditor.selection = selection;
- m_WeightEditor.emptySelectionEditsAll = true;
- }
- private void UpdateBrushSelection(Brush brush)
- {
- m_BrushSelection.Clear();
- m_CircleVertexSelector.spriteMeshData = meshTool.mesh;
- m_CircleVertexSelector.position = brush.position;
- m_CircleVertexSelector.radius = brush.size;
- m_CircleVertexSelector.selection = m_BrushSelection;
- m_CircleVertexSelector.Select();
- }
- private void DrawBrush(Brush brush)
- {
- var oldColor = Handles.color;
- Handles.color = Color.white;
- if (EditorGUI.actionKey)
- Handles.color = Color.red;
- if (brush.isHot)
- Handles.color = Color.yellow;
- Handles.DrawWireDisc(brush.position, Vector3.forward, brush.size);
- Handles.color = oldColor;
- }
- protected override void OnGUI()
- {
- m_MeshPreviewBehaviour.showWeightMap = true;
- m_MeshPreviewBehaviour.overlaySelected = true;
- skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
- skeletonMode = SkeletonMode.EditPose;
- meshMode = SpriteMeshViewMode.EditGeometry;
- disableMeshEditor = true;
- var isBoneHovered = skeletonTool.hoveredBone != null && !m_Brush.isHot;
- var useBrush = paintMode == WeightPainterMode.Brush;
- meshTool.selectionOverride = null;
- if (useBrush)
- meshTool.selectionOverride = m_BrushSelection;
- DoSkeletonGUI();
- DoMeshGUI();
- if (useBrush && !isBoneHovered)
- {
- var handlesMatrix = Handles.matrix;
- var selectedSprite = skinningCache.selectedSprite;
- var matrix = Matrix4x4.identity;
- if (selectedSprite != null)
- matrix = selectedSprite.GetLocalToWorldMatrixFromMode();
- Handles.matrix *= matrix;
- skinningCache.brushSize = m_Brush.size = m_WeightPainterPanel.size;
- skinningCache.brushHardness = m_Brush.hardness = m_WeightPainterPanel.hardness;
- skinningCache.brushStep = m_Brush.step = m_WeightPainterPanel.step;
- if (m_Brush.isHot || !skinningCache.IsOnVisualElement())
- {
- meshTool.BeginPositionOverride();
- m_Brush.OnGUI();
- meshTool.EndPositionOverride();
- }
- Handles.matrix = handlesMatrix;
- }
- }
- }
- }
|