]> git.localhorst.tv Git - blank.git/blob - src/world/Entity.cpp
fb62f2757d545757f35fcff11132295e4b33e6fd
[blank.git] / src / world / Entity.cpp
1 #include "Entity.hpp"
2
3 #include "../model/Shape.hpp"
4
5 #include <cmath>
6 #include <glm/gtx/quaternion.hpp>
7 #include <glm/gtx/transform.hpp>
8
9 namespace {
10
11 blank::EntityModel::Buffer model_buffer;
12
13 }
14
15 namespace blank {
16
17 Entity::Entity() noexcept
18 : model()
19 , name("anonymous")
20 , bounds()
21 , velocity(0, 0, 0)
22 , chunk(0, 0, 0)
23 , angular_velocity(0.0f)
24 , world_collision(false)
25 , remove(false) {
26
27 }
28
29
30 void Entity::Position(const Chunk::Pos &c, const glm::vec3 &pos) noexcept {
31         chunk = c;
32         model.Position(pos);
33 }
34
35 void Entity::Position(const glm::vec3 &pos) noexcept {
36         glm::vec3 position(pos);
37         while (position.x >= Chunk::width) {
38                 position.x -= Chunk::width;
39                 ++chunk.x;
40         }
41         while (position.x < 0) {
42                 position.x += Chunk::width;
43                 --chunk.x;
44         }
45         while (position.y >= Chunk::height) {
46                 position.y -= Chunk::height;
47                 ++chunk.y;
48         }
49         while (position.y < 0) {
50                 position.y += Chunk::height;
51                 --chunk.y;
52         }
53         while (position.z >= Chunk::depth) {
54                 position.z -= Chunk::depth;
55                 ++chunk.z;
56         }
57         while (position.z < 0) {
58                 position.z += Chunk::depth;
59                 --chunk.z;
60         }
61         model.Position(position);
62 }
63
64 void Entity::Move(const glm::vec3 &delta) noexcept {
65         Position(Position() + delta);
66 }
67
68 void Entity::Rotate(const glm::quat &delta) noexcept {
69         Orientation(delta * Orientation());
70 }
71
72 glm::mat4 Entity::ChunkTransform(const Chunk::Pos &chunk_offset) const noexcept {
73         const glm::vec3 translation = glm::vec3((chunk - chunk_offset) * Chunk::Extent());
74         return glm::translate(translation);
75 }
76
77 glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const noexcept {
78         const glm::vec3 translation = glm::vec3((chunk - chunk_offset) * Chunk::Extent()) + Position();
79         glm::mat4 transform(toMat4(Orientation()));
80         transform[3].x = translation.x;
81         transform[3].y = translation.y;
82         transform[3].z = translation.z;
83         return transform;
84 }
85
86 Ray Entity::Aim(const Chunk::Pos &chunk_offset) const noexcept {
87         glm::mat4 transform = Transform(chunk_offset);
88         glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
89         from /= from.w;
90         glm::vec4 to = transform * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
91         to /= to.w;
92         return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) };
93 }
94
95 namespace {
96
97 glm::quat delta_rot(const glm::vec3 &av, float dt) {
98         glm::vec3 half(av * dt * 0.5f);
99         float mag = length(half);
100         if (mag > 0.0f) {
101                 float smag = std::sin(mag) / mag;
102                 return glm::quat(std::cos(mag), half * smag);
103         } else {
104                 return glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
105         }
106 }
107
108 }
109
110 void Entity::Update(int dt) noexcept {
111         float fdt = float(dt);
112         Move(velocity * fdt);
113         Rotate(delta_rot(angular_velocity, fdt));
114 }
115
116 }