TDME2 1.9.121
CameraInputHandler.cpp
Go to the documentation of this file.
2
3#include <tdme/tdme.h>
10#include <tdme/gui/GUI.h>
12#include <tdme/math/Vector3.h>
15
22using tdme::gui::GUI;
28
29CameraInputHandler::CameraInputHandler(Engine* engine, CameraInputHandlerEventHandler* eventHandler):
30 camLookRotationX(Vector3(1.0f, 0.0f, 0.0f), -45.0f),
31 camLookRotationY(Vector3(0.0f, 1.0f, 0.0f), 0.0f)
32{
33 this->engine = engine;
34 this->eventHandler = eventHandler;
35 reset();
36}
37
39}
40
41
43 resetRequested = true;
48 camScale = 1.0f;
49}
50
52 for (auto i = 0; i < engine->getGUI()->getKeyboardEvents().size(); i++) {
53 auto& event = engine->getGUI()->getKeyboardEvents()[i];
54 if (event.isProcessed() == true) continue;
55 if (event.getType() == GUIKeyboardEvent::KEYBOARDEVENT_KEY_TYPED) continue;
56 auto isKeyDown = event.getType() == GUIKeyboardEvent::KEYBOARDEVENT_KEY_PRESSED;
57
58 //
59 if (event.getKeyCode() == GUIKeyboardEvent::KEYCODE_LEFT) {
60 keyLeft = isKeyDown;
61 event.setProcessed(true);
62 }
63 if (event.getKeyCode() == GUIKeyboardEvent::KEYCODE_RIGHT) {
64 keyRight = isKeyDown;
65 event.setProcessed(true);
66 }
67 if (event.getKeyCode() == GUIKeyboardEvent::KEYCODE_UP) {
68 keyUp = isKeyDown;
69 event.setProcessed(true);
70 }
71 if (event.getKeyCode() == GUIKeyboardEvent::KEYCODE_DOWN) {
72 keyDown = isKeyDown;
73 event.setProcessed(true);
74 }
75 if (Character::toLowerCase(event.getKeyChar()) == 'a') {
76 keyA = isKeyDown;
77 event.setProcessed(true);
78 }
79 if (Character::toLowerCase(event.getKeyChar()) == 'd') {
80 keyD = isKeyDown;
81 event.setProcessed(true);
82 }
83 if (Character::toLowerCase(event.getKeyChar()) == 'w') {
84 keyW = isKeyDown;
85 event.setProcessed(true);
86 }
87 if (Character::toLowerCase(event.getKeyChar()) == 's') {
88 keyS = isKeyDown;
89 event.setProcessed(true);
90 }
91 if (Character::toLowerCase(event.getKeyChar()) == '+') {
92 keyPlus = isKeyDown;
93 event.setProcessed(true);
94 }
95 if (Character::toLowerCase(event.getKeyChar()) == '-') {
96 keyMinus = isKeyDown;
97 event.setProcessed(true);
98 }
99 if (Character::toLowerCase(event.getKeyChar()) == 'r') {
100 keyR = isKeyDown;
101 event.setProcessed(true);
102 }
103 }
104
105 auto mousePanningSide = MOUSE_PANNING_NONE;
106 auto mousePanningForward = MOUSE_PANNING_NONE;
107 for (auto i = 0; i < engine->getGUI()->getMouseEvents().size(); i++) {
108 auto& event = engine->getGUI()->getMouseEvents()[i];
109
110 if (event.isProcessed() == true) continue;
111
112 if (event.getType() == GUIMouseEvent::MOUSEEVENT_DRAGGED) {
113 if (mouseDragging == false) {
114 mouseDragging = true;
115 mouseDownLastX = event.getXUnscaled();
116 mouseDownLastY = event.getYUnscaled();
117 event.setProcessed(true);
118 }
119 } else {
120 if (mouseDragging == true) {
123 mouseDragging = false;
124 event.setProcessed(true);
125 }
126 }
127 if (event.getButton() == MOUSE_BUTTON_RIGHT && mouseDragging == true) {
129 mousePanningSide = event.getXUnscaled() - mouseDownLastX;
130 mousePanningForward = event.getYUnscaled() - mouseDownLastY;
131 }
132 event.setProcessed(true);
133 } else
134 if (event.getButton() == MOUSE_BUTTON_MIDDLE && mouseDragging == true) {
136 mouseRotationX = event.getXUnscaled() - mouseDownLastX;
137 mouseRotationY = event.getYUnscaled() - mouseDownLastY;
138 }
139 event.setProcessed(true);
140 }
141 if (event.getButton() != MOUSE_BUTTON_NONE) {
142 if (event.getType() == GUIMouseEvent::MOUSEEVENT_RELEASED) {
145 } else {
146 mouseDownLastX = event.getXUnscaled();
147 mouseDownLastY = event.getYUnscaled();
148 }
149 event.setProcessed(true);
150 }
151 auto mouseWheel = event.getWheelY();
152 if (mouseWheel != 0) {
153 camScale += -mouseWheel * 0.1f;
156 event.setProcessed(true);
157 }
158 }
159
160 //
161 auto cam = engine->getCamera();
165 mouseRotationX = 0;
166 if (eventHandler != nullptr) eventHandler->onCameraRotation();
167 }
171 mouseRotationY = 0;
172 if (eventHandler != nullptr) eventHandler->onCameraRotation();
173 }
178 if (keyMinus == true || keyPlus == true) {
179 if (keyMinus == true) camScale += 0.05f;
180 if (keyPlus == true) camScale -= 0.05f;
183 if (eventHandler != nullptr) eventHandler->onCameraScale();
184 }
185
186 if (keyR == true || resetRequested == true) {
191 cam->setLookAt(sceneCenter);
192 camScale = 1.0f;
194 resetRequested = false;
195 keyR = false;
196 }
197 if (keyA == true|| keyD == true) {
200 }
201
202 if (keyW == true || keyS == true) {
203 if (camLookRotationX.getAngle() > 89.99f) camLookRotationX.setAngle(89.99f);
204 if (camLookRotationX.getAngle() < -89.99f) camLookRotationX.setAngle(-89.99f);
207 }
208
209 //
210 if (engine->getTiming()->getDeltaTime() <= 0LL) return;
211
212 //
213 Vector3 forwardVector(0.0f, 0.0f, 1.0f);
214 Vector3 sideVector(1.0f, 0.0f, 0.0f);
215 auto forwardVectorTransformed = camLookRotationX.getQuaternion().multiply(forwardVector);
216 forwardVectorTransformed = camLookRotationY.getQuaternion().multiply(forwardVectorTransformed);
217 auto camLookAtToFromVector = forwardVectorTransformed.clone().scale(camScale * 10.0f);
218 auto camForwardVector = camLookRotationY.getQuaternion().multiply(forwardVector).scale(engine->getTiming()->getDeltaTime() * 60.0f / 1000.0f);
219 auto camSideVector = camLookRotationY.getQuaternion().multiply(sideVector).scale(engine->getTiming()->getDeltaTime() * 60.0f / 1000.0f);
220
221 auto camLookAt = cam->getLookAt();
222 if (keyUp == true) camLookAt.sub(forwardVectorTransformed.set(camForwardVector).scale(0.1f));
223 if (keyDown == true) camLookAt.add(forwardVectorTransformed.set(camForwardVector).scale(0.1f));
224 if (keyLeft == true) camLookAt.sub(forwardVectorTransformed.set(camSideVector).scale(0.1f));
225 if (keyRight == true) camLookAt.add(forwardVectorTransformed.set(camSideVector).scale(0.1f));
226 if (mousePanningForward != MOUSE_PANNING_NONE) {
227 camLookAt.sub(forwardVectorTransformed.set(camForwardVector).scale(mousePanningForward / 15.0f));
228 mousePanningForward = MOUSE_PANNING_NONE;
230 }
231 if (mousePanningSide != MOUSE_PANNING_NONE) {
232 camLookAt.sub(forwardVectorTransformed.set(camSideVector).scale(mousePanningSide / 15.0f));
233 mousePanningSide = MOUSE_PANNING_NONE;
235 }
236 cam->setLookAt(camLookAt);
237 cam->setLookFrom(cam->getLookAt().clone().add(camLookAtToFromVector));
238 cam->setUpVector(cam->computeUpVector(cam->getLookFrom(), cam->getLookAt()));
239}
#define MOUSE_BUTTON_NONE
#define MOUSE_BUTTON_MIDDLE
#define MOUSE_BUTTON_RIGHT
Engine main class.
Definition: Engine.h:122
Timing * getTiming()
Definition: Engine.h:900
Camera * getCamera()
Definition: Engine.h:907
Rotation representation.
Definition: Rotation.h:18
void setAngle(const float angle)
Definition: Rotation.h:63
const Quaternion & getQuaternion() const
Definition: Rotation.h:85
void update()
Computes rotation matrix.
Definition: Rotation.cpp:54
const float getAngle() const
Definition: Rotation.h:56
Timing class.
Definition: Timing.h:17
int64_t getDeltaTime()
Gets the time passed between last and current frame.
Definition: Timing.h:83
GUI module class.
Definition: GUI.h:66
vector< GUIMouseEvent > & getMouseEvents()
Definition: GUI.h:212
vector< GUIKeyboardEvent > & getKeyboardEvents()
Definition: GUI.h:219
Quaternion class.
Definition: Quaternion.h:22
Quaternion & multiply(const Quaternion q)
Multiplies this quaternion with quaternion q.
Definition: Quaternion.h:227
Quaternion clone() const
Clones the quaternion.
Definition: Quaternion.h:477
Quaternion & scale(float value)
Scales this quaternion with given value.
Definition: Quaternion.h:268
Quaternion & sub(const Quaternion &q)
Subtracts given quaternion q from this quaternion.
Definition: Quaternion.h:255
Quaternion & add(const Quaternion &q)
Adds given quaternion q to this quaternion.
Definition: Quaternion.h:242
3D vector 3 class
Definition: Vector3.h:22
void handleInputEvents() override
Handle input events that have not yet been processed.
CameraInputHandlerEventHandler * eventHandler
Character class.
Definition: Character.h:15
virtual void onCameraRotation()=0
On rotation event to be overloaded.
virtual void onCameraTranslation()=0
On translation event to be overloaded.
virtual void onCameraScale()=0
On scale event to be overloaded.