outline_visible = true;
outline.Clear();
chunk->BlockAt(blkid).type->FillOutlineModel(outline);
- outline_transform = glm::translate(chunk->Transform(), pos);
+ outline_transform = glm::translate(chunk->Transform(world.Player().ChunkCoords()), pos);
outline_transform = glm::scale(outline_transform, glm::vec3(1.0001f));
} else {
outline_visible = false;
Chunk::Chunk()
: blocks(Size())
, model()
-, transform(1.0f)
, dirty(false) {
}
Chunk::Chunk(Chunk &&other)
: blocks(std::move(other.blocks))
, model(std::move(other.model))
-, transform(other.transform)
, dirty(other.dirty) {
}
Chunk &Chunk::operator =(Chunk &&other) {
blocks = std::move(other.blocks);
model = std::move(other.model);
- transform = other.transform;
dirty = other.dirty;
return *this;
}
void Chunk::Position(const glm::vec3 &pos) {
position = pos;
- transform = glm::translate(pos * Extent());
+}
+
+glm::mat4 Chunk::Transform(const glm::vec3 &offset) const {
+ return glm::translate((position - offset) * Extent());
}
void Position(const glm::vec3 &);
const glm::vec3 &Position() const { return position; }
- const glm::mat4 &Transform() const { return transform; }
+ glm::mat4 Transform(const glm::vec3 &offset) const;
void Draw();
std::vector<Block> blocks;
Model model;
glm::vec3 position;
- glm::mat4 transform;
bool dirty;
};
public:
explicit FPSController(Entity &);
- Ray Aim() const { return entity.Aim(); }
+ Ray Aim() const { return entity.Aim(entity.ChunkCoords()); }
// all angles in radians (full circle = 2π)
float Pitch() const { return pitch; }
#include "entity.hpp"
+#include "chunk.hpp"
+
+#include <cmath>
#include <glm/gtx/transform.hpp>
Entity::Entity()
: velocity()
, position()
-, rotation(1.0f)
-, transform(1.0f)
-, dirty(false) {
+, rotation(1.0f) {
}
void Entity::Position(const glm::vec3 &pos) {
position = pos;
- dirty = true;
+ while (position.x >= Chunk::Width()) {
+ position.x -= Chunk::Width();
+ ++chunk.x;
+ }
+ while (position.x < 0) {
+ position.x += Chunk::Width();
+ --chunk.x;
+ }
+ while (position.y >= Chunk::Height()) {
+ position.y -= Chunk::Height();
+ ++chunk.y;
+ }
+ while (position.y < 0) {
+ position.y += Chunk::Height();
+ --chunk.y;
+ }
+ while (position.z >= Chunk::Depth()) {
+ position.z -= Chunk::Depth();
+ ++chunk.z;
+ }
+ while (position.z < 0) {
+ position.z += Chunk::Depth();
+ --chunk.z;
+ }
}
void Entity::Move(const glm::vec3 &delta) {
- position += delta;
- dirty = true;
+ Position(position + delta);
}
void Entity::Rotation(const glm::mat4 &rot) {
rotation = rot;
}
-const glm::mat4 &Entity::Transform() const {
- if (dirty) {
- transform = glm::translate(position) * rotation;
- dirty = false;
- }
- return transform;
+glm::mat4 Entity::Transform(const glm::tvec3<int> &chunk_offset) const {
+ const glm::vec3 chunk_pos = glm::vec3(chunk - chunk_offset) * Chunk::Extent();
+ return glm::translate(position + chunk_pos) * rotation;
}
-Ray Entity::Aim() const {
- Transform();
+Ray Entity::Aim(const glm::tvec3<int> &chunk_offset) const {
+ glm::mat4 transform = Transform(chunk_offset);
glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
from /= from.w;
glm::vec4 to = transform * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
void Position(const glm::vec3 &);
void Move(const glm::vec3 &delta);
+ const glm::tvec3<int> ChunkCoords() const { return chunk; }
+
const glm::mat4 &Rotation() const { return rotation; }
void Rotation(const glm::mat4 &);
- const glm::mat4 &Transform() const;
- Ray Aim() const;
+ glm::mat4 Transform(const glm::tvec3<int> &chunk_offset) const;
+ Ray Aim(const glm::tvec3<int> &chunk_offset) const;
void Update(int dt);
private:
glm::vec3 velocity;
glm::vec3 position;
+ glm::tvec3<int> chunk;
glm::mat4 rotation;
- mutable glm::mat4 transform;
- mutable bool dirty;
-
};
}
int cur_blkid;
float cur_dist;
glm::vec3 cur_normal;
- if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(), &cur_blkid, &cur_dist, &cur_normal)) {
+ if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player.ChunkCoords()), &cur_blkid, &cur_dist, &cur_normal)) {
if (cur_dist < closest_dist) {
closest_chunk = &cur_chunk;
closest_blkid = cur_blkid;
void World::Render(DirectionalLighting &program) {
program.SetLightDirection({ -1.0f, -3.0f, -2.0f });
- program.SetView(glm::inverse(player.Transform()));
+ program.SetView(glm::inverse(player.Transform(player.ChunkCoords())));
for (Chunk &chunk : LoadedChunks()) {
- program.SetM(chunk.Transform());
+ program.SetM(chunk.Transform(player.ChunkCoords()));
chunk.Draw();
}
}