3 #include "../graphics/BlockLighting.hpp"
4 #include "../graphics/DirectionalLighting.hpp"
8 #include <glm/gtx/transform.hpp>
13 World::World(const Config &config)
15 , blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }})
16 , stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f })
17 , slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }})
18 , generate(config.gen)
19 , chunks(config.load, blockType, generate)
22 , light_direction(config.light_direction)
23 , fog_density(config.fog_density) {
24 BlockType::Faces block_fill = { true, true, true, true, true, true };
25 BlockType::Faces slab_fill = { false, true, false, false, false, false };
26 BlockType::Faces stair_fill = { false, true, false, false, false, true };
29 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape);
30 type.block_light = true;
31 type.fill = block_fill;
35 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape);
36 type.block_light = true;
37 type.fill = slab_fill;
41 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape);
42 type.block_light = true;
43 type.fill = stair_fill;
48 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape);
49 type.block_light = true;
50 type.fill = block_fill;
54 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape);
55 type.block_light = true;
56 type.fill = slab_fill;
60 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape);
61 type.block_light = true;
62 type.fill = stair_fill;
67 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape);
68 type.block_light = true;
69 type.fill = block_fill;
73 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape);
74 type.block_light = true;
75 type.fill = slab_fill;
79 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape);
80 type.block_light = true;
81 type.fill = stair_fill;
86 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape);
87 type.block_light = true;
88 type.fill = block_fill;
92 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape);
93 type.block_light = true;
94 type.fill = slab_fill;
98 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape);
99 type.block_light = true;
100 type.fill = stair_fill;
104 { // glowing yellow block
105 BlockType type(true, { 1.0f, 1.0f, 0.0f }, &blockShape);
106 type.luminosity = 15;
107 type.block_light = true;
108 type.fill = block_fill;
114 generate.Solids({ 1, 4, 7, 10 });
116 player = &AddEntity();
117 player->Name("player");
118 player->Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
119 player->WorldCollidable(true);
120 player->Position(config.spawn);
122 chunks.GenerateSurrounding(player->ChunkCoords());
133 std::vector<Candidate> candidates;
137 bool World::Intersection(
147 for (Chunk &cur_chunk : chunks.Loaded()) {
149 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
150 candidates.push_back({ &cur_chunk, cur_dist });
154 if (candidates.empty()) return false;
157 dist = std::numeric_limits<float>::infinity();
160 for (Candidate &cand : candidates) {
161 if (cand.dist > dist) continue;
164 glm::vec3 cur_normal;
165 if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
166 if (cur_dist < dist) {
178 bool World::Intersection(const Entity &e) {
179 AABB box = e.Bounds();
180 glm::mat4 M = e.Transform(player->ChunkCoords());
181 for (Chunk &cur_chunk : chunks.Loaded()) {
182 if (cur_chunk.Intersection(box, M, cur_chunk.Transform(player->ChunkCoords()))) {
190 Chunk &World::PlayerChunk() {
191 return chunks.ForceLoad(player->ChunkCoords());
194 Chunk &World::Next(const Chunk &to, const glm::tvec3<int> &dir) {
195 const Chunk::Pos tgt_pos = to.Position() + dir;
196 return chunks.ForceLoad(tgt_pos);
200 void World::Update(int dt) {
201 for (Entity &entity : entities) {
204 for (Entity &entity : entities) {
205 if (entity.WorldCollidable() && Intersection(entity)) {
206 // entity collides with the world
207 std::cout << entity.Name() << " entity intersects world" << std::endl;
210 chunks.Rebase(player->ChunkCoords());
215 void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) {
216 chunk_prog.Activate();
217 chunk_prog.SetFogDensity(fog_density);
218 chunk_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
220 for (Chunk &chunk : chunks.Loaded()) {
221 glm::mat4 m(chunk.Transform(player->ChunkCoords()));
223 glm::mat4 mvp(chunk_prog.GetVP() * m);
224 if (!CullTest(Chunk::Bounds(), mvp)) {
229 entity_prog.Activate();
230 entity_prog.SetLightDirection(light_direction);
231 entity_prog.SetFogDensity(fog_density);
232 entity_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
234 for (Entity &entity : entities) {
235 if (entity.HasShape()) {
236 entity_prog.SetM(entity.Transform(player->ChunkCoords()));