public MeshSplitterConvex(MeshContainer meshContainer, Plane splitPlane, Quaternion splitRotation)
    {
        _mesh          = meshContainer;
        _splitPlane    = splitPlane;
        _splitRotation = splitRotation;
        _ownRotation   = meshContainer.transform.rotation;

        capInds = new List <int>(meshContainer.vertexCount / 10);
    }
    public MeshSplitterConcave(MeshContainer meshContainer, Plane splitPlane, Quaternion splitRotation)
    {
        _mesh          = meshContainer;
        _splitPlane    = splitPlane;
        _splitRotation = splitRotation;
        _ownRotation   = meshContainer.transform.rotation;

        _edges = new List <Edge>(meshContainer.vertexCount / 10);
    }
    public void Split(Transform splitTransform)
    {
        if (!_isSplitting)
        {
            _isSplitting = _splitMesh = true;
            _splitPlane  = new Plane(splitTransform);

            MeshFilter[]          meshFilters     = GetComponentsInChildren <MeshFilter>();
            SkinnedMeshRenderer[] skinnedRenderes = GetComponentsInChildren <SkinnedMeshRenderer>();

            _meshContainerStatic = new MeshContainer[meshFilters.Length];
            _meshSplitterStatic  = new IMeshSplitter[meshFilters.Length];

            for (int i = 0; i < meshFilters.Length; i++)
            {
                _meshContainerStatic[i] = new MeshContainer(meshFilters[i]);

                _meshSplitterStatic[i] = Convex ? (IMeshSplitter) new MeshSplitterConvex(_meshContainerStatic[i], _splitPlane, splitTransform.rotation) :
                                         (IMeshSplitter) new MeshSplitterConcave(_meshContainerStatic[i], _splitPlane, splitTransform.rotation);

                if (UseCapUV)
                {
                    _meshSplitterStatic[i].SetCapUV(UseCapUV, CustomUV, CapUVMin, CapUVMax);
                }
#if UNITY_EDITOR
                _meshSplitterStatic[i].DebugDraw(ShowDebug);
#endif
            }

            _meshSplitterSkinned  = new IMeshSplitter[skinnedRenderes.Length];
            _meshContainerSkinned = new MeshContainer[skinnedRenderes.Length];

            for (int i = 0; i < skinnedRenderes.Length; i++)
            {
                _meshContainerSkinned[i] = new MeshContainer(skinnedRenderes[i]);

                _meshSplitterSkinned[i] = Convex ? (IMeshSplitter) new MeshSplitterConvex(_meshContainerSkinned[i], _splitPlane, splitTransform.rotation) :
                                          (IMeshSplitter) new MeshSplitterConcave(_meshContainerSkinned[i], _splitPlane, splitTransform.rotation);

                if (UseCapUV)
                {
                    _meshSplitterSkinned[i].SetCapUV(UseCapUV, CustomUV, CapUVMin, CapUVMax);
                }
#if UNITY_EDITOR
                _meshSplitterSkinned[i].DebugDraw(ShowDebug);
#endif
            }
        }
    }
    /// <summary>
    /// Test if the angle between next edge and current edge is less or equal to 180 degrees.
    /// </summary>
    /// <param name="currentEdge">Current Edge</param>
    /// <param name="nextEdge">Next Edge</param>
    /// <param name="cw">Direction is clockwise?</param>
    /// <returns></returns>
    private int TestInnerSide(Edge currentEdge, Edge nextEdge, bool cw)
    {
        Plane plane     = new Plane(currentEdge.Left, currentEdge.Normal);
        float pointSide = plane.PointSide(cw ? nextEdge.Right : nextEdge.Left);

        if (pointSide < -.000001f)  // less than zero with a threshold, inner side
        {
            return(1);
        }

        if (pointSide < .000001f) // < 180 degree angle, needs to be melted
        {
            return(0);
        }

        return(-1);
    }