private static int GetVoxelVertexExploredNeighbors(VoxelHandle V, Geo.TemplateFace Face, SliceCache Cache)
        {
            var exploredVerts = 0;

            if (V.IsExplored)
            {
                exploredVerts = 4;
            }
            else
            {
                for (int faceVertex = 0; faceVertex < Face.Mesh.VertexCount; ++faceVertex)
                {
                    var cacheKey            = SliceCache.GetCacheKey(V, Face.Mesh.Verticies[faceVertex].LogicalVertex);
                    var anyNeighborExplored = true;

                    if (!Cache.ExploredCache.TryGetValue(cacheKey, out anyNeighborExplored))
                    {
                        anyNeighborExplored = VoxelHelpers.EnumerateVertexNeighbors2D(V.Coordinate, Face.Mesh.Verticies[faceVertex].LogicalVertex)
                                              .Select(c => new VoxelHandle(V.Chunk.Manager, c))
                                              .Any(n => n.IsValid && n.IsExplored);
                        Cache.ExploredCache.Add(cacheKey, anyNeighborExplored);
                    }

                    if (anyNeighborExplored)
                    {
                        exploredVerts += 1;
                    }
                }
            }

            return(exploredVerts);
        }
        private static void PrecomputeVoxelSlopes(ChunkManager Chunks, VoxelHandle V)
        {
            if (!V.IsValid)
            {
                return;
            }

            if (V.IsEmpty || !V.IsVisible || V.Type == null || !V.Type.CanRamp)
            {
                V.RampType = RampType.None;
                return;
            }

            var vAbove = VoxelHelpers.GetVoxelAbove(V);

            if (vAbove.IsValid && !vAbove.IsEmpty)
            {
                V.RampType = RampType.None;
                return;
            }

            var compositeRamp = RampType.None;

            foreach (var vertex in TopVerticies)
            {
                // If there are no empty neighbors, no slope.


                // - Check manhattan neighbors - both full?
                //      then check if they can slope - if yes, and diagonal is empty, slope
                //          if not, then no slope
                //      if diagonal full - obviously no slope.
                if (!VoxelHelpers.EnumerateVertexNeighbors2D(V.Coordinate, vertex) // Todo: Account for case where only open voxel is diagonal between two full ones
                    .Any(n =>
                {
                    var handle = Chunks.CreateVoxelHandle(n);
                    if (handle.IsValid)
                    {
                        return(handle.IsEmpty);
                    }
                    return(false);
                }))
                {
                    continue;
                }

                switch (vertex)
                {
                case VoxelVertex.FrontTopLeft:
                    compositeRamp |= RampType.TopFrontLeft;
                    break;

                case VoxelVertex.FrontTopRight:
                    compositeRamp |= RampType.TopFrontRight;
                    break;

                case VoxelVertex.BackTopLeft:
                    compositeRamp |= RampType.TopBackLeft;
                    break;

                case VoxelVertex.BackTopRight:
                    compositeRamp |= RampType.TopBackRight;
                    break;
                }
            }

            V.RampType = compositeRamp;
        }