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