Browse Source

Fixed Camera Z rotation bug

Thomas Buck 10 years ago
parent
commit
b4360d62d2
3 changed files with 41 additions and 30 deletions
  1. 2
    0
      ChangeLog.md
  2. 3
    4
      include/Camera.h
  3. 36
    26
      src/Camera.cpp

+ 2
- 0
ChangeLog.md View File

5
     [ 20140108 ]
5
     [ 20140108 ]
6
     * FPS and Camera position now displayed in imgui Overlay
6
     * FPS and Camera position now displayed in imgui Overlay
7
     * Removed many unnecessary includes
7
     * Removed many unnecessary includes
8
+    * Camera now using combination of quaternion and X/Y angle.
9
+        * Fixes strange bug that sometimes rotated Camera on Z Axis.
8
 
10
 
9
     [ 20140107 ]
11
     [ 20140107 ]
10
     * Fixed problems with FontTTFs Glyph Baseline
12
     * Fixed problems with FontTTFs Glyph Baseline

+ 3
- 4
include/Camera.h View File

8
 #ifndef _CAMERA_H_
8
 #ifndef _CAMERA_H_
9
 #define _CAMERA_H_
9
 #define _CAMERA_H_
10
 
10
 
11
-#include <glm/gtc/quaternion.hpp>
12
 #include <glm/gtc/type_precision.hpp>
11
 #include <glm/gtc/type_precision.hpp>
13
 
12
 
14
 #include "RoomData.h"
13
 #include "RoomData.h"
26
 
25
 
27
     //! \fixme The Y axis seems to be the source of all evil?
26
     //! \fixme The Y axis seems to be the source of all evil?
28
     static void setPosition(glm::vec3 p) { pos = glm::vec3(p.x, -p.y, p.z); }
27
     static void setPosition(glm::vec3 p) { pos = glm::vec3(p.x, -p.y, p.z); }
29
-    static glm::vec3 getPosition() { return glm::vec3(pos.x, -pos.y, pos.z); }
28
+    static glm::vec3 getPosition() { return pos; }
30
 
29
 
31
-    static glm::vec2 getRotation();
30
+    static glm::vec2 getRotation() { return rot; }
32
     static glm::mat4 getProjectionMatrix() { return projection; }
31
     static glm::mat4 getProjectionMatrix() { return projection; }
33
     static glm::mat4 getViewMatrix() { return view; }
32
     static glm::mat4 getViewMatrix() { return view; }
34
 
33
 
48
     static void calculateFrustumPlanes();
47
     static void calculateFrustumPlanes();
49
 
48
 
50
     static glm::vec3 pos;
49
     static glm::vec3 pos;
51
-    static glm::quat quaternion;
50
+    static glm::vec2 rot;
52
     static glm::vec3 posSpeed;
51
     static glm::vec3 posSpeed;
53
     static glm::vec2 rotSpeed;
52
     static glm::vec2 rotSpeed;
54
     static glm::mat4 projection;
53
     static glm::mat4 projection;

+ 36
- 26
src/Camera.cpp View File

16
 
16
 
17
 #include <glm/gtc/epsilon.hpp>
17
 #include <glm/gtc/epsilon.hpp>
18
 #include <glm/gtc/matrix_transform.hpp>
18
 #include <glm/gtc/matrix_transform.hpp>
19
+#include <glm/gtc/quaternion.hpp>
19
 #include <glm/gtx/quaternion.hpp>
20
 #include <glm/gtx/quaternion.hpp>
20
 
21
 
