aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Camera.h
blob: 7fe3bd91310b33af9c4422a3a852c3d4eb48e047 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#pragma once

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GLFW/glfw3.h>

#define _USE_MATH_DEFINES
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

namespace Donut
{
    enum class CameraMode
    {
        FPS,
        Orbital
    };

    class Camera
    {
    public:
        Camera(float fov = 45.0f, float aspectRatio = 16.0f / 9.0f, 
               float nearPlane = 0.1f, float farPlane = 100.0f);
        ~Camera() = default;

        // FPS Camera Methods
        void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); }
        void SetRotation(const glm::vec3& rotation) { m_Rotation = rotation; RecalculateViewMatrix(); }
        
        const glm::vec3& GetPosition() const { return m_Position; }
        const glm::vec3& GetRotation() const { return m_Rotation; }
        
        glm::vec3 GetForwardDirection() const;
        glm::vec3 GetRightDirection()   const;
        glm::vec3 GetUpDirection()      const;

        const glm::mat4& GetProjectionMatrix()     const { return m_ProjectionMatrix; }
        const glm::mat4& GetViewMatrix()           const { return m_ViewMatrix; }
        const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; }

        void SetProjection(float fov, float aspectRatio, float nearPlane, float farPlane);
        void OnMouseMove(float xOffset, float yOffset, bool constrainPitch = true);
        
        void MoveForward(float deltaTime);
        void MoveBackward(float deltaTime);
        void MoveRight(float deltaTime);
        void MoveLeft(float deltaTime);
        void MoveUp(float deltaTime);
        void MoveDown(float deltaTime);

        void SetMouseSensitivity(float sensitivity) { m_MouseSensitivity = sensitivity; }
        float GetMouseSensitivity() const  { return m_MouseSensitivity; }

        void SetMovementSpeed(float speed) { m_MovementSpeed = speed;   }
        float GetMovementSpeed()    const  { return m_MovementSpeed;    }

        // Orbital Camera Methods
        void SetOrbitalMode(bool enabled);
        bool IsOrbitalMode() const { return m_CameraMode == CameraMode::Orbital; }
        
        void SetTarget(const glm::vec3& target) { m_Target = target; }
        const glm::vec3& GetTarget() const { return m_Target; }
        
        void SetRadius(double radius) { m_Radius = radius; }
        double GetRadius() const { return m_Radius; }
        
        void SetMinRadius(double minRadius) { m_MinRadius = minRadius; }
        double GetMinRadius() const { return m_MinRadius; }
        
        void SetMaxRadius(double maxRadius) { m_MaxRadius = maxRadius; }
        double GetMaxRadius() const { return m_MaxRadius; }
        
        void SetAzimuth(float azimuth) { m_Azimuth = azimuth; }
        float GetAzimuth() const { return m_Azimuth; }
        
        void SetElevation(float elevation) { m_Elevation = elevation; }
        float GetElevation() const { return m_Elevation; }
        
        void SetOrbitSpeed(float orbitSpeed) { m_OrbitSpeed = orbitSpeed; }
        float GetOrbitSpeed() const { return m_OrbitSpeed; }
        
        void SetZoomSpeed(double zoomSpeed) { m_ZoomSpeed = zoomSpeed; }
        double GetZoomSpeed() const { return m_ZoomSpeed; }
        
        // Orbital camera position calculation
        glm::vec3 GetOrbitalPosition() const;
        
        // Input handling for orbital camera
        void ProcessOrbitalMouseMove(double x, double y);
        void ProcessOrbitalMouseButton(int button, int action, int mods);
        void ProcessOrbitalScroll(double xoffset, double yoffset);
        
        // State management
        bool IsDragging() const { return m_Dragging; }
        bool IsPanning() const { return m_Panning; }
        bool IsMoving() const { return m_Moving; }

    private:
        void RecalculateViewMatrix();
        void RecalculateProjectionMatrix();
        void UpdateOrbitalState();

    private:
        // Camera mode
        CameraMode m_CameraMode = CameraMode::FPS;

        // FPS Camera members
        glm::mat4 m_ProjectionMatrix;
        glm::mat4 m_ViewMatrix;
        glm::mat4 m_ViewProjectionMatrix;

        glm::vec3 m_Position = { 0.0f, 0.0f, 3.0f };
        glm::vec3 m_Rotation = { 0.0f, 0.0f, 0.0f };

        float m_FOV         = 45.0f;
        float m_AspectRatio = 16.0f / 9.0f;
        float m_NearPlane   = 0.1f;
        float m_FarPlane    = 100.0f;

        float m_MouseSensitivity = 0.1f;
        float m_MovementSpeed    = 5.0f;
        bool  m_FirstMouse       = true;
        float m_LastX            = 0.0f;
        float m_LastY            = 0.0f;

        // Orbital Camera members
        glm::vec3 m_Target = glm::vec3(0.0f, 0.0f, 0.0f);
        double m_Radius = 6.34194e10;
        double m_MinRadius = 1e10;
        double m_MaxRadius = 1e12;
        float m_Azimuth = 0.0f;
        float m_Elevation = static_cast<float>(M_PI) / 2.0f;
        float m_OrbitSpeed = 0.01f;
        double m_ZoomSpeed = 25e9f;
        bool m_Dragging = false;
        bool m_Panning = false;
        bool m_Moving = false;
        double m_OrbitalLastX = 0.0;
        double m_OrbitalLastY = 0.0;
    };
}