using UnityEngine; namespace UnityEditor.U2D.Animation { internal class MeshTool : BaseTool { MeshCache m_Mesh; ISelection m_SelectionOverride; SpriteMeshController m_SpriteMeshController; SpriteMeshView m_SpriteMeshView; RectSelectionTool m_RectSelectionTool = new RectSelectionTool(); RectVertexSelector m_RectVertexSelector = new RectVertexSelector(); UnselectTool m_UnselectTool = new UnselectTool(); ITriangulator m_Triangulator; public MeshCache mesh => m_Mesh; public SpriteMeshViewMode mode { set => m_SpriteMeshView.mode = value; } public bool disable { set => m_SpriteMeshController.disable = value; } public ISelection selectionOverride { get => m_SelectionOverride; set => m_SelectionOverride = value; } public override int defaultControlID { get { if (m_Mesh == null) return 0; return m_RectSelectionTool.controlID; } } ISelection selection { get { if (selectionOverride != null) return selectionOverride; return skinningCache.vertexSelection; } } internal override void OnCreate() { m_SpriteMeshController = new SpriteMeshController(); m_SpriteMeshView = new SpriteMeshView(new GUIWrapper()); m_Triangulator = new Triangulator(); } protected override void OnActivate() { m_SpriteMeshController.disable = false; m_SelectionOverride = null; SetupSprite(skinningCache.selectedSprite); skinningCache.events.selectedSpriteChanged.AddListener(OnSelectedSpriteChanged); } protected override void OnDeactivate() { skinningCache.events.selectedSpriteChanged.RemoveListener(OnSelectedSpriteChanged); } void OnSelectedSpriteChanged(SpriteCache sprite) { SetupSprite(sprite); } internal void SetupSprite(SpriteCache sprite) { var mesh = sprite.GetMesh(); if (m_Mesh != null && m_Mesh != mesh && selection.Count > 0) selection.Clear(); m_Mesh = mesh; m_SpriteMeshController.spriteMeshData = m_Mesh; } void SetupGUI() { m_SpriteMeshController.spriteMeshView = m_SpriteMeshView; m_SpriteMeshController.triangulator = m_Triangulator; m_SpriteMeshController.cacheUndo = skinningCache; m_RectSelectionTool.cacheUndo = skinningCache; m_RectSelectionTool.rectSelector = m_RectVertexSelector; m_RectVertexSelector.selection = selection; m_UnselectTool.cacheUndo = skinningCache; m_UnselectTool.selection = selection; m_SpriteMeshController.frame = new Rect(Vector2.zero, m_Mesh.sprite.textureRect.size); m_SpriteMeshController.selection = selection; m_SpriteMeshView.defaultControlID = defaultControlID; m_RectVertexSelector.spriteMeshData = m_Mesh; } protected override void OnGUI() { if (m_Mesh == null) return; SetupGUI(); var handlesMatrix = Handles.matrix; Handles.matrix *= m_Mesh.sprite.GetLocalToWorldMatrixFromMode(); BeginPositionOverride(); EditorGUI.BeginChangeCheck(); var guiEnabled = GUI.enabled; var moveAction = m_SpriteMeshController.spriteMeshView.IsActionHot(MeshEditorAction.MoveEdge) || m_SpriteMeshController.spriteMeshView.IsActionHot(MeshEditorAction.MoveVertex); GUI.enabled = (!skinningCache.IsOnVisualElement() && guiEnabled) || moveAction; m_SpriteMeshController.OnGUI(); GUI.enabled = guiEnabled; if (EditorGUI.EndChangeCheck()) UpdateMesh(); m_RectSelectionTool.OnGUI(); m_UnselectTool.OnGUI(); Handles.matrix = handlesMatrix; EndPositionOverride(); } public void BeginPositionOverride() { if (m_Mesh != null) { var skeleton = skinningCache.GetEffectiveSkeleton(m_Mesh.sprite); Debug.Assert(skeleton != null); if (skeleton.isPosePreview) { var overrideVertices = m_Mesh.sprite.GetMeshPreview().vertices; var convertedVerts = new Vector2[overrideVertices.Count]; for (var i = 0; i < convertedVerts.Length; ++i) convertedVerts[i] = new Vector2(overrideVertices[i].x, overrideVertices[i].y); m_Mesh.SetVertexPositionsOverride(convertedVerts); } } } public void EndPositionOverride() { if(m_Mesh != null) m_Mesh.ClearVertexPositionOverride(); } public void UpdateWeights() { InvokeMeshChanged(); } public void UpdateMesh() { InvokeMeshChanged(); } void InvokeMeshChanged() { if(m_Mesh != null) skinningCache.events.meshChanged.Invoke(m_Mesh); } } }