]> git.localhorst.tv Git - blank.git/blob - src/world.cpp
minor optimizations in chunk
[blank.git] / src / world.cpp
1 #include "world.hpp"
2
3 #include <limits>
4 #include <glm/gtx/transform.hpp>
5
6
7 namespace blank {
8
9 World::World(const Config &config)
10 : blockType()
11 , blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }})
12 , stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f })
13 , slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }})
14 , generate(config.gen)
15 , chunks(config.load, blockType, generate)
16 , player()
17 , entities()
18 , light_direction(config.light_direction)
19 , fog_density(config.fog_density) {
20         BlockType::Faces block_fill = {  true,  true,  true,  true,  true,  true };
21         BlockType::Faces slab_fill  = { false,  true, false, false, false, false };
22         BlockType::Faces stair_fill = { false,  true, false, false, false,  true };
23
24         { // white block
25                 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape);
26                 type.block_light = true;
27                 type.fill = block_fill;
28                 blockType.Add(type);
29         }
30         { // white slab
31                 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape);
32                 type.block_light = true;
33                 type.fill = slab_fill;
34                 blockType.Add(type);
35         }
36         { // white stair
37                 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape);
38                 type.block_light = true;
39                 type.fill = stair_fill;
40                 blockType.Add(type);
41         }
42
43         { // red block
44                 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape);
45                 type.block_light = true;
46                 type.fill = block_fill;
47                 blockType.Add(type);
48         }
49         { // red slab
50                 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape);
51                 type.block_light = true;
52                 type.fill = slab_fill;
53                 blockType.Add(type);
54         }
55         { // red stair
56                 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape);
57                 type.block_light = true;
58                 type.fill = stair_fill;
59                 blockType.Add(type);
60         }
61
62         { // green block
63                 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape);
64                 type.block_light = true;
65                 type.fill = block_fill;
66                 blockType.Add(type);
67         }
68         { // green slab
69                 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape);
70                 type.block_light = true;
71                 type.fill = slab_fill;
72                 blockType.Add(type);
73         }
74         { // green stair
75                 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape);
76                 type.block_light = true;
77                 type.fill = stair_fill;
78                 blockType.Add(type);
79         }
80
81         { // blue block
82                 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape);
83                 type.block_light = true;
84                 type.fill = block_fill;
85                 blockType.Add(type);
86         }
87         { // blue slab
88                 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape);
89                 type.block_light = true;
90                 type.fill = slab_fill;
91                 blockType.Add(type);
92         }
93         { // blue stair
94                 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape);
95                 type.block_light = true;
96                 type.fill = stair_fill;
97                 blockType.Add(type);
98         }
99
100         { // glowing yellow block
101                 BlockType type(true, { 1.0f, 1.0f, 0.0f }, &blockShape);
102                 type.luminosity = 15;
103                 type.block_light = true;
104                 type.fill = block_fill;
105                 blockType.Add(type);
106         }
107
108         generate.Space(0);
109         generate.Light(13);
110         generate.Solids({ 1, 4, 7, 10 });
111
112         player = &AddEntity();
113         player->Position(config.spawn);
114
115         chunks.GenerateSurrounding(player->ChunkCoords());
116 }
117
118
119 namespace {
120
121 struct Candidate {
122         Chunk *chunk;
123         float dist;
124 };
125
126 std::vector<Candidate> candidates;
127
128 }
129
130 bool World::Intersection(
131                 const Ray &ray,
132                 const glm::mat4 &M,
133                 Chunk **chunk,
134                 int *blkid,
135                 float *dist,
136                 glm::vec3 *normal) {
137         candidates.clear();
138
139         for (Chunk &cur_chunk : chunks.Loaded()) {
140                 float cur_dist;
141                 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
142                         candidates.push_back({ &cur_chunk, cur_dist });
143                 }
144         }
145
146         if (candidates.empty()) return false;
147
148         Chunk *closest_chunk = nullptr;
149         float closest_dist = std::numeric_limits<float>::infinity();
150         int closest_blkid = -1;
151         glm::vec3 closest_normal;
152
153         for (Candidate &cand : candidates) {
154                 if (cand.dist > closest_dist) continue;
155                 int cur_blkid;
156                 float cur_dist;
157                 glm::vec3 cur_normal;
158                 if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
159                         if (cur_dist < closest_dist) {
160                                 closest_chunk = cand.chunk;
161                                 closest_blkid = cur_blkid;
162                                 closest_dist = cur_dist;
163                                 closest_normal = cur_normal;
164                         }
165                 }
166         }
167
168         if (chunk) {
169                 *chunk = closest_chunk;
170         }
171         if (blkid) {
172                 *blkid = closest_blkid;
173         }
174         if (dist) {
175                 *dist = closest_dist;
176         }
177         if (normal) {
178                 *normal = closest_normal;
179         }
180         return closest_chunk;
181 }
182
183
184 Chunk &World::PlayerChunk() {
185         return chunks.ForceLoad(player->ChunkCoords());
186 }
187
188 Chunk &World::Next(const Chunk &to, const glm::tvec3<int> &dir) {
189         const Chunk::Pos tgt_pos = to.Position() + dir;
190         return chunks.ForceLoad(tgt_pos);
191 }
192
193
194 void World::Update(int dt) {
195         for (Entity &entity : entities) {
196                 entity.Update(dt);
197         }
198         chunks.Rebase(player->ChunkCoords());
199         chunks.Update();
200 }
201
202
203 void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) {
204         chunk_prog.Activate();
205         chunk_prog.SetFogDensity(fog_density);
206         chunk_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
207
208         for (Chunk &chunk : chunks.Loaded()) {
209                 glm::mat4 m(chunk.Transform(player->ChunkCoords()));
210                 chunk_prog.SetM(m);
211                 glm::mat4 mvp(chunk_prog.GetVP() * m);
212                 if (!CullTest(Chunk::Bounds(), mvp)) {
213                         chunk.Draw();
214                 }
215         }
216
217         entity_prog.Activate();
218         entity_prog.SetLightDirection(light_direction);
219         entity_prog.SetFogDensity(fog_density);
220         entity_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
221
222         for (Entity &entity : entities) {
223                 if (entity.HasShape()) {
224                         entity_prog.SetM(entity.Transform(player->ChunkCoords()));
225                         entity.Draw();
226                 }
227         }
228 }
229
230 }