/** This file is a part of our_dick Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifndef OUR_DICK_ENGINE_CAMERA_HPP #define OUR_DICK_ENGINE_CAMERA_HPP #include #include "object.hpp" namespace egn{ //Virtual base for camera types //Provides general object functionality as well as projection and view matrices. //Derived classes must provide method of recalculating the projection matrix. class camera_iface : public object { protected: enum update{ VIEW_UPDATE = 8, PROJ_UPDATE = 16, }; protected: //mutable because they're only really a cached value representation of the data //in position, orientation, near, far, etc mutable rml::mat4f m_projection_matrix; //camera-to-sceen matrix mutable rml::mat4f m_view_matrix; //world-to-camera matrix float m_near = 1; //near clipping plane in camera space float m_far = 100; //far clipping plane in camera space public: camera_iface(void) = default; //Initialize with given projection matrix and clipping planes camera_iface(const rml::mat4f& proj, float n, float f); camera_iface(const camera_iface&) = default; camera_iface(camera_iface&&) = default; virtual ~camera_iface(void) = default; camera_iface& operator=(const camera_iface&) = default; camera_iface& operator=(camera_iface&&) = default; //Set the camera's location and update relevant data structures void set_position(const rml::vec3f& pos)override; //Set the camera's facing angle and update relevant data structures void set_orientation(const rml::quat_f& distance)override; //getters const rml::mat4f& get_projection_matrix(void)const; const rml::mat4f& get_view_matrix(void)const; float get_near_plane(void)const; float get_far_plane(void)const; //setters void set_near_plane(float n); void set_far_plane(float f); //No control over matrices directly is done purposefully protected: void recalc_view_matrix(void)const; virtual void recalc_projection_matrix(void)const = 0; }; //Camera which performs an orthographic projection. Essentially camera will have no depth perspective class ortho_camera : public camera_iface { protected: float m_width, m_height; //width and height of the camera space box public: //Build camera with width, height, near, and far planes ortho_camera(float w, float h, float n, float f); ortho_camera(const ortho_camera&) = default; ortho_camera(ortho_camera&&) = default; ~ortho_camera(void) = default; ortho_camera& operator=(const ortho_camera&) = default; ortho_camera& operator=(ortho_camera&&) = default; //Getters float get_projection_width(void)const; float get_projection_height(void)const; //Setters void set_projection_width(float w); void set_projection_height(float h); void set_projection_box(float w, float h); protected: void recalc_projection_matrix(void)const override; }; class flat_camera : public ortho_camera { public: flat_camera(float w, float h); flat_camera(const flat_camera&) = default; flat_camera(flat_camera&&) = default; ~flat_camera(void) = default; flat_camera& operator=(const flat_camera&) = default; flat_camera& operator=(flat_camera&&) = default; }; } #endif