
前言本篇是在上一篇【qt openGL入门笔记】FPS相机-CSDN博客的基础上增加轨道相交功能。两种相机在概念上是不一样的FPS相机是以第一人称行走时“眼睛”的角度看物体的变化而轨道相交是绕着目标点转类似于绕着轨道转动的卫星视角是一直看着目标点。效果图功能详解整体改动较小主要改动在渲染和键值响应上。键值改动GLWidget类中增加了多Key_Space键值捕获用于切换相机模式。鼠标点击事件传递进Camera类中增加了右键和中键的平移左键的绕目标旋转效果if (m_mode Mode::Orbit) { if (m_rotating) { // 左键绕目标旋转 m_yaw dx * m_lookSensitivity; m_pitch qBound(-89, m_pitch dyUp * ..., 89); } else if (m_panning) { // 右键平移目标点(平移视角) const float wpp worldPerPixel(); m_target - m_right * (dx * wpp); m_target - m_up * (dyUp * wpp); } } else { if (m_rotating) { /* FPS只有左键转视角 */ } } //屏幕上拖动 1 个像素等于世界里平移了多少单位 float Camera::worldPerPixel() const { const float h m_viewportH 0 ? float(m_viewportH) : 800.0f; return 2.0f * m_orbitDistance * qTan(qDegreesToRadians(m_fov) * 0.5f) / h; }新增了滚轮的缩放效果if (m_mode Mode::Orbit) {//滚轮缩放 m_orbitDistance * qPow(0.85f, steps); m_orbitDistance qBound(m_minDistance, m_orbitDistance, m_maxDistance); } else { m_moveSpeed * qPow(1.15f, steps); m_moveSpeed qBound(1.0f, m_moveSpeed, 300.0f); }重置功能的变化// // F 复位只复位当前模式不切换模式 // void Camera::reset() { m_keysHeld.clear(); m_rotating m_panning false; if (m_mode Mode::FPS) { applySpawnPose(m_mode); // FPS瞬间重置 updateCameraVectors(); return; } // Orbit记录起点0.6s 缓动飞回默认机位 const QVector3D eye m_spawnEye[int(m_mode)]; const QVector3D center m_spawnCenter[int(m_mode)]; const QVector3D dir (center - eye).normalized(); m_flyToYaw qRadiansToDegrees(qAtan2(dir.z(), dir.x())); m_flyToPitch qRadiansToDegrees(qAsin(qBound(-1.0f, dir.y(), 1.0f))); m_flyToDist (center - eye).length(); m_flyToTarget center; m_flyFromYaw m_yaw; m_flyFromPitch m_pitch; m_flyFromDist m_orbitDistance; m_flyFromTarget m_target; m_flyT 0.0f; m_flying true; }渲染改动updateCameraVectors()增加重新计算了m_position不是FPS相机的跟随移动而是绕着目标转if (m_mode Mode::Orbit) { m_position m_target - m_front * m_orbitDistance; }新增了模式切换函数// // 模式切换保持视角连续 // void Camera::setMode(Mode mode) { if (mode m_mode) return; m_flying false; // 切模式打断飞行动画 if (mode Mode::Orbit) { m_target m_position m_front * m_orbitDistance; } m_mode mode; m_rotating false; m_panning false; m_keysHeld.clear(); updateCameraVectors(); }需要注意的时视图矩阵函数viewMatrix()和投影矩阵函数projectionMatrix()中的公式是没有变化的但是公式里面的成员变量m_position, m_position m_front, m_worldUp已经在键值变化时一起变化了所以VP也是一起变化的。