#include <cmath>
#include <glm/gtx/transform.hpp>
+namespace {
+
+blank::Model::Buffer model_buffer;
+
+}
namespace blank {
Entity::Entity()
-: velocity()
-, position()
+: shape(nullptr)
+, model()
+, velocity(0, 0, 0)
+, position(0, 0, 0)
+, chunk(0, 0, 0)
+, angular_velocity(1.0f, 0.0f, 0.0f, 0.0f)
, rotation(1.0f) {
}
+void Entity::SetShape(Shape *s, const glm::vec3 &color) {
+ shape = s;
+ model_buffer.Clear();
+ shape->Vertices(model_buffer.vertices, model_buffer.normals, model_buffer.indices);
+ model_buffer.colors.resize(shape->VertexCount(), color);
+ model.Update(model_buffer);
+}
+
+void Entity::SetShapeless() {
+ shape = nullptr;
+}
+
+
void Entity::Velocity(const glm::vec3 &vel) {
velocity = vel;
}
Position(position + delta);
}
+void Entity::AngularVelocity(const glm::quat &v) {
+ angular_velocity = v;
+}
+
void Entity::Rotation(const glm::mat4 &rot) {
rotation = rot;
}
+void Entity::Rotate(const glm::quat &delta) {
+ Rotation(rotation * glm::mat4_cast(delta));
+}
+
glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const {
const glm::vec3 chunk_pos = (chunk - chunk_offset) * Chunk::Extent();
return glm::translate(position + chunk_pos) * rotation;
void Entity::Update(int dt) {
Move(velocity * float(dt));
+ Rotate(angular_velocity * float(dt));
+}
+
+
+void Entity::Draw() {
+ model.Draw();
}
}
#include "block.hpp"
#include "chunk.hpp"
#include "geometry.hpp"
+#include "model.hpp"
+#include "shape.hpp"
#include <glm/glm.hpp>
+#include <glm/gtc/quaternion.hpp>
namespace blank {
+class Shape;
+
class Entity {
public:
Entity();
+ bool HasShape() const { return shape; }
+ const Shape *GetShape() const { return shape; }
+ void SetShape(Shape *, const glm::vec3 &color);
+ void SetShapeless();
+
const glm::vec3 &Velocity() const { return velocity; }
void Velocity(const glm::vec3 &);
const Chunk::Pos ChunkCoords() const { return chunk; }
+ const glm::quat &AngularVelocity() const { return angular_velocity; }
+ void AngularVelocity(const glm::quat &);
+
const glm::mat4 &Rotation() const { return rotation; }
void Rotation(const glm::mat4 &);
+ void Rotate(const glm::quat &delta);
glm::mat4 Transform(const Chunk::Pos &chunk_offset) const;
Ray Aim(const Chunk::Pos &chunk_offset) const;
void Update(int dt);
+ void Draw();
+
private:
+ Shape *shape;
+ Model model;
+
glm::vec3 velocity;
Block::Pos position;
Chunk::Pos chunk;
+ glm::quat angular_velocity;
glm::mat4 rotation;
};
generate.Space(0);
generate.Solids({ 1, 4, 7, 10 });
- player.Position({ 4.0f, 4.0f, 4.0f });
+ player = &AddEntity();
+ player->Position({ 4.0f, 4.0f, 4.0f });
+
+ Entity &test_entity = AddEntity();
+ test_entity.Position({ 0.0f, 0.0f, 0.0f });
+ test_entity.SetShape(&blockShape, { 1.0f, 1.0f, 0.0f });
+ test_entity.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
chunks.Generate({ -4, -4, -4 }, { 5, 5, 5});
}
for (Chunk &cur_chunk : chunks.Loaded()) {
float cur_dist;
- if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player.ChunkCoords()), cur_dist)) {
+ if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
candidates.push_back({ &cur_chunk, cur_dist });
}
}
int cur_blkid;
float cur_dist;
glm::vec3 cur_normal;
- if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player.ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
+ if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
if (cur_dist < closest_dist) {
closest_chunk = cand.chunk;
closest_blkid = cur_blkid;
void World::Update(int dt) {
- player.Update(dt);
- chunks.Rebase(player.ChunkCoords());
+ for (Entity &entity : entities) {
+ entity.Update(dt);
+ }
+ chunks.Rebase(player->ChunkCoords());
chunks.Update();
}
void World::Render(DirectionalLighting &program) {
program.SetLightDirection({ -1.0f, -3.0f, -2.0f });
- program.SetView(glm::inverse(player.Transform(player.ChunkCoords())));
+ program.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
for (Chunk &chunk : chunks.Loaded()) {
- glm::mat4 m(chunk.Transform(player.ChunkCoords()));
+ glm::mat4 m(chunk.Transform(player->ChunkCoords()));
program.SetM(m);
glm::mat4 mvp(program.GetVP() * m);
if (!CullTest(Chunk::Bounds(), mvp)) {
chunk.Draw();
}
}
+
+ for (Entity &entity : entities) {
+ if (entity.HasShape()) {
+ program.SetM(entity.Transform(player->ChunkCoords()));
+ entity.Draw();
+ }
+ }
}
}