#pragma once #include #include #include #include #include namespace endofthejedi { // TODO: // add shaking attributes to camera too // and dirt effects class Camera { public: Camera() : m_aspectRatio(1.0), m_fov(util::deg2rad(90.0)) , m_zoom(1.0), m_position(0.0, 0.0, 0.0), m_angles(0.0, 0.0, 0.0) , m_dirty(true) { } // set camera zoom: // 0 makes no sense, // << 1 scales down // 1 is neutral // >> 1 makes things bigger void setZoom(float zoom) { if (zoom != m_zoom) { m_zoom = zoom; m_dirty = true; } } // set field of view. // degree or radian? find it out. void setFov(float fov) { if (fov != m_fov) { m_fov = fov; m_dirty = true; } } // position of the camera in world space void setPosition(const glm::vec3 &pos) { if (pos != m_position) { m_position = pos; m_dirty = true; } } // some angles (in rad) for the camera. void setAngles(const glm::vec3 &angles) { if (angles != m_angles) { m_angles = angles; m_dirty = true; } } // all three arguments. void setPositionAnglesZoom(const glm::vec3 &position, const glm::vec3 &angles, float zoom) { setZoom(zoom); setPosition(position); setAngles(angles); } float fov() const { return m_fov; } float zoom() const { return m_zoom; } const glm::vec3 &position() const { return m_position; } const glm::vec3 &angles() const { return m_angles; } float aspectRatio() const { return m_aspectRatio; } void setAspectRatio(float r) { if (r != m_aspectRatio) { m_aspectRatio = r; m_dirty = true; } } // recompute view matrix. return true if it was dirty and is now clean // and recomputed. bool refresh() { if (m_dirty) { m_dirty = false; recomputeMatrix(); return true; } return false; } const glm::mat4 &viewMatrix() const { return m_viewMatrix; } void recomputeMatrix() { glm::mat4 view; // TODO: rest is smissing //float a = 2.0*M_PI*m_lastTime/10.0; //float s = glm::mod(m_lastTime, 5.0f)/1.0f; view = glm::scale(view, glm::vec3(m_zoom, m_zoom, m_zoom)); view = glm::translate(view, m_position); view = glm::rotate(view, m_angles.x, glm::vec3(1.0f, 0.0f, 0.0f)); view = glm::rotate(view, m_angles.y, glm::vec3(0.0f, 1.0f, 0.0f)); view = glm::rotate(view, m_angles.z, glm::vec3(0.0f, 0.0f, 1.0f)); // Generates a really hard-to-read matrix, but a normal, standard 4x4 matrix nonetheless glm::mat4 projectionMatrix = glm::perspective( // The horizontal Field of View, in degrees : the amount of // "zoom". Think "camera lens". Usually between 90° (extra // wide) and 30° (quite zoomed in) m_fov, m_aspectRatio, // aspect ratio 0.1f, // near clipping plane 100.0f // far clipping plane ); //m_viewMatrix = view; m_viewMatrix = projectionMatrix * view; } private: float m_aspectRatio; float m_fov; float m_zoom; glm::vec3 m_position; glm::vec3 m_angles; bool m_dirty; glm::mat4 m_viewMatrix; }; }