]> git.localhorst.tv Git - blank.git/commitdiff
orientable blocks
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 12 Mar 2015 18:50:09 +0000 (19:50 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 12 Mar 2015 18:50:09 +0000 (19:50 +0100)
src/app.cpp
src/block.cpp
src/block.hpp
src/chunk.cpp
src/chunk.hpp
src/geometry.hpp
src/shape.cpp
src/shape.hpp

index 0f1277535367ca060caffbcf018dd4a356630623..716fb3caa4ee7530ddddcaa47975de228efd58a6 100644 (file)
@@ -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;
        }
index 236a61ff62bcb0b2d122f78fc33691f35db2d3d1..fa39790ee35e0e396224d12581ed102baba1083e 100644 (file)
@@ -1,8 +1,49 @@
 #include "block.hpp"
 
+#include "geometry.hpp"
+
+#include <glm/gtx/euler_angles.hpp>
+#include <glm/gtx/transform.hpp>
+
 
 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);
 }
 
index 967cc1fccc69cf192950d0247fc0f9429e8ab88e..a63cf26b59671cab7468a6372eca2fdc675d18b1 100644 (file)
@@ -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(
index 16ff4e5023bb65f4f68495294b7b940007b67239..14930863ed1c38063fc2e919563dae0f5c7d1a6b 100644 (file)
@@ -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 &reg, const Generator &gen)
 : base(0, 0, 0)
index e27cf5ed09d5b3e6a9b018e5bd1b4ca927450a47..255d73b163f70ff25db4bade6f1b9a087a767aee 100644 (file)
@@ -51,6 +51,7 @@ public:
                        0.5f + (idx / (Width() * Height()))
                );
        }
+       glm::mat4 ToTransform(int idx) const;
 
        static constexpr bool IsBorder(int idx) {
                return
index 9a9690b245cd59c0fff0c14baa6c74800120b054..16651d82be46427b89296784c46735cc65a2c9c2 100644 (file)
@@ -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;
index c96a07422d6c8407721010449c182b3798169857..3d6f4420833efba99231876f13e8adbfaf78bf9f 100644 (file)
@@ -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,
index 909d1c40691bc6cae174eb4cdcedc7456ad4a3d6..f31075b10fb48f8e2103bbad1349af97b9c10dfd 100644 (file)
@@ -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(); }