/// <summary>
 /// Add the mesh data to the correct side and calulate normals
 /// </summary>
 /// <param name="side"></param>
 /// <param name="vertex1"></param>
 /// <param name="vertex1Uv"></param>
 /// <param name="vertex2"></param>
 /// <param name="vertex2Uv"></param>
 /// <param name="vertex3"></param>
 /// <param name="vertex3Uv"></param>
 /// <param name="shareVertices"></param>
 private void AddTrianglesNormalAndUvs(MeshSide side, Vector3 vertex1, Vector3?normal1, Vector2 uv1, Vector3 vertex2, Vector3?normal2, Vector2 uv2, Vector3 vertex3, Vector3?normal3, Vector2 uv3, bool shareVertices, bool addFirst)
 {
     if (side == MeshSide.Positive)
     {
         AddTrianglesNormalsAndUvs(ref _positiveSideVertices, ref _positiveSideTriangles, ref _positiveSideNormals, ref _positiveSideUvs, vertex1, normal1, uv1, vertex2, normal2, uv2, vertex3, normal3, uv3, shareVertices, addFirst);
     }
     else
     {
         AddTrianglesNormalsAndUvs(ref _negativeSideVertices, ref _negativeSideTriangles, ref _negativeSideNormals, ref _negativeSideUvs, vertex1, normal1, uv1, vertex2, normal2, uv2, vertex3, normal3, uv3, shareVertices, addFirst);
     }
 }
 /// <summary>
 /// Setup the mesh object for the specified side
 /// </summary>
 /// <param name="side"></param>
 private void SetMeshData(MeshSide side)
 {
     if (side == MeshSide.Positive)
     {
         _positiveSideMesh.vertices  = _positiveSideVertices.ToArray();
         _positiveSideMesh.triangles = _positiveSideTriangles.ToArray();
         _positiveSideMesh.normals   = _positiveSideNormals.ToArray();
         _positiveSideMesh.uv        = _positiveSideUvs.ToArray();
     }
     else
     {
         _negativeSideMesh.vertices  = _negativeSideVertices.ToArray();
         _negativeSideMesh.triangles = _negativeSideTriangles.ToArray();
         _negativeSideMesh.normals   = _negativeSideNormals.ToArray();
         _negativeSideMesh.uv        = _negativeSideUvs.ToArray();
     }
 }
    /// <summary>
    /// Compute the positive and negative meshes based on the plane and mesh
    /// </summary>
    private void ComputeNewMeshes()
    {
        int[]     meshTriangles = _mesh.triangles;
        Vector3[] meshVerts     = _mesh.vertices;
        Vector3[] meshNormals   = _mesh.normals;
        Vector2[] meshUvs       = _mesh.uv;

        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            //We need the verts in order so that we know which way to wind our new mesh triangles.
            Vector3 vert1      = meshVerts[meshTriangles[i]];
            int     vert1Index = Array.IndexOf(meshVerts, vert1);
            Vector2 uv1        = meshUvs[vert1Index];
            Vector3 normal1    = meshNormals[vert1Index];
            bool    vert1Side  = _plane.GetSide(vert1);

            Vector3 vert2      = meshVerts[meshTriangles[i + 1]];
            int     vert2Index = Array.IndexOf(meshVerts, vert2);
            Vector2 uv2        = meshUvs[vert2Index];
            Vector3 normal2    = meshNormals[vert2Index];
            bool    vert2Side  = _plane.GetSide(vert2);

            Vector3 vert3      = meshVerts[meshTriangles[i + 2]];
            bool    vert3Side  = _plane.GetSide(vert3);
            int     vert3Index = Array.IndexOf(meshVerts, vert3);
            Vector3 normal3    = meshNormals[vert3Index];
            Vector2 uv3        = meshUvs[vert3Index];

            //All verts are on the same side
            if (vert1Side == vert2Side && vert2Side == vert3Side)
            {
                //Add the relevant triangle
                MeshSide side = (vert1Side) ? MeshSide.Positive : MeshSide.Negative;
                AddTrianglesNormalAndUvs(side, vert1, normal1, uv1, vert2, normal2, uv2, vert3, normal3, uv3, true, false);
            }
            else
            {
                //we need the two points where the plane intersects the triangle.
                Vector3 intersection1;
                Vector3 intersection2;

                Vector2 intersection1Uv;
                Vector2 intersection2Uv;

                MeshSide side1 = (vert1Side) ? MeshSide.Positive : MeshSide.Negative;
                MeshSide side2 = (vert1Side) ? MeshSide.Negative : MeshSide.Positive;

                //vert 1 and 2 are on the same side
                if (vert1Side == vert2Side)
                {
                    //Cast a ray from v2 to v3 and from v3 to v1 to get the intersections
                    intersection1 = GetRayPlaneIntersectionPointAndUv(vert2, uv2, vert3, uv3, out intersection1Uv);
                    intersection2 = GetRayPlaneIntersectionPointAndUv(vert3, uv3, vert1, uv1, out intersection2Uv);

                    //Add the positive or negative triangles
                    AddTrianglesNormalAndUvs(side1, vert1, null, uv1, vert2, null, uv2, intersection1, null, intersection1Uv, _useSharedVertices, false);
                    AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, _useSharedVertices, false);

                    AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert3, null, uv3, intersection2, null, intersection2Uv, _useSharedVertices, false);
                }
                //vert 1 and 3 are on the same side
                else if (vert1Side == vert3Side)
                {
                    //Cast a ray from v1 to v2 and from v2 to v3 to get the intersections
                    intersection1 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert2, uv2, out intersection1Uv);
                    intersection2 = GetRayPlaneIntersectionPointAndUv(vert2, uv2, vert3, uv3, out intersection2Uv);

                    //Add the positive triangles
                    AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, vert3, null, uv3, _useSharedVertices, false);
                    AddTrianglesNormalAndUvs(side1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, vert3, null, uv3, _useSharedVertices, false);

                    AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert2, null, uv2, intersection2, null, intersection2Uv, _useSharedVertices, false);
                }
                //Vert1 is alone
                else
                {
                    //Cast a ray from v1 to v2 and from v1 to v3 to get the intersections
                    intersection1 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert2, uv2, out intersection1Uv);
                    intersection2 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert3, uv3, out intersection2Uv);

                    AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, _useSharedVertices, false);

                    AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert2, null, uv2, vert3, null, uv3, _useSharedVertices, false);
                    AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert3, null, uv3, intersection2, null, intersection2Uv, _useSharedVertices, false);
                }

                //Add the newly created points on the plane.
                _pointsAlongPlane.Add(intersection1);
                _pointsAlongPlane.Add(intersection2);
            }
        }

        //If the object is solid, join the new points along the plane otherwise do the reverse winding
        if (_isSolid)
        {
            JoinPointsAlongPlane();
        }
        else if (_createReverseTriangleWindings)
        {
            AddReverseTriangleWinding();
        }

        if (_smoothVertices)
        {
            SmoothVertices();
        }
    }