From b4995967309bf5570161db2287e27b84ca94ab9a Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 12 Mar 2015 19:50:09 +0100 Subject: [PATCH 1/1] orientable blocks --- src/app.cpp | 6 +++--- src/block.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/block.hpp | 26 +++++++++++++++++++++++--- src/chunk.cpp | 9 ++++++--- src/chunk.hpp | 1 + src/geometry.hpp | 3 +++ src/shape.cpp | 18 ++++++++++++++++++ src/shape.hpp | 7 +++++++ 8 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 0f12775..716fb3c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -137,12 +137,12 @@ void Application::Update(int dt) { float dist; glm::vec3 normal; if (world.Intersection(aim, glm::mat4(1.0f), &chunk, &blkid, &dist, &normal)) { - glm::vec3 pos = Chunk::ToCoords(blkid); outline_visible = true; outline.Clear(); chunk->Type(chunk->BlockAt(blkid)).FillOutlineModel(outline); - outline_transform = glm::translate(chunk->Transform(world.Player().ChunkCoords()), pos); - outline_transform = glm::scale(outline_transform, glm::vec3(1.0001f)); + outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f)); + outline_transform = chunk->Transform(world.Player().ChunkCoords()); + outline_transform *= chunk->ToTransform(blkid); } else { outline_visible = false; } diff --git a/src/block.cpp b/src/block.cpp index 236a61f..fa39790 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -1,8 +1,49 @@ #include "block.hpp" +#include "geometry.hpp" + +#include +#include + namespace blank { +namespace { + +const glm::mat4 block_transforms[Block::DIR_COUNT * Block::ROT_COUNT] = { + glm::mat4(1.0f), + glm::eulerAngleY(PI_0p5), + glm::eulerAngleY(PI), + glm::eulerAngleY(PI_1p5), + glm::eulerAngleX(PI), + glm::eulerAngleYX(PI_0p5, PI), + glm::eulerAngleYX(PI, PI), + glm::eulerAngleYX(PI_1p5, PI), + glm::eulerAngleZ(PI_0p5), + glm::eulerAngleYZ(PI_0p5, PI_0p5), + glm::eulerAngleYZ(PI, PI_0p5), + glm::eulerAngleYZ(PI_1p5, PI_0p5), + glm::eulerAngleZ(PI_1p5), + glm::eulerAngleYZ(PI_0p5, PI_1p5), + glm::eulerAngleYZ(PI, PI_1p5), + glm::eulerAngleYZ(PI_1p5, PI_1p5), + glm::eulerAngleX(PI_0p5), + glm::eulerAngleYX(PI_0p5, PI_0p5), + glm::eulerAngleYX(PI, PI_0p5), + glm::eulerAngleYX(PI_1p5, PI_0p5), + glm::eulerAngleX(PI_1p5), + glm::eulerAngleYX(PI_0p5, PI_1p5), + glm::eulerAngleYX(PI, PI_1p5), + glm::eulerAngleYX(PI_1p5, PI_1p5), +}; + +} + +const glm::mat4 &Block::Transform() const { + return block_transforms[orient]; +} + + const NullShape BlockType::DEFAULT_SHAPE; BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) @@ -17,10 +58,10 @@ BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) void BlockType::FillModel( Model::Buffer &buf, - const glm::vec3 &pos_offset, + const glm::mat4 &transform, Model::Index idx_offset ) const { - shape->Vertices(buf.vertices, buf.normals, buf.indices, pos_offset, idx_offset); + shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset); buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); } diff --git a/src/block.hpp b/src/block.hpp index 967cc1f..a63cf26 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -17,10 +17,30 @@ struct Block { using Type = unsigned short; using Pos = glm::vec3; + enum Direction { + DIR_UP, + DIR_DOWN, + DIR_LEFT, + DIR_RIGHT, + DIR_FRONT, + DIR_BACK, + DIR_COUNT, + }; + enum Rotation { + ROT_NONE, + ROT_90, + ROT_180, + ROT_270, + ROT_COUNT, + }; + Type type; + unsigned char orient; + + constexpr explicit Block(Type type = 0, Direction dir = DIR_UP, Rotation rot = ROT_NONE) + : type(type), orient(dir * ROT_COUNT + rot) { } - constexpr explicit Block(Type type = 0) - : type(type) { } + const glm::mat4 &Transform() const; }; @@ -56,7 +76,7 @@ struct BlockType { void FillModel( Model::Buffer &m, - const glm::vec3 &pos_offset = { 0, 0, 0 }, + const glm::mat4 &transform = glm::mat4(1.0f), Model::Index idx_offset = 0 ) const; void FillOutlineModel( diff --git a/src/chunk.cpp b/src/chunk.cpp index 16ff4e5..1493086 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -82,8 +82,7 @@ bool Chunk::Intersection( } float cur_dist; glm::vec3 cur_norm; - Block::Pos pos(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f); - if (Type(blocks[id]).shape->Intersects(ray, glm::translate(M, pos), cur_dist, cur_norm)) { + if (Type(blocks[id]).shape->Intersects(ray, M * ToTransform(id), cur_dist, cur_norm)) { if (cur_dist < closest_dist) { closest_id = id; closest_dist = cur_dist; @@ -140,7 +139,7 @@ void Chunk::Update() { if (Obstructed(i)) continue; const BlockType &type = Type(blocks[i]); - type.FillModel(buf, ToCoords(i), vtx_counter); + type.FillModel(buf, ToTransform(i), vtx_counter); vtx_counter += type.shape->VertexCount(); } @@ -176,6 +175,10 @@ bool Chunk::Obstructed(int idx) const { return true; } +glm::mat4 Chunk::ToTransform(int idx) const { + return glm::translate(glm::mat4(1.0f), ToCoords(idx)) * blocks[idx].Transform(); +} + ChunkLoader::ChunkLoader(const BlockTypeRegistry ®, const Generator &gen) : base(0, 0, 0) diff --git a/src/chunk.hpp b/src/chunk.hpp index e27cf5e..255d73b 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -51,6 +51,7 @@ public: 0.5f + (idx / (Width() * Height())) ); } + glm::mat4 ToTransform(int idx) const; static constexpr bool IsBorder(int idx) { return diff --git a/src/geometry.hpp b/src/geometry.hpp index 9a9690b..16651d8 100644 --- a/src/geometry.hpp +++ b/src/geometry.hpp @@ -8,6 +8,9 @@ namespace blank { constexpr float PI = 3.141592653589793238462643383279502884; +constexpr float PI_0p5 = PI * 0.5f; +constexpr float PI_1p5 = PI * 1.5f; +constexpr float PI_2p0 = PI * 2.0f; struct AABB { glm::vec3 min; diff --git a/src/shape.cpp b/src/shape.cpp index c96a074..3d6f442 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -19,6 +19,24 @@ void Shape::Vertices( } } +void Shape::Vertices( + Model::Positions &vertex, + Model::Normals &normal, + Model::Indices &index, + const glm::mat4 &transform, + Model::Index idx_offset +) const { + for (const auto &pos : vtx_pos) { + vertex.emplace_back(transform * glm::vec4(pos, 1.0f)); + } + for (const auto &nrm : vtx_nrm) { + normal.emplace_back(transform * glm::vec4(nrm, 0.0f)); + } + for (auto idx : vtx_idx) { + index.emplace_back(idx_offset + idx); + } +} + void Shape::Outline( OutlineModel::Positions &vertex, OutlineModel::Indices &index, diff --git a/src/shape.hpp b/src/shape.hpp index 909d1c4..f31075b 100644 --- a/src/shape.hpp +++ b/src/shape.hpp @@ -26,6 +26,13 @@ struct Shape { const Model::Position &elem_offset = { 0.0f, 0.0f, 0.0f }, Model::Index idx_offset = 0 ) const; + void Vertices( + Model::Positions &vertex, + Model::Normals &normal, + Model::Indices &index, + const glm::mat4 &transform, + Model::Index idx_offset = 0 + ) const; /// the number of vertices this shape's outline has size_t OutlineCount() const { return out_pos.size(); } -- 2.39.2