]> git.localhorst.tv Git - blank.git/commitdiff
move controller from camera to world
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 8 Mar 2015 18:45:59 +0000 (19:45 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 8 Mar 2015 18:45:59 +0000 (19:45 +0100)
src/app.cpp
src/app.hpp
src/camera.cpp
src/camera.hpp
src/controller.cpp
src/controller.hpp
src/geometry.hpp
src/shader.cpp
src/shader.hpp
src/world.cpp
src/world.hpp

index 8c0793dfc123b4ab0f14bafd806aafc8c118f09e..21eb85c309830eca5f332d6f5cdd719d1b8da04a 100644 (file)
@@ -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);
index e1f328ac5e7717acf37fd933c62ad3f5843d8f93..0443942108906b14e59dcaf87b10ff17fae1a376 100644 (file)
@@ -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;
index 4bbb0f12f0fadb6955bf230d99a88fa116d65355..8f618672f5a4b17266ab64388a1fc3d3a1524b0e 100644 (file)
@@ -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);
index 805109c313af3a8f0fd692448e02c7bab7190b0c..22e2ba598fd9f9990e228fda37f43f7878c0ca1f 100644 (file)
@@ -3,21 +3,14 @@
 
 #include <glm/glm.hpp>
 
-#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;
 
 };
 
index d0a026b7069111284a38ef259819c83ed9af2377..3911e0f26c5c0716226a9303ae3c6411dc56bb40 100644 (file)
@@ -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));
 }
 
 }
index f636bcdccd15bc64339a287044a32cabae9fc45a..853eeff3bd244603727866d03df28f0f858621b7 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef BLANK_CONTROLLER_HPP_
 #define BLANK_CONTROLLER_HPP_
 
+#include "geometry.hpp"
+
+#include <SDL.h>
 #include <glm/glm.hpp>
 
 
@@ -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;
+
 };
 
 }
index bcc9c9a0918ef1dabfe270441818340bc1f45104..d74e08e6b6fc8c29a5bc104ce381d6f0632e6289 100644 (file)
@@ -7,6 +7,8 @@
 
 namespace blank {
 
+constexpr float PI = 3.141592653589793238462643383279502884;
+
 struct AABB {
        glm::vec3 min;
        glm::vec3 max;
index e01c11fcc1aac8f282aaaec1804d9eb32f708ca6..43b3910096789bb4aaece8133abd8ac2b42e75a4 100644 (file)
@@ -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;
 }
 
index 97211c4aa6799860eb7f748c838369800d680f7d..195376c0ce093ab5bdf13ebe601a688febff4d63 100644 (file)
@@ -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;
index 57583e6ed4e2267a48a241412a16159ddf7c42ab..7a498c37e45c3c07ae89ca96d31db495c0e5c129 100644 (file)
@@ -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();
+       }
+}
+
 }
index ce44c7c1144352c4c31aedfb0505f86ea5317e05..8ca03a25b73c82285b441731b589206266332c13 100644 (file)
@@ -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 <list>
@@ -179,8 +181,14 @@ public:
        BlockTypeRegistry &BlockTypes() { return blockType; }
        std::list<Chunk> &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<Chunk> chunks;
 
 };