123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- using UnityEngine;
- namespace UnityEditor.U2D.Animation
- {
- internal class SpriteMeshView : ISpriteMeshView
- {
- readonly int m_VertexHashCode = "Vertex".GetHashCode();
- readonly int m_EdgeHashCode = "Edge".GetHashCode();
- const string kDeleteCommandName = "Delete";
- const string kSoftDeleteCommandName = "SoftDelete";
- static readonly Color kEdgeColor = Color.cyan;
- static readonly Color kEdgeHoveredColor = Color.yellow;
- static readonly Color kEdgeSelectedColor = Color.yellow;
- const float kEdgeWidth = 2f;
- const float kVertexRadius = 2.5f;
- private class Styles
- {
- public readonly GUIStyle pointNormalStyle;
- public readonly GUIStyle pointHoveredStyle;
- public readonly GUIStyle pointSelectedStyle;
- public Styles()
- {
- Texture2D pointNormal = ResourceLoader.Load<Texture2D>("SkinningModule/dotCyan.png");
- Texture2D pointHovered = ResourceLoader.Load<Texture2D>("SkinningModule/dotYellow.png");
- Texture2D pointSelected = ResourceLoader.Load<Texture2D>("SkinningModule/dotYellow.png");
- pointNormalStyle = new GUIStyle();
- pointNormalStyle.normal.background = pointNormal;
- pointNormalStyle.fixedWidth = 8f;
- pointNormalStyle.fixedHeight = 8f;
- pointHoveredStyle = new GUIStyle();
- pointHoveredStyle.normal.background = pointHovered;
- pointHoveredStyle.fixedWidth = 10f;
- pointHoveredStyle.fixedHeight = 10f;
- pointSelectedStyle = new GUIStyle();
- pointSelectedStyle.normal.background = pointSelected;
- pointSelectedStyle.fixedWidth = 10f;
- pointSelectedStyle.fixedHeight = 10f;
- }
- }
- private Styles m_Styles;
- private Styles styles
- {
- get
- {
- if (m_Styles == null)
- m_Styles = new Styles();
- return m_Styles;
- }
- }
- int m_HoveredEdge = -1;
- int m_HoveredEdgeControlID = -1;
- int m_MoveEdgeControlID = -1;
- int m_HoveredVertex = -1;
- int m_PrevHoveredVertex = -1;
- int m_HoveredVertexControlID = -1;
- int m_MoveVertexControlID = -1;
- Color m_TempColor;
- SliderData m_HotSliderData = SliderData.zero;
- MeshEditorAction m_PreviousActiveAction = MeshEditorAction.None;
- private Vector2 m_MouseWorldPosition;
- private float m_NearestVertexDistance;
- private float m_NearestEdgeDistance;
- private int m_NearestVertex = -1;
- private int m_NearestEdge = -1;
- public SpriteMeshViewMode mode { get; set; }
- public ISelection<int> selection { get; set; }
- public int defaultControlID { get; set; }
- public Rect frame { get; set; }
- private IGUIWrapper guiWrapper { get; set; }
- public Vector2 mouseWorldPosition
- {
- get { return m_MouseWorldPosition; }
- }
- public int hoveredVertex
- {
- get { return m_HoveredVertex; }
- }
- public int hoveredEdge
- {
- get { return m_HoveredEdge; }
- }
- public int closestEdge
- {
- get { return m_NearestEdge; }
- }
- public SpriteMeshView(IGUIWrapper gw)
- {
- guiWrapper = gw;
- }
- public void CancelMode()
- {
- if (mode != SpriteMeshViewMode.EditGeometry)
- {
- if (guiWrapper.IsKeyDown(KeyCode.Escape) || guiWrapper.IsMouseDown(1))
- {
- mode = SpriteMeshViewMode.EditGeometry;
- guiWrapper.UseCurrentEvent();
- }
- }
- }
- public void BeginLayout()
- {
- var vertexControlID = guiWrapper.GetControlID(m_VertexHashCode, FocusType.Passive);
- var edgeControlID = guiWrapper.GetControlID(m_EdgeHashCode, FocusType.Passive);
- if (guiWrapper.eventType == EventType.Layout || guiWrapper.eventType == EventType.MouseMove)
- {
- m_NearestVertexDistance = float.MaxValue;
- m_NearestEdgeDistance = float.MaxValue;
- m_NearestVertex = -1;
- m_NearestEdge = -1;
- m_MouseWorldPosition = guiWrapper.GUIToWorld(guiWrapper.mousePosition);
- m_HoveredVertexControlID = vertexControlID;
- m_HoveredEdgeControlID = edgeControlID;
- m_PrevHoveredVertex = m_HoveredVertex;
- m_HoveredVertex = -1;
- m_HoveredEdge = -1;
- if (guiWrapper.IsControlHot(0))
- {
- m_MoveVertexControlID = -1;
- m_MoveEdgeControlID = -1;
- }
- }
- }
- public void EndLayout()
- {
- guiWrapper.LayoutControl(m_HoveredEdgeControlID, m_NearestEdgeDistance);
- guiWrapper.LayoutControl(m_HoveredVertexControlID, m_NearestVertexDistance);
- if(guiWrapper.IsControlNearest(m_HoveredVertexControlID))
- m_HoveredVertex = m_NearestVertex;
- if (guiWrapper.IsControlNearest(m_HoveredEdgeControlID))
- m_HoveredEdge = m_NearestEdge;
- if (guiWrapper.eventType == EventType.Layout || guiWrapper.eventType == EventType.MouseMove)
- if (m_PrevHoveredVertex != m_HoveredVertex)
- guiWrapper.Repaint();
- }
- public void LayoutVertex(Vector2 position, int index)
- {
- if (guiWrapper.eventType == EventType.Layout)
- {
- var distance = guiWrapper.DistanceToCircle(position, kVertexRadius);
- if (distance <= m_NearestVertexDistance)
- {
- m_NearestVertexDistance = distance;
- m_NearestVertex = index;
- }
- }
- }
- public void LayoutEdge(Vector2 startPosition, Vector2 endPosition, int index)
- {
- if (guiWrapper.eventType == EventType.Layout)
- {
- var distance = guiWrapper.DistanceToSegment(startPosition, endPosition);
- if (distance < m_NearestEdgeDistance)
- {
- m_NearestEdgeDistance = distance;
- m_NearestEdge = index;
- }
- }
- }
- public bool DoCreateVertex()
- {
- if (mode == SpriteMeshViewMode.CreateVertex && IsActionActive(MeshEditorAction.CreateVertex))
- ConsumeMouseMoveEvents();
- if (IsActionTriggered(MeshEditorAction.CreateVertex))
- {
- guiWrapper.SetGuiChanged(true);
- guiWrapper.UseCurrentEvent();
- return true;
- }
- return false;
- }
- public bool DoSelectVertex(out bool additive)
- {
- additive = false;
- if (IsActionTriggered(MeshEditorAction.SelectVertex))
- {
- additive = guiWrapper.isActionKeyDown;
- guiWrapper.Repaint();
- return true;
- }
- return false;
- }
- public bool DoMoveVertex(out Vector2 delta)
- {
- delta = Vector2.zero;
- if (IsActionTriggered(MeshEditorAction.MoveVertex))
- {
- m_MoveVertexControlID = m_HoveredVertexControlID;
- m_HotSliderData.position = mouseWorldPosition;
- }
- Vector3 newPosition;
- if (guiWrapper.DoSlider(m_MoveVertexControlID, m_HotSliderData, out newPosition))
- {
- delta = newPosition - m_HotSliderData.position;
- m_HotSliderData.position = newPosition;
- return true;
- }
- return false;
- }
- public bool DoMoveEdge(out Vector2 delta)
- {
- delta = Vector2.zero;
- if (IsActionTriggered(MeshEditorAction.MoveEdge))
- {
- m_MoveEdgeControlID = m_HoveredEdgeControlID;
- m_HotSliderData.position = mouseWorldPosition;
- }
- Vector3 newPosition;
- if (guiWrapper.DoSlider(m_MoveEdgeControlID, m_HotSliderData, out newPosition))
- {
- delta = newPosition - m_HotSliderData.position;
- m_HotSliderData.position = newPosition;
- return true;
- }
- return false;
- }
- public bool DoCreateEdge()
- {
- if (IsActionActive(MeshEditorAction.CreateEdge))
- ConsumeMouseMoveEvents();
- if (IsActionTriggered(MeshEditorAction.CreateEdge))
- {
- guiWrapper.SetGuiChanged(true);
- guiWrapper.UseCurrentEvent();
- return true;
- }
- return false;
- }
- public bool DoSplitEdge()
- {
- if (IsActionActive(MeshEditorAction.SplitEdge))
- ConsumeMouseMoveEvents();
- if (IsActionTriggered(MeshEditorAction.SplitEdge))
- {
- guiWrapper.UseCurrentEvent();
- guiWrapper.SetGuiChanged(true);
- return true;
- }
- return false;
- }
- public bool DoSelectEdge(out bool additive)
- {
- additive = false;
- if (IsActionTriggered(MeshEditorAction.SelectEdge))
- {
- additive = guiWrapper.isActionKeyDown;
- guiWrapper.Repaint();
- return true;
- }
- return false;
- }
- public bool DoRemove()
- {
- if (IsActionTriggered(MeshEditorAction.Remove))
- {
- guiWrapper.UseCurrentEvent();
- guiWrapper.SetGuiChanged(true);
- return true;
- }
- return false;
- }
- public void DrawVertex(Vector2 position)
- {
- DrawingUtility.DrawGUIStyleCap(0, position, Quaternion.identity, 1f, styles.pointNormalStyle);
- }
- public void DrawVertexHovered(Vector2 position)
- {
- DrawingUtility.DrawGUIStyleCap(0, position, Quaternion.identity, 1f, styles.pointHoveredStyle);
- }
- public void DrawVertexSelected(Vector2 position)
- {
- DrawingUtility.DrawGUIStyleCap(0, position, Quaternion.identity, 1f, styles.pointSelectedStyle);
- }
- public void BeginDrawEdges()
- {
- if (guiWrapper.eventType != EventType.Repaint)
- return;
- DrawingUtility.BeginSolidLines();
- m_TempColor = Handles.color;
- }
- public void EndDrawEdges()
- {
- if (guiWrapper.eventType != EventType.Repaint)
- return;
- DrawingUtility.EndLines();
- Handles.color = m_TempColor;
- }
- public void DrawEdge(Vector2 startPosition, Vector2 endPosition)
- {
- DrawEdge(startPosition, endPosition, kEdgeColor);
- }
- public void DrawEdgeHovered(Vector2 startPosition, Vector2 endPosition)
- {
- DrawEdge(startPosition, endPosition, kEdgeHoveredColor);
- }
- public void DrawEdgeSelected(Vector2 startPosition, Vector2 endPosition)
- {
- DrawEdge(startPosition, endPosition, kEdgeSelectedColor);
- }
- public bool IsActionActive(MeshEditorAction action)
- {
- if (guiWrapper.isAltDown || !guiWrapper.IsControlHot(0))
- return false;
- var canCreateEdge = CanCreateEdge();
- var canSplitEdge = CanSplitEdge();
- if (action == MeshEditorAction.None)
- return guiWrapper.IsControlNearest(defaultControlID);
- if (action == MeshEditorAction.CreateVertex)
- {
- if(!frame.Contains(mouseWorldPosition))
- return false;
- if (mode == SpriteMeshViewMode.EditGeometry)
- return guiWrapper.IsControlNearest(defaultControlID);
- if (mode == SpriteMeshViewMode.CreateVertex)
- return hoveredVertex == -1;
- }
- if (action == MeshEditorAction.MoveVertex)
- return guiWrapper.IsControlNearest(m_HoveredVertexControlID);
- if (action == MeshEditorAction.CreateEdge)
- return canCreateEdge;
- if (action == MeshEditorAction.SplitEdge)
- return canSplitEdge;
- if (action == MeshEditorAction.MoveEdge)
- return guiWrapper.IsControlNearest(m_HoveredEdgeControlID);
- if (action == MeshEditorAction.SelectVertex)
- return guiWrapper.IsControlNearest(m_HoveredVertexControlID);
- if (action == MeshEditorAction.SelectEdge)
- return mode == SpriteMeshViewMode.EditGeometry &&
- guiWrapper.IsControlNearest(m_HoveredEdgeControlID) &&
- !canCreateEdge && !canSplitEdge;
- if (action == MeshEditorAction.Remove)
- return true;
- return false;
- }
- public bool IsActionHot(MeshEditorAction action)
- {
- if (action == MeshEditorAction.None)
- return guiWrapper.IsControlHot(0);
- if (action == MeshEditorAction.MoveVertex)
- return guiWrapper.IsControlHot(m_HoveredVertexControlID);
- if (action == MeshEditorAction.MoveEdge)
- return guiWrapper.IsControlHot(m_HoveredEdgeControlID);
- return false;
- }
- public bool IsActionTriggered(MeshEditorAction action)
- {
- if (!IsActionActive(action))
- return false;
- if (action == MeshEditorAction.CreateVertex)
- {
- if (mode == SpriteMeshViewMode.EditGeometry)
- return guiWrapper.IsMouseDown(0) && guiWrapper.clickCount == 2;
- }
- if (action == MeshEditorAction.Remove)
- {
- if ((guiWrapper.eventType == EventType.ValidateCommand || guiWrapper.eventType == EventType.ExecuteCommand)
- && (guiWrapper.commandName == kSoftDeleteCommandName || guiWrapper.commandName == kDeleteCommandName))
- {
- if (guiWrapper.eventType == EventType.ExecuteCommand)
- return true;
- guiWrapper.UseCurrentEvent();
- }
- return false;
- }
- if(action != MeshEditorAction.None)
- return guiWrapper.IsMouseDown(0);
- return false;
- }
- public Vector2 WorldToScreen(Vector2 position)
- {
- return HandleUtility.WorldToGUIPoint(position);
- }
- private void ConsumeMouseMoveEvents()
- {
- if (guiWrapper.eventType == EventType.MouseMove || (guiWrapper.eventType == EventType.MouseDrag && guiWrapper.mouseButton == 0))
- guiWrapper.UseCurrentEvent();
- }
- private bool CanCreateEdge()
- {
- if(!frame.Contains(mouseWorldPosition) || !(guiWrapper.IsControlNearest(defaultControlID) || guiWrapper.IsControlNearest(m_HoveredVertexControlID) || guiWrapper.IsControlNearest(m_HoveredEdgeControlID)))
- return false;
- if (mode == SpriteMeshViewMode.EditGeometry)
- return guiWrapper.isShiftDown && selection.Count == 1 && !selection.Contains(hoveredVertex);
- if (mode == SpriteMeshViewMode.CreateEdge)
- return selection.Count == 1 && !selection.Contains(hoveredVertex);
- return false;
- }
- private bool CanSplitEdge()
- {
- if(!frame.Contains(mouseWorldPosition) || !(guiWrapper.IsControlNearest(defaultControlID) || guiWrapper.IsControlNearest(m_HoveredEdgeControlID)))
- return false;
- if (mode == SpriteMeshViewMode.EditGeometry)
- return guiWrapper.isShiftDown && m_NearestEdge != -1 && hoveredVertex == -1 && selection.Count == 0;
- if (mode == SpriteMeshViewMode.SplitEdge)
- return m_NearestEdge != -1 && hoveredVertex == -1;
- return false;
- }
- private void DrawEdge(Vector2 startPosition, Vector2 endPosition, Color color)
- {
- if (guiWrapper.eventType != EventType.Repaint)
- return;
- Handles.color = color;
- float width = kEdgeWidth / Handles.matrix.m00;
- DrawingUtility.DrawSolidLine(width, startPosition, endPosition);
- }
- public void DoRepaint()
- {
- if(guiWrapper.eventType != EventType.Layout)
- return;
- var action = MeshEditorAction.None;
- if(IsActionActive(MeshEditorAction.CreateVertex))
- action = MeshEditorAction.CreateVertex;
- else if(IsActionActive(MeshEditorAction.CreateEdge))
- action = MeshEditorAction.CreateEdge;
- else if(IsActionActive(MeshEditorAction.SplitEdge))
- action = MeshEditorAction.SplitEdge;
- if(m_PreviousActiveAction != action)
- {
- m_PreviousActiveAction = action;
- guiWrapper.Repaint();
- }
- }
- public bool CanRepaint()
- {
- return guiWrapper.eventType == EventType.Repaint;
- }
- public bool CanLayout()
- {
- return guiWrapper.eventType == EventType.Layout;
- }
- }
- }
|