#pragma once #include "ui-mousectrl.hh" /*= T_Camera =================================================================*/ /* Data for a camera. * * For the field of view, both the near plane distance and the angle are * stored. Updating one causes the other to be updated. * * For the camera position and orientation, the data is stored as two different * sets: * - target, angles, distance * - position, direction and up vectors * Modifying one of the sets updates the other. */ struct T_Camera { T_Camera( ) noexcept; DEF_COPY( T_Camera ); DEF_MOVE( T_Camera ); // --------------------------------------------------------------------- // FIELD OF VIEW / NEAR PLANE public: void fieldOfView( const float angle ) noexcept { fov_ = std::min( 179.f , std::max( 1.f , angle ) ); cvtFov2Np( ); } void nearPlane( const float distance ) noexcept { np_ = std::max( .001f , distance ); cvtNp2Fov( ); } float fieldOfView( ) const noexcept { return fov_; } float& fieldOfView( ) noexcept { return fov_; } float nearPlane( ) const noexcept { return np_; } float& nearPlane( ) noexcept { return np_; } private: float fov_ = 90.f; float np_; // --------------------------------------------------------------------- // POSITION AND ORIENTATION public: void camera( glm::vec3 const& lookAt , glm::vec3 const& angles , float distance ) noexcept; void camera( glm::vec3 const& lookAt , glm::vec3 const& position , glm::vec3 const& up ) noexcept; glm::vec3 const& lookAt( ) const noexcept { return lookAt_; } glm::vec3& lookAt( ) noexcept { return lookAt_; } glm::vec3 const& angles( ) const noexcept { return angles_; } glm::vec3& angles( ) noexcept { return angles_; } float distance( ) const noexcept { return distance_; } float& distance( ) noexcept { return distance_; } glm::vec3 const& position( ) const noexcept { return pos_; } glm::vec3& position( ) noexcept { return pos_; } glm::vec3 const& upVector( ) const noexcept { return up_; } glm::vec3& upVector( ) noexcept { return up_; } glm::vec3 const& direction( ) const noexcept { return dir_; } glm::vec3& direction( ) noexcept { return dir_; } private: glm::vec3 lookAt_ = glm::vec3( 0 ); glm::vec3 angles_ = glm::vec3( 0 ); float distance_ = 10; glm::vec3 dir_; glm::vec3 up_; glm::vec3 pos_; glm::mat3x3 rotMat_; // --------------------------------------------------------------------- // CONVERSION public: void cvtFov2Np( ) noexcept { np_ = 2 * tanf( M_PI * ( 180.f - fov_ ) / 360.f ); } void cvtNp2Fov( ) noexcept { fov_ = 180.f - atanf( .5 * np_ ) * 360.f / M_PI; } void cvtAnglesToVectors( ) noexcept; void cvtVectorsToAngles( ) noexcept; };