]> git.localhorst.tv Git - blank.git/blob - src/world.cpp
248685cc4add2b8c7840b5ecf3211d2d1bcac1a2
[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()
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(0)
15 , chunks(blockType, generate)
16 , player() {
17         blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &blockShape }); // white block
18         blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &stairShape }); // white stair
19         blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &slabShape }); // white slab
20         blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &blockShape }); // red block
21         blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &stairShape }); // red stair
22         blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &slabShape }); // red slab
23         blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &blockShape }); // green block
24         blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &stairShape }); // green stair
25         blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &slabShape }); // green slab
26         blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &blockShape }); // blue block
27         blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &stairShape }); // blue stair
28         blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &slabShape }); // blue slab
29
30         generate.Space(0);
31         generate.Solids({ 1, 4, 7, 10 });
32
33         player.Position({ 4.0f, 4.0f, 4.0f });
34
35         chunks.Generate({ -4, -4, -4 }, { 5, 5, 5});
36 }
37
38
39 bool World::Intersection(
40                 const Ray &ray,
41                 const glm::mat4 &M,
42                 Chunk **chunk,
43                 int *blkid,
44                 float *dist,
45                 glm::vec3 *normal) {
46         Chunk *closest_chunk = nullptr;
47         int closest_blkid = -1;
48         float closest_dist = std::numeric_limits<float>::infinity();
49         glm::vec3 closest_normal;
50
51         for (Chunk &cur_chunk : chunks.Loaded()) {
52                 int cur_blkid;
53                 float cur_dist;
54                 glm::vec3 cur_normal;
55                 if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(player.ChunkCoords()), &cur_blkid, &cur_dist, &cur_normal)) {
56                         if (cur_dist < closest_dist) {
57                                 closest_chunk = &cur_chunk;
58                                 closest_blkid = cur_blkid;
59                                 closest_dist = cur_dist;
60                                 closest_normal = cur_normal;
61                         }
62                 }
63         }
64
65         if (chunk) {
66                 *chunk = closest_chunk;
67         }
68         if (blkid) {
69                 *blkid = closest_blkid;
70         }
71         if (dist) {
72                 *dist = closest_dist;
73         }
74         if (normal) {
75                 *normal = closest_normal;
76         }
77         return closest_chunk;
78 }
79
80
81 Chunk &World::Next(const Chunk &to, const glm::tvec3<int> &dir) {
82         const Chunk::Pos tgt_pos = to.Position() + dir;
83         return chunks.ForceLoad(tgt_pos);
84 }
85
86
87 void World::Update(int dt) {
88         player.Update(dt);
89         chunks.Rebase(player.ChunkCoords());
90         chunks.Update();
91 }
92
93
94 void World::Render(DirectionalLighting &program) {
95         program.SetLightDirection({ -1.0f, -3.0f, -2.0f });
96         program.SetView(glm::inverse(player.Transform(player.ChunkCoords())));
97
98         for (Chunk &chunk : chunks.Loaded()) {
99                 glm::mat4 m(chunk.Transform(player.ChunkCoords()));
100                 program.SetM(m);
101                 glm::mat4 mvp(program.GetVP() * m);
102                 if (!CullTest(Chunk::Bounds(), mvp)) {
103                         chunk.Draw();
104                 }
105         }
106 }
107
108 }