4 #include <glm/gtx/transform.hpp>
9 World::World(const Config &config)
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)
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 };
25 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape);
26 type.block_light = true;
27 type.fill = block_fill;
31 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape);
32 type.block_light = true;
33 type.fill = slab_fill;
37 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape);
38 type.block_light = true;
39 type.fill = stair_fill;
44 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape);
45 type.block_light = true;
46 type.fill = block_fill;
50 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape);
51 type.block_light = true;
52 type.fill = slab_fill;
56 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape);
57 type.block_light = true;
58 type.fill = stair_fill;
63 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape);
64 type.block_light = true;
65 type.fill = block_fill;
69 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape);
70 type.block_light = true;
71 type.fill = slab_fill;
75 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape);
76 type.block_light = true;
77 type.fill = stair_fill;
82 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape);
83 type.block_light = true;
84 type.fill = block_fill;
88 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape);
89 type.block_light = true;
90 type.fill = slab_fill;
94 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape);
95 type.block_light = true;
96 type.fill = stair_fill;
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;
110 generate.Solids({ 1, 4, 7, 10 });
112 player = &AddEntity();
113 player->Position(config.spawn);
115 chunks.GenerateSurrounding(player->ChunkCoords());
126 std::vector<Candidate> candidates;
130 bool World::Intersection(
139 for (Chunk &cur_chunk : chunks.Loaded()) {
141 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
142 candidates.push_back({ &cur_chunk, cur_dist });
146 if (candidates.empty()) return false;
148 Chunk *closest_chunk = nullptr;
149 float closest_dist = std::numeric_limits<float>::infinity();
150 int closest_blkid = -1;
151 glm::vec3 closest_normal;
153 for (Candidate &cand : candidates) {
154 if (cand.dist > closest_dist) continue;
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;
169 *chunk = closest_chunk;
172 *blkid = closest_blkid;
175 *dist = closest_dist;
178 *normal = closest_normal;
180 return closest_chunk;
184 Chunk &World::PlayerChunk() {
185 return chunks.ForceLoad(player->ChunkCoords());
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);
194 void World::Update(int dt) {
195 for (Entity &entity : entities) {
198 chunks.Rebase(player->ChunkCoords());
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())));
208 for (Chunk &chunk : chunks.Loaded()) {
209 glm::mat4 m(chunk.Transform(player->ChunkCoords()));
211 glm::mat4 mvp(chunk_prog.GetVP() * m);
212 if (!CullTest(Chunk::Bounds(), mvp)) {
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())));
222 for (Entity &entity : entities) {
223 if (entity.HasShape()) {
224 entity_prog.SetM(entity.Transform(player->ChunkCoords()));