]> git.localhorst.tv Git - blank.git/blob - src/world.cpp
c958a65cf3144942f8d47af09576872fd48aae9c
[blank.git] / src / world.cpp
1 #include "world.hpp"
2
3 #include <limits>
4
5
6 namespace blank {
7
8 const BlockType BlockType::DEFAULT;
9
10 void BlockType::FillVBO(
11         const glm::vec3 &pos,
12         std::vector<glm::vec3> &vertices,
13         std::vector<glm::vec3> &colors,
14         std::vector<glm::vec3> &normals
15 ) const {
16         vertices.emplace_back(pos.x    , pos.y    , pos.z + 1); // front
17         vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
18         vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
19         vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
20         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
21         vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
22         vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // back
23         vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
24         vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
25         vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
26         vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
27         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
28         vertices.emplace_back(pos.x    , pos.y + 1, pos.z    ); // top
29         vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
30         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
31         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
32         vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
33         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
34         vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // bottom
35         vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
36         vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
37         vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
38         vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
39         vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
40         vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // left
41         vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
42         vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
43         vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
44         vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
45         vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
46         vertices.emplace_back(pos.x + 1, pos.y    , pos.z    ); // right
47         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
48         vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
49         vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
50         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
51         vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
52
53         colors.insert(colors.end(), 6 * 6, color);
54
55         normals.insert(normals.end(), 6, glm::vec3( 0.0f,  0.0f,  1.0f)); // front
56         normals.insert(normals.end(), 6, glm::vec3( 0.0f,  0.0f, -1.0f)); // back
57         normals.insert(normals.end(), 6, glm::vec3( 0.0f,  1.0f,  0.0f)); // top
58         normals.insert(normals.end(), 6, glm::vec3( 0.0f, -1.0f,  0.0f)); // bottom
59         normals.insert(normals.end(), 6, glm::vec3(-1.0f,  0.0f,  0.0f)); // left
60         normals.insert(normals.end(), 6, glm::vec3( 1.0f,  0.0f,  0.0f)); // right
61 }
62
63
64 BlockTypeRegistry::BlockTypeRegistry() {
65         Add(BlockType::DEFAULT);
66 }
67
68 int BlockTypeRegistry::Add(const BlockType &t) {
69         int id = types.size();
70         types.push_back(t);
71         types.back().id = id;
72         return id;
73 }
74
75
76 Chunk::Chunk()
77 : blocks(Size())
78 , model()
79 , dirty(false) {
80
81 }
82
83
84 void Chunk::Draw() {
85         if (dirty) {
86                 Update();
87         }
88         model.Draw();
89 }
90
91
92 bool Chunk::Intersection(const Ray &ray, const glm::mat4 &M, int *blkid, float *dist) const {
93         { // rough check
94                 const AABB bb{{0, 0, 0}, {Width(), Height(), Depth()}};
95                 if (!blank::Intersection(ray, bb, M)) {
96                         return false;
97                 }
98         }
99
100         if (!blkid && !dist) {
101                 return true;
102         }
103
104         // TODO: should be possible to heavily optimize this
105         int id = 0;
106         int closest_id = -1;
107         float closest_dist = std::numeric_limits<float>::infinity();
108         for (int z = 0; z < Depth(); ++z) {
109                 for (int y = 0; y < Height(); ++y) {
110                         for (int x = 0; x < Width(); ++x, ++id) {
111                                 if (!blocks[id].type->visible) {
112                                         continue;
113                                 }
114                                 const AABB bb{{x, y, z}, {x+1, y+1, z+1}};
115                                 float cur_dist;
116                                 if (blank::Intersection(ray, bb, M, &cur_dist)) {
117                                         if (cur_dist < closest_dist) {
118                                                 closest_id = id;
119                                                 closest_dist = cur_dist;
120                                         }
121                                 }
122                         }
123                 }
124         }
125
126         if (closest_id < 0) {
127                 return false;
128         }
129
130         if (blkid) {
131                 *blkid = closest_id;
132         }
133         if (dist) {
134                 *dist = closest_dist;
135         }
136         return true;
137 }
138
139
140 int Chunk::VertexCount() const {
141         // TODO: query blocks as soon as type shapes are implemented
142         return Size() * 6 * 6;
143 }
144
145 void Chunk::Update() {
146         model.Clear();
147         model.Reserve(VertexCount());
148
149         for (int i = 0; i < Size(); ++i) {
150                 if (blocks[i].type->visible) {
151                         blocks[i].type->FillModel(ToCoords(i), model);
152                 }
153         }
154
155         model.Invalidate();
156         dirty = false;
157 }
158
159 }