OpenGL里相機的運動控制

相機的核心構造一個是glm::lookAt函數,一個是glm::perspective函數,本文相機的一切運動都在于如何構建相應的參數傳入上述兩個函數里。

glm::mat4 glm::lookAt(glm::vec3 const &eye,//相機所在位置glm::vec3 const &center,//要凝視的點glm::vec3 const &up //相機上向量
);
glm::mat4 perspective(
float fovy, 
float aspect, 
float near, 
float far);

首先我們通常默認相機的Front向量為(0,0,-1),位置eye為(0,0,0),則center=eye+Front=(0,0,-1)。

默認up向量為(0,1,0),通過Front向量和up向量可以叉積出right向量。

1.視角抬起與左右環視

通過修改Front向量即可。簡單點可直接用歐拉角,相機引入yaw跟pitch,麻煩點就直接用向量做。可知相機自身的Front向量,right向量以及叉積出來的Up向量(注意不是up向量),這三組向量構成一組坐標基。

    //上下抬動thetaFront=Front*cos(theta)+Up*sin(theta)center=eye+Front;//up 不變,eye不變//上下旋轉動betaFront=Front*cos(beta)+right*sin(beta)center=eye+Front;//up 不變,eye不變

2.視角平移

前后平移即通過Front向量平移,左右平移即通過right向量平移。將eye跟center加減Front向量和right向量即可實現平移。

    //前后方向平移eye+=Front*k;//k為平移系數center+=Front*k;//up 不變//左右方向平移eye+=right*k;//k為平移系數center+=right*k;//up 不變

3.zoomIn/zoomOut

1)普通的視野變換

直接通過修改fov即可,fov越大則視野越寬看到的東西更多,但是屏幕上呈現的物體會變小;反之則視野越窄看到的東西更少,但是屏幕上呈現的物體會變大

2)在鼠標位置進行區域的視野放大縮小

這時候直接修改fov就不管用了,需要通過平移相機的方式來實現。

獲取鼠標所在點映射的世界空間點P,然后讓相機沿著有eye與P兩點構成的向量前后移動即可達到zoomIn/zoomOut的效果。其本質還是利用了相似的性質,這種實現方法可以巧妙地保證鼠標所在位置對應的三維空間點永遠會在鼠標所對應的屏幕像素點上。

    glm::vec3 dir=P-eye;//k為視野縮放系數,正數時zoomIn視野變大,負數則相反eye+=dir*k;center+=dir*k;//up 不變

4.聚焦到某個物體

首先獲取到這個物體的包圍盒中心點P,然后用相機當前的Front向量與之加減獲得到新的相機的eye。然后將相機的center設置為P即可。

    //k為系數,可以根據包圍盒的大小設置,包圍盒越大可以讓相機離遠點    eye=k*(P-Front);center=P;//up 不變

5.繞某個物體旋轉

可以先聚焦到這個物體。接下來獲取到這個物體的包圍盒中心點P,這個P可固定為相機center,然后P與eye的距離為r。然后如果向上旋轉theta,相機的eye會繞著以P為球心,r為半徑的面沿著相機當前Up向量方向旋轉theta。如果向右旋轉,相機的eye會繞著以P為球心,r為半徑的面沿著相機當前right向量方向旋轉beta。當然,如果相機引入yaw跟pitch的話會相對更簡單一些。

// 計算單位球面上點P繞切線n旋轉theta角后的新坐標
// O: 球心
// P: 球面上的點
// n: 切線方向向量(需單位化且與OP垂直)
// theta: 旋轉角度(弧度)
glm::vec3 rotatePointOnSphere(const glm::vec3& O, const glm::vec3& P, const glm::vec3& n, float theta
) 
{// 驗證輸入條件glm::vec3 OP = P - O;float opLength = glm::length(OP);// 檢查是否為單位球面(允許微小誤差)if (std::abs(opLength - 1.0f) > 1e-6f) {std::cerr << "警告:輸入點不在單位球面上,將進行歸一化處理" << std::endl;}// 檢查切線是否與半徑垂直float dotProduct = glm::dot(OP, n);if (std::abs(dotProduct) > 1e-6f) {std::cerr << "警告:輸入的切線方向不與半徑垂直,將重新計算垂直分量" << std::endl;}// 確保OP是單位向量glm::vec3 unitOP = glm::normalize(OP);// 確保n是單位向量且與OP垂直glm::vec3 tangent = glm::normalize(n - dotProduct * unitOP);// 創建旋轉四元數:繞切線方向旋轉theta角glm::quat rotation = glm::angleAxis(theta, tangent);// 執行旋轉:首先將點平移到原點,旋轉后再平移回球心glm::vec3 P_origin = P - O;  // 點P相對于球心的坐標glm::vec3 P_rotated_origin = rotation * P_origin;  // 旋轉glm::vec3 P_rotated = P_rotated_origin + O;  // 平移回球心// 由于浮點誤差,可能需要重新歸一化以確保在單位球面上return O + glm::normalize(P_rotated - O);
}//繞P點上下轉動theta
center=P;
eye=rotatePointOnSphere(P,eye,Up,theta);
//up向量不變//繞P點左右轉動beta
center=P;
eye=rotatePointOnSphere(P,eye,right,beta);
//up向量不變

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90872.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90872.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90872.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java設計模式 -【策略模式】

