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;
}
#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)
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);
}
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;
};
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(
}
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;
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();
}
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)
0.5f + (idx / (Width() * Height()))
);
}
+ glm::mat4 ToTransform(int idx) const;
static constexpr bool IsBorder(int idx) {
return
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;
}
}
+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,
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(); }