private void RemoveEdge(Edge edge)
 {
     cacheUndo.BeginUndoOperation(TextContent.removeEdge);
     m_SpriteMeshDataController.RemoveEdge(edge);
     Triangulate();
 }
        private EdgeIntersectionResult CalculateEdgeIntersection(int vertexIndex, int hoveredVertexIndex, int hoveredEdgeIndex, Vector2 targetPosition)
        {
            Debug.Assert(vertexIndex >= 0);

            EdgeIntersectionResult edgeIntersection = new EdgeIntersectionResult();

            edgeIntersection.startVertexIndex   = vertexIndex;
            edgeIntersection.endVertexIndex     = hoveredVertexIndex;
            edgeIntersection.endPosition        = targetPosition;
            edgeIntersection.intersectEdgeIndex = -1;

            Vector2 startPoint = m_SpriteMeshData.GetPosition(edgeIntersection.startVertexIndex);

            bool intersectsEdge            = false;
            int  lastIntersectingEdgeIndex = -1;

            do
            {
                lastIntersectingEdgeIndex = edgeIntersection.intersectEdgeIndex;

                if (intersectsEdge)
                {
                    Vector2 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
                if (intersectsEdge && m_SpriteMeshData.edges[edgeIntersection.intersectEdgeIndex].Contains(edgeIntersection.endVertexIndex))
                {
                    edgeIntersection.intersectEdgeIndex = -1;
                    intersectsEdge = false;
                    edgeIntersection.endPosition = m_SpriteMeshData.GetPosition(edgeIntersection.endVertexIndex);
                }

                if (intersectsEdge)
                {
                    edgeIntersection.endVertexIndex = -1;

                    Edge    intersectingEdge = m_SpriteMeshData.edges[edgeIntersection.intersectEdgeIndex];
                    Vector2 newPointScreen   = spriteMeshView.WorldToScreen(edgeIntersection.endPosition);
                    Vector2 edgeV1           = spriteMeshView.WorldToScreen(m_SpriteMeshData.GetPosition(intersectingEdge.index1));
                    Vector2 edgeV2           = spriteMeshView.WorldToScreen(m_SpriteMeshData.GetPosition(intersectingEdge.index2));

                    if ((newPointScreen - edgeV1).magnitude <= kSnapDistance)
                    {
                        edgeIntersection.endVertexIndex = intersectingEdge.index1;
                    }
                    else if ((newPointScreen - edgeV2).magnitude <= kSnapDistance)
                    {
                        edgeIntersection.endVertexIndex = intersectingEdge.index2;
                    }

                    if (edgeIntersection.endVertexIndex != -1)
                    {
                        edgeIntersection.intersectEdgeIndex = -1;
                        intersectsEdge = false;
                        edgeIntersection.endPosition = m_SpriteMeshData.GetPosition(edgeIntersection.endVertexIndex);
                    }
                }
            }while (intersectsEdge && lastIntersectingEdgeIndex != edgeIntersection.intersectEdgeIndex);

            edgeIntersection.intersectEdgeIndex = intersectsEdge ? edgeIntersection.intersectEdgeIndex : hoveredEdgeIndex;

            if (edgeIntersection.endVertexIndex != -1 && !intersectsEdge)
            {
                edgeIntersection.endPosition = m_SpriteMeshData.GetPosition(edgeIntersection.endVertexIndex);
            }

            return(edgeIntersection);
        }
        private void CreateVertex(Vector2 position, int edgeIndex)
        {
            position = MathUtility.ClampPositionToRect(position, frame);
            cacheUndo.BeginUndoOperation(TextContent.createVertex);

            BoneWeight boneWeight = new BoneWeight();

            Vector3Int indices;
            Vector3    barycentricCoords;

            if (m_SpriteMeshDataController.FindTriangle(position, out indices, out barycentricCoords))
            {
                EditableBoneWeight bw1 = m_SpriteMeshData.GetWeight(indices.x);
                EditableBoneWeight bw2 = m_SpriteMeshData.GetWeight(indices.y);
                EditableBoneWeight bw3 = m_SpriteMeshData.GetWeight(indices.z);

                EditableBoneWeight result = new EditableBoneWeight();

                foreach (BoneWeightChannel channel in bw1)
                {
                    if (!channel.enabled)
                    {
                        continue;
                    }

                    var weight = channel.weight * barycentricCoords.x;

                    if (weight > 0f)
                    {
                        result.AddChannel(channel.boneIndex, weight, true);
                    }
                }

                foreach (BoneWeightChannel channel in bw2)
                {
                    if (!channel.enabled)
                    {
                        continue;
                    }

                    var weight = channel.weight * barycentricCoords.y;

                    if (weight > 0f)
                    {
                        result.AddChannel(channel.boneIndex, weight, true);
                    }
                }

                foreach (BoneWeightChannel 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);

                boneWeight = result.ToBoneWeight(true);
            }
            else if (edgeIndex != -1)
            {
                Edge    edge = m_SpriteMeshData.edges[edgeIndex];
                Vector2 pos1 = m_SpriteMeshData.GetPosition(edge.index1);
                Vector2 pos2 = m_SpriteMeshData.GetPosition(edge.index2);
                Vector2 dir1 = (position - pos1);
                Vector2 dir2 = (pos2 - pos1);
                float   t    = Vector2.Dot(dir1, dir2.normalized) / dir2.magnitude;
                t = Mathf.Clamp01(t);
                BoneWeight bw1 = m_SpriteMeshData.GetWeight(edge.index1).ToBoneWeight(true);
                BoneWeight bw2 = m_SpriteMeshData.GetWeight(edge.index2).ToBoneWeight(true);

                boneWeight = EditableBoneWeightUtility.Lerp(bw1, bw2, t);
            }

            m_SpriteMeshDataController.CreateVertex(position, edgeIndex);
            m_SpriteMeshData.GetWeight(m_SpriteMeshData.vertexCount - 1).SetFromBoneWeight(boneWeight);
            Triangulate();
        }