diff options
Diffstat (limited to 'src/World/Generation/ChunkMeshing.hpp')
| -rw-r--r-- | src/World/Generation/ChunkMeshing.hpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/src/World/Generation/ChunkMeshing.hpp b/src/World/Generation/ChunkMeshing.hpp index fb5fea9..5401580 100644 --- a/src/World/Generation/ChunkMeshing.hpp +++ b/src/World/Generation/ChunkMeshing.hpp @@ -5,11 +5,32 @@ #include "../BlockSide.hpp" #include "../Chunk.hpp" #include "ChunkNeighbors.hpp" +#include "../ChunkRegistry.hpp" namespace MC::World::Generation::ChunkMeshing { +// Literally just the blocks squarely surrounding a chunk. +// Example context for a 2x1x2 chunk: +// c c c c +// c x x c +// c x x c +// c c c c +class SurroundingContext { +public: + struct Block { Bool does_exist; Chunk::BlockData block; }; + + Block& at(Position::BlockOffset p); + const Block& at(Position::BlockOffset p) const; +private: + static USize pos(Position::BlockOffset p); + static constexpr USize surrounding_block_count = Chunk::Width * 4 + 4; + + Block m_blocks[surrounding_block_count * Chunk::Height] = {}; +}; +SurroundingContext create_meshing_context(const Chunk& chunk, ChunkNeighbors& neighbors); + struct ChunkMesh { GFX::Mesh land_mesh, water_mesh; }; -ChunkMesh mesh_chunk(Chunk& chunk, const ChunkNeighbors& neighbors); +ChunkMesh mesh_chunk(Chunk& chunk, const SurroundingContext& context); namespace Detail { @@ -23,7 +44,7 @@ template <typename T> using Face = std::array<T, 4>; template <typename Decisions> -GFX::Mesh create_mesh(Chunk& chunk, const ChunkNeighbors& neighbors) { +GFX::Mesh create_mesh(Chunk& chunk, const SurroundingContext& context) { GFX::Util::MeshBuilder<Normal, TexCoord, Light, AO> builder; for (Int x = 0; x < Chunk::Width; x++) { @@ -34,7 +55,7 @@ GFX::Mesh create_mesh(Chunk& chunk, const ChunkNeighbors& neighbors) { continue; for (auto side: BlockSide::all()) { - if (!Decisions::is_face_visible(chunk, neighbors, x, y, z, side)) + if (!Decisions::is_face_visible(chunk, context, x, y, z, side)) continue; U32 s = builder.vertex_count(); @@ -42,8 +63,8 @@ GFX::Mesh create_mesh(Chunk& chunk, const ChunkNeighbors& neighbors) { builder.positions(Decisions::face_positions(side, x, y, z)); builder.attributes<0>(Decisions::face_normals(side)); builder.attributes<1>(Decisions::face_tex_coords(block.type, side)); - builder.attributes<2>(Decisions::face_light(chunk, neighbors, x, y, z, side)); - builder.attributes<3>(Decisions::face_ao_values(chunk, neighbors, x, y, z, side)); + builder.attributes<2>(Decisions::face_light(chunk, context, x, y, z, side)); + builder.attributes<3>(Decisions::face_ao_values(chunk, context, x, y, z, side)); builder.indices(std::array{ s + 0, s + 1, s + 2, s + 2, s + 3, s + 0 }); } } @@ -58,19 +79,20 @@ public: static Face<Vertex> face_positions(BlockSide side, U32 x, U32 y, U32 z); static Face<TexCoord> face_tex_coords(BlockType type, BlockSide side); static Face<Normal> face_normals(BlockSide side); - static Face<Light> face_light(Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side); - static Face<AO> face_ao_values(Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side); + static Face<Light> face_light(Chunk& chunk, const SurroundingContext& context, U32 x, U32 y, U32 z, BlockSide side); + static Face<AO> face_ao_values(Chunk& chunk, const SurroundingContext& context, U32 x, U32 y, U32 z, BlockSide side); static Vector<3, I32> get_face_normal(BlockSide side); - static Chunk::BlockData get_opposing_neighbor(const Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side); + static SurroundingContext::Block get_block_from_chunk_or_context(const Chunk& chunk, const SurroundingContext& context, Position::BlockOffset pos); + static SurroundingContext::Block get_opposing_neighbor(const Chunk& chunk, const SurroundingContext& context, U32 x, U32 y, U32 z, BlockSide side); - static Bool is_face_visible(Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side); + static Bool is_face_visible(Chunk& chunk, const SurroundingContext& context, U32 x, U32 y, U32 z, BlockSide side); static Bool should_ignore_block(Chunk::BlockData block); }; class WaterMeshDecisions final : public DefaultMeshDecisions { public: - static Bool is_face_visible(Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side); + static Bool is_face_visible(Chunk& chunk, const SurroundingContext& context, U32 x, U32 y, U32 z, BlockSide side); static Bool should_ignore_block(Chunk::BlockData block); }; |
