summaryrefslogtreecommitdiffstats
path: root/game/client/chunk_mesher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/chunk_mesher.cc')
-rw-r--r--game/client/chunk_mesher.cc252
1 files changed, 160 insertions, 92 deletions
diff --git a/game/client/chunk_mesher.cc b/game/client/chunk_mesher.cc
index 7e185f1..962997c 100644
--- a/game/client/chunk_mesher.cc
+++ b/game/client/chunk_mesher.cc
@@ -1,4 +1,5 @@
#include "client/pch.hh"
+
#include "client/chunk_mesher.hh"
#include "core/crc64.hh"
@@ -18,19 +19,19 @@ using QuadBuilder = std::vector<ChunkQuad>;
using CachedChunkCoord = unsigned short;
constexpr static CachedChunkCoord CPOS_ITSELF = 0x0000;
-constexpr static CachedChunkCoord CPOS_NORTH = 0x0001;
-constexpr static CachedChunkCoord CPOS_SOUTH = 0x0002;
-constexpr static CachedChunkCoord CPOS_EAST = 0x0003;
-constexpr static CachedChunkCoord CPOS_WEST = 0x0004;
-constexpr static CachedChunkCoord CPOS_TOP = 0x0005;
+constexpr static CachedChunkCoord CPOS_NORTH = 0x0001;
+constexpr static CachedChunkCoord CPOS_SOUTH = 0x0002;
+constexpr static CachedChunkCoord CPOS_EAST = 0x0003;
+constexpr static CachedChunkCoord CPOS_WEST = 0x0004;
+constexpr static CachedChunkCoord CPOS_TOP = 0x0005;
constexpr static CachedChunkCoord CPOS_BOTTOM = 0x0006;
constexpr static const size_t NUM_CACHED_CPOS = 7;
-static const CachedChunkCoord get_cached_cpos(const chunk_pos &pivot, const chunk_pos &cpos)
+static const CachedChunkCoord get_cached_cpos(const chunk_pos& pivot, const chunk_pos& cpos)
{
- static const CachedChunkCoord nx[3] = {CPOS_WEST, 0, CPOS_EAST};
- static const CachedChunkCoord ny[3] = {CPOS_BOTTOM, 0, CPOS_TOP};
- static const CachedChunkCoord nz[3] = {CPOS_NORTH, 0, CPOS_SOUTH};
+ static const CachedChunkCoord nx[3] = { CPOS_WEST, 0, CPOS_EAST };
+ static const CachedChunkCoord ny[3] = { CPOS_BOTTOM, 0, CPOS_TOP };
+ static const CachedChunkCoord nz[3] = { CPOS_NORTH, 0, CPOS_SOUTH };
if(pivot != cpos) {
chunk_pos delta = pivot - cpos;
@@ -38,11 +39,13 @@ static const CachedChunkCoord get_cached_cpos(const chunk_pos &pivot, const chun
delta[1] = cxpr::clamp<std::int64_t>(delta[1], -1, 1);
delta[2] = cxpr::clamp<std::int64_t>(delta[2], -1, 1);
- if(delta[0])
+ if(delta[0]) {
return nx[delta[0] + 1];
- if(delta[1])
+ } else if(delta[1]) {
return ny[delta[1] + 1];
- return nz[delta[2] + 1];
+ } else {
+ return nz[delta[2] + 1];
+ }
}
return CPOS_ITSELF;
@@ -52,36 +55,46 @@ static voxel_facing get_facing(voxel_face face, voxel_type type)
{
if(type == voxel_type::CROSS) {
switch(face) {
- case voxel_face::CROSS_NESW: return voxel_facing::NESW;
- case voxel_face::CROSS_NWSE: return voxel_facing::NWSE;
- default: return voxel_facing::NORTH;
+ case voxel_face::CROSS_NESW:
+ return voxel_facing::NESW;
+ case voxel_face::CROSS_NWSE:
+ return voxel_facing::NWSE;
+ default:
+ return voxel_facing::NORTH;
}
}
switch(face) {
- case voxel_face::CUBE_NORTH: return voxel_facing::NORTH;
- case voxel_face::CUBE_SOUTH: return voxel_facing::SOUTH;
- case voxel_face::CUBE_EAST: return voxel_facing::EAST;
- case voxel_face::CUBE_WEST: return voxel_facing::WEST;
- case voxel_face::CUBE_TOP: return voxel_facing::UP;
- case voxel_face::CUBE_BOTTOM: return voxel_facing::DOWN;
- default: return voxel_facing::NORTH;
+ case voxel_face::CUBE_NORTH:
+ return voxel_facing::NORTH;
+ case voxel_face::CUBE_SOUTH:
+ return voxel_facing::SOUTH;
+ case voxel_face::CUBE_EAST:
+ return voxel_facing::EAST;
+ case voxel_face::CUBE_WEST:
+ return voxel_facing::WEST;
+ case voxel_face::CUBE_TOP:
+ return voxel_facing::UP;
+ case voxel_face::CUBE_BOTTOM:
+ return voxel_facing::DOWN;
+ default:
+ return voxel_facing::NORTH;
}
}
class GL_MeshingTask final : public Task {
public:
- explicit GL_MeshingTask(entt::entity entity, const chunk_pos &cpos);
+ explicit GL_MeshingTask(entt::entity entity, const chunk_pos& cpos);
virtual ~GL_MeshingTask(void) = default;
virtual void process(void) override;
virtual void finalize(void) override;
private:
- bool vis_test(voxel_id voxel, const VoxelInfo *info, const local_pos &lpos) const;
- void push_quad_a(const VoxelInfo *info, const glm::fvec3 &pos, const glm::fvec2 &size, voxel_face face);
- void push_quad_v(const VoxelInfo *info, const glm::fvec3 &pos, const glm::fvec2 &size, voxel_face face, std::size_t entropy);
- void make_cube(voxel_id voxel, const VoxelInfo *info, const local_pos &lpos, voxel_vis vis, std::size_t entropy);
- void cache_chunk(const chunk_pos &cpos);
+ bool vis_test(voxel_id voxel, const VoxelInfo* info, const local_pos& lpos) const;
+ void push_quad_a(const VoxelInfo* info, const glm::fvec3& pos, const glm::fvec2& size, voxel_face face);
+ void push_quad_v(const VoxelInfo* info, const glm::fvec3& pos, const glm::fvec2& size, voxel_face face, std::size_t entropy);
+ void make_cube(voxel_id voxel, const VoxelInfo* info, const local_pos& lpos, voxel_vis vis, std::size_t entropy);
+ void cache_chunk(const chunk_pos& cpos);
private:
std::array<VoxelStorage, NUM_CACHED_CPOS> m_cache;
@@ -91,7 +104,7 @@ private:
chunk_pos m_cpos;
};
-GL_MeshingTask::GL_MeshingTask(entt::entity entity, const chunk_pos &cpos)
+GL_MeshingTask::GL_MeshingTask(entt::entity entity, const chunk_pos& cpos)
{
m_entity = entity;
m_cpos = cpos;
@@ -110,7 +123,7 @@ void GL_MeshingTask::process(void)
m_quads_b.resize(voxel_atlas::plane_count());
m_quads_s.resize(voxel_atlas::plane_count());
- const auto &voxels = m_cache.at(CPOS_ITSELF);
+ const auto& voxels = m_cache.at(CPOS_ITSELF);
for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) {
if(m_status == task_status::CANCELLED) {
@@ -131,18 +144,30 @@ void GL_MeshingTask::process(void)
}
voxel_vis vis = 0;
- if(vis_test(voxel, info, lpos + DIR_NORTH<local_pos::value_type>))
+
+ if(vis_test(voxel, info, lpos + DIR_NORTH<local_pos::value_type>)) {
vis |= VIS_NORTH;
- if(vis_test(voxel, info, lpos + DIR_SOUTH<local_pos::value_type>))
+ }
+
+ if(vis_test(voxel, info, lpos + DIR_SOUTH<local_pos::value_type>)) {
vis |= VIS_SOUTH;
- if(vis_test(voxel, info, lpos + DIR_EAST<local_pos::value_type>))
+ }
+
+ if(vis_test(voxel, info, lpos + DIR_EAST<local_pos::value_type>)) {
vis |= VIS_EAST;
- if(vis_test(voxel, info, lpos + DIR_WEST<local_pos::value_type>))
+ }
+
+ if(vis_test(voxel, info, lpos + DIR_WEST<local_pos::value_type>)) {
vis |= VIS_WEST;
- if(vis_test(voxel, info, lpos + DIR_UP<local_pos::value_type>))
+ }
+
+ if(vis_test(voxel, info, lpos + DIR_UP<local_pos::value_type>)) {
vis |= VIS_UP;
- if(vis_test(voxel, info, lpos + DIR_DOWN<local_pos::value_type>))
+ }
+
+ if(vis_test(voxel, info, lpos + DIR_DOWN<local_pos::value_type>)) {
vis |= VIS_DOWN;
+ }
const auto vpos = coord::to_voxel(m_cpos, lpos);
const auto entropy_src = vpos[0] * vpos[1] * vpos[2];
@@ -161,7 +186,7 @@ void GL_MeshingTask::finalize(void)
return;
}
- auto &component = globals::dimension->chunks.emplace_or_replace<ChunkMeshComponent>(m_entity);
+ auto& component = globals::dimension->chunks.emplace_or_replace<ChunkMeshComponent>(m_entity);
const std::size_t plane_count_nb = m_quads_s.size();
const std::size_t plane_count_b = m_quads_b.size();
@@ -173,8 +198,8 @@ void GL_MeshingTask::finalize(void)
component.quad_b.resize(plane_count_b);
for(std::size_t plane = 0; plane < plane_count_nb; ++plane) {
- QuadBuilder &builder = m_quads_s[plane];
- ChunkVBO &buffer = component.quad_nb[plane];
+ QuadBuilder& builder = m_quads_s[plane];
+ ChunkVBO& buffer = component.quad_nb[plane];
if(builder.empty()) {
if(buffer.handle) {
@@ -182,20 +207,21 @@ void GL_MeshingTask::finalize(void)
buffer.handle = 0;
buffer.size = 0;
}
- }
- else {
- if(!buffer.handle)
+ } else {
+ if(!buffer.handle) {
glGenBuffers(1, &buffer.handle);
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, buffer.handle);
glBufferData(GL_ARRAY_BUFFER, sizeof(ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW);
buffer.size = builder.size();
has_no_submeshes_nb = false;
- }
+ }
}
for(std::size_t plane = 0; plane < plane_count_b; ++plane) {
- QuadBuilder &builder = m_quads_b[plane];
- ChunkVBO &buffer = component.quad_b[plane];
+ QuadBuilder& builder = m_quads_b[plane];
+ ChunkVBO& buffer = component.quad_b[plane];
if(builder.empty()) {
if(buffer.handle) {
@@ -203,15 +229,16 @@ void GL_MeshingTask::finalize(void)
buffer.handle = 0;
buffer.size = 0;
}
- }
- else {
- if(!buffer.handle)
+ } else {
+ if(!buffer.handle) {
glGenBuffers(1, &buffer.handle);
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, buffer.handle);
glBufferData(GL_ARRAY_BUFFER, sizeof(ChunkQuad) * builder.size(), builder.data(), GL_STATIC_DRAW);
buffer.size = builder.size();
has_no_submeshes_b = false;
- }
+ }
}
if(has_no_submeshes_b && has_no_submeshes_nb) {
@@ -219,7 +246,7 @@ void GL_MeshingTask::finalize(void)
}
}
-bool GL_MeshingTask::vis_test(voxel_id voxel, const VoxelInfo *info, const local_pos &lpos) const
+bool GL_MeshingTask::vis_test(voxel_id voxel, const VoxelInfo* info, const local_pos& lpos) const
{
const auto pvpos = coord::to_voxel(m_cpos, lpos);
const auto pcpos = coord::to_chunk(pvpos);
@@ -227,71 +254,113 @@ bool GL_MeshingTask::vis_test(voxel_id voxel, const VoxelInfo *info, const local
const auto index = coord::to_index(plpos);
const auto cached_cpos = get_cached_cpos(m_cpos, pcpos);
- const auto &voxels = m_cache.at(cached_cpos);
+ const auto& voxels = m_cache.at(cached_cpos);
const auto neighbour = voxels[index];
- if(neighbour == NULL_VOXEL_ID)
- return true;
- if(neighbour == voxel)
- return false;
+ bool result;
- if(const VoxelInfo *neighbour_info = voxel_registry::find(neighbour)) {
+ if(neighbour == NULL_VOXEL_ID) {
+ result = true;
+ } else if(neighbour == voxel) {
+ result = false;
+ } else if(auto neighbour_info = voxel_registry::find(neighbour)) {
if(neighbour_info->blending != info->blending) {
// Voxel types that use blending are semi-transparent;
// this means they're rendered using a different setup
// and they must have visible faces with opaque voxels
- return neighbour_info->blending;
+ result = neighbour_info->blending;
+ } else {
+ result = false;
}
+ } else {
+ result = false;
}
- return false;
+ return result;
}
-void GL_MeshingTask::push_quad_a(const VoxelInfo *info, const glm::fvec3 &pos, const glm::fvec2 &size, voxel_face face)
+void GL_MeshingTask::push_quad_a(const VoxelInfo* info, const glm::fvec3& pos, const glm::fvec2& size, voxel_face face)
{
const voxel_facing facing = get_facing(face, info->type);
- const VoxelTexture &vtex = info->textures[static_cast<std::size_t>(face)];
+ const VoxelTexture& vtex = info->textures[static_cast<std::size_t>(face)];
- if(info->blending)
+ if(info->blending) {
m_quads_b[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset, vtex.paths.size()));
- else m_quads_s[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset, vtex.paths.size()));
+ } else {
+ m_quads_s[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset, vtex.paths.size()));
+ }
}
-void GL_MeshingTask::push_quad_v(const VoxelInfo *info, const glm::fvec3 &pos, const glm::fvec2 &size, voxel_face face, std::size_t entropy)
+void GL_MeshingTask::push_quad_v(const VoxelInfo* info, const glm::fvec3& pos, const glm::fvec2& size, voxel_face face, std::size_t entropy)
{
const voxel_facing facing = get_facing(face, info->type);
- const VoxelTexture &vtex = info->textures[static_cast<std::size_t>(face)];
+ const VoxelTexture& vtex = info->textures[static_cast<std::size_t>(face)];
const std::size_t entropy_mod = entropy % vtex.paths.size();
- if(info->blending)
+ if(info->blending) {
m_quads_b[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset + entropy_mod, 0));
- else m_quads_s[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset + entropy_mod, 0));
+ } else {
+ m_quads_s[vtex.cached_plane].push_back(make_chunk_quad(pos, size, facing, vtex.cached_offset + entropy_mod, 0));
+ }
}
-void GL_MeshingTask::make_cube(voxel_id voxel, const VoxelInfo *info, const local_pos &lpos, voxel_vis vis, std::size_t entropy)
+void GL_MeshingTask::make_cube(voxel_id voxel, const VoxelInfo* info, const local_pos& lpos, voxel_vis vis, std::size_t entropy)
{
const glm::fvec3 fpos = glm::fvec3(lpos);
const glm::fvec2 fsize = glm::fvec2(1.0f, 1.0f);
if(info->animated) {
- if(vis & VIS_NORTH) push_quad_a(info, fpos, fsize, voxel_face::CUBE_NORTH);
- if(vis & VIS_SOUTH) push_quad_a(info, fpos, fsize, voxel_face::CUBE_SOUTH);
- if(vis & VIS_EAST) push_quad_a(info, fpos, fsize, voxel_face::CUBE_EAST);
- if(vis & VIS_WEST) push_quad_a(info, fpos, fsize, voxel_face::CUBE_WEST);
- if(vis & VIS_UP) push_quad_a(info, fpos, fsize, voxel_face::CUBE_TOP);
- if(vis & VIS_DOWN) push_quad_a(info, fpos, fsize, voxel_face::CUBE_BOTTOM);
- }
- else {
- if(vis & VIS_NORTH) push_quad_v(info, fpos, fsize, voxel_face::CUBE_NORTH, entropy);
- if(vis & VIS_SOUTH) push_quad_v(info, fpos, fsize, voxel_face::CUBE_SOUTH, entropy);
- if(vis & VIS_EAST) push_quad_v(info, fpos, fsize, voxel_face::CUBE_EAST, entropy);
- if(vis & VIS_WEST) push_quad_v(info, fpos, fsize, voxel_face::CUBE_WEST, entropy);
- if(vis & VIS_UP) push_quad_v(info, fpos, fsize, voxel_face::CUBE_TOP, entropy);
- if(vis & VIS_DOWN) push_quad_v(info, fpos, fsize, voxel_face::CUBE_BOTTOM, entropy);
+ if(vis & VIS_NORTH) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_NORTH);
+ }
+
+ if(vis & VIS_SOUTH) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_SOUTH);
+ }
+
+ if(vis & VIS_EAST) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_EAST);
+ }
+
+ if(vis & VIS_WEST) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_WEST);
+ }
+
+ if(vis & VIS_UP) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_TOP);
+ }
+
+ if(vis & VIS_DOWN) {
+ push_quad_a(info, fpos, fsize, voxel_face::CUBE_BOTTOM);
+ }
+ } else {
+ if(vis & VIS_NORTH) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_NORTH, entropy);
+ }
+
+ if(vis & VIS_SOUTH) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_SOUTH, entropy);
+ }
+
+ if(vis & VIS_EAST) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_EAST, entropy);
+ }
+
+ if(vis & VIS_WEST) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_WEST, entropy);
+ }
+
+ if(vis & VIS_UP) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_TOP, entropy);
+ }
+
+ if(vis & VIS_DOWN) {
+ push_quad_v(info, fpos, fsize, voxel_face::CUBE_BOTTOM, entropy);
+ }
}
}
-void GL_MeshingTask::cache_chunk(const chunk_pos &cpos)
+void GL_MeshingTask::cache_chunk(const chunk_pos& cpos)
{
const auto index = get_cached_cpos(m_cpos, cpos);
@@ -304,7 +373,7 @@ void GL_MeshingTask::cache_chunk(const chunk_pos &cpos)
// Bogus internal flag component
struct NeedsMeshingComponent final {};
-static void on_chunk_create(const ChunkCreateEvent &event)
+static void on_chunk_create(const ChunkCreateEvent& event)
{
const std::array<chunk_pos, 6> neighbours = {
event.cpos + DIR_NORTH<chunk_pos::value_type>,
@@ -317,15 +386,15 @@ static void on_chunk_create(const ChunkCreateEvent &event)
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
- for(const chunk_pos &cpos : neighbours) {
- if(const Chunk *chunk = globals::dimension->find_chunk(cpos)) {
+ for(const chunk_pos& cpos : neighbours) {
+ if(const Chunk* chunk = globals::dimension->find_chunk(cpos)) {
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
continue;
}
}
}
-static void on_chunk_update(const ChunkUpdateEvent &event)
+static void on_chunk_update(const ChunkUpdateEvent& event)
{
const std::array<chunk_pos, 6> neighbours = {
event.cpos + DIR_NORTH<chunk_pos::value_type>,
@@ -338,15 +407,15 @@ static void on_chunk_update(const ChunkUpdateEvent &event)
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
- for(const chunk_pos &cpos : neighbours) {
- if(const Chunk *chunk = globals::dimension->find_chunk(cpos)) {
+ for(const chunk_pos& cpos : neighbours) {
+ if(const Chunk* chunk = globals::dimension->find_chunk(cpos)) {
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
continue;
}
}
}
-static void on_voxel_set(const VoxelSetEvent &event)
+static void on_voxel_set(const VoxelSetEvent& event)
{
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(event.chunk->get_entity());
@@ -367,8 +436,8 @@ static void on_voxel_set(const VoxelSetEvent &event)
}
}
- for(const chunk_pos &cpos : neighbours) {
- if(const Chunk *chunk = globals::dimension->find_chunk(cpos)) {
+ for(const chunk_pos& cpos : neighbours) {
+ if(const Chunk* chunk = globals::dimension->find_chunk(cpos)) {
globals::dimension->chunks.emplace_or_replace<NeedsMeshingComponent>(chunk->get_entity());
continue;
}
@@ -384,7 +453,6 @@ void chunk_mesher::init(void)
void chunk_mesher::deinit(void)
{
-
}
void chunk_mesher::update(void)