#include "client/world/block.hh" namespace client { namespace world { struct glvert_args { glm::vec3 translate; float rotate_degrees; glm::vec3 rotate_axis; glm::vec3 texture_offset; }; static block::glface_t make_glface(const glvert_args& args) noexcept { static constexpr block::glface_t glverts = { block::glvert{{-0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}}, block::glvert{{0.5f, -0.5f, 0.0f}, {1.0f, 1.0f, 0.0f}}, block::glvert{{0.5f, 0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}, block::glvert{{0.5f, 0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}, block::glvert{{-0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 0.0f}}, block::glvert{{-0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}}}; // We have to be careful here not to rotate/translate a zero vector. constexpr auto zero = glm::vec3{}; const glm::mat4 mtranslate = args.translate == zero ? glm::mat4{1.0f} : glm::translate(glm::mat4{1.0f}, args.translate); const glm::mat4 mrotate = args.rotate_axis == zero ? glm::mat4{1.0f} : glm::rotate(glm::mat4{1.0f}, glm::radians(args.rotate_degrees), args.rotate_axis); block::glface_t ret; std::ranges::transform(glverts, std::begin(ret), [&](auto f) { f.vertice = glm::vec3(mtranslate * mrotate * glm::vec4{f.vertice, 1.0f}); f.texture += args.texture_offset; return f; }); return ret; } static const block::glfaces_t& get_shrub_faces() noexcept { static block::glfaces_t faces{ make_glface({.translate = {0.0f, 0.0f, 0.0f}, .rotate_degrees = 45.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 0.0f}}), make_glface({.translate = {0.0f, 0.0f, 0.0f}, .rotate_degrees = 135.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 0.0f}}), make_glface({.translate = {0.0f, 0.0f, 0.0f}, .rotate_degrees = 225.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 0.0f}}), make_glface({.translate = {0.0f, 0.0f, 0.0f}, .rotate_degrees = 315.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 0.0f}})}; return faces; } static const block::glfaces_t& get_cube_faces() noexcept { static block::glfaces_t faces{ make_glface({.translate = {0.0f, 0.0f, 0.5f}, .rotate_degrees = 0.0f, .rotate_axis = {0.0f, 0.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 0.0f}}), make_glface({.translate = {0.5f, 0.0f, 0.0f}, .rotate_degrees = 90.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 1.0f}}), make_glface({.translate = {0.0f, 0.0f, -0.5f}, .rotate_degrees = 180.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 2.0f}}), make_glface({.translate = {-0.5f, 0.0f, 0.0f}, .rotate_degrees = 270.0f, .rotate_axis = {0.0f, 1.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 3.0f}}), make_glface({.translate = {0.0f, 0.5f, 0.0f}, .rotate_degrees = -90.0f, .rotate_axis = {1.0f, 0.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 4.0f}}), make_glface({.translate = {0.0f, -0.5f, 0.0f}, .rotate_degrees = 90.0f, .rotate_axis = {1.0f, 0.0f, 0.0f}, .texture_offset = {0.0f, 0.0f, 5.0f}}), }; return faces; } enum block::draw_type block::get_draw_type(const enum block::type& type) noexcept { using t = enum shared::world::block::type; switch (type) { case t::dead_shrub: case t::shrub: case t::snowy_shrub: return draw_type::custom; default: return draw_type::block; } } const block::glfaces_t& block::get_glfaces(const enum block::type& type) noexcept { const auto draw_type = get_draw_type(type); if (draw_type == block::draw_type::custom) { return get_shrub_faces(); } return get_cube_faces(); } } // namespace world } // namespace client