1+ #pragma once
2+
3+ #include " StratusCommon.h"
4+ #include " glm/glm.hpp"
5+ #include " StratusWindow.h"
6+ #include " StratusRendererFrontend.h"
7+ #include " StratusLog.h"
8+ #include " StratusCamera.h"
9+ #include " StratusLight.h"
10+
11+ struct CameraController : public stratus ::InputHandler {
12+ CameraController () {
13+ _camera = stratus::CameraPtr (new stratus::Camera ());
14+ stratus::RendererFrontend::Instance ()->SetCamera (_camera);
15+
16+ _cameraLight = stratus::LightPtr (new stratus::PointLight (/* staticLight = */ false ));
17+ _cameraLight->setCastsShadows (false );
18+ _cameraLight->setIntensity (600 .0f );
19+
20+ if (_cameraLightEnabled) {
21+ stratus::RendererFrontend::Instance ()->AddLight (_cameraLight);
22+ }
23+ }
24+
25+ // This class is deleted when the Window is deleted so the Renderer has likely already
26+ // been taken offline. The check is for if the camera controller is removed while the engine
27+ // is still running.
28+ virtual ~CameraController () {
29+ INSTANCE (RendererFrontend)->SetCamera (nullptr );
30+
31+ if (_cameraLightEnabled) {
32+ INSTANCE (RendererFrontend)->RemoveLight (_cameraLight);
33+ }
34+ }
35+
36+ void HandleInput (const stratus::MouseState& mouse, const std::vector<SDL_Event>& input, const double deltaSeconds) {
37+ const float camSpeed = 100 .0f ;
38+
39+ // Handle WASD movement
40+ for (auto e : input) {
41+ switch (e.type ) {
42+ case SDL_MOUSEMOTION:
43+ _camera->modifyAngle (stratus::Degrees (0 .0f ), stratus::Degrees (-e.motion .xrel ), stratus::Degrees (0 .0f ));
44+ // STRATUS_LOG << camera.getRotation() << std::endl;
45+ break ;
46+ case SDL_KEYDOWN:
47+ case SDL_KEYUP: {
48+ bool released = e.type == SDL_KEYUP;
49+ SDL_Scancode key = e.key .keysym .scancode ;
50+ switch (key) {
51+ case SDL_SCANCODE_SPACE:
52+ if (!released) {
53+ _camSpeedDivide = 1 .0f ;
54+ }
55+ else {
56+ _camSpeedDivide = 0 .25f ;
57+ }
58+ break ;
59+ case SDL_SCANCODE_W:
60+ case SDL_SCANCODE_S:
61+ if (!released) {
62+ _cameraSpeed.x = key == SDL_SCANCODE_W ? camSpeed : -camSpeed;
63+ } else {
64+ _cameraSpeed.x = 0 .0f ;
65+ }
66+ break ;
67+ case SDL_SCANCODE_A:
68+ case SDL_SCANCODE_D:
69+ if (!released) {
70+ _cameraSpeed.y = key == SDL_SCANCODE_D ? camSpeed : -camSpeed;
71+ } else {
72+ _cameraSpeed.y = 0 .0f ;
73+ }
74+ break ;
75+ // Adds or removes the light following the camera
76+ case SDL_SCANCODE_F:
77+ if (released) {
78+ _cameraLightEnabled = !_cameraLightEnabled;
79+
80+ if (_cameraLightEnabled) {
81+ stratus::RendererFrontend::Instance ()->AddLight (_cameraLight);
82+ }
83+ else {
84+ stratus::RendererFrontend::Instance ()->RemoveLight (_cameraLight);
85+ }
86+ }
87+
88+ break ;
89+ }
90+ }
91+ }
92+ }
93+
94+ // Check mouse state for move up/down
95+ uint32_t buttonState = mouse.mask ;
96+ _cameraSpeed.z = 0 .0f ;
97+ if ((buttonState & SDL_BUTTON_LMASK) != 0 ) { // left mouse button
98+ _cameraSpeed.z = -camSpeed;
99+ }
100+ else if ((buttonState & SDL_BUTTON_RMASK) != 0 ) { // right mouse button
101+ _cameraSpeed.z = camSpeed;
102+ }
103+
104+ // Final camera speed update
105+ glm::vec3 tmpCamSpeed = _cameraSpeed * _camSpeedDivide;
106+ _camera->setSpeed (tmpCamSpeed.y , tmpCamSpeed.z , tmpCamSpeed.x );
107+
108+ _cameraLight->SetPosition (_camera->getPosition ());
109+ }
110+
111+ private:
112+ stratus::CameraPtr _camera;
113+ stratus::LightPtr _cameraLight;
114+ bool _cameraLightEnabled = true ;
115+ glm::vec3 _cameraSpeed = glm::vec3(0 .0f );
116+ float _camSpeedDivide = 0 .25f ; // For slowing camera down
117+ };
0 commit comments