3D Computer Grapihcs Using OpenGL - 18 相机移动
2024-10-07 06:11:22
移动相机需要用到键盘按键,按键事件的引入需要包含头文件
#include <Qt3DInput\qkeyevent.h>
并实现QWidget中定义的虚函数keyPressEvent
我们首先在MyGlWindow中重写这个虚函数。
在MyGlWindow.h加入
void keyPressEvent(QKeyEvent*);
在MyGlWindow.cpp中定义:
void MyGlWindow::keyPressEvent(QKeyEvent * e)
{
switch (e->key())
{
case Qt::Key::Key_W:
camera.moveForward();
break;
case Qt::Key::Key_S:
camera.moveBackward();
break;
case Qt::Key::Key_A:
camera.strafeLeft();
break;
case Qt::Key::Key_D:
camera.strafeRight();
break;
case Qt::Key::Key_Q:
camera.moveUp();
break;
case Qt::Key::Key_E:
camera.moveDown();
break; default:
break;
}
repaint();
}
代码很简单,从中我们可以看到按下W 和 S键会分别前进、后退,按下A和D键会分别向左向右平移,按下Q和E键会分别向上向下平移。
但是目前我们还没有在Camera类中实现这6个移动的函数。
下面就来实现这些函数:
在Camera.h中添加成员:
void moveForward();
void moveBackward();
void strafeLeft();
void strafeRight();
void moveUp();
void moveDown(); float moveSpeed = 0.1f;
在Camera.cpp中定义这些方法:
void Camera::moveForward()
{
position += viewDirection * moveSpeed;
} void Camera::moveBackward()
{
position -= viewDirection * moveSpeed;
} void Camera::strafeLeft()
{
glm::vec3 pitchAxis = glm::cross(viewDirection, UP);
position += pitchAxis * moveSpeed;
} void Camera::strafeRight()
{
glm::vec3 pitchAxis = glm::cross(viewDirection, UP);
position -= pitchAxis * moveSpeed; } void Camera::moveUp()
{
position += UP * moveSpeed;
} void Camera::moveDown()
{
position -= UP * moveSpeed;
}
编译运行,我们发现相机可以前进后退上下左右平移了。
PS:
这里的上下并不是依照相机的局部坐标的上下,而是世界坐标的上下。要改成局部坐标的上下有些麻烦。
我做了一些尝试,定义一个新的成员cameraUp,用来表示相机的上方,每次旋转过后都重新使用向量差乘来重新计算cameraUp。这样确实可以按照相机的上下移动,但是带来了一些其他问题,相机在世界中不再是“正”的了,经过几次旋转,会累积一些偏差,导致相机倾斜。这里需要解决这个问题可能需要用到四元数,但是暂时不再深究了。
最新文章
- MongoDB 创建 Database 和 Collection
- 使用SAXReader读取ftp服务器上的xml文件(原创)
- VS2015如何新建MVC空模版项目
- web.xml 模板和Servlet版本
- linux文件描述符数量的坑
- C# 调用 Outlook发送邮件实例
- 用VS2010+Qt4.6.4编译QtAV
- boa移植
- 【API】短信通106端口验证短信的实现
- SQL Server 2008 过期
- iOS - UITabBarController
- Array和ArrayList的异同点【转】
- Serverless 架构:用服务代替服务器
- BZOJ_1623:_[Usaco2008_Open]_Cow_Cars_奶牛飞车_(贪心)
- 使用Fiddler提高前端工作效率 (介绍篇)
- asp.net执行cmd命令(包括第三方应用的命令行)
- Oracle学习之start with...connect by子句的用法
- Spring Boot 学习笔记--整合Thymeleaf
- 【重学计算机】操作系统D4章:设备管理
- Java-IO流之File操作和Properties操作
热门文章
- 使用自定义View
- Windows2012r2 安装SQLSERVER2017 与 SQLSERVER2016 的错误提示解决KB2919355 以及 KB2919442
- java对象 Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
- MySQL总结(5)
- ubuntu下python3虚拟环境的配置
- sqlserver2008 批量导出所有的作业
- js apply与call的用法与区别
- 通过JNI实现java调用C代码和C代码调用java的代码
- Idea多模块工程创建——继承、聚合
- 2019-11-29-dotnet-core-使用-CoreRT-将程序编译为-Native-程序