3D Computer Grapihcs Using OpenGL - 18 相機移動
阿新 • • 發佈:2018-02-02
傾斜 col def 成員 clas osi 可能 帶來 編譯
移動相機需要用到鍵盤按鍵,按鍵事件的引入需要包含頭文件
#include <Qt3DInput\qkeyevent.h>
並實現QWidget中定義的虛函數keyPressEvent
我們首先在MyGlWindow中重寫這個虛函數。
在MyGlWindow.h加入
void keyPressEvent(QKeyEvent*);
在MyGlWindow.cpp中定義:
1 void MyGlWindow::keyPressEvent(QKeyEvent * e) 2 { 3 switch (e->key()) 4 { 5 caseQt::Key::Key_W: 6 camera.moveForward(); 7 break; 8 case Qt::Key::Key_S: 9 camera.moveBackward(); 10 break; 11 case Qt::Key::Key_A: 12 camera.strafeLeft(); 13 break; 14 case Qt::Key::Key_D: 15 camera.strafeRight(); 16 break; 17 case Qt::Key::Key_Q: 18 camera.moveUp(); 19 break; 20 case Qt::Key::Key_E: 21 camera.moveDown(); 22 break; 23 24 default: 25 break; 26 } 27 repaint(); 28 }
代碼很簡單,從中我們可以看到按下W 和 S鍵會分別前進、後退,按下A和D鍵會分別向左向右平移,按下Q和E鍵會分別向上向下平移。
但是目前我們還沒有在Camera類中實現這6個移動的函數。
下面就來實現這些函數:
在Camera.h中添加成員:
1 void moveForward(); 2 void moveBackward(); 3 void strafeLeft(); 4 void strafeRight(); 5 void moveUp(); 6 void moveDown(); 7 8 float moveSpeed = 0.1f;
在Camera.cpp中定義這些方法:
1 void Camera::moveForward() 2 { 3 position += viewDirection * moveSpeed; 4 } 5 6 void Camera::moveBackward() 7 { 8 position -= viewDirection * moveSpeed; 9 } 10 11 void Camera::strafeLeft() 12 { 13 glm::vec3 pitchAxis = glm::cross(viewDirection, UP); 14 position += pitchAxis * moveSpeed; 15 } 16 17 void Camera::strafeRight() 18 { 19 glm::vec3 pitchAxis = glm::cross(viewDirection, UP); 20 position -= pitchAxis * moveSpeed; 21 22 } 23 24 void Camera::moveUp() 25 { 26 position += UP * moveSpeed; 27 } 28 29 void Camera::moveDown() 30 { 31 position -= UP * moveSpeed; 32 }
編譯運行,我們發現相機可以前進後退上下左右平移了。
PS:
這裏的上下並不是依照相機的局部坐標的上下,而是世界坐標的上下。要改成局部坐標的上下有些麻煩。
我做了一些嘗試,定義一個新的成員cameraUp,用來表示相機的上方,每次旋轉過後都重新使用向量差乘來重新計算cameraUp。這樣確實可以按照相機的上下移動,但是帶來了一些其他問題,相機在世界中不再是“正”的了,經過幾次旋轉,會累積一些偏差,導致相機傾斜。這裏需要解決這個問題可能需要用到四元數,但是暫時不再深究了。
3D Computer Grapihcs Using OpenGL - 18 相機移動