#include "../model/Shape.hpp"
#include <cmath>
+#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/transform.hpp>
namespace {
-blank::Model::Buffer model_buffer;
+blank::EntityModel::Buffer model_buffer;
}
namespace blank {
Entity::Entity() noexcept
-: shape(nullptr)
-, model()
+: model()
+, id(-1)
, name("anonymous")
, bounds()
, 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)
-, world_collision(false) {
+, angular_velocity(0.0f)
+, ref_count(0)
+, world_collision(false)
+, dead(false) {
}
-void Entity::SetShape(const 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::Position(const Chunk::Pos &c, const glm::vec3 &pos) noexcept {
+ chunk = c;
+ model.Position(pos);
}
-void Entity::SetShapeless() noexcept {
- shape = nullptr;
-}
-
-
-void Entity::Velocity(const glm::vec3 &vel) noexcept {
- velocity = vel;
-}
-
-void Entity::Position(const Block::Pos &pos) noexcept {
- position = pos;
+void Entity::Position(const glm::vec3 &pos) noexcept {
+ glm::vec3 position(pos);
while (position.x >= Chunk::width) {
position.x -= Chunk::width;
++chunk.x;
position.z += Chunk::depth;
--chunk.z;
}
+ model.Position(position);
}
void Entity::Move(const glm::vec3 &delta) noexcept {
- Position(position + delta);
+ Position(Position() + delta);
}
-void Entity::AngularVelocity(const glm::quat &v) noexcept {
- angular_velocity = v;
+void Entity::Rotate(const glm::quat &delta) noexcept {
+ Orientation(delta * Orientation());
}
-void Entity::Rotation(const glm::mat4 &rot) noexcept {
- rotation = rot;
-}
-
-void Entity::Rotate(const glm::quat &delta) noexcept {
- Rotation(rotation * glm::mat4_cast(delta));
+glm::mat4 Entity::ChunkTransform(const Chunk::Pos &chunk_offset) const noexcept {
+ const glm::vec3 translation = glm::vec3((chunk - chunk_offset) * Chunk::Extent());
+ return glm::translate(translation);
}
glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const noexcept {
- const glm::vec3 chunk_pos = (chunk - chunk_offset) * Chunk::Extent();
- return glm::translate(position + chunk_pos) * rotation;
+ const glm::vec3 translation = glm::vec3((chunk - chunk_offset) * Chunk::Extent()) + Position();
+ glm::mat4 transform(toMat4(Orientation()));
+ transform[3].x = translation.x;
+ transform[3].y = translation.y;
+ transform[3].z = translation.z;
+ return transform;
}
Ray Entity::Aim(const Chunk::Pos &chunk_offset) const noexcept {
return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) };
}
-void Entity::Update(int dt) noexcept {
- Move(velocity * float(dt));
- Rotate(angular_velocity * float(dt));
+namespace {
+
+glm::quat delta_rot(const glm::vec3 &av, float dt) {
+ glm::vec3 half(av * dt * 0.5f);
+ float mag = length(half);
+ if (mag > 0.0f) {
+ float smag = std::sin(mag) / mag;
+ return glm::quat(std::cos(mag), half * smag);
+ } else {
+ return glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
+ }
}
+}
-void Entity::Draw() noexcept {
- model.Draw();
+void Entity::Update(int dt) noexcept {
+ float fdt = float(dt);
+ Move(velocity * fdt);
+ Rotate(delta_rot(angular_velocity, fdt));
}
}