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 Entity &test_entity = AddEntity();
92 test_entity.Position({ 0.0f, 0.0f, 0.0f });
93 test_entity.SetShape(&blockShape, { 1.0f, 1.0f, 0.0f });
94 test_entity.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
96 chunks.Generate({ -4, -4, -4 }, { 5, 5, 5});
107 std::vector<Candidate> candidates;
111 bool World::Intersection(
120 for (Chunk &cur_chunk : chunks.Loaded()) {
122 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player->ChunkCoords()), cur_dist)) {
123 candidates.push_back({ &cur_chunk, cur_dist });
127 if (candidates.empty()) return false;
129 Chunk *closest_chunk = nullptr;
130 float closest_dist = std::numeric_limits<float>::infinity();
131 int closest_blkid = -1;
132 glm::vec3 closest_normal;
134 for (Candidate &cand : candidates) {
135 if (cand.dist > closest_dist) continue;
138 glm::vec3 cur_normal;
139 if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
140 if (cur_dist < closest_dist) {
141 closest_chunk = cand.chunk;
142 closest_blkid = cur_blkid;
143 closest_dist = cur_dist;
144 closest_normal = cur_normal;
150 *chunk = closest_chunk;
153 *blkid = closest_blkid;
156 *dist = closest_dist;
159 *normal = closest_normal;
161 return closest_chunk;
165 Chunk &World::Next(const Chunk &to, const glm::tvec3<int> &dir) {
166 const Chunk::Pos tgt_pos = to.Position() + dir;
167 return chunks.ForceLoad(tgt_pos);
171 void World::Update(int dt) {
172 for (Entity &entity : entities) {
175 chunks.Rebase(player->ChunkCoords());
180 void World::Render(DirectionalLighting &program) {
181 program.SetLightDirection({ -1.0f, -3.0f, -2.0f });
182 program.SetView(glm::inverse(player->Transform(player->ChunkCoords())));
184 for (Chunk &chunk : chunks.Loaded()) {
185 glm::mat4 m(chunk.Transform(player->ChunkCoords()));
187 glm::mat4 mvp(program.GetVP() * m);
188 if (!CullTest(Chunk::Bounds(), mvp)) {
193 for (Entity &entity : entities) {
194 if (entity.HasShape()) {
195 program.SetM(entity.Transform(player->ChunkCoords()));