]> git.localhorst.tv Git - blank.git/blob - src/world.hpp
move controller from camera to world
[blank.git] / src / world.hpp
1 #ifndef BLANK_WORLD_HPP_
2 #define BLANK_WORLD_HPP_
3
4 #include "controller.hpp"
5 #include "geometry.hpp"
6 #include "model.hpp"
7 #include "noise.hpp"
8 #include "shader.hpp"
9 #include "shape.hpp"
10
11 #include <list>
12 #include <vector>
13 #include <GL/glew.h>
14 #include <glm/glm.hpp>
15
16
17 namespace blank {
18
19 /// attributes of a type of block
20 struct BlockType {
21
22         int id;
23
24         bool visible;
25
26         const Shape *shape;
27         glm::vec3 color;
28         glm::vec3 outline_color;
29
30         explicit BlockType(
31                 bool v = false,
32                 const glm::vec3 &color = { 1, 1, 1 },
33                 const Shape *shape = &DEFAULT_SHAPE,
34                 const glm::vec3 &outline_color = { -1, -1, -1 })
35         : id(-1), visible(v), shape(shape), color(color), outline_color(outline_color) { }
36
37         static const BlockType DEFAULT;
38         static const NullShape DEFAULT_SHAPE;
39
40
41         void FillVBO(
42                 const glm::vec3 &pos,
43                 std::vector<glm::vec3> &vertices,
44                 std::vector<glm::vec3> &colors,
45                 std::vector<glm::vec3> &normals
46         ) const;
47
48         void FillModel(const glm::vec3 &pos, Model &m) const {
49                 FillVBO(pos, m.vertices, m.colors, m.normals);
50                 m.Invalidate();
51         }
52
53
54         void FillOutlineVBO(
55                 std::vector<glm::vec3> &vertices,
56                 std::vector<glm::vec3> &colors
57         ) const;
58
59         void FillOutlineModel(OutlineModel &m) const {
60                 FillOutlineVBO(m.vertices, m.colors);
61                 m.Invalidate();
62         }
63
64 };
65
66
67 class BlockTypeRegistry {
68
69 public:
70         BlockTypeRegistry();
71
72 public:
73         int Add(const BlockType &);
74
75         size_t Size() const { return types.size(); }
76
77         BlockType *operator [](int id) { return &types[id]; }
78         const BlockType *Get(int id) const { return &types[id]; }
79
80 private:
81         std::vector<BlockType> types;
82
83 };
84
85
86 /// single 1x1x1 cube
87 struct Block {
88
89         const BlockType *type;
90
91         constexpr explicit Block(const BlockType *t = &BlockType::DEFAULT)
92         : type(t) { }
93
94 };
95
96
97 /// cube of size 16 (256 tiles, 4096 blocks)
98 class Chunk {
99
100 public:
101         Chunk();
102
103         Chunk(Chunk &&);
104         Chunk &operator =(Chunk &&);
105
106         static constexpr int Width() { return 16; }
107         static constexpr int Height() { return 16; }
108         static constexpr int Depth() { return 16; }
109         static glm::vec3 Extent() { return glm::vec3(Width(), Height(), Depth()); }
110         static constexpr int Size() { return Width() * Height() * Depth(); }
111
112         static constexpr bool InBounds(const glm::vec3 &pos) {
113                 return
114                         pos.x >= 0 && pos.x < Width() &&
115                         pos.y >= 0 && pos.y < Height() &&
116                         pos.z >= 0 && pos.z < Depth();
117         }
118         static constexpr int ToIndex(const glm::vec3 &pos) {
119                 return int(pos.x) + int(pos.y) * Width() + int(pos.z) * Width() * Height();
120         }
121         static constexpr bool InBounds(int idx) {
122                 return idx >= 0 && idx < Size();
123         }
124         static glm::vec3 ToCoords(int idx) {
125                 return glm::vec3(
126                         0.5f + idx % Width(),
127                         0.5f + (idx / Width()) % Height(),
128                         0.5f + idx / (Width() * Height())
129                 );
130         }
131
132         void Invalidate() { dirty = true; }
133
134         Block &BlockAt(int index) { return blocks[index]; }
135         const Block &BlockAt(int index) const { return blocks[index]; }
136         Block &BlockAt(const glm::vec3 &pos) { return BlockAt(ToIndex(pos)); }
137         const Block &BlockAt(const glm::vec3 &pos) const { return BlockAt(ToIndex(pos)); }
138
139         bool Intersection(
140                 const Ray &,
141                 const glm::mat4 &M,
142                 int *blkid = nullptr,
143                 float *dist = nullptr,
144                 glm::vec3 *normal = nullptr) const;
145
146         void Position(const glm::vec3 &);
147         const glm::vec3 &Position() const { return position; }
148         const glm::mat4 &Transform() const { return transform; }
149
150         void Draw();
151
152 private:
153         int VertexCount() const;
154         void Update();
155
156 private:
157         std::vector<Block> blocks;
158         Model model;
159         glm::vec3 position;
160         glm::mat4 transform;
161         bool dirty;
162
163 };
164
165
166 class World {
167
168 public:
169         World();
170
171         void Generate();
172
173         bool Intersection(
174                 const Ray &,
175                 const glm::mat4 &M,
176                 Chunk **chunk = nullptr,
177                 int *blkid = nullptr,
178                 float *dist = nullptr,
179                 glm::vec3 *normal = nullptr);
180
181         BlockTypeRegistry &BlockTypes() { return blockType; }
182         std::list<Chunk> &LoadedChunks() { return chunks; }
183
184         FPSController &Controller() { return player; }
185
186         Chunk &Next(const Chunk &, const glm::vec3 &dir);
187
188         void Update(int dt);
189
190         void Render(DirectionalLighting &);
191
192 private:
193         Chunk &Generate(const glm::vec3 &);
194
195 private:
196         BlockTypeRegistry blockType;
197         CuboidShape blockShape;
198         StairShape stairShape;
199         CuboidShape slabShape;
200
201         SimplexNoise blockNoise;
202         SimplexNoise colorNoise;
203
204         FPSController player;
205
206         std::list<Chunk> chunks;
207
208 };
209
210 }
211
212 #endif