我目前正在研究在 3d 空間中移動相機。我希望它只在 x 和 z 軸(水平)上移動。到目前為止,當相機的旋轉全部為零時它是正確移動的,但是當我改變它的值時,相機開始表現得有點奇怪,朝著錯誤的方向移動。我正在使用 SFML,但我認為這是導致問題的數學。這很奇怪,因為我移動相機的代碼與我之前撰寫的專案之一相同,但該專案運行良好。
這是限制旋轉的代碼:
camera.rot.x = movey;
if (glm::degrees(camera.rot.x) < -180.0f) camera.rot.x = glm::radians(180.0f) camera.rot.x;
if (glm::degrees(camera.rot.x) > 180.0f) camera.rot.x = camera.rot.x glm::radians(-180.0f);
camera.rot.y -= movex;
if (glm::degrees(camera.rot.y) < -180.0f) camera.rot.y = glm::radians(180.0f) camera.rot.y;
if (glm::degrees(camera.rot.y) > 180.0f) camera.rot.y = camera.rot.y glm::radians(-180.0f);
我用來移動相機的代碼:
float x = sin(camera.rot.y) * camera.speed; float z = cos(camera.rot.y) * camera.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { camera.pos.x -= x; camera.pos.z -= z; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { camera.pos.x = x; camera.pos.z = z; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { camera.pos.x = z; camera.pos.z -= x; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { camera.pos.x -= z; camera.pos.z = x; }
如果有人可以幫助我解決這個問題,我將不勝感激。
對于任何想知道的人,這是我用來將 3d 坐標轉換為螢屏坐標的代碼:
glm::mat3 x(0.0f);
x[0][0] = 1.0f;
x[1][1] = cos(camera.rot.x);
x[1][2] = sin(camera.rot.x);
x[2][1] = -sin(camera.rot.x);
x[2][2] = cos(camera.rot.x);
glm::mat3 y(0.0f);
y[0][0] = cos(camera.rot.y);
y[0][2] = -sin(camera.rot.y);
y[1][1] = 1.0f;
y[2][0] = sin(camera.rot.y);
y[2][2] = cos(camera.rot.y);
glm::mat3 z(0.0f);
z[0][0] = cos(camera.rot.z);
z[0][1] = sin(camera.rot.z);
z[1][0] = -sin(camera.rot.z);
z[1][1] = cos(camera.rot.z);
z[2][2] = 1.0f;
glm::mat3 trans = x * y * z;
//trans is the perspective matrix
glm::vec3 e(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, (float)tan(camera.fov / 2) * (float)(SCREEN_WIDTH / 2));
//e is the distance from the camera pinhole relate to the 'screen'
glm::mat3 ScreenTrans(0.0f);
ScreenTrans[0][0] = 1.0f;
ScreenTrans[0][2] = e.x / e.z;
ScreenTrans[1][1] = 1.0f;
ScreenTrans[1][2] = e.y / e.z;
ScreenTrans[2][2] = 1.0f / e.z;
//ScreenTrans is the matrix use to transform Camera space into Screen space
std::vector<glm::vec3> 3D_coords = Some3DPoints;
for (glm::vec3 coord: 3D_coords){
glm::vec3 afterTrans = trans * coord;
glm::vec3 cameraSpace = afterTrans - camera.pos;
glm::vec3 2DScreenCoord = cameraSpace * ScreenTrans;
}
uj5u.com熱心網友回復:
在深入研究我的代碼很長時間后,我發現問題出在我限制旋轉的代碼中,以及我如何獲得“trans”矩陣。
首先,約束代碼應該是:
camera.rot.x -= movey;
if (glm::degrees(camera.rot.x) < -90.0f) camera.rot.x = glm::radians(180.0f) camera.rot.x;
if (glm::degrees(camera.rot.x) > 90.0f) camera.rot.x = camera.rot.x glm::radians(-180.0f);
camera.rot.y = movex;
if (glm::degrees(camera.rot.y) < -180.0f) camera.rot.y = glm::radians(360.0f) camera.rot.y;
if (glm::degrees(camera.rot.y) > 180.0f) camera.rot.y = camera.rot.y glm::radians(-360.0f);
我錯過了計算值并錯誤地將 rot.x 作為 y 軸,將 rot.y 作為 x 軸。
接下來是“反式”矩陣。它應該是:
glm::mat3 trans = z * y * x;
它應該首先處理 y 軸的旋轉,而不是 x 軸,否則 y 軸(相機空間)的旋轉將始終在 y 軸(世界空間)上。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/435882.html
下一篇:X,Y坐標轉換
