1 #include "interface.hpp"
3 #include "geometry.hpp"
8 #include <glm/gtc/matrix_transform.hpp>
9 #include <glm/gtx/io.hpp>
14 Interface::Interface(const Config &config, World &world)
16 , ctrl(world.Player())
17 , hud(world.BlockTypes())
22 , outline_transform(1.0f)
32 hud.Viewport(960, 600);
33 hud.Display(selection);
37 void Interface::Handle(const SDL_KeyboardEvent &event) {
38 if (config.keyboard_disabled) return;
40 switch (event.keysym.sym) {
42 front = event.state == SDL_PRESSED;
45 back = event.state == SDL_PRESSED;
48 left = event.state == SDL_PRESSED;
51 right = event.state == SDL_PRESSED;
54 up = event.state == SDL_PRESSED;
57 down = event.state == SDL_PRESSED;
61 if (event.state == SDL_PRESSED) {
66 if (event.state == SDL_PRESSED) {
72 if (event.state == SDL_PRESSED) {
77 if (event.state == SDL_PRESSED) {
82 if (event.state == SDL_PRESSED) {
87 if (event.state == SDL_PRESSED) {
94 void Interface::FaceBlock() {
95 selection.SetFace(Block::Face((selection.GetFace() + 1) % Block::FACE_COUNT));
96 hud.Display(selection);
99 void Interface::TurnBlock() {
100 selection.SetTurn(Block::Turn((selection.GetTurn() + 1) % Block::TURN_COUNT));
101 hud.Display(selection);
104 void Interface::PrintBlockInfo() {
105 std::cout << std::endl;
107 std::cout << "not looking at any block" << std::endl;
110 std::cout << "looking at block " << aim_block
111 << " " << Chunk::ToCoords(aim_block)
112 << " of chunk " << aim_chunk->Position()
114 Print(aim_chunk->BlockAt(aim_block));
117 void Interface::PrintChunkInfo() {
118 std::cout << std::endl;
120 std::cout << "not looking at any block" << std::endl;
123 std::cout << "looking at chunk "
124 << aim_chunk->Position()
127 std::cout << " neighbors:";
128 if (aim_chunk->HasNeighbor(Block::FACE_LEFT)) {
129 std::cout << " left";
131 if (aim_chunk->HasNeighbor(Block::FACE_RIGHT)) {
132 std::cout << " right";
134 if (aim_chunk->HasNeighbor(Block::FACE_UP)) {
137 if (aim_chunk->HasNeighbor(Block::FACE_DOWN)) {
138 std::cout << " down";
140 if (aim_chunk->HasNeighbor(Block::FACE_FRONT)) {
141 std::cout << " front";
143 if (aim_chunk->HasNeighbor(Block::FACE_BACK)) {
144 std::cout << " back";
146 std::cout << std::endl;
149 void Interface::PrintLightInfo() {
151 << "light level " << world.PlayerChunk().GetLight(world.Player().Position())
152 << " at position " << world.Player().Position()
156 void Interface::PrintSelectionInfo() {
157 std::cout << std::endl;
161 void Interface::Print(const Block &block) {
162 std::cout << "type: " << block.type
163 << ", face: " << block.GetFace()
164 << ", turn: " << block.GetTurn()
169 void Interface::Handle(const SDL_MouseMotionEvent &event) {
170 if (config.mouse_disabled) return;
171 ctrl.RotateYaw(event.xrel * config.yaw_sensitivity);
172 ctrl.RotatePitch(event.yrel * config.pitch_sensitivity);
175 void Interface::Handle(const SDL_MouseButtonEvent &event) {
176 if (config.mouse_disabled) return;
178 if (event.state != SDL_PRESSED) return;
180 if (event.button == 1) {
182 } else if (event.button == 2) {
184 } else if (event.button == 3) {
189 void Interface::PickBlock() {
190 if (!aim_chunk) return;
191 selection = aim_chunk->BlockAt(aim_block);
192 hud.Display(selection);
195 void Interface::PlaceBlock() {
196 if (!aim_chunk) return;
197 Chunk *mod_chunk = aim_chunk;
198 glm::vec3 next_pos = Chunk::ToCoords(aim_block) + aim_normal;
199 if (!Chunk::InBounds(next_pos)) {
200 mod_chunk = &world.Next(*aim_chunk, aim_normal);
201 next_pos -= aim_normal * glm::vec3(Chunk::Extent());
203 mod_chunk->SetBlock(next_pos, selection);
204 mod_chunk->Invalidate();
207 void Interface::RemoveBlock() {
208 if (!aim_chunk) return;
209 aim_chunk->SetBlock(aim_block, remove);
210 aim_chunk->Invalidate();
214 void Interface::Handle(const SDL_MouseWheelEvent &event) {
215 if (config.mouse_disabled) return;
219 } else if (event.y > 0) {
224 void Interface::SelectNext() {
226 if (size_t(selection.type) >= world.BlockTypes().Size()) {
229 hud.Display(selection);
232 void Interface::SelectPrevious() {
234 if (selection.type <= 0) {
235 selection.type = world.BlockTypes().Size() - 1;
237 hud.Display(selection);
240 void Interface::Handle(const SDL_WindowEvent &event) {
241 if (event.event == SDL_WINDOWEVENT_RESIZED) {
242 hud.Viewport(event.data1, event.data2);
247 void Interface::Update(int dt) {
249 if (right && !left) {
250 vel.x = config.move_velocity;
251 } else if (left && !right) {
252 vel.x = -config.move_velocity;
255 vel.y = config.move_velocity;
256 } else if (down && !up) {
257 vel.y = -config.move_velocity;
259 if (back && !front) {
260 vel.z = config.move_velocity;
261 } else if (front && !back) {
262 vel.z = -config.move_velocity;
267 Ray aim = ctrl.Aim();
269 if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) {
271 aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline);
272 outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f));
273 outline_transform = aim_chunk->Transform(world.Player().ChunkCoords());
274 outline_transform *= aim_chunk->ToTransform(aim_block);
282 void Interface::Render(DirectionalLighting &program) {
283 if (config.visual_disabled) return;
286 program.SetM(outline_transform);