4 #include <glm/gtx/transform.hpp>
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 }})
15 , chunks(blockType, generate)
17 BlockType::Faces block_fill = { true, true, true, true, true, true };
18 BlockType::Faces slab_fill = { false, true, false, false, false, false };
19 BlockType::Faces stair_fill = { false, true, false, false, false, true };
22 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape);
23 type.fill = block_fill;
27 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape);
28 type.fill = slab_fill;
32 BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape);
33 type.fill = stair_fill;
38 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape);
39 type.fill = block_fill;
43 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape);
44 type.fill = slab_fill;
48 BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape);
49 type.fill = stair_fill;
54 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape);
55 type.fill = block_fill;
59 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape);
60 type.fill = slab_fill;
64 BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape);
65 type.fill = stair_fill;
70 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape);
71 type.fill = block_fill;
75 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape);
76 type.fill = slab_fill;
80 BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape);
81 type.fill = stair_fill;
86 generate.Solids({ 1, 4, 7, 10 });
88 player = &AddEntity();
89 player->Position({ 4.0f, 4.0f, 4.0f });
91 chunks.Generate({ -4, -4, -4 }, { 5, 5, 5});
102 std::vector<Candidate> candidates;
106 bool World::Intersection(
115 for (Chunk &cur_chunk : chunks.Loaded()) {
117 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
118 candidates.push_back({ &cur_chunk, cur_dist });
122 if (candidates.empty()) return false;
124 Chunk *closest_chunk = nullptr;
125 float closest_dist = std::numeric_limits<float>::infinity();
126 int closest_blkid = -1;
127 glm::vec3 closest_normal;
129 for (Candidate &cand : candidates) {
130 if (cand.dist > closest_dist) continue;
133 glm::vec3 cur_normal;
134 if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
135 if (cur_dist < closest_dist) {
136 closest_chunk = cand.chunk;
137 closest_blkid = cur_blkid;
138 closest_dist = cur_dist;
139 closest_normal = cur_normal;
145 *chunk = closest_chunk;
148 *blkid = closest_blkid;
151 *dist = closest_dist;
154 *normal = closest_normal;
156 return closest_chunk;
160 Chunk &World::Next(const Chunk &to, const glm::tvec3<int> &dir) {
161 const Chunk::Pos tgt_pos = to.Position() + dir;
162 return chunks.ForceLoad(tgt_pos);
166 void World::Update(int dt) {
167 for (Entity &entity : entities) {
170 chunks.Rebase(player->ChunkCoords());
175 void World::Render(DirectionalLighting &program) {
176 program.SetLightDirection({ -1.0f, -3.0f, -2.0f });
177 program.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
179 for (Chunk &chunk : chunks.Loaded()) {
180 glm::mat4 m(chunk.Transform(player->ChunkCoords()));
182 glm::mat4 mvp(program.GetVP() * m);
183 if (!CullTest(Chunk::Bounds(), mvp)) {
188 for (Entity &entity : entities) {
189 if (entity.HasShape()) {
190 program.SetM(entity.Transform(player->ChunkCoords()));