1 #include "interface.hpp"
6 #include <glm/gtc/matrix_transform.hpp>
7 #include <glm/gtx/io.hpp>
12 Interface::Interface(const Config &config, World &world)
14 , ctrl(world.Player())
15 , hud(world.BlockTypes())
16 , aim{{ 0, 0, 0 }, { 0, 0, -1 }}
21 , outline_transform(1.0f)
29 hud.Viewport(960, 600);
30 hud.Display(selection);
34 void Interface::HandlePress(const SDL_KeyboardEvent &event) {
35 if (config.keyboard_disabled) return;
37 switch (event.keysym.sym) {
79 void Interface::HandleRelease(const SDL_KeyboardEvent &event) {
80 if (config.keyboard_disabled) return;
82 switch (event.keysym.sym) {
104 void Interface::FaceBlock() {
105 selection.SetFace(Block::Face((selection.GetFace() + 1) % Block::FACE_COUNT));
106 hud.Display(selection);
109 void Interface::TurnBlock() {
110 selection.SetTurn(Block::Turn((selection.GetTurn() + 1) % Block::TURN_COUNT));
111 hud.Display(selection);
114 void Interface::PrintBlockInfo() {
115 std::cout << std::endl;
117 std::cout << "not looking at any block" << std::endl;
118 Ray aim = ctrl.Aim();
119 std::cout << "aim ray: " << aim.orig << ", " << aim.dir << std::endl;
122 std::cout << "looking at block " << aim_block
123 << " " << Chunk::ToCoords(aim_block)
124 << " of chunk " << aim_chunk->Position()
126 Print(aim_chunk->BlockAt(aim_block));
129 void Interface::PrintChunkInfo() {
130 std::cout << std::endl;
132 std::cout << "not looking at any block" << std::endl;
135 std::cout << "looking at chunk "
136 << aim_chunk->Position()
139 std::cout << " neighbors:" << std::endl;
140 if (aim_chunk->HasNeighbor(Block::FACE_LEFT)) {
141 std::cout << " left " << aim_chunk->GetNeighbor(Block::FACE_LEFT).Position() << std::endl;
143 if (aim_chunk->HasNeighbor(Block::FACE_RIGHT)) {
144 std::cout << " right " << aim_chunk->GetNeighbor(Block::FACE_RIGHT).Position() << std::endl;
146 if (aim_chunk->HasNeighbor(Block::FACE_UP)) {
147 std::cout << " up " << aim_chunk->GetNeighbor(Block::FACE_UP).Position() << std::endl;
149 if (aim_chunk->HasNeighbor(Block::FACE_DOWN)) {
150 std::cout << " down " << aim_chunk->GetNeighbor(Block::FACE_DOWN).Position() << std::endl;
152 if (aim_chunk->HasNeighbor(Block::FACE_FRONT)) {
153 std::cout << " front " << aim_chunk->GetNeighbor(Block::FACE_FRONT).Position() << std::endl;
155 if (aim_chunk->HasNeighbor(Block::FACE_BACK)) {
156 std::cout << " back " << aim_chunk->GetNeighbor(Block::FACE_BACK).Position() << std::endl;
158 std::cout << std::endl;
161 void Interface::PrintLightInfo() {
163 << "light level " << world.PlayerChunk().GetLight(world.Player().Position())
164 << " at position " << world.Player().Position()
168 void Interface::PrintSelectionInfo() {
169 std::cout << std::endl;
173 void Interface::Print(const Block &block) {
174 std::cout << "type: " << block.type
175 << ", face: " << block.GetFace()
176 << ", turn: " << block.GetTurn()
181 void Interface::Handle(const SDL_MouseMotionEvent &event) {
182 if (config.mouse_disabled) return;
183 ctrl.RotateYaw(event.xrel * config.yaw_sensitivity);
184 ctrl.RotatePitch(event.yrel * config.pitch_sensitivity);
187 void Interface::HandlePress(const SDL_MouseButtonEvent &event) {
188 if (config.mouse_disabled) return;
190 if (event.button == 1) {
192 remove_timer.Start();
193 } else if (event.button == 2) {
195 } else if (event.button == 3) {
201 void Interface::HandleRelease(const SDL_MouseButtonEvent &event) {
202 if (config.mouse_disabled) return;
204 if (event.button == 1) {
206 } else if (event.button == 3) {
211 void Interface::PickBlock() {
212 if (!aim_chunk) return;
213 selection = aim_chunk->BlockAt(aim_block);
214 hud.Display(selection);
217 void Interface::PlaceBlock() {
218 if (!aim_chunk) return;
219 Chunk *mod_chunk = aim_chunk;
220 glm::vec3 next_pos = Chunk::ToCoords(aim_block) + aim_normal;
221 if (!Chunk::InBounds(next_pos)) {
222 mod_chunk = &world.Next(*aim_chunk, aim_normal);
223 next_pos -= aim_normal * glm::vec3(Chunk::Extent());
225 mod_chunk->SetBlock(next_pos, selection);
226 mod_chunk->Invalidate();
229 void Interface::RemoveBlock() noexcept {
230 if (!aim_chunk) return;
231 aim_chunk->SetBlock(aim_block, remove);
232 aim_chunk->Invalidate();
236 void Interface::Handle(const SDL_MouseWheelEvent &event) {
237 if (config.mouse_disabled) return;
241 } else if (event.y > 0) {
246 void Interface::SelectNext() {
248 if (size_t(selection.type) >= world.BlockTypes().Size()) {
251 hud.Display(selection);
254 void Interface::SelectPrevious() {
256 if (selection.type <= 0) {
257 selection.type = world.BlockTypes().Size() - 1;
259 hud.Display(selection);
262 void Interface::Handle(const SDL_WindowEvent &event) noexcept {
263 if (event.event == SDL_WINDOWEVENT_RESIZED) {
264 hud.Viewport(event.data1, event.data2);
269 void Interface::Update(int dt) {
270 ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity);
273 place_timer.Update(dt);
274 remove_timer.Update(dt);
279 if (remove_timer.Hit()) {
284 if (place_timer.Hit()) {
290 void Interface::CheckAim() {
292 if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) {
294 aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline);
295 outline_transform = glm::scale(glm::vec3(1.0002f));
296 outline_transform *= aim_chunk->Transform(world.Player().ChunkCoords());
297 outline_transform *= aim_chunk->ToTransform(aim_block);
304 void Interface::Render(DirectionalLighting &program) noexcept {
305 if (config.visual_disabled) return;
308 program.SetM(outline_transform);