123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- using System;
- using Unity.Mathematics;
- using UnityEngine;
-
- namespace UnityEditor.U2D.Animation
- {
- internal class SpriteMeshController
- {
- const float k_SnapDistance = 10f;
-
- struct EdgeIntersectionResult
- {
- public int startVertexIndex;
- public int endVertexIndex;
- public int intersectEdgeIndex;
- public Vector2 endPosition;
- }
-
- SpriteMeshDataController m_SpriteMeshDataController = new();
- EdgeIntersectionResult m_EdgeIntersectionResult;
-
- public ISpriteMeshView spriteMeshView { get; set; }
- public BaseSpriteMeshData spriteMeshData { get; set; }
- public ISelection<int> selection { get; set; }
- public ICacheUndo cacheUndo { get; set; }
- public ITriangulator triangulator { get; set; }
-
- public bool disable { get; set; }
- public Rect frame { get; set; }
-
- public void OnGUI()
- {
- m_SpriteMeshDataController.spriteMeshData = spriteMeshData;
-
- Debug.Assert(spriteMeshView != null);
- Debug.Assert(spriteMeshData != null);
- Debug.Assert(selection != null);
- Debug.Assert(cacheUndo != null);
-
- ValidateSelectionValues();
-
- spriteMeshView.selection = selection;
- spriteMeshView.frame = frame;
-
- EditorGUI.BeginDisabledGroup(disable);
-
- spriteMeshView.BeginLayout();
-
- if (spriteMeshView.CanLayout())
- {
- LayoutVertices();
- LayoutEdges();
- }
-
- spriteMeshView.EndLayout();
-
- if (spriteMeshView.CanRepaint())
- {
- DrawEdges();
-
- if (GUI.enabled)
- {
- PreviewCreateVertex();
- PreviewCreateEdge();
- PreviewSplitEdge();
- }
-
- DrawVertices();
- }
-
-
- HandleSplitEdge();
- HandleCreateEdge();
- HandleCreateVertex();
-
- EditorGUI.EndDisabledGroup();
-
- HandleSelectVertex();
- HandleSelectEdge();
-
- EditorGUI.BeginDisabledGroup(disable);
-
- HandleMoveVertexAndEdge();
-
- EditorGUI.EndDisabledGroup();
-
- EditorGUI.BeginDisabledGroup(disable);
-
- HandleRemoveVertices();
-
- spriteMeshView.DoRepaint();
-
- EditorGUI.EndDisabledGroup();
- }
-
- void ValidateSelectionValues()
- {
- foreach (var index in selection.elements)
- {
- if (index >= spriteMeshData.vertexCount)
- {
- selection.Clear();
- break;
- }
- }
- }
-
- void LayoutVertices()
- {
- for (var i = 0; i < spriteMeshData.vertexCount; i++)
- {
- spriteMeshView.LayoutVertex(spriteMeshData.vertices[i], i);
- }
- }
-
- void LayoutEdges()
- {
- for (var i = 0; i < spriteMeshData.edges.Length; i++)
- {
- var edge = spriteMeshData.edges[i];
- var startPosition = spriteMeshData.vertices[edge.x];
- var endPosition = spriteMeshData.vertices[edge.y];
-
- spriteMeshView.LayoutEdge(startPosition, endPosition, i);
- }
- }
-
- void DrawEdges()
- {
- UpdateEdgeIntersection();
-
- spriteMeshView.BeginDrawEdges();
-
- for (var i = 0; i < spriteMeshData.edges.Length; ++i)
- {
- if (SkipDrawEdge(i))
- continue;
-
- var edge = spriteMeshData.edges[i];
- var startPosition = spriteMeshData.vertices[edge.x];
- var endPosition = spriteMeshData.vertices[edge.y];
-
- if (selection.Contains(edge.x) && selection.Contains(edge.y))
- spriteMeshView.DrawEdgeSelected(startPosition, endPosition);
- else
- spriteMeshView.DrawEdge(startPosition, endPosition);
- }
-
- if (spriteMeshView.IsActionActive(MeshEditorAction.SelectEdge))
- {
- var hoveredEdge = spriteMeshData.edges[spriteMeshView.hoveredEdge];
- var startPosition = spriteMeshData.vertices[hoveredEdge.x];
- var endPosition = spriteMeshData.vertices[hoveredEdge.y];
-
- spriteMeshView.DrawEdgeHovered(startPosition, endPosition);
- }
-
- spriteMeshView.EndDrawEdges();
- }
-
- bool SkipDrawEdge(int edgeIndex)
- {
- if (GUI.enabled == false)
- return false;
-
- return edgeIndex == -1 ||
- spriteMeshView.hoveredEdge == edgeIndex && spriteMeshView.IsActionActive(MeshEditorAction.SelectEdge) ||
- spriteMeshView.hoveredEdge == edgeIndex && spriteMeshView.IsActionActive(MeshEditorAction.CreateVertex) ||
- spriteMeshView.closestEdge == edgeIndex && spriteMeshView.IsActionActive(MeshEditorAction.SplitEdge) ||
- edgeIndex == m_EdgeIntersectionResult.intersectEdgeIndex && spriteMeshView.IsActionActive(MeshEditorAction.CreateEdge);
- }
-
- void PreviewCreateVertex()
- {
- if (spriteMeshView.mode == SpriteMeshViewMode.CreateVertex &&
- spriteMeshView.IsActionActive(MeshEditorAction.CreateVertex))
- {
- var clampedMousePos = ClampToFrame(spriteMeshView.mouseWorldPosition);
-
- if (spriteMeshView.hoveredEdge != -1)
- {
- var edge = spriteMeshData.edges[spriteMeshView.hoveredEdge];
-
- spriteMeshView.BeginDrawEdges();
-
- spriteMeshView.DrawEdge(spriteMeshData.vertices[edge.x], clampedMousePos);
- spriteMeshView.DrawEdge(spriteMeshData.vertices[edge.y], clampedMousePos);
-
- spriteMeshView.EndDrawEdges();
- }
-
- spriteMeshView.DrawVertex(clampedMousePos);
- }
- }
-
- void PreviewCreateEdge()
- {
- if (!spriteMeshView.IsActionActive(MeshEditorAction.CreateEdge))
- return;
-
- spriteMeshView.BeginDrawEdges();
-
- spriteMeshView.DrawEdge(spriteMeshData.vertices[m_EdgeIntersectionResult.startVertexIndex], m_EdgeIntersectionResult.endPosition);
-
- if (m_EdgeIntersectionResult.intersectEdgeIndex != -1)
- {
- var intersectingEdge = spriteMeshData.edges[m_EdgeIntersectionResult.intersectEdgeIndex];
- spriteMeshView.DrawEdge(spriteMeshData.vertices[intersectingEdge.x], m_EdgeIntersectionResult.endPosition);
- spriteMeshView.DrawEdge(spriteMeshData.vertices[intersectingEdge.y], m_EdgeIntersectionResult.endPosition);
- }
-
- spriteMeshView.EndDrawEdges();
-
- if (m_EdgeIntersectionResult.endVertexIndex == -1)
- spriteMeshView.DrawVertex(m_EdgeIntersectionResult.endPosition);
- }
-
- void PreviewSplitEdge()
- {
- if (!spriteMeshView.IsActionActive(MeshEditorAction.SplitEdge))
- return;
-
- var clampedMousePos = ClampToFrame(spriteMeshView.mouseWorldPosition);
-
- var closestEdge = spriteMeshData.edges[spriteMeshView.closestEdge];
-
- spriteMeshView.BeginDrawEdges();
-
- spriteMeshView.DrawEdge(spriteMeshData.vertices[closestEdge.x], clampedMousePos);
- spriteMeshView.DrawEdge(spriteMeshData.vertices[closestEdge.y], clampedMousePos);
-
- spriteMeshView.EndDrawEdges();
-
- spriteMeshView.DrawVertex(clampedMousePos);
- }
-
- void DrawVertices()
- {
- for (var i = 0; i < spriteMeshData.vertexCount; i++)
- {
- var position = spriteMeshData.vertices[i];
-
- if (selection.Contains(i))
- spriteMeshView.DrawVertexSelected(position);
- else if (i == spriteMeshView.hoveredVertex && spriteMeshView.IsActionHot(MeshEditorAction.None))
- spriteMeshView.DrawVertexHovered(position);
- else
- spriteMeshView.DrawVertex(position);
- }
- }
-
- void HandleSelectVertex()
- {
- if (spriteMeshView.DoSelectVertex(out var additive))
- SelectVertex(spriteMeshView.hoveredVertex, additive);
- }
-
- void HandleSelectEdge()
- {
- if (spriteMeshView.DoSelectEdge(out var additive))
- SelectEdge(spriteMeshView.hoveredEdge, additive);
- }
-
- void HandleMoveVertexAndEdge()
- {
- if (selection.Count == 0)
- return;
-
- if (spriteMeshView.DoMoveVertex(out var finalDeltaPos) || spriteMeshView.DoMoveEdge(out finalDeltaPos))
- {
- var selectionArray = selection.elements;
-
- finalDeltaPos = MathUtility.MoveRectInsideFrame(CalculateRectFromSelection(), frame, finalDeltaPos);
- var movedVertexSelection = GetMovedVertexSelection(in selectionArray, spriteMeshData.vertices, finalDeltaPos);
-
- if (IsMovedEdgeIntersectingWithOtherEdge(in selectionArray, in movedVertexSelection, spriteMeshData.edges, spriteMeshData.vertices))
- return;
- if (IsMovedVertexIntersectingWithOutline(in selectionArray, in movedVertexSelection, spriteMeshData.outlineEdges, spriteMeshData.vertices))
- return;
-
- cacheUndo.BeginUndoOperation(TextContent.moveVertices);
- MoveSelectedVertices(in movedVertexSelection);
- }
- }
-
- void HandleCreateVertex()
- {
- if (spriteMeshView.DoCreateVertex())
- {
- var position = ClampToFrame(spriteMeshView.mouseWorldPosition);
- var edgeIndex = spriteMeshView.hoveredEdge;
- if (spriteMeshView.hoveredEdge != -1)
- CreateVertex(position, edgeIndex);
- else if (m_SpriteMeshDataController.FindTriangle(position, out var indices, out var barycentricCoords))
- CreateVertex(position, indices, barycentricCoords);
- }
- }
-
- void HandleSplitEdge()
- {
- if (spriteMeshView.DoSplitEdge())
- SplitEdge(ClampToFrame(spriteMeshView.mouseWorldPosition), spriteMeshView.closestEdge);
- }
-
- void HandleCreateEdge()
- {
- if (spriteMeshView.DoCreateEdge())
- {
- var clampedMousePosition = ClampToFrame(spriteMeshView.mouseWorldPosition);
- var edgeIntersectionResult = CalculateEdgeIntersection(selection.activeElement, spriteMeshView.hoveredVertex, spriteMeshView.hoveredEdge, clampedMousePosition);
-
- if (edgeIntersectionResult.endVertexIndex != -1)
- {
- CreateEdge(selection.activeElement, edgeIntersectionResult.endVertexIndex);
- }
- else
- {
- if (edgeIntersectionResult.intersectEdgeIndex != -1)
- {
- CreateVertex(edgeIntersectionResult.endPosition, edgeIntersectionResult.intersectEdgeIndex);
- CreateEdge(selection.activeElement, spriteMeshData.vertexCount - 1);
- }
- else if (m_SpriteMeshDataController.FindTriangle(edgeIntersectionResult.endPosition, out var indices, out var barycentricCoords))
- {
- CreateVertex(edgeIntersectionResult.endPosition, indices, barycentricCoords);
- CreateEdge(selection.activeElement, spriteMeshData.vertexCount - 1);
- }
- }
- }
- }
-
- void HandleRemoveVertices()
- {
- if (spriteMeshView.DoRemove())
- RemoveSelectedVertices();
- }
-
- void CreateVertex(Vector2 position, Vector3Int indices, Vector3 barycentricCoords)
- {
- var bw1 = spriteMeshData.vertexWeights[indices.x];
- var bw2 = spriteMeshData.vertexWeights[indices.y];
- var bw3 = spriteMeshData.vertexWeights[indices.z];
-
- var result = new EditableBoneWeight();
-
- foreach (var channel in bw1)
- {
- if (!channel.enabled)
- continue;
-
- var weight = channel.weight * barycentricCoords.x;
- if (weight > 0f)
- result.AddChannel(channel.boneIndex, weight, true);
- }
-
- foreach (var channel in bw2)
- {
- if (!channel.enabled)
- continue;
-
- var weight = channel.weight * barycentricCoords.y;
- if (weight > 0f)
- result.AddChannel(channel.boneIndex, weight, true);
- }
-
- foreach (var channel in bw3)
- {
- if (!channel.enabled)
- continue;
-
- var weight = channel.weight * barycentricCoords.z;
- if (weight > 0f)
- result.AddChannel(channel.boneIndex, weight, true);
- }
-
- result.UnifyChannelsWithSameBoneIndex();
- result.FilterChannels(0f);
- result.Clamp(4, true);
-
- var boneWeight = result.ToBoneWeight(true);
-
- cacheUndo.BeginUndoOperation(TextContent.createVertex);
-
- m_SpriteMeshDataController.CreateVertex(position, -1);
- spriteMeshData.vertexWeights[spriteMeshData.vertexCount - 1].SetFromBoneWeight(boneWeight);
- Triangulate();
- }
-
- void CreateVertex(Vector2 position, int edgeIndex)
- {
- var edge = spriteMeshData.edges[edgeIndex];
- var pos1 = spriteMeshData.vertices[edge.x];
- var pos2 = spriteMeshData.vertices[edge.y];
- var dir1 = (position - pos1);
- var dir2 = (pos2 - pos1);
- var t = Vector2.Dot(dir1, dir2.normalized) / dir2.magnitude;
- t = Mathf.Clamp01(t);
- var bw1 = spriteMeshData.vertexWeights[edge.x].ToBoneWeight(true);
- var bw2 = spriteMeshData.vertexWeights[edge.y].ToBoneWeight(true);
-
- var boneWeight = EditableBoneWeightUtility.Lerp(bw1, bw2, t);
-
- cacheUndo.BeginUndoOperation(TextContent.createVertex);
-
- m_SpriteMeshDataController.CreateVertex(position, edgeIndex);
- spriteMeshData.vertexWeights[spriteMeshData.vertexCount - 1].SetFromBoneWeight(boneWeight);
- Triangulate();
- }
-
- void SelectVertex(int index, bool additiveToggle)
- {
- if (index < 0)
- throw new ArgumentException("Index out of range");
-
- var selected = selection.Contains(index);
- if (selected)
- {
- if (additiveToggle)
- {
- cacheUndo.BeginUndoOperation(TextContent.selection);
- selection.Select(index, false);
- }
- }
- else
- {
- cacheUndo.BeginUndoOperation(TextContent.selection);
-
- if (!additiveToggle)
- ClearSelection();
-
- selection.Select(index, true);
- }
-
- cacheUndo.IncrementCurrentGroup();
- }
-
- void SelectEdge(int index, bool additiveToggle)
- {
- Debug.Assert(index >= 0);
-
- var edge = spriteMeshData.edges[index];
-
- cacheUndo.BeginUndoOperation(TextContent.selection);
-
- var selected = selection.Contains(edge.x) && selection.Contains(edge.y);
- if (selected)
- {
- if (additiveToggle)
- {
- selection.Select(edge.x, false);
- selection.Select(edge.y, false);
- }
- }
- else
- {
- if (!additiveToggle)
- ClearSelection();
-
- selection.Select(edge.x, true);
- selection.Select(edge.y, true);
- }
-
- cacheUndo.IncrementCurrentGroup();
- }
-
- void ClearSelection()
- {
- cacheUndo.BeginUndoOperation(TextContent.selection);
- selection.Clear();
- }
-
- void MoveSelectedVertices(in Vector2[] movedVertices)
- {
- for (var i = 0; i < selection.Count; ++i)
- {
- var index = selection.elements[i];
- spriteMeshData.vertices[index] = movedVertices[i];
- }
-
- Triangulate();
- }
-
- void CreateEdge(int fromVertexIndex, int toVertexIndex)
- {
- cacheUndo.BeginUndoOperation(TextContent.createEdge);
-
- m_SpriteMeshDataController.CreateEdge(fromVertexIndex, toVertexIndex);
- Triangulate();
- ClearSelection();
- selection.Select(toVertexIndex, true);
-
- cacheUndo.IncrementCurrentGroup();
- }
-
- void SplitEdge(Vector2 position, int edgeIndex)
- {
- cacheUndo.BeginUndoOperation(TextContent.splitEdge);
-
- CreateVertex(position, edgeIndex);
-
- cacheUndo.IncrementCurrentGroup();
- }
-
- bool IsEdgeSelected()
- {
- if (selection.Count != 2)
- return false;
-
- var indices = selection.elements;
-
- var index1 = indices[0];
- var index2 = indices[1];
-
- var edge = new int2(index1, index2);
- return spriteMeshData.edges.ContainsAny(edge);
- }
-
- void RemoveSelectedVertices()
- {
- cacheUndo.BeginUndoOperation(IsEdgeSelected() ? TextContent.removeEdge : TextContent.removeVertices);
-
- var verticesToRemove = selection.elements;
-
- var noOfVertsToDelete = verticesToRemove.Length;
- var noOfVertsInMesh = m_SpriteMeshDataController.spriteMeshData.vertexCount;
- var shouldClearMesh = (noOfVertsInMesh - noOfVertsToDelete) < 3;
-
- if (shouldClearMesh)
- {
- m_SpriteMeshDataController.spriteMeshData.Clear();
- m_SpriteMeshDataController.CreateQuad();
- }
- else
- m_SpriteMeshDataController.RemoveVertex(verticesToRemove);
-
- Triangulate();
-
- selection.Clear();
- }
-
- void Triangulate()
- {
- m_SpriteMeshDataController.Triangulate(triangulator);
- m_SpriteMeshDataController.SortTrianglesByDepth();
- }
-
- Vector2 ClampToFrame(Vector2 position)
- {
- return MathUtility.ClampPositionToRect(position, frame);
- }
-
- Rect CalculateRectFromSelection()
- {
- var rect = new Rect();
-
- var min = new Vector2(float.MaxValue, float.MaxValue);
- var max = new Vector2(float.MinValue, float.MinValue);
-
- var indices = selection.elements;
-
- foreach (var index in indices)
- {
- var v = spriteMeshData.vertices[index];
-
- min.x = Mathf.Min(min.x, v.x);
- min.y = Mathf.Min(min.y, v.y);
-
- max.x = Mathf.Max(max.x, v.x);
- max.y = Mathf.Max(max.y, v.y);
- }
-
- rect.min = min;
- rect.max = max;
-
- return rect;
- }
-
- void UpdateEdgeIntersection()
- {
- if (selection.Count == 1)
- m_EdgeIntersectionResult = CalculateEdgeIntersection(selection.activeElement, spriteMeshView.hoveredVertex, spriteMeshView.hoveredEdge, ClampToFrame(spriteMeshView.mouseWorldPosition));
- }
-
- EdgeIntersectionResult CalculateEdgeIntersection(int vertexIndex, int hoveredVertexIndex, int hoveredEdgeIndex, Vector2 targetPosition)
- {
- Debug.Assert(vertexIndex >= 0);
-
- var edgeIntersection = new EdgeIntersectionResult
- {
- startVertexIndex = vertexIndex,
- endVertexIndex = hoveredVertexIndex,
- endPosition = targetPosition,
- intersectEdgeIndex = -1
- };
-
- var startPoint = spriteMeshData.vertices[edgeIntersection.startVertexIndex];
-
- var intersectsEdge = false;
- var lastIntersectingEdgeIndex = -1;
-
- do
- {
- lastIntersectingEdgeIndex = edgeIntersection.intersectEdgeIndex;
-
- if (intersectsEdge)
- {
- var dir = edgeIntersection.endPosition - startPoint;
- edgeIntersection.endPosition += dir.normalized * 10f;
- }
-
- intersectsEdge = SegmentIntersectsEdge(startPoint, edgeIntersection.endPosition, vertexIndex, ref edgeIntersection.endPosition, out edgeIntersection.intersectEdgeIndex);
-
- //if we are hovering a vertex and intersect an edge indexing it we forget about the intersection
- var edges = spriteMeshData.edges;
- var edge = intersectsEdge ? edges[edgeIntersection.intersectEdgeIndex] : default;
- if (intersectsEdge && (edge.x == edgeIntersection.endVertexIndex || edge.y == edgeIntersection.endVertexIndex))
- {
- edgeIntersection.intersectEdgeIndex = -1;
- intersectsEdge = false;
- edgeIntersection.endPosition = spriteMeshData.vertices[edgeIntersection.endVertexIndex];
- }
-
- if (intersectsEdge)
- {
- edgeIntersection.endVertexIndex = -1;
-
- var intersectingEdge = spriteMeshData.edges[edgeIntersection.intersectEdgeIndex];
- var newPointScreen = spriteMeshView.WorldToScreen(edgeIntersection.endPosition);
- var edgeV1 = spriteMeshView.WorldToScreen(spriteMeshData.vertices[intersectingEdge.x]);
- var edgeV2 = spriteMeshView.WorldToScreen(spriteMeshData.vertices[intersectingEdge.y]);
-
- if ((newPointScreen - edgeV1).magnitude <= k_SnapDistance)
- edgeIntersection.endVertexIndex = intersectingEdge.x;
- else if ((newPointScreen - edgeV2).magnitude <= k_SnapDistance)
- edgeIntersection.endVertexIndex = intersectingEdge.y;
-
- if (edgeIntersection.endVertexIndex != -1)
- {
- edgeIntersection.intersectEdgeIndex = -1;
- intersectsEdge = false;
- edgeIntersection.endPosition = spriteMeshData.vertices[edgeIntersection.endVertexIndex];
- }
- }
- } while (intersectsEdge && lastIntersectingEdgeIndex != edgeIntersection.intersectEdgeIndex);
-
- edgeIntersection.intersectEdgeIndex = intersectsEdge ? edgeIntersection.intersectEdgeIndex : hoveredEdgeIndex;
-
- if (edgeIntersection.endVertexIndex != -1 && !intersectsEdge)
- edgeIntersection.endPosition = spriteMeshData.vertices[edgeIntersection.endVertexIndex];
-
- return edgeIntersection;
- }
-
- bool SegmentIntersectsEdge(Vector2 p1, Vector2 p2, int ignoreIndex, ref Vector2 point, out int intersectingEdgeIndex)
- {
- intersectingEdgeIndex = -1;
-
- var sqrDistance = float.MaxValue;
-
- for (var i = 0; i < spriteMeshData.edges.Length; i++)
- {
- var edge = spriteMeshData.edges[i];
- var v1 = spriteMeshData.vertices[edge.x];
- var v2 = spriteMeshData.vertices[edge.y];
- var pointTmp = Vector2.zero;
-
- if (edge.x != ignoreIndex && edge.y != ignoreIndex &&
- MathUtility.SegmentIntersection(p1, p2, v1, v2, ref pointTmp))
- {
- var sqrMagnitude = (pointTmp - p1).sqrMagnitude;
- if (sqrMagnitude < sqrDistance)
- {
- sqrDistance = sqrMagnitude;
- intersectingEdgeIndex = i;
- point = pointTmp;
- }
- }
- }
-
- return intersectingEdgeIndex != -1;
- }
-
-
- static Vector2[] GetMovedVertexSelection(in int[] selection, in Vector2[] vertices, Vector2 deltaPosition)
- {
- var movedVertices = new Vector2[selection.Length];
- for (var i = 0; i < selection.Length; i++)
- {
- var index = selection[i];
- movedVertices[i] = vertices[index] + deltaPosition;
- }
- return movedVertices;
- }
-
- static bool IsMovedEdgeIntersectingWithOtherEdge(in int[] selection, in Vector2[] movedVertices, in int2[] meshEdges, in Vector2[] meshVertices)
- {
- var edgeCount = meshEdges.Length;
- var edgeIntersectionPoint = Vector2.zero;
-
- for (var i = 0; i < edgeCount; i++)
- {
- var selectionIndex = FindSelectionIndexFromEdge(selection, meshEdges[i]);
- if (selectionIndex.x == -1 && selectionIndex.y == -1)
- continue;
-
- var edgeStart = selectionIndex.x != -1 ? movedVertices[selectionIndex.x] : meshVertices[meshEdges[i].x];
- var edgeEnd = selectionIndex.y != -1 ? movedVertices[selectionIndex.y] : meshVertices[meshEdges[i].y];
-
- for (var o = 0; o < edgeCount; o++)
- {
- if (o == i)
- continue;
-
- if (meshEdges[i].x == meshEdges[o].x || meshEdges[i].y == meshEdges[o].x ||
- meshEdges[i].x == meshEdges[o].y || meshEdges[i].y == meshEdges[o].y)
- continue;
-
- var otherSelectionIndex = FindSelectionIndexFromEdge(in selection, meshEdges[o]);
- var otherEdgeStart = otherSelectionIndex.x != -1 ? movedVertices[otherSelectionIndex.x] : meshVertices[meshEdges[o].x];
- var otherEdgeEnd = otherSelectionIndex.y != -1 ? movedVertices[otherSelectionIndex.y] : meshVertices[meshEdges[o].y];
-
- if (MathUtility.SegmentIntersection(edgeStart, edgeEnd, otherEdgeStart, otherEdgeEnd, ref edgeIntersectionPoint))
- return true;
- }
- }
-
- return false;
- }
-
- static int2 FindSelectionIndexFromEdge(in int[] selection, int2 edge)
- {
- var selectionIndex = new int2(-1, -1);
- for (var m = 0; m < selection.Length; ++m)
- {
- if (selection[m] == edge.x)
- {
- selectionIndex.x = m;
- break;
- }
- if (selection[m] == edge.y)
- {
- selectionIndex.y = m;
- break;
- }
- }
-
- return selectionIndex;
- }
-
- static bool IsMovedVertexIntersectingWithOutline(in int[] selection, in Vector2[] movedVertices, in int2[] outlineEdges, in Vector2[] meshVertices)
- {
- var edgeIntersectionPoint = Vector2.zero;
-
- for (var i = 0; i < selection.Length; ++i)
- {
- var edgeStart = meshVertices[selection[i]];
- var edgeEnd = movedVertices[i];
-
- for (var m = 0; m < outlineEdges.Length; ++m)
- {
- if (selection[i] == outlineEdges[m].x || selection[i] == outlineEdges[m].y)
- continue;
-
- var otherSelectionIndex = FindSelectionIndexFromEdge(in selection, outlineEdges[m]);
- var otherEdgeStart = otherSelectionIndex.x != -1 ? movedVertices[otherSelectionIndex.x] : meshVertices[outlineEdges[m].x];
- var otherEdgeEnd = otherSelectionIndex.y != -1 ? movedVertices[otherSelectionIndex.y] : meshVertices[outlineEdges[m].y];
-
- if (MathUtility.SegmentIntersection(edgeStart, edgeEnd, otherEdgeStart, otherEdgeEnd, ref edgeIntersectionPoint))
- return true;
- }
- }
-
- return false;
- }
- }
- }
|