private List <MeshGeneratorNode> GetSurfaceNodes(int[,,] matrix)
        {
            int length = matrix.GetLength(0);
            int width  = matrix.GetLength(1);
            int height = matrix.GetLength(2);

            List <MeshGeneratorNode> nodes = new List <MeshGeneratorNode>();

            MeshGeneratorNode[,,] nodeMatrix = new MeshGeneratorNode[length, width, height];

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    for (int k = 0; k < height; k++)
                    {
                        MeshGeneratorNode node = GetSurfaceNode(matrix, i, j, k);
                        nodeMatrix[i, j, k] = node;

                        if (node == null)
                        {
                            continue;
                        }

                        if (i != 0)
                        {
                            MeshGeneratorNode prevNode = nodeMatrix[i - 1, j, k];
                            prevNode?.CreateMutualLink(node);
                        }

                        if (j != 0)
                        {
                            MeshGeneratorNode prevNode = nodeMatrix[i, j - 1, k];
                            prevNode?.CreateMutualLink(node);
                        }
                        if (k != 0)
                        {
                            MeshGeneratorNode prevNode = nodeMatrix[i, j, k - 1];
                            prevNode?.CreateMutualLink(node);
                        }

                        nodes.Add(node);
                    }
                }
            }

            return(nodes);
        }
        public List <Vector3> GetAllTriangles()
        {
            List <Vector3> triangles = new List <Vector3>(TriangleCount * 3);

            for (int i = 0; i < LinkedNodes.Count; i++)
            {
                MeshGeneratorNode firstNode = LinkedNodes[i];

                for (int j = i + 1; j < LinkedNodes.Count; j++)
                {
                    MeshGeneratorNode secondNode = LinkedNodes[j];

                    //if ((firstNode.HaveCreatedTriangle && !secondNode.HaveCreatedTriangle) || (!firstNode.HaveCreatedTriangle && secondNode.HaveCreatedTriangle))
                    //continue;

                    if ((firstNode.MatrixPosition.x == secondNode.MatrixPosition.x && firstNode.MatrixPosition.y != secondNode.MatrixPosition.y && firstNode.MatrixPosition.z != secondNode.MatrixPosition.z) ||
                        (firstNode.MatrixPosition.y == secondNode.MatrixPosition.y && firstNode.MatrixPosition.x != secondNode.MatrixPosition.x && firstNode.MatrixPosition.z != secondNode.MatrixPosition.z) ||
                        (firstNode.MatrixPosition.z == secondNode.MatrixPosition.z && firstNode.MatrixPosition.x != secondNode.MatrixPosition.x && firstNode.MatrixPosition.y != secondNode.MatrixPosition.y))
                    {
                        Vector3Int oppositeMatrixPoint = (firstNode.MatrixPosition + secondNode.MatrixPosition) - MatrixPosition;

                        Vector3Int minCoordinate = new Vector3Int(Mathf.Min(MatrixPosition.x, firstNode.MatrixPosition.x, secondNode.MatrixPosition.x, oppositeMatrixPoint.x) + 1,
                                                                  Mathf.Min(MatrixPosition.y, firstNode.MatrixPosition.y, secondNode.MatrixPosition.y, oppositeMatrixPoint.y) + 1,
                                                                  Mathf.Min(MatrixPosition.z, firstNode.MatrixPosition.z, secondNode.MatrixPosition.z, oppositeMatrixPoint.z) + 1);
                        Vector3Int maxCoordinate = new Vector3Int(Mathf.Max(MatrixPosition.x, firstNode.MatrixPosition.x, secondNode.MatrixPosition.x, oppositeMatrixPoint.x),
                                                                  Mathf.Max(MatrixPosition.y, firstNode.MatrixPosition.y, secondNode.MatrixPosition.y, oppositeMatrixPoint.y),
                                                                  Mathf.Max(MatrixPosition.z, firstNode.MatrixPosition.z, secondNode.MatrixPosition.z, oppositeMatrixPoint.z));

                        int firstCommonPoint  = PointsMatrix[minCoordinate.x, minCoordinate.y, minCoordinate.z];
                        int secondCommonPoint = PointsMatrix[maxCoordinate.x, maxCoordinate.y, maxCoordinate.z];

                        //HaveCreatedTriangle = true; //TODO HACK, make better

                        if (firstCommonPoint == secondCommonPoint)
                        {
                            continue;
                        }

                        triangles.Add(Position);

                        Vector3Int normal = Cross(firstNode.MatrixPosition - MatrixPosition, secondNode.MatrixPosition - MatrixPosition);

                        if (firstCommonPoint > secondCommonPoint)
                        {
                            if (normal + minCoordinate == maxCoordinate)
                            {
                                triangles.Add(firstNode.Position);
                                triangles.Add(secondNode.Position);
                            }
                            else
                            {
                                triangles.Add(secondNode.Position);
                                triangles.Add(firstNode.Position);
                            }
                        }
                        else
                        {
                            if (normal + maxCoordinate == minCoordinate)
                            {
                                triangles.Add(firstNode.Position);
                                triangles.Add(secondNode.Position);
                            }
                            else
                            {
                                triangles.Add(secondNode.Position);
                                triangles.Add(firstNode.Position);
                            }
                        }
                    }
                }
            }

            return(triangles);
        }
 public void CreateMutualLink(MeshGeneratorNode node)
 {
     LinkedNodes.Add(node);
     node.LinkedNodes.Add(this);
 }