/*
     * Small diagram for reference :)
     *       |      |  /|
     *       |      | / |P1
     *       |      |/  |
     *       |    I1|   |
     *       |     /|   |
     *      y|    / |   |
     *       | P0/__|___|P2
     *       |      |I2
     *       |      |
     *       |___________________
     */

    public bool TrianglePlaneIntersect(List <Vector3> vertices, List <Vector2> uvs, List <int> triangles, int startIdx, ref Plane plane, TempMesh posMesh, TempMesh negMesh, Vector3[] intersectVectors)
    {
        int i;

        // Store triangle, vertex and uv from indices
        for (i = 0; i < 3; ++i)
        {
            t[i] = triangles[startIdx + i];
            v[i] = vertices[t[i]];
            u[i] = uvs[t[i]];
        }

        // Store wether the vertex is on positive mesh
        posMesh.ContainsKeys(triangles, startIdx, positive);

        // If they're all on the same side, don't do intersection
        if (positive[0] == positive[1] && positive[1] == positive[2])
        {
            // All points are on the same side. No intersection
            // Add them to either positive or negative mesh
            (positive[0] ? posMesh : negMesh).AddOgTriangle(t);
            return(false);
        }

        // Find lonely point
        int lonelyPoint = 0;

        if (positive[0] != positive[1])
        {
            lonelyPoint = positive[0] != positive[2] ? 0 : 1;
        }
        else
        {
            lonelyPoint = 2;
        }

        // Set previous point in relation to front face order
        int prevPoint = lonelyPoint - 1;

        if (prevPoint == -1)
        {
            prevPoint = 2;
        }
        // Set next point in relation to front face order
        int nextPoint = lonelyPoint + 1;

        if (nextPoint == 3)
        {
            nextPoint = 0;
        }

        // Get the 2 intersection points
        ValueTuple <Vector3, Vector2> newPointPrev = Intersect(plane, v[lonelyPoint], v[prevPoint], u[lonelyPoint], u[prevPoint]);
        ValueTuple <Vector3, Vector2> newPointNext = Intersect(plane, v[lonelyPoint], v[nextPoint], u[lonelyPoint], u[nextPoint]);

        //Set the new triangles and store them in respective tempmeshes
        (positive[lonelyPoint] ? posMesh : negMesh).AddSlicedTriangle(t[lonelyPoint], newPointNext.Item1, newPointPrev.Item1, newPointNext.Item2, newPointPrev.Item2);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[prevPoint], newPointPrev.Item1, newPointPrev.Item2, t[nextPoint]);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[nextPoint], newPointPrev.Item1, newPointNext.Item1, newPointPrev.Item2, newPointNext.Item2);

        // We return the edge that will be in the correct orientation for the positive side mesh
        if (positive[lonelyPoint])
        {
            intersectVectors[0] = newPointPrev.Item1;
            intersectVectors[1] = newPointNext.Item1;
        }
        else
        {
            intersectVectors[0] = newPointNext.Item1;
            intersectVectors[1] = newPointPrev.Item1;
        }
        return(true);
    }
    public bool TrianglePlaneIntersect(List <Vector3> vertices, List <Vector2> uvs, List <int> triangles, int startIdx, ref Plane plane, TempMesh posMesh, TempMesh negMesh, Vector3[] intersectVectors)
    {
        int i;

        for (i = 0; i < 3; ++i)
        {
            t[i] = triangles[startIdx + i];
            v[i] = vertices[t[i]];
            u[i] = uvs[t[i]];
        }

        // Находится ли вершина на положительной сетке
        posMesh.ContainsKeys(triangles, startIdx, positive);

        // Если они все на одной стороне, не пересечения нет
        if (positive[0] == positive[1] && positive[1] == positive[2])
        {
            // Все точки на одной стороне, пересечения нет
            // Добавляем их в положительный или отрицательный меш
            (positive[0] ? posMesh : negMesh).AddOriginalTriangle(t);
            return(false);
        }

        // Поиск одиноой точки
        int lonelyPoint = 0;

        if (positive[0] != positive[1])
        {
            lonelyPoint = positive[0] != positive[2] ? 0 : 1;
        }
        else
        {
            lonelyPoint = 2;
        }

        // Устанавливаем предыдущую точку относительно порядка передней грани
        int prevPoint = lonelyPoint - 1;

        if (prevPoint == -1)
        {
            prevPoint = 2;
        }
        // Устанавливаем следующую точку
        int nextPoint = lonelyPoint + 1;

        if (nextPoint == 3)
        {
            nextPoint = 0;
        }

        // Получаем 2 точки пересечения
        ValueTuple <Vector3, Vector2> newPointPrev = Intersect(plane, v[lonelyPoint], v[prevPoint], u[lonelyPoint], u[prevPoint]);
        ValueTuple <Vector3, Vector2> newPointNext = Intersect(plane, v[lonelyPoint], v[nextPoint], u[lonelyPoint], u[nextPoint]);

        // Добавляем новые треугольники и сохраните их в соответствующих буферных мешах
        (positive[lonelyPoint] ? posMesh : negMesh).AddSlicedTriangle(t[lonelyPoint], newPointNext.Item1, newPointPrev.Item1, newPointNext.Item2, newPointPrev.Item2);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[prevPoint], newPointPrev.Item1, newPointPrev.Item2, t[nextPoint]);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[nextPoint], newPointPrev.Item1, newPointNext.Item1, newPointPrev.Item2, newPointNext.Item2);

        // Возвращаем ребро, которое будет в правильной ориентации для положительного меша
        if (positive[lonelyPoint])
        {
            intersectVectors[0] = newPointPrev.Item1;
            intersectVectors[1] = newPointNext.Item1;
        }
        else
        {
            intersectVectors[0] = newPointNext.Item1;
            intersectVectors[1] = newPointPrev.Item1;
        }
        return(true);
    }