aboutsummaryrefslogtreecommitdiff
path: root/src/client/world/block.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/world/block.cc')
-rw-r--r--src/client/world/block.cc117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/client/world/block.cc b/src/client/world/block.cc
new file mode 100644
index 0000000..df3ddcd
--- /dev/null
+++ b/src/client/world/block.cc
@@ -0,0 +1,117 @@
+#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