From c3c5045f06327db2a3c97eae77a072bc06677286 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 12 Mar 2015 23:42:17 +0100 Subject: [PATCH] move human I/O related stuff into separate file --- src/app.cpp | 103 +++----------------------- src/app.hpp | 19 +---- src/controller.cpp | 60 +-------------- src/controller.hpp | 15 ++-- src/interface.cpp | 179 +++++++++++++++++++++++++++++++++++++++++++++ src/interface.hpp | 65 ++++++++++++++++ 6 files changed, 263 insertions(+), 178 deletions(-) create mode 100644 src/interface.cpp create mode 100644 src/interface.hpp diff --git a/src/app.cpp b/src/app.cpp index 0005443..4a890d5 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,7 +1,5 @@ #include "app.hpp" -#include "geometry.hpp" - #include #include @@ -17,23 +15,11 @@ Application::Application() , init_glew() , program() , cam() -, hud() , world() -, controller(world.Player()) -, outline() -, outline_visible(false) -, outline_transform(1.0f) -, running(false) -, place(false) -, remove(false) -, pick(false) -, remove_id(0) -, place_id(1) { +, interface(world) +, running(false) { GLContext::EnableVSync(); - hud.Viewport(960, 600); - hud.Display(*world.BlockTypes()[place_id]); - glClearColor(0.0, 0.0, 0.0, 1.0); } @@ -91,37 +77,16 @@ void Application::HandleEvents() { switch (event.type) { case SDL_KEYDOWN: case SDL_KEYUP: - controller.HandleKeyboard(event.key); + interface.Handle(event.key); break; case SDL_MOUSEBUTTONDOWN: - if (event.button.button == 1) { - // left - remove = true; - } else if (event.button.button == 2) { - // middle - pick = true; - } else if (event.button.button == 3) { - // right - place = true; - } + interface.Handle(event.button); break; case SDL_MOUSEMOTION: - controller.HandleMouse(event.motion); + interface.Handle(event.motion); break; case SDL_MOUSEWHEEL: - if (event.wheel.y < 0) { - ++place_id; - if (size_t(place_id) >= world.BlockTypes().Size()) { - place_id = 1; - } - hud.Display(*world.BlockTypes()[place_id]); - } else if (event.wheel.y > 0) { - --place_id; - if (place_id <= 0) { - place_id = world.BlockTypes().Size() - 1; - } - hud.Display(*world.BlockTypes()[place_id]); - } + interface.Handle(event.wheel); break; case SDL_QUIT: running = false; @@ -136,9 +101,10 @@ void Application::HandleEvents() { break; case SDL_WINDOWEVENT_RESIZED: cam.Viewport(event.window.data1, event.window.data2); - hud.Viewport(event.window.data1, event.window.data2); + interface.Handle(event.window); break; default: + interface.Handle(event.window); break; } break; @@ -149,52 +115,8 @@ void Application::HandleEvents() { } void Application::Update(int dt) { - controller.Update(dt); + interface.Update(dt); world.Update(dt); - - Ray aim = controller.Aim(); - Chunk *chunk; - int blkid; - float dist; - glm::vec3 normal; - if (world.Intersection(aim, glm::mat4(1.0f), &chunk, &blkid, &dist, &normal)) { - outline_visible = true; - outline.Clear(); - chunk->Type(chunk->BlockAt(blkid)).FillOutlineModel(outline); - outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f)); - outline_transform = chunk->Transform(world.Player().ChunkCoords()); - outline_transform *= chunk->ToTransform(blkid); - } else { - outline_visible = false; - } - - if (pick) { - if (chunk) { - place_id = chunk->BlockAt(blkid).type; - hud.Display(*world.BlockTypes()[place_id]); - } - pick = false; - } - if (remove) { - if (chunk) { - chunk->BlockAt(blkid).type = remove_id; - chunk->Invalidate(); - } - remove = false; - } - if (place) { - if (chunk) { - Chunk *mod_chunk = chunk; - glm::vec3 next_pos = Chunk::ToCoords(blkid) + normal; - if (!Chunk::InBounds(next_pos)) { - mod_chunk = &world.Next(*chunk, normal); - next_pos -= normal * glm::vec3(Chunk::Extent()); - } - mod_chunk->BlockAt(next_pos).type = place_id; - mod_chunk->Invalidate(); - } - place = false; - } } void Application::Render() { @@ -205,12 +127,7 @@ void Application::Render() { program.SetProjection(cam.Projection()); world.Render(program); - if (outline_visible) { - program.SetM(outline_transform); - outline.Draw(); - } - - hud.Render(program); + interface.Render(program); window.Flip(); } diff --git a/src/app.hpp b/src/app.hpp index cb71411..6bd4e0d 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -1,14 +1,9 @@ #ifndef BLANK_APP_HPP_ #define BLANK_APP_HPP_ -#include -#include - #include "camera.hpp" -#include "controller.hpp" -#include "hud.hpp" #include "init.hpp" -#include "model.hpp" +#include "interface.hpp" #include "shader.hpp" #include "world.hpp" @@ -48,21 +43,11 @@ private: DirectionalLighting program; Camera cam; - HUD hud; World world; - FPSController controller; - - OutlineModel outline; - bool outline_visible; - glm::mat4 outline_transform; + Interface interface; bool running; - bool place, remove, pick; - - int remove_id; - int place_id; - }; } diff --git a/src/controller.cpp b/src/controller.cpp index a1d3a98..b996f9e 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -9,16 +9,7 @@ namespace blank { FPSController::FPSController(Entity &entity) : entity(entity) , pitch(0) -, yaw(0) -, move_velocity(0.005f) -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) -, front(false) -, back(false) -, left(false) -, right(false) -, up(false) -, down(false) { +, yaw(0) { } @@ -50,56 +41,9 @@ void FPSController::RotateYaw(float delta) { } -void FPSController::HandleKeyboard(const SDL_KeyboardEvent &event) { - switch (event.keysym.sym) { - case SDLK_w: - front = event.state == SDL_PRESSED; - break; - case SDLK_s: - back = event.state == SDL_PRESSED; - break; - case SDLK_a: - left = event.state == SDL_PRESSED; - break; - case SDLK_d: - right = event.state == SDL_PRESSED; - break; - case SDLK_q: - case SDLK_SPACE: - up = event.state == SDL_PRESSED; - break; - case SDLK_e: - case SDLK_LSHIFT: - down = event.state == SDL_PRESSED; - break; - } -} - -void FPSController::HandleMouse(const SDL_MouseMotionEvent &event) { - RotateYaw(event.xrel * yaw_sensitivity); - RotatePitch(event.yrel * pitch_sensitivity); -} - - void FPSController::Update(int dt) { - glm::vec3 vel; - if (right && !left) { - vel.x = move_velocity; - } else if (left && !right) { - vel.x = -move_velocity; - } - if (up && !down) { - vel.y = move_velocity; - } else if (down && !up) { - vel.y = -move_velocity; - } - if (back && !front) { - vel.z = move_velocity; - } else if (front && !back) { - vel.z = -move_velocity; - } entity.Rotation(glm::eulerAngleYX(yaw, pitch)); - entity.Velocity(glm::rotateY(vel, yaw)); + entity.Velocity(glm::rotateY(velocity, yaw)); } } diff --git a/src/controller.hpp b/src/controller.hpp index aaa51f5..c13a14e 100644 --- a/src/controller.hpp +++ b/src/controller.hpp @@ -4,7 +4,6 @@ #include "entity.hpp" #include "geometry.hpp" -#include #include @@ -17,6 +16,9 @@ public: Ray Aim() const { return entity.Aim(entity.ChunkCoords()); } + const glm::vec3 &Velocity() const { return velocity; } + void Velocity(const glm::vec3 &vel) { velocity = vel; } + // all angles in radians (full circle = 2π) float Pitch() const { return pitch; } void Pitch(float p); @@ -25,23 +27,16 @@ public: void Yaw(float y); void RotateYaw(float delta); - void HandleKeyboard(const SDL_KeyboardEvent &); - void HandleMouse(const SDL_MouseMotionEvent &); - void Update(int dt); private: Entity &entity; + glm::vec3 velocity; + float pitch; float yaw; - float move_velocity; - float pitch_sensitivity; - float yaw_sensitivity; - - bool front, back, left, right, up, down; - }; } diff --git a/src/interface.cpp b/src/interface.cpp new file mode 100644 index 0000000..f20903b --- /dev/null +++ b/src/interface.cpp @@ -0,0 +1,179 @@ +#include "interface.hpp" + +#include "geometry.hpp" +#include "world.hpp" + +#include +#include + + +namespace blank { + +Interface::Interface(World &world) +: world(world) +, ctrl(world.Player()) +, hud() +, aim_chunk(nullptr) +, aim_block(0) +, aim_normal() +, outline() +, outline_transform(1.0f) +, move_velocity(0.005f) +, pitch_sensitivity(-0.0025f) +, yaw_sensitivity(-0.001f) +, remove(0) +, selection(1) +, front(false) +, back(false) +, left(false) +, right(false) +, up(false) +, down(false) { + hud.Viewport(960, 600); + hud.Display(*world.BlockTypes()[selection.type]); +} + + +void Interface::Handle(const SDL_KeyboardEvent &event) { + switch (event.keysym.sym) { + case SDLK_w: + front = event.state == SDL_PRESSED; + break; + case SDLK_s: + back = event.state == SDL_PRESSED; + break; + case SDLK_a: + left = event.state == SDL_PRESSED; + break; + case SDLK_d: + right = event.state == SDL_PRESSED; + break; + case SDLK_q: + case SDLK_SPACE: + up = event.state == SDL_PRESSED; + break; + case SDLK_e: + case SDLK_LSHIFT: + down = event.state == SDL_PRESSED; + break; + } +} + +void Interface::Handle(const SDL_MouseMotionEvent &event) { + ctrl.RotateYaw(event.xrel * yaw_sensitivity); + ctrl.RotatePitch(event.yrel * pitch_sensitivity); +} + +void Interface::Handle(const SDL_MouseButtonEvent &event) { + if (event.state != SDL_PRESSED) return; + + if (event.button == 1) { + RemoveBlock(); + } else if (event.button == 2) { + PickBlock(); + } else if (event.button == 3) { + PlaceBlock(); + } +} + +void Interface::PickBlock() { + if (!aim_chunk) return; + selection = aim_chunk->BlockAt(aim_block); + hud.Display(*world.BlockTypes()[selection.type]); +} + +void Interface::PlaceBlock() { + if (!aim_chunk) return; + Chunk *mod_chunk = aim_chunk; + glm::vec3 next_pos = Chunk::ToCoords(aim_block) + aim_normal; + if (!Chunk::InBounds(next_pos)) { + mod_chunk = &world.Next(*aim_chunk, aim_normal); + next_pos -= aim_normal * glm::vec3(Chunk::Extent()); + } + mod_chunk->BlockAt(next_pos) = selection; + mod_chunk->Invalidate(); +} + +void Interface::RemoveBlock() { + if (!aim_chunk) return; + aim_chunk->BlockAt(aim_block) = remove; + aim_chunk->Invalidate(); +} + + +void Interface::Handle(const SDL_MouseWheelEvent &event) { + if (event.y < 0) { + SelectNext(); + } else if (event.y > 0) { + SelectPrevious(); + } +} + +void Interface::SelectNext() { + ++selection.type; + if (size_t(selection.type) >= world.BlockTypes().Size()) { + selection.type = 1; + } + hud.Display(*world.BlockTypes()[selection.type]); +} + +void Interface::SelectPrevious() { + --selection.type; + if (selection.type <= 0) { + selection.type = world.BlockTypes().Size() - 1; + } + hud.Display(*world.BlockTypes()[selection.type]); +} + +void Interface::Handle(const SDL_WindowEvent &event) { + if (event.event == SDL_WINDOWEVENT_RESIZED) { + hud.Viewport(event.data1, event.data2); + } +} + + +void Interface::Update(int dt) { + glm::vec3 vel; + if (right && !left) { + vel.x = move_velocity; + } else if (left && !right) { + vel.x = -move_velocity; + } + if (up && !down) { + vel.y = move_velocity; + } else if (down && !up) { + vel.y = -move_velocity; + } + if (back && !front) { + vel.z = move_velocity; + } else if (front && !back) { + vel.z = -move_velocity; + } + ctrl.Velocity(vel); + ctrl.Update(dt); + + Ray aim = ctrl.Aim(); + float dist; + if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) { + outline.Clear(); + aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline); + outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f)); + outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); + outline_transform *= aim_chunk->ToTransform(aim_block); + } else { + aim_chunk = nullptr; + } + +} + + +void Interface::Render(DirectionalLighting &program) { + if (aim_chunk) { + program.SetM(outline_transform); + outline.Draw(); + } + + hud.Render(program); +} + +} diff --git a/src/interface.hpp b/src/interface.hpp new file mode 100644 index 0000000..ed41708 --- /dev/null +++ b/src/interface.hpp @@ -0,0 +1,65 @@ +#ifndef BLANK_INTERFACE_HPP_ +#define BLANK_INTERFACE_HPP_ + +#include "block.hpp" +#include "controller.hpp" +#include "hud.hpp" +#include "model.hpp" +#include "shader.hpp" + +#include + + +namespace blank { + +class Chunk; +class World; + +class Interface { + +public: + explicit Interface(World &); + + void Handle(const SDL_KeyboardEvent &); + void Handle(const SDL_MouseMotionEvent &); + void Handle(const SDL_MouseButtonEvent &); + void Handle(const SDL_MouseWheelEvent &); + void Handle(const SDL_WindowEvent &); + + void PickBlock(); + void PlaceBlock(); + void RemoveBlock(); + + void SelectNext(); + void SelectPrevious(); + + void Update(int dt); + + void Render(DirectionalLighting &); + +private: + World &world; + FPSController ctrl; + HUD hud; + + Chunk *aim_chunk; + int aim_block; + glm::vec3 aim_normal; + + OutlineModel outline; + glm::mat4 outline_transform; + + float move_velocity; + float pitch_sensitivity; + float yaw_sensitivity; + + Block remove; + Block selection; + + bool front, back, left, right, up, down; + +}; + +} + +#endif -- 2.39.2