DeerithEngine/deerith_client/src/world/cluster_storage.cpp
2026-11-08 21:31:52 +01:00

94 lines
2.8 KiB
C++

#include <deerith/client/cluster.h>
#include <deerith/world/environment.h>
#include <unordered_map>
#include <deerith/client/graphics/shader.h>
#include <deerith/client/graphics/camera.h>
#include <deerith/client/graphics/mesh.h>
#include <deerith/client/graphics/primitive.h>
#include <deerith/client/internals/world.h>
#include <deerith/client/cluster.h>
namespace deerith
{
std::unordered_map<glm::ivec3, std::unique_ptr<mesh_3d_t>, ivec3_hash_t> loaded_clusters;
void render_cluster(glm::ivec3);
}
void deerith::shutdown_environment()
{
loaded_clusters.clear();
}
void deerith::flush_cluster_to_gpu()
{
std::lock_guard<std::mutex> lock(cluster_workers_mutex);
for (std::unique_ptr<cluster_generator_t> &cluster_generator : cluster_workers)
{
glm::ivec3 cluster_position;
cluster_position.x = cluster_generator->cluster->surface_id.x;
cluster_position.z = cluster_generator->cluster->surface_id.y;
cluster_position.y = cluster_generator->cluster->layer;
loaded_clusters[cluster_position] = std::make_unique<mesh_3d_t>(cluster_generator->build_data);
}
cluster_workers.clear();
}
void deerith::render_clusters(glm::ivec3 position, int rad, const camera_t &camera)
{
texture_t *voxel_texture = get_voxel_texture();
get_voxel_shader()->use();
get_voxel_shader()->set_vec4("u_color", glm::vec4(1, 0.4f, 0.6f, 1));
set_camera_to_shader(camera, get_voxel_shader());
if (voxel_texture)
{
voxel_texture->bind(0);
get_voxel_shader()->set_int("u_texture", 0);
}
// Radial outward
for (int r = 0; r < rad; r++)
{
for (int x = -r; x <= r; x++)
{
for (int y = -r; y <= r; y++)
{
for (int z = -r; z <= r; z++)
{
// Only process the current outer layer
if (std::max({std::abs(x), std::abs(y), std::abs(z)}) != r)
{
continue;
}
glm::ivec3 cluster_position = position + glm::ivec3(x, y, z);
render_cluster(cluster_position);
}
}
}
}
}
void deerith::render_cluster(glm::ivec3 pos)
{
if (!loaded_clusters.contains(pos))
{
return;
}
std::unique_ptr<mesh_3d_t> &cluster_mesh = loaded_clusters[pos];
float offset = static_cast<float>(CLUSTER_SIZE) * static_cast<float>(VOXEL_SIZE);
glm::vec3 position = glm::vec3(offset * static_cast<float>(pos.x), offset * static_cast<float>(pos.y), offset * static_cast<float>(pos.z));
glm::quat rotation = glm::identity<glm::quat>();
glm::vec3 scale = glm::vec3(1, 1, 1);
set_transform_to_shader(position, rotation, scale, get_voxel_shader());
cluster_mesh->draw();
}