From: Daniel Karbach Date: Sun, 8 Mar 2015 18:45:59 +0000 (+0100) Subject: move controller from camera to world X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=753be639d7d04f9f7415db9fc2721485c531f0a1;p=blank.git move controller from camera to world --- diff --git a/src/app.cpp b/src/app.cpp index 8c0793d..21eb85c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -16,9 +16,6 @@ Application::Application() , ctx(window.CreateContext()) , init_glew() , program() -, move_velocity(0.003f) -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) , cam() , hud() , world() @@ -26,12 +23,6 @@ Application::Application() , outline_visible(false) , outline_transform(1.0f) , running(false) -, front(false) -, back(false) -, left(false) -, right(false) -, up(false) -, down(false) , place(false) , remove(false) , pick(false) @@ -45,7 +36,6 @@ Application::Application() world.Generate(); - cam.Position(glm::vec3(0, 4, 4)); hud.Viewport(960, 600); hud.Display(*world.BlockTypes()[place_id]); @@ -78,28 +68,7 @@ void Application::HandleEvents() { switch (event.type) { case SDL_KEYDOWN: case SDL_KEYUP: - switch (event.key.keysym.sym) { - case SDLK_w: - front = event.key.state == SDL_PRESSED; - break; - case SDLK_s: - back = event.key.state == SDL_PRESSED; - break; - case SDLK_a: - left = event.key.state == SDL_PRESSED; - break; - case SDLK_d: - right = event.key.state == SDL_PRESSED; - break; - case SDLK_q: - case SDLK_SPACE: - up = event.key.state == SDL_PRESSED; - break; - case SDLK_e: - case SDLK_LSHIFT: - down = event.key.state == SDL_PRESSED; - break; - } + world.Controller().HandleKeyboard(event.key); break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == 1) { @@ -114,8 +83,7 @@ void Application::HandleEvents() { } break; case SDL_MOUSEMOTION: - cam.RotateYaw(event.motion.xrel * yaw_sensitivity); - cam.RotatePitch(event.motion.yrel * pitch_sensitivity); + world.Controller().HandleMouse(event.motion); break; case SDL_QUIT: running = false; @@ -137,27 +105,9 @@ void Application::HandleEvents() { } void Application::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; - } - cam.OrientationVelocity(vel); + world.Update(dt); - cam.Update(dt); - - Ray aim = cam.Aim(); + Ray aim = world.Controller().Aim(); Chunk *chunk; int blkid; float dist; @@ -207,13 +157,8 @@ void Application::Render() { program.Activate(); - program.SetLightDirection({ -1.0f, -3.0f, -2.0f }); - program.SetVP(cam.View(), cam.Projection()); - - for (Chunk &chunk : world.LoadedChunks()) { - program.SetM(chunk.Transform()); - chunk.Draw(); - } + program.SetProjection(cam.Projection()); + world.Render(program); if (outline_visible) { program.SetM(outline_transform); diff --git a/src/app.hpp b/src/app.hpp index e1f328a..0443942 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -39,21 +39,16 @@ private: InitGLEW init_glew; DirectionalLighting program; - float move_velocity; - float pitch_sensitivity; - float yaw_sensitivity; - Camera cam; HUD hud; World world; - OutlineModel outline; + OutlineModel outline; bool outline_visible; glm::mat4 outline_transform; bool running; - bool front, back, left, right, up, down; bool place, remove, pick; int remove_id; diff --git a/src/camera.cpp b/src/camera.cpp index 4bbb0f1..8f61867 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -7,13 +7,11 @@ namespace blank { Camera::Camera() -: FPSController() -, fov(45.0f) +: fov(45.0f) , aspect(1.0f) , near_clip(0.1f) , far_clip(100.0f) -, projection(glm::perspective(fov, aspect, near_clip, far_clip)) -, view(glm::inverse(Transform())) { +, projection(glm::perspective(fov, aspect, near_clip, far_clip)) { } @@ -47,20 +45,6 @@ void Camera::Clip(float near, float far) { UpdateProjection(); } -Ray Camera::Aim() const { - const glm::mat4 inv_vp(glm::inverse(projection * view)); - glm::vec4 from = inv_vp * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f); - from /= from.w; - glm::vec4 to = inv_vp * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f); - to /= to.w; - return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) }; -} - - -void Camera::Update(int dt) { - FPSController::Update(dt); - view = glm::inverse(Transform()); -} void Camera::UpdateProjection() { projection = glm::perspective(fov, aspect, near_clip, far_clip); diff --git a/src/camera.hpp b/src/camera.hpp index 805109c..22e2ba5 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -3,21 +3,14 @@ #include -#include "controller.hpp" -#include "geometry.hpp" - namespace blank { -class Camera -: public FPSController { +class Camera { public: Camera(); - Camera(const Camera &) = delete; - Camera &operator =(const Camera &) = delete; - void Viewport(int width, int height); void Viewport(int x, int y, int width, int height); @@ -26,12 +19,7 @@ public: void Aspect(float w, float h); void Clip(float near, float far); - Ray Aim() const; - const glm::mat4 &Projection() { return projection; } - const glm::mat4 &View() { return view; } - - void Update(int dt); private: void UpdateProjection(); @@ -43,7 +31,6 @@ private: float far_clip; glm::mat4 projection; - glm::mat4 view; }; diff --git a/src/controller.cpp b/src/controller.cpp index d0a026b..3911e0f 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -12,23 +12,124 @@ FPSController::FPSController() : velocity(0, 0, 0) , position(0, 0, 0) , pitch(0) -, yaw(0) { +, yaw(0) +, transform(1.0f) +, dirty(true) +, move_velocity(0.003f) +, pitch_sensitivity(-0.0025f) +, yaw_sensitivity(-0.001f) +, front(false) +, back(false) +, left(false) +, right(false) +, up(false) +, down(false) { } -glm::mat4 FPSController::Transform() const { - return glm::translate(position) * glm::eulerAngleYX(yaw, pitch); +const glm::mat4 &FPSController::Transform() const { + if (dirty) { + transform = glm::translate(position) * glm::eulerAngleYX(yaw, pitch); + dirty = false; + } + return transform; +} + +Ray FPSController::Aim() const { + glm::vec4 from = Transform() * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f); + from /= from.w; + glm::vec4 to = Transform() * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f); + to /= to.w; + return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) }; } void FPSController::OrientationVelocity(const glm::vec3 &vel) { - velocity = glm::rotateY(vel, yaw); + Velocity(glm::rotateY(vel, yaw)); +} + + +void FPSController::Pitch(float p) { + pitch = p; + if (pitch > PI / 2) { + pitch = PI / 2; + } else if (pitch < -PI / 2) { + pitch = -PI / 2; + } + dirty = true; +} + +void FPSController::RotatePitch(float delta) { + Pitch(pitch + delta); +} + +void FPSController::Yaw(float y) { + yaw = y; + if (yaw > PI) { + yaw -= PI * 2; + } else if (yaw < -PI) { + yaw += PI * 2; + } + dirty = true; +} + +void FPSController::RotateYaw(float delta) { + Yaw(yaw + 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) { - position += velocity * float(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; + } + OrientationVelocity(vel); + + Move(velocity * float(dt)); } } diff --git a/src/controller.hpp b/src/controller.hpp index f636bcd..853eeff 100644 --- a/src/controller.hpp +++ b/src/controller.hpp @@ -1,6 +1,9 @@ #ifndef BLANK_CONTROLLER_HPP_ #define BLANK_CONTROLLER_HPP_ +#include "geometry.hpp" + +#include #include @@ -11,20 +14,24 @@ class FPSController { public: FPSController(); - glm::mat4 Transform() const; + const glm::mat4 &Transform() const; + Ray Aim() const; - void Velocity(glm::vec3 vel) { velocity = vel; } + void Velocity(glm::vec3 vel) { velocity = vel; dirty = true; } void OrientationVelocity(const glm::vec3 &vel); - void Position(glm::vec3 pos) { position = pos; } - void Move(glm::vec3 delta) { position += delta; } + void Position(glm::vec3 pos) { position = pos; dirty = true; } + void Move(glm::vec3 delta) { Position(position + delta); } // all angles in radians (full circle = 2π) float Pitch() const { return pitch; } - void Pitch(float p) { pitch = p; } - void RotatePitch(float delta) { pitch += delta; } + void Pitch(float p); + void RotatePitch(float delta); float Yaw() const { return yaw; } - void Yaw(float y) { yaw = y; } - void RotateYaw(float delta) { yaw += delta; } + void Yaw(float y); + void RotateYaw(float delta); + + void HandleKeyboard(const SDL_KeyboardEvent &); + void HandleMouse(const SDL_MouseMotionEvent &); void Update(int dt); @@ -34,6 +41,15 @@ private: float pitch; float yaw; + mutable glm::mat4 transform; + mutable bool dirty; + + float move_velocity; + float pitch_sensitivity; + float yaw_sensitivity; + + bool front, back, left, right, up, down; + }; } diff --git a/src/geometry.hpp b/src/geometry.hpp index bcc9c9a..d74e08e 100644 --- a/src/geometry.hpp +++ b/src/geometry.hpp @@ -7,6 +7,8 @@ namespace blank { +constexpr float PI = 3.141592653589793238462643383279502884; + struct AABB { glm::vec3 min; glm::vec3 max; diff --git a/src/shader.cpp b/src/shader.cpp index e01c11f..43b3910 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -211,7 +211,19 @@ void DirectionalLighting::SetLightDirection(const glm::vec3 &dir) { glUniform3f(light_direction_handle, light_direction.x, light_direction.y, light_direction.z); } +void DirectionalLighting::SetProjection(const glm::mat4 &p) { + projection = p; + vp = p * view; +} + +void DirectionalLighting::SetView(const glm::mat4 &v) { + view = v; + vp = projection * v; +} + void DirectionalLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) { + projection = p; + view = v; vp = p * v; } diff --git a/src/shader.hpp b/src/shader.hpp index 97211c4..195376c 100644 --- a/src/shader.hpp +++ b/src/shader.hpp @@ -70,6 +70,8 @@ public: void SetLightDirection(const glm::vec3 &); void SetM(const glm::mat4 &m); + void SetProjection(const glm::mat4 &p); + void SetView(const glm::mat4 &v); void SetVP(const glm::mat4 &v, const glm::mat4 &p); void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p); @@ -79,6 +81,8 @@ private: glm::vec3 light_direction; glm::vec3 light_color; + glm::mat4 projection; + glm::mat4 view; glm::mat4 vp; GLuint m_handle; diff --git a/src/world.cpp b/src/world.cpp index 57583e6..7a498c3 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -179,6 +179,8 @@ World::World() blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &blockShape }); // blue block blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &stairShape }); // blue stair blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &slabShape }); // blue slab + + player.Position({ 4.0f, 4.0f, 4.0f }); } @@ -273,4 +275,20 @@ Chunk &World::Next(const Chunk &to, const glm::vec3 &dir) { return Generate(tgt_pos); } + +void World::Update(int dt) { + player.Update(dt); +} + + +void World::Render(DirectionalLighting &program) { + program.SetLightDirection({ -1.0f, -3.0f, -2.0f }); + program.SetView(glm::inverse(player.Transform())); + + for (Chunk &chunk : LoadedChunks()) { + program.SetM(chunk.Transform()); + chunk.Draw(); + } +} + } diff --git a/src/world.hpp b/src/world.hpp index ce44c7c..8ca03a2 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -1,9 +1,11 @@ #ifndef BLANK_WORLD_HPP_ #define BLANK_WORLD_HPP_ +#include "controller.hpp" #include "geometry.hpp" #include "model.hpp" #include "noise.hpp" +#include "shader.hpp" #include "shape.hpp" #include @@ -179,8 +181,14 @@ public: BlockTypeRegistry &BlockTypes() { return blockType; } std::list &LoadedChunks() { return chunks; } + FPSController &Controller() { return player; } + Chunk &Next(const Chunk &, const glm::vec3 &dir); + void Update(int dt); + + void Render(DirectionalLighting &); + private: Chunk &Generate(const glm::vec3 &); @@ -193,6 +201,8 @@ private: SimplexNoise blockNoise; SimplexNoise colorNoise; + FPSController player; + std::list chunks; };