策略模式定義 策略模式&#xff08;Strategy Pattern&#xff09;是一種行為設計模式&#xff0c;允許在運行時選擇算法的行為。它將算法封裝成獨立的類&#xff0c;使得它們可以相互替換&#xff0c;而不影響客戶端代碼。 核心組成 Context&#xff08;上下文&#xff09;&…

項目重新發布更新緩存問題,Nginx清除緩存更新網頁

server {listen 80;server_name your.domain.com; # 替換為你的域名root /usr/share/nginx/html; # 替換為你的項目根目錄# 規則1&#xff1a;HTML 文件 - 永不緩存# 這是最關鍵的一步&#xff0c;確保瀏覽器總是獲取最新的入口文件。location /index.html {add_header Cache-…

系統架構師:系統安全與分析-思維導圖

系統安全與分析的定義??系統安全與分析是系統架構師在系統全生命周期中貫穿的核心職責&#xff0c;其本質是通過??識別、評估、防控安全風險&#xff0c;并基于數據與威脅情報進行動態分析??&#xff0c;構建從技術到管理的多層次防護體系&#xff0c;確保系統的保密性&a…

利用 Google Guava 的令牌桶限流實現數據處理限流控制

目錄 一、令牌桶限流機制原理 二、場景設計與目標 三、核心實現代碼&#xff08;Java&#xff09; 1. 完整代碼實現 四、運行效果分析 五、應用建議 在高吞吐數據處理場景中&#xff0c;如何限制數據處理速率、保護系統資源、防止下游服務過載是系統設計中重要的環節。本文…

小黑課堂計算機二級 WPS Office題庫安裝包2.52_Win中文_計算機二級考試_安裝教程

軟件下載 【名稱】&#xff1a;小黑課堂計算機二級 WPS Office題庫安裝包2.52 【大小】&#xff1a;584M 【語言】&#xff1a;簡體中文 【安裝環境】&#xff1a;Win10/Win11&#xff08;其他系統不清楚&#xff09; 【迅雷網盤下載鏈接】&#xff08;務必手機注冊&#…

CSS3知識補充

1.偽類和偽元素&#xff1a; 簡單的偽類實例 :first-chlid :last-child :only-child :invalid 用戶行為偽類 :hover——上面提到過&#xff0c;只會在用戶將指針挪到元素上的時候才會激活&#xff0c;一般就是鏈接元素。:focus——只會在用戶使用鍵盤控制&#xff0c;選…

Spring Retry 異常重試機制:從入門到生產實踐

Spring Retry 異常重試機制&#xff1a;從入門到生產實踐 適用版本&#xff1a;Spring Boot 3.x spring-retry 2.x 本文覆蓋 注解聲明式、RetryTemplate 編程式、監聽器、最佳實踐 與 避坑清單&#xff0c;可直接落地生產。 一、核心坐標 <!-- Spring Boot Starter 已經幫…

VTK交互——CallData

0. 概要 這段代碼https://examples.vtk.org/site/Cxx/Interaction/CallData/是一個使用VTK(Visualization Toolkit)庫的示例程序,主要演示了自定義事件、回調函數和定時器的使用。程序創建一個旋轉球體場景,并通過定時器觸發自定義事件來更新計數器。以下是詳細解釋: 1.…

OCR工具集下載與保姆級安裝教程!!

軟件下載 軟件名稱&#xff1a;OCR工具集1.1 軟件語言&#xff1a;簡體中文 軟件大小&#xff1a;78.8M 系統要求&#xff1a;Windows7或更高&#xff0c; 32/64位操作系統 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM4G或更高 盤丨下載&#xff1a;https://tool.nineya…

平時遇到的錯誤碼及場景?404?400?502?都是什么場景下什么含義,該怎么做 ?

? 一、常見 HTTP 錯誤碼及含義狀態碼含義簡述類型400Bad Request&#xff1a;請求格式有誤客戶端錯誤401Unauthorized&#xff1a;未授權客戶端錯誤403Forbidden&#xff1a;禁止訪問客戶端錯誤404Not Found&#xff1a;資源不存在客戶端錯誤405Method Not Allowed&#xff1a…

基于Tornado的WebSocket實時聊天系統:從零到一構建與解析

引言 在當今互聯網應用中&#xff0c;實時通信已成為不可或缺的一部分。無論是社交媒體、在線游戲還是協同辦公&#xff0c;用戶都期待即時、流暢的交互體驗。傳統的HTTP協議是無狀態的、單向的請求-響應模式&#xff0c;客戶端發起請求&#xff0c;服務器返回響應&#xff0c…

【語義分割】記錄2:yolo系列

圖像分割筆記1、源碼下載2、數據獲取3、環境配置4、模型訓練5、模型推理6、模型部署6.1 yolov5_flask學習7、版本上傳1、源碼下載 git clone https://github.com/ultralytics/ultralytics.gitgit回到對應版本&#xff1a; 方式一&#xff1a;使用 git checkout&#xff08;臨…

ubuntu22.04系統 算力4090服務器 病毒防護 查殺等 運維入門(三)clamAV工具離線查殺

以下有免費的4090云主機提供ubuntu22.04系統的其他入門實踐操作 地址&#xff1a;星宇科技 | GPU服務器 高性能云主機 云服務器-登錄 相關兌換碼星宇社區---4090算力卡免費體驗、共享開發社區-CSDN博客 兌換碼要是過期了&#xff0c;可以私信我獲取最新兌換碼&#xff01;&a…

微信小程序文件下載與預覽功能實現詳解

在微信小程序開發中&#xff0c;文件處理是常見需求&#xff0c;尤其是涉及合同、文檔等場景。本文將通過一個實際案例&#xff0c;詳細講解如何實現文件的下載、解壓、列表展示及預覽功能。 功能概述 該頁面主要實現了以下核心功能&#xff1a; 列表展示可下載的文件信息支持 …

postgresql執行創建和刪除時遇到的問題

刪除數據庫的時候出現的問題 有連接在占用 postgres=# DROP DATABASE "subgraph-dev"; ERROR: database "subgraph-dev" is being accessed by other users DETAIL: There is 1 other session using the database.強制斷開在用的連接 -- 替換 subgraph…

linux 應用層直接操作GPIO的方法

了解&#xff01;你使用的是 Rockchip RK3588S 平臺&#xff0c;需要操作 GPIO3_D5_d 這個引腳&#xff08;即 MCU_JTAG_TMS_M1/.../GPIO3_D5_d&#xff09;。以下是基于你提供的系統信息的具體操作步驟&#xff1a;&#x1f50d; 第一步&#xff1a;確認 GPIO 系統編號 在 RK3…

JavaScript核心概念全解析

目錄 1. 作用域 (1) 局部作用域 (2) 全局作用域 2. 垃圾回收 (1) 引用計數法 (2) 標記清除法 3. 閉包 (1) 作用 (2) 風險 4. 變量提升 (1) var (2) let 和 const (3) const 5. 函數提升 (1) 函數聲明 (2) 函數表達式 6. 函數參數 (1) 動態參數 (2) 剩余參數…

力扣刷題(第一百天)

靈感來源 - 保持更新&#xff0c;努力學習- python腳本學習提莫攻擊解題思路初始化總中毒時間 total。遍歷每次攻擊的時間點&#xff08;從第二個開始&#xff09;&#xff1a;計算當前攻擊與前一次攻擊的時間間隔 gap。若 gap < duration&#xff0c;則本次中毒時間為 gap&…

JMeter 性能測試實戰筆記

JMeter 性能測試實戰筆記 本文檔是一份詳細的 JMeter 指南&#xff0c;涵蓋了從創建測試計劃、執行測試到解讀性能結果的全過程。 一、創建測試計劃 一個完整的測試計劃是執行性能測試的基礎。下面將分步介紹如何創建一個針對文件上傳接口的測試場景。 第一步&#xff1a;添加線…

圖像處理:第二篇 —— 選擇鏡頭的基礎知識及對圖像處理的影響

一、圖像傳感器的典型應用圖像處理過程大致可分為如下四步&#xff1a;1.拍 攝 按下快門&#xff0c;拍攝圖像2.傳 送 將圖像數據由照相機傳送到控制器。3.處 理 前處理 : 對于圖像數據進行加工&#xff0c;使其特征更加明顯。測算處理 : 根據圖像數據對于損…