From a66bb2d34e6552648a6088f2edc441ec5f84d937 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Tue, 15 Jun 2021 15:09:57 +0200
Subject: [PATCH] [#42] Simplified update methods, replaced clones to
 references, added namespace, corrected applications

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 modules/camera/CMakeLists.txt                 |   1 -
 modules/camera/include/vkcv/camera/Camera.hpp |  46 ++++---
 .../include/vkcv/camera/CameraController.hpp  |  12 +-
 .../include/vkcv/camera/CameraManager.hpp     |  42 ++++---
 .../vkcv/camera/PilotCameraController.hpp     |  19 +--
 .../vkcv/camera/TrackballCameraController.hpp |  18 +--
 modules/camera/src/vkcv/camera/Camera.cpp     | 116 ++++++++++--------
 .../src/vkcv/camera/CameraController.cpp      |  17 ---
 .../camera/src/vkcv/camera/CameraManager.cpp  |  78 +++++++-----
 .../src/vkcv/camera/PilotCameraController.cpp |  41 +++----
 .../vkcv/camera/TrackballCameraController.cpp |  49 +++-----
 projects/cmd_sync_test/src/main.cpp           |  20 ++-
 projects/first_mesh/src/main.cpp              |  13 +-
 projects/first_triangle/src/main.cpp          |  13 +-
 14 files changed, 239 insertions(+), 246 deletions(-)
 delete mode 100644 modules/camera/src/vkcv/camera/CameraController.cpp

diff --git a/modules/camera/CMakeLists.txt b/modules/camera/CMakeLists.txt
index 5c17d8d3..73f2dd1c 100644
--- a/modules/camera/CMakeLists.txt
+++ b/modules/camera/CMakeLists.txt
@@ -14,7 +14,6 @@ set(vkcv_camera_sources
 		${vkcv_camera_include}/vkcv/camera/CameraManager.hpp
 		${vkcv_camera_source}/vkcv/camera/CameraManager.cpp
 		${vkcv_camera_include}/vkcv/camera/CameraController.hpp
-		${vkcv_camera_source}/vkcv/camera/CameraController.cpp
 		${vkcv_camera_include}/vkcv/camera/PilotCameraController.hpp
 		${vkcv_camera_source}/vkcv/camera/PilotCameraController.cpp
 		${vkcv_camera_include}/vkcv/camera/TrackballCameraController.hpp
diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp
index 31f4aae6..dc9f2dcb 100644
--- a/modules/camera/include/vkcv/camera/Camera.hpp
+++ b/modules/camera/include/vkcv/camera/Camera.hpp
@@ -6,7 +6,7 @@
 #include <glm/gtc/matrix_transform.hpp>
 #include <glm/gtc/matrix_access.hpp>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     /**
      * @brief Used to create a camera which governs the view and projection matrices.
@@ -18,8 +18,6 @@ namespace vkcv {
 
 		float m_near;
 		float m_far;
-		float m_fov;
-		float m_ratio;
 
 		glm::vec3 m_up;
         glm::vec3 m_position;
@@ -27,6 +25,18 @@ namespace vkcv {
 
         float m_pitch;
         float m_yaw;
+	
+		/**
+		 * @brief Sets the view matrix of the camera to @p view
+		 * @param[in] view The view matrix
+		 */
+		void setView(const glm::mat4& view);
+	
+		/**
+		 * @brief Sets the projection matrix of the camera to @p projection
+		 * @param[in] projection The projection matrix
+		 */
+		void setProjection(const glm::mat4& projection);
 
     public:
 
@@ -53,7 +63,7 @@ namespace vkcv {
          * @brief Gets the view matrix of the camera
          * @return The view matrix of the camera
          */
-        glm::mat4& getView();
+        const glm::mat4& getView() const;
 
         /**
          * @brief Sets the view matrix of the camera according to @p position, @p center and @p up
@@ -61,22 +71,16 @@ namespace vkcv {
          * @param[in] center The target position the camera is looking at
          * @param[in] up The vector that defines which direction is 'up' depending on the camera's orientation
          */
-        void lookAt(glm::vec3 position, glm::vec3 center, glm::vec3 up);
+        void lookAt(const glm::vec3& position, const glm::vec3& center, const glm::vec3& up);
 
         /**
          * @brief Gets the current projection of the camera
          * @return The current projection matrix
          */
-        glm::mat4& getProjection();
+        const glm::mat4& getProjection() const;
 
         /**
-         * @brief Sets the projection matrix of the camera to @p projection
-         * @param[in] projection The projection matrix
-         */
-        void setProjection(const glm::mat4 projection);
-
-        /**
-         * @brief Gets the model-view-projection matrix of the camera
+         * @brief Gets the model-view-projection matrix of the camera with y-axis-correction applied
          * @return The model-view-projection matrix
          */
         glm::mat4 getMVP() const;
@@ -124,30 +128,36 @@ namespace vkcv {
          * @return The current front vector of the camera
          */
         glm::vec3 getFront() const;
+        
+        /**
+         * @brief Sets the front vector of the camera in world space to @p front
+         * @param[in] front The new front vector of the camera
+         */
+        void setFront(const glm::vec3& front);
 
         /**
          * @brief Gets the current position of the camera in world space
          * @return The current position of the camera in world space
          */
-        glm::vec3 getPosition() const;
+        const glm::vec3& getPosition() const;
 
         /**
          * @brief Sets the position of the camera to @p position
          * @param[in] position The new position of the camera
          */
-        void setPosition( glm::vec3 position );
+        void setPosition( const glm::vec3& position );
 
         /**
          * @brief Gets the center point.
          * @return The center point.
          */
-        glm::vec3 getCenter() const;
+        const glm::vec3& getCenter() const;
 
         /**
          * @brief Sets @p center as the new center point.
          * @param[in] center The new center point.
          */
-        void setCenter(glm::vec3 center);
+        void setCenter(const glm::vec3& center);
 
         /**
          * @brief Gets the pitch value of the camera in degrees.
@@ -177,7 +187,7 @@ namespace vkcv {
          * @brief Gets the up vector.
          * @return The up vector.
          */
-        glm::vec3 getUp() const;
+        const glm::vec3& getUp() const;
 
         /**
          * @brief Sets @p up as the new up vector.
diff --git a/modules/camera/include/vkcv/camera/CameraController.hpp b/modules/camera/include/vkcv/camera/CameraController.hpp
index 467992c3..5fe7aba5 100644
--- a/modules/camera/include/vkcv/camera/CameraController.hpp
+++ b/modules/camera/include/vkcv/camera/CameraController.hpp
@@ -3,7 +3,7 @@
 #include "Camera.hpp"
 #include "vkcv/Window.hpp"
 
-namespace vkcv {
+namespace vkcv::camera {
 
     /**
      * @brief Used as a base class for defining camera controller classes with different behaviors, e.g. the
@@ -23,7 +23,7 @@ namespace vkcv {
          * @param[in] deltaTime The time that has passed since last update.
          * @param[in] camera The camera object.
          */
-        virtual void updateCamera(double deltaTime, Camera &camera);
+        virtual void updateCamera(double deltaTime, Camera &camera) = 0;
 
         /**
          * @brief A callback function for key events.
@@ -33,7 +33,7 @@ namespace vkcv {
          * @param[in] mods The modifier bits.
          * @param[in] camera The camera object.
          */
-        virtual void keyCallback(int key, int scancode, int action, int mods, Camera &camera);
+        virtual void keyCallback(int key, int scancode, int action, int mods, Camera &camera) = 0;
 
         /**
          * @brief A callback function for mouse scrolling events.
@@ -41,7 +41,7 @@ namespace vkcv {
          * @param[in] offsetY The offset in vertical direction.
          * @param[in] camera The camera object.
          */
-        virtual void scrollCallback( double offsetX, double offsetY, Camera &camera);
+        virtual void scrollCallback( double offsetX, double offsetY, Camera &camera) = 0;
 
         /**
          * @brief A callback function for mouse movement events.
@@ -49,7 +49,7 @@ namespace vkcv {
          * @param[in] y The vertical mouse position.
          * @param[in] camera The camera object.
          */
-        virtual void mouseMoveCallback(double offsetX, double offsetY, Camera &camera);
+        virtual void mouseMoveCallback(double offsetX, double offsetY, Camera &camera) = 0;
 
         /**
          * @brief A callback function for mouse button events.
@@ -58,7 +58,7 @@ namespace vkcv {
          * @param[in] mods The modifier bits.
          * @param[in] camera The camera object.
          */
-        virtual void mouseButtonCallback(int button, int action, int mods, Camera &camera);
+        virtual void mouseButtonCallback(int button, int action, int mods, Camera &camera) = 0;
     };
 
 }
\ No newline at end of file
diff --git a/modules/camera/include/vkcv/camera/CameraManager.hpp b/modules/camera/include/vkcv/camera/CameraManager.hpp
index e75ec169..2d8df437 100644
--- a/modules/camera/include/vkcv/camera/CameraManager.hpp
+++ b/modules/camera/include/vkcv/camera/CameraManager.hpp
@@ -7,7 +7,7 @@
 #include <GLFW/glfw3.h>
 #include <functional>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     /**
      * @brief Used for specifying existing types of camera controllers when adding a new controller object to the
@@ -86,7 +86,19 @@ namespace vkcv {
          * @param[in] height The new height of the window.
          */
         void resizeCallback(int width, int height);
-
+	
+		/**
+		 * @brief Gets a camera controller object of specified @p controllerType.
+		 * @param[in] controllerType The type of the camera controller.
+		 * @return The specified camera controller object.
+		 */
+		CameraController& getControllerByType(ControllerType controllerType);
+        
+        /**
+         * @briof A method to get the currently active controller for the active camera.
+         * @return Reference to the active #CameraController
+         */
+        CameraController& getActiveController();
 
     public:
 
@@ -104,19 +116,22 @@ namespace vkcv {
          */
         ~CameraManager();
 
-        /**
-         * @brief Adds a new camera object to the #CameraManager. The camera is not binded to a controller type.
-         * @return The index of the newly created camera object.
-         */
-        int addCamera();
-
         /**
          * @brief Adds a new camera object to the #CameraManager and binds it to a camera controller object of specified
          * @p controllerType.
          * @param[in] controllerType The type of the camera controller.
          * @return The index of the newly created camera object.
          */
-        int addCamera(ControllerType controllerType);
+		uint32_t addCamera(ControllerType controllerType = ControllerType::NONE);
+	
+		/**
+		 * @brief Adds a new camera object to the #CameraManager and binds it to a camera controller object of specified
+		 * @p controllerType.
+		 * @param[in] controllerType The type of the camera controller.
+		 * @param[in] camera The new camera object.
+		 * @return The index of the newly bound camera object.
+		 */
+		uint32_t addCamera(ControllerType controllerType, const Camera& camera);
 
         /**
          * @brief Gets the stored camera object located at @p cameraIndex.
@@ -143,7 +158,7 @@ namespace vkcv {
          * @brief Gets the index of the stored active camera object.
          * @return The active camera index.
          */
-        uint32_t getActiveCameraIndex();
+        uint32_t getActiveCameraIndex() const;
 
         /**
          * @brief Binds a stored camera object located at @p cameraIndex to a camera controller of specified
@@ -162,13 +177,6 @@ namespace vkcv {
          */
         ControllerType getControllerType(uint32_t cameraIndex);
 
-        /**
-         * @brief Gets a camera controller object of specified @p controllerType.
-         * @param[in] controllerType The type of the camera controller.
-         * @return The specified camera controller object.
-         */
-        CameraController& getControllerByType(ControllerType controllerType);
-
         /**
          * @brief Updates all stored camera controllers in respect to @p deltaTime.
          * @param[in] deltaTime The time that has passed since last update.
diff --git a/modules/camera/include/vkcv/camera/PilotCameraController.hpp b/modules/camera/include/vkcv/camera/PilotCameraController.hpp
index 68a9eb44..c6a9f7c7 100644
--- a/modules/camera/include/vkcv/camera/PilotCameraController.hpp
+++ b/modules/camera/include/vkcv/camera/PilotCameraController.hpp
@@ -2,7 +2,7 @@
 
 #include <vkcv/camera/CameraController.hpp>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     /**
      * @brief Used to move around a camera object in world space.
@@ -25,23 +25,6 @@ namespace vkcv {
         float m_fov_min;
         float m_fov_max;
 
-
-        /**
-         * @brief Updates the position of @p camera with respect to @p deltaTime.
-         * @param[in] deltaTime The time that has passed since last update.
-         * @param[in] camera The camera object.
-         * @return The updated camera position.
-         */
-        glm::vec3 updatePosition(double deltaTime, Camera &camera);
-
-        /**
-         * @brief Updates the view matrix of @p camera with respect to @p deltaTime.
-         * @param[in] deltaTime The time that has passed since last update.
-         * @param[in] camera The camera object.
-         * @return The updated view matrix of the camera.
-         */
-        glm::mat4 updateView(double deltaTime, Camera &camera);
-
         /**
          * @brief Indicates forward movement of the camera depending on the performed @p action.
          * @param[in] action The performed action.
diff --git a/modules/camera/include/vkcv/camera/TrackballCameraController.hpp b/modules/camera/include/vkcv/camera/TrackballCameraController.hpp
index e541645d..0211043a 100644
--- a/modules/camera/include/vkcv/camera/TrackballCameraController.hpp
+++ b/modules/camera/include/vkcv/camera/TrackballCameraController.hpp
@@ -2,7 +2,7 @@
 
 #include "CameraController.hpp"
 
-namespace vkcv {
+namespace vkcv::camera {
 
     /**
      * @brief Used to orbit a camera around its center point.
@@ -15,22 +15,6 @@ namespace vkcv {
         float m_scrollSensitivity;
         float m_radius;
 
-
-        /**
-         * @brief Updates the position of @p camera.
-         * @param[in] camera The camera object.
-         * @param[in] camera The camera object.
-         * @return The updated camera position.
-         */
-        glm::vec3 updatePosition(Camera &camera);
-
-        /**
-         * @brief Updates the view matrix of @p camera.
-         * @param[in] camera The camera object.
-         * @return The updated view matrix of the camera.
-         */
-        glm::mat4 updateView(Camera &camera);
-
         /**
          * @brief Updates the current radius of @p camera in respect to the @p offset.
          * @param[in] offset The offset between the old and new radius.
diff --git a/modules/camera/src/vkcv/camera/Camera.cpp b/modules/camera/src/vkcv/camera/Camera.cpp
index 60bc08a0..b08559f5 100644
--- a/modules/camera/src/vkcv/camera/Camera.cpp
+++ b/modules/camera/src/vkcv/camera/Camera.cpp
@@ -1,25 +1,26 @@
 #include "vkcv/camera/Camera.hpp"
 #include <iostream>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     Camera::Camera() {
-        m_position = glm::vec3(0.0f, 0.0f, -1.0f);
-        m_up = glm::vec3(0.0f, 1.0f, 0.0f);
-        m_center = glm::vec3(0.0f, 0.0f, 0.0f);
-        lookAt(m_position, m_center, m_up);
-        glm::vec3 front = glm::normalize(m_center - m_position);
-        m_pitch = std::atan2(front.y, std::sqrt(front.x * front.x + front.z * front.z));
-        m_yaw = std::atan2(front.x, front.z);
+        lookAt(
+			glm::vec3(0.0f, 0.0f, -1.0f),
+			glm::vec3(0.0f, 0.0f, 0.0f),
+			glm::vec3(0.0f, 1.0f, 0.0f)
+		);
+  
+		setFront(glm::normalize(m_center - m_position));
     }
 
     Camera::~Camera() = default;
 
-    void Camera::lookAt(glm::vec3 position, glm::vec3 center, glm::vec3 up){
-		m_position = position;
-		m_center = center;
-		m_up = up;
-        m_view = glm::lookAt(m_position, m_center, m_up);
+    void Camera::lookAt(const glm::vec3& position, const glm::vec3& center, const glm::vec3& up) {
+    	m_position = position;
+    	m_center = center;
+    	m_up = up;
+    	
+		setView(glm::lookAt(position, center, up));
     }
 
     void Camera::getNearFar( float &near, float &far) const {
@@ -27,55 +28,67 @@ namespace vkcv {
         far = m_far;
     }
 
-    glm::mat4& Camera::getView() {
+    const glm::mat4& Camera::getView() const {
         return m_view;
     }
+    
+    void Camera::setView(const glm::mat4 &view) {
+		m_view = view;
+	}
 
-    glm::mat4& Camera::getProjection() {
+    const glm::mat4& Camera::getProjection() const {
         return m_projection;
     }
 
-    void Camera::setProjection(const glm::mat4 projection){
-        m_projection = projection;
+    void Camera::setProjection(const glm::mat4& projection) {
+        m_projection =  projection;
     }
 
     glm::mat4 Camera::getMVP() const {
-        return m_projection * m_view;
+		const glm::mat4 y_correction (
+				1.0f,  0.0f,  0.0f,  0.0f,
+				0.0f, -1.0f,  0.0f,  0.0f,
+				0.0f,  0.0f,  1.0f,  0.0f,
+				0.0f,  0.0f,  0.0f,  1.0f
+		);
+    	
+        return y_correction * m_projection * m_view;
     }
 
     float Camera::getFov() const {
-        return m_fov;
+    	const float tanHalfFovy = 1.0f / m_projection[1][1];
+    	float halfFovy = std::atan(tanHalfFovy);
+    	
+    	if (halfFovy < 0) {
+    		halfFovy += M_PIf32;
+    	}
+    	
+        return halfFovy * 2.0f;
     }
 
     void Camera::setFov( float fov){
-        setPerspective(fov, m_ratio, m_near, m_far);
+        setPerspective(fov, getRatio(), m_near, m_far);
     }
 
     float Camera::getRatio() const {
-        return m_ratio;
+    	const float aspectProduct = 1.0f / m_projection[0][0];
+		const float tanHalfFovy = 1.0f / m_projection[1][1];
+		
+        return aspectProduct / tanHalfFovy;
     }
 
     void Camera::setRatio(float ratio){
-        setPerspective( m_fov, ratio, m_near, m_far);
+        setPerspective( getFov(), ratio, m_near, m_far);
     }
 
     void Camera::setNearFar(float near, float far){
-        setPerspective(m_fov, m_ratio, near, far);
+        setPerspective(getFov(), getRatio(), near, far);
     }
 
     void Camera::setPerspective(float fov, float ratio, float near, float far) {
-    	const glm::mat4 y_correction (
-    			1.0f,  0.0f,  0.0f,  0.0f,
-    			0.0f, -1.0f,  0.0f,  0.0f,
-    			0.0f,  0.0f,  1.0f,  0.0f,
-    			0.0f,  0.0f,  0.0f,  1.0f
-		);
-    	
-        m_fov = fov;
-        m_ratio = ratio;
-        m_near = near;
-        m_far = far;
-        m_projection = y_correction * glm::perspective(m_fov, m_ratio, m_near, m_far);
+		m_near = near;
+		m_far = far;
+		setProjection(glm::perspective(fov, ratio, near, far));
     }
 
     glm::vec3 Camera::getFront() const {
@@ -85,22 +98,35 @@ namespace vkcv {
         direction.z = std::cos(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch));
         return glm::normalize(direction);
     }
+    
+    void Camera::setFront(const glm::vec3 &front) {
+		m_pitch = std::atan2(front.y, std::sqrt(front.x * front.x + front.z * front.z));
+		m_yaw = std::atan2(front.x, front.z);
+    }
 
-    glm::vec3 Camera::getPosition() const {
+    const glm::vec3& Camera::getPosition() const {
         return m_position;
     }
 
-    void Camera::setPosition( glm::vec3 position ){
-        m_position = position;
+    void Camera::setPosition( const glm::vec3& position ){
+		lookAt(position, m_center, m_up);
     }
 
-    glm::vec3 Camera::getCenter() const {
+    const glm::vec3& Camera::getCenter() const {
         return m_center;
     }
 
-    void Camera::setCenter(glm::vec3 center) {
-        m_center = center;
+    void Camera::setCenter(const glm::vec3& center) {
+		lookAt(m_position, center, m_up);
     }
+	
+	const glm::vec3& Camera::getUp() const {
+		return m_up;
+	}
+	
+	void Camera::setUp(const glm::vec3 &up) {
+		lookAt(m_position, m_center, up);
+	}
 
     float Camera::getPitch() const {
         return m_pitch;
@@ -118,12 +144,4 @@ namespace vkcv {
         m_yaw = yaw;
     }
 
-    glm::vec3 Camera::getUp() const {
-        return m_up;
-    }
-
-    void Camera::setUp(const glm::vec3 &up) {
-        m_up = up;
-    }
-
 }
\ No newline at end of file
diff --git a/modules/camera/src/vkcv/camera/CameraController.cpp b/modules/camera/src/vkcv/camera/CameraController.cpp
deleted file mode 100644
index 94f8d6ce..00000000
--- a/modules/camera/src/vkcv/camera/CameraController.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "vkcv/camera/CameraController.hpp"
-#include <iostream>
-
-namespace vkcv {
-    
-    void CameraController::updateCamera(double deltaTime, Camera &camera) {
-    }
-
-    void CameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {}
-
-    void CameraController::scrollCallback( double offsetX, double offsetY, Camera &camera) {}
-
-    void CameraController::mouseMoveCallback(double offsetX, double offsetY, Camera &camera) {}
-
-    void CameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) {}
-
-}
\ No newline at end of file
diff --git a/modules/camera/src/vkcv/camera/CameraManager.cpp b/modules/camera/src/vkcv/camera/CameraManager.cpp
index a8c01861..977c61d0 100644
--- a/modules/camera/src/vkcv/camera/CameraManager.cpp
+++ b/modules/camera/src/vkcv/camera/CameraManager.cpp
@@ -1,17 +1,17 @@
-#include <iostream>
-#include <string>
+
 #include "vkcv/camera/CameraManager.hpp"
 
-namespace vkcv{
+#include <vkcv/Logger.hpp>
+
+namespace vkcv::camera {
 
     CameraManager::CameraManager(Window &window, float width, float height)
     : m_window(window)
     {
         bindCameraToEvents();
         m_activeCameraIndex = 0;
-        m_lastX = window.getWidth() / 2.0f;
-        m_lastY = window.getHeight() / 2.0f;
-
+        m_lastX = static_cast<float>(window.getWidth()) / 2.0f;
+        m_lastY = static_cast<float>(window.getHeight()) / 2.0f;
     }
 
     CameraManager::~CameraManager() {}
@@ -37,7 +37,7 @@ namespace vkcv{
         else if(button == GLFW_MOUSE_BUTTON_2 && action == GLFW_RELEASE){
             glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
         }
-        getControllerByType(getControllerType(getActiveCameraIndex())).mouseButtonCallback(button, action, mods, getActiveCamera());
+		getActiveController().mouseButtonCallback(button, action, mods, getActiveCamera());
     }
 
     void CameraManager::mouseMoveCallback(double x, double y){
@@ -45,11 +45,11 @@ namespace vkcv{
 		auto yoffset = static_cast<float>(y - m_lastY);
         m_lastX = x;
         m_lastY = y;
-        getControllerByType(getControllerType(getActiveCameraIndex())).mouseMoveCallback(xoffset, yoffset, getActiveCamera());
+		getActiveController().mouseMoveCallback(xoffset, yoffset, getActiveCamera());
     }
 
     void CameraManager::scrollCallback(double offsetX, double offsetY) {
-        getControllerByType(getControllerType(getActiveCameraIndex())).scrollCallback(offsetX, offsetY, getActiveCamera());
+		getActiveController().scrollCallback(offsetX, offsetY, getActiveCamera());
     }
 
     void CameraManager::keyCallback(int key, int scancode, int action, int mods)  {
@@ -67,33 +67,39 @@ namespace vkcv{
                     case GLFW_KEY_ESCAPE:
                         glfwSetWindowShouldClose(m_window.getWindow(), 1);
                         return;
+					default:
+						break;
                 }
             default:
-                getControllerByType(getControllerType(getActiveCameraIndex())).keyCallback(key, scancode, action, mods, getActiveCamera());
+				getActiveController().keyCallback(key, scancode, action, mods, getActiveCamera());
+                break;
         }
     }
-
-    int CameraManager::addCamera() {
-        Camera camera;
-        m_cameras.push_back(camera);
-        m_cameras.back().setPerspective(glm::radians(60.0f), m_window.getWidth() / m_window.getHeight(), 0.1f, 10.0f);
-        m_cameraControllerTypes.push_back(ControllerType::NONE);
-        return m_cameras.size() - 1;
+    
+    CameraController& CameraManager::getActiveController() {
+    	const ControllerType type = getControllerType(getActiveCameraIndex());
+    	return getControllerByType(type);
     }
-
-    int CameraManager::addCamera(ControllerType controllerType) {
+	
+	uint32_t CameraManager::addCamera(ControllerType controllerType) {
         Camera camera;
-        m_cameras.push_back(camera);
-        m_cameras.back().setPerspective(glm::radians(60.0f), m_window.getWidth() / m_window.getHeight(), 0.1f, 10.0f);
-        m_cameraControllerTypes.push_back(controllerType);
-        return m_cameras.size() - 1;
+        camera.setPerspective(glm::radians(60.0f), m_window.getWidth() / m_window.getHeight(), 0.1f, 10.0f);
+        return addCamera(controllerType, camera);
+    }
+    
+    uint32_t CameraManager::addCamera(ControllerType controllerType, const Camera &camera) {
+    	const uint32_t index = static_cast<uint32_t>(m_cameras.size());
+    	m_cameras.push_back(camera);
+		m_cameraControllerTypes.push_back(controllerType);
+		return index;
     }
 
     Camera& CameraManager::getCamera(uint32_t cameraIndex) {
         if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
-            throw std::runtime_error("Invalid camera index. The index must range from 0 to " +
-                std::to_string(m_cameras.size()) + ".");
+        	vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
+        	return getActiveCamera();
         }
+        
         return m_cameras[cameraIndex];
     }
 
@@ -103,29 +109,32 @@ namespace vkcv{
 
     void CameraManager::setActiveCamera(uint32_t cameraIndex) {
         if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
-            throw std::runtime_error("Invalid camera index. The index must range from 0 to " +
-                std::to_string(m_cameras.size()) + ".");
+			vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
+			return;
         }
+        
         m_activeCameraIndex = cameraIndex;
     }
 
-    uint32_t CameraManager::getActiveCameraIndex() {
+    uint32_t CameraManager::getActiveCameraIndex() const {
         return m_activeCameraIndex;
     }
 
     void CameraManager::setControllerType(uint32_t cameraIndex, ControllerType controllerType) {
         if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
-            throw std::runtime_error("Invalid camera index. The index must range from 0 to " +
-                std::to_string(m_cameras.size()) + ".");
+			vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
+			return;
         }
+        
         m_cameraControllerTypes[cameraIndex] = controllerType;
     }
 
     ControllerType CameraManager::getControllerType(uint32_t cameraIndex) {
         if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
-            throw std::runtime_error("Invalid camera index. The index must range from 0 to " +
-                std::to_string(m_cameras.size()) + ".");
+			vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
+			return ControllerType::NONE;
         }
+        
         return m_cameraControllerTypes[cameraIndex];
     }
 
@@ -141,6 +150,7 @@ namespace vkcv{
     }
 
     void CameraManager::update(double deltaTime) {
-            getControllerByType(getControllerType(getActiveCameraIndex())).updateCamera(deltaTime, getActiveCamera());
-        }
+		getActiveController().updateCamera(deltaTime, getActiveCamera());
+	}
+	
 }
\ No newline at end of file
diff --git a/modules/camera/src/vkcv/camera/PilotCameraController.cpp b/modules/camera/src/vkcv/camera/PilotCameraController.cpp
index 3ac327f2..1a50a0ef 100644
--- a/modules/camera/src/vkcv/camera/PilotCameraController.cpp
+++ b/modules/camera/src/vkcv/camera/PilotCameraController.cpp
@@ -2,7 +2,7 @@
 
 #include <GLFW/glfw3.h>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     PilotCameraController::PilotCameraController() {
         m_forward = false;
@@ -56,32 +56,25 @@ namespace vkcv {
         }
         camera.setPitch(pitch);
     }
-
-    glm::mat4 PilotCameraController::updateView(double deltaTime, Camera &camera){
-        updatePosition(deltaTime, camera);
-        glm::vec3 position = camera.getPosition();
-        glm::vec3 front = camera.getFront();
-        glm::vec3 up = camera.getUp();
-        camera.lookAt(position, position + front, up);
-        return camera.getView();
-    }
-
-    glm::vec3 PilotCameraController::updatePosition(double deltaTime, Camera &camera){
-        glm::vec3 position = camera.getPosition();
-        glm::vec3 front = camera.getFront();
-        glm::vec3 up = camera.getUp();
-        position += (m_cameraSpeed * front * static_cast<float> (m_forward) * static_cast<float>(deltaTime));
-        position -= (m_cameraSpeed * front * static_cast<float> (m_backward) * static_cast<float>(deltaTime));
-        position += (glm::normalize(glm::cross(front, up)) * m_cameraSpeed * static_cast<float> (m_left) * static_cast<float>(deltaTime));
-        position -= (glm::normalize(glm::cross(front, up)) * m_cameraSpeed * static_cast<float> (m_right) * static_cast<float>(deltaTime));
-        position += up * m_cameraSpeed * static_cast<float> (m_upward) * static_cast<float>(deltaTime);
-        position -= up * m_cameraSpeed * static_cast<float> (m_downward) * static_cast<float>(deltaTime);
-        camera.setPosition(position);
-        return position;
+    
+    constexpr float getDirectionFactor(bool positive, bool negative) {
+    	return static_cast<float>(positive) - static_cast<float>(negative);
     }
 
     void PilotCameraController::updateCamera(double deltaTime, Camera &camera) {
-        updateView(deltaTime, camera);
+		glm::vec3 position = camera.getPosition();
+	
+		const glm::vec3 front = camera.getFront();
+		const glm::vec3 up = camera.getUp();
+		const glm::vec3 left = glm::normalize(glm::cross(front, up));
+	
+		const float distance = m_cameraSpeed * static_cast<float>(deltaTime);
+	
+		position += distance * getDirectionFactor(m_forward, m_backward) * front;
+		position += distance * getDirectionFactor(m_left, m_right) * left;
+		position += distance * getDirectionFactor(m_upward, m_downward) * up;
+	
+		camera.lookAt(position, position + front, up);
     }
 
     void PilotCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {
diff --git a/modules/camera/src/vkcv/camera/TrackballCameraController.cpp b/modules/camera/src/vkcv/camera/TrackballCameraController.cpp
index a9c83d08..9498317f 100644
--- a/modules/camera/src/vkcv/camera/TrackballCameraController.cpp
+++ b/modules/camera/src/vkcv/camera/TrackballCameraController.cpp
@@ -2,7 +2,7 @@
 
 #include <GLFW/glfw3.h>
 
-namespace vkcv {
+namespace vkcv::camera {
 
     TrackballCameraController::TrackballCameraController() {
         m_rotationActive = false;
@@ -42,33 +42,6 @@ namespace vkcv {
         camera.setPitch(pitch);
     }
 
-    glm::vec3 TrackballCameraController::updatePosition(Camera &camera) {
-        float yaw = camera.getYaw();
-        float pitch = camera.getPitch();
-        glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
-        glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
-
-        glm::mat4 rotationY = glm::rotate(glm::mat4(1.0f), glm::radians(yaw), yAxis);
-        glm::mat4 rotationX = glm::rotate(rotationY, glm::radians(pitch), xAxis);
-        glm::vec3 translate = glm::vec3(0.0f, 0.0f, m_radius);
-        translate = glm::vec3(rotationX * glm::vec4(translate, 0.0f));
-        glm::vec3 center = camera.getCenter();
-        glm::vec3 position = center + translate;
-        camera.setPosition(position);
-        glm::vec3 up = glm::vec3(rotationX * glm::vec4(glm::vec3(0.0f, 1.0f, 0.0f), 0.0f));
-        camera.setUp(up);
-        return position;
-    }
-
-    glm::mat4 TrackballCameraController::updateView(Camera &camera) {
-        updatePosition(camera);
-        glm::vec3 position = camera.getPosition();
-        glm::vec3 center = camera.getCenter();
-        glm::vec3 up = camera.getUp();
-        camera.lookAt(position, center, up);
-        return camera.getView();
-    }
-
     void TrackballCameraController::updateRadius(double offset, Camera &camera) {
         glm::vec3 cameraPosition = camera.getPosition();
         glm::vec3 cameraCenter = camera.getCenter();
@@ -77,7 +50,25 @@ namespace vkcv {
     }
 
     void TrackballCameraController::updateCamera(double deltaTime, Camera &camera) {
-        updateView(camera);
+		float yaw = camera.getYaw();
+		float pitch = camera.getPitch();
+		
+		const glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
+		const glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
+	
+		const glm::mat4 rotationY = glm::rotate(glm::mat4(1.0f), glm::radians(yaw), yAxis);
+		const glm::mat4 rotationX = glm::rotate(rotationY, glm::radians(pitch), xAxis);
+		const glm::vec3 translation = glm::vec3(
+				rotationX * glm::vec4(0.0f, 0.0f, m_radius, 0.0f)
+		);
+		
+		const glm::vec3 center = camera.getCenter();
+		const glm::vec3 position = center + translation;
+		const glm::vec3 up = glm::vec3(
+				rotationX * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)
+		);
+		
+		camera.lookAt(position, center, up);
     }
 
     void TrackballCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {}
diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp
index cf804437..a02c4542 100644
--- a/projects/cmd_sync_test/src/main.cpp
+++ b/projects/cmd_sync_test/src/main.cpp
@@ -18,9 +18,15 @@ int main(int argc, const char** argv) {
 		true
 	);
 
-    vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
-    uint32_t camIndex = cameraManager.addCamera(vkcv::ControllerType::PILOT);
-    uint32_t camIndex2 = cameraManager.addCamera(vkcv::ControllerType::TRACKBALL);
+    vkcv::camera::CameraManager cameraManager(window, windowWidth, windowHeight);
+    uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
+    uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+    
+    cameraManager.getCamera(camIndex).setPosition(glm::vec3(0.f, 0.f, 3.f));
+    cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f);
+	cameraManager.getCamera(camIndex).setYaw(180.0f);
+	
+	cameraManager.getCamera(camIndex2).setNearFar(0.1f, 30.0f);
 
 	window.initEvents();
 
@@ -233,11 +239,13 @@ int main(int argc, const char** argv) {
 		
 		auto end = std::chrono::system_clock::now();
 		auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
+		
 		start = end;
-		cameraManager.update(std::chrono::duration<double>(deltatime).count());
+		cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
 
-
-		const float sunTheta = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime).count() * 0.001f;
+		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime);
+		
+		const float sunTheta = 0.001f * static_cast<float>(duration.count());
 		lightInfo.direction = glm::normalize(glm::vec3(std::cos(sunTheta), 1, std::sin(sunTheta)));
 
 		const float shadowProjectionSize = 5.f;
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 5af9438f..42b1f595 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -146,9 +146,11 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetUsage    descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
 	vkcv::DrawcallInfo          drawcall(renderMesh, { descriptorUsage });
 
-    vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
-    uint32_t camIndex0 = cameraManager.addCamera(vkcv::ControllerType::PILOT);
-	uint32_t camIndex1 = cameraManager.addCamera(vkcv::ControllerType::TRACKBALL);
+    vkcv::camera::CameraManager cameraManager(window, windowWidth, windowHeight);
+    uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
+	uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+	
+	cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3));
 
     auto start = std::chrono::system_clock::now();
     
@@ -171,9 +173,10 @@ int main(int argc, const char** argv) {
 		}
   
 		auto end = std::chrono::system_clock::now();
-		auto deltatime = end - start;
+		auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
+		
 		start = end;
-		cameraManager.update(std::chrono::duration<double>(deltatime).count());
+		cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
         glm::mat4 mvp = cameraManager.getActiveCamera().getMVP();
 
 		vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4));
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 3e985940..8ecea2b6 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -159,9 +159,11 @@ int main(int argc, const char** argv) {
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 	
-    vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
-    uint32_t camIndex = cameraManager.addCamera(vkcv::ControllerType::PILOT);
-    uint32_t camIndex2 = cameraManager.addCamera(vkcv::ControllerType::TRACKBALL);
+    vkcv::camera::CameraManager cameraManager(window, windowWidth, windowHeight);
+    uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
+    uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+	
+	cameraManager.getCamera(camIndex).setPosition(glm::vec3(0, 0, -2));
 
 	while (window.isWindowOpen())
 	{
@@ -173,9 +175,10 @@ int main(int argc, const char** argv) {
 		}
 		
         auto end = std::chrono::system_clock::now();
-        auto deltatime = end - start;
+        auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
         start = end;
-		cameraManager.update(std::chrono::duration<double>(deltatime).count());
+		
+		cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
         glm::mat4 mvp = cameraManager.getActiveCamera().getMVP();
 
 		vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4));
-- 
GitLab