21
 static bool equal(float a, float b) {
22
 static bool equal(float a, float b) {
36
 const static float nearDist = 0.1f;
37
 const static float nearDist = 0.1f;
37
 const static float farDist = 75000.0f;
38
 const static float farDist = 75000.0f;
38
 const static float maxSpeed = 2048.0f;
39
 const static float maxSpeed = 2048.0f;
39
-const static float controllerViewFactor = 384.0f;
40
+const static float controllerViewFactor = glm::pi<float>();
40
 const static float controllerDeadZone = 0.1f;
41
 const static float controllerDeadZone = 0.1f;
41
 
42
 
42
 const static glm::vec3 rightUnit(1.0f, 0.0f, 0.0f);
43
 const static glm::vec3 rightUnit(1.0f, 0.0f, 0.0f);
44
 const static glm::vec3 dirUnit(0.0f, 0.0f, -1.0f);
45
 const static glm::vec3 dirUnit(0.0f, 0.0f, -1.0f);
45
 
46
 
46
 glm::vec3 Camera::pos(0.0f, 0.0f, 0.0f);
47
 glm::vec3 Camera::pos(0.0f, 0.0f, 0.0f);
47
-glm::quat Camera::quaternion(glm::vec3(0.0f, 0.0f, 0.0f));
48
+glm::vec2 Camera::rot(glm::pi<float>(), 0.0f);
48
 glm::vec3 Camera::posSpeed(0.0f, 0.0f, 0.0f);
49
 glm::vec3 Camera::posSpeed(0.0f, 0.0f, 0.0f);
49
 glm::vec2 Camera::rotSpeed(0.0f, 0.0f);
50
 glm::vec2 Camera::rotSpeed(0.0f, 0.0f);
50
 glm::mat4 Camera::projection(1.0f);
51
 glm::mat4 Camera::projection(1.0f);
56
 
57
 
57
 void Camera::reset() {
58
 void Camera::reset() {
58
     pos = glm::vec3(0.0f, 0.0f, 0.0f);
59
     pos = glm::vec3(0.0f, 0.0f, 0.0f);
59
-    quaternion = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
60
+    rot = glm::vec2(glm::pi<float>(), 0.0f);
60
     posSpeed = glm::vec3(0.0f, 0.0f, 0.0f);
61
     posSpeed = glm::vec3(0.0f, 0.0f, 0.0f);
61
     rotSpeed = glm::vec2(0.0f, 0.0f);
62
     rotSpeed = glm::vec2(0.0f, 0.0f);
62
     dirty = true;
63
     dirty = true;
96
 }
97
 }
97
 
98
 
98
 void Camera::handleMouseMotion(int x, int y) {
99
 void Camera::handleMouseMotion(int x, int y) {
99
-    if (x != 0) {
100
-        quaternion = glm::quat(upUnit * (rotationDeltaX * x)) * quaternion;
100
+    if ((x != 0) || (y != 0))
101
         dirty = true;
101
         dirty = true;
102
+
103
+    while (x > 0) {
104
+        rot.x += rotationDeltaX;
105
+        x--;
106
+    }
107
+
108
+    while (x < 0) {
109
+        rot.x -= rotationDeltaX;
110
+        x++;
102
     }
111
     }
103
 
112
 
104
-    if (y != 0) {
105
-        static int lastDir = 0;
106
-        float a = glm::dot(upUnit, quaternion * upUnit);
107
-        if (((lastDir >= 0) && (y < 0)) || ((lastDir <= 0) && (y > 0)) || (a > 0.5f)) {
108
-            quaternion = glm::quat(quaternion * -rightUnit * (rotationDeltaY * y)) * quaternion;
109
-            dirty = true;
113
+    while (y > 0) {
114
+        if (rot.y > -(glm::pi<float>() / 2.0f)) {
115
+            rot.y -= rotationDeltaY;
116
+        }
117
+        y--;
118
+    }
110
 
119
 
111
-            // TODO find better way to clamp Y rotation axis!
112
-            if (a > 0.5f)
113
-                lastDir = y;
120
+    while (y < 0) {
121
+        if (rot.y < (glm::pi<float>() / 2.0f)) {
122
+            rot.y += rotationDeltaY;
114
         }
123
         }
124
+        y++;
115
     }
125
     }
126
+
127
+    while (rot.x > (glm::pi<float>() * 2.0f))
128
+        rot.x -= glm::pi<float>() * 2.0f;
129
+
130
+    while (rot.x < -(glm::pi<float>() * 2.0f))
131
+        rot.x += glm::pi<float>() * 2.0f;
116
 }
132
 }
117
 
133
 
118
 void Camera::handleControllerAxis(float value, KeyboardButton axis) {
134
 void Camera::handleControllerAxis(float value, KeyboardButton axis) {
128
     } else if (axis == rightXAxis) {
144
     } else if (axis == rightXAxis) {
129
         rotSpeed.x = controllerViewFactor * value;
145
         rotSpeed.x = controllerViewFactor * value;
130
     } else if (axis == rightYAxis) {
146
     } else if (axis == rightYAxis) {
131
-        rotSpeed.y = controllerViewFactor * value;
147
+        rotSpeed.y = -controllerViewFactor * value;
132
     } else {
148
     } else {
133
         return;
149
         return;
134
     }
150
     }
161
         return false;
177
         return false;
162
 
178
 
163
     float dT = RunTime::getLastFrameTime();
179
     float dT = RunTime::getLastFrameTime();
164
-    pos += quaternion * posSpeed * dT;
180
+    rot += rotSpeed * dT;
165
 
181
 
166
-    if (glm::epsilonNotEqual(rotSpeed.x, 0.0f, controllerDeadZone))
167
-        quaternion = glm::quat(upUnit * rotationDeltaX * rotSpeed.x * dT) * quaternion;
182
+    glm::quat quatY = glm::angleAxis(rot.x, glm::vec3(0.0f, 1.0f, 0.0f));
183
+    glm::quat quatX = glm::angleAxis(rot.y, glm::vec3(1.0f, 0.0f, 0.0f));
184
+    glm::quat quaternion = quatY * quatX;
168
 
185
 
169
-    if (glm::epsilonNotEqual(rotSpeed.y, 0.0f, controllerDeadZone))
170
-        quaternion = glm::quat(quaternion * -rightUnit * rotationDeltaY * rotSpeed.y * dT) * quaternion;
186
+    pos += quaternion * posSpeed * dT;
171
 
187
 
172
     glm::mat4 translate = glm::translate(glm::mat4(1.0f), pos);
188
     glm::mat4 translate = glm::translate(glm::mat4(1.0f), pos);
173
     glm::mat4 rotate = glm::toMat4(quaternion);
189
     glm::mat4 rotate = glm::toMat4(quaternion);
180
     return updateViewFrustum;
196
     return updateViewFrustum;
181
 }
197
 }
182
 
198
 
183
-glm::vec2 Camera::getRotation() {
184
-    float x = glm::dot(dirUnit, quaternion * dirUnit);
185
-    float y = glm::dot(upUnit, quaternion * upUnit);
186
-    return glm::vec2(x, y);
187
-}
188
-
189
 // ----------------------------------------------------------------------------
199
 // ----------------------------------------------------------------------------
190
 
200
 
191
 class FrustumPlane {
201
 class FrustumPlane {

Loading…
Cancel
Save