我目前正在制作一个X-Plane插件来添加对Oculus Rift的支持,我在使用四元数进行旋转时遇到了问题。我以前用旋转矩阵或欧拉角做过这类事情,但既然四元数似乎是现在的发展方向,我就抓住机会学习它们。四元数也是Oculus SDK原生使用的,所以使用它们是阻力最小的路径。
我试图解决的问题是在哪里定位相机,所以它是在飞行员头部的位置,因为飞机本身改变了它在飞行中的方向。这对我来说似乎很简单。我有一个矢量,表示飞行员头部与飞机重心的相对位置,我想围绕飞机z矢量旋转滚动度。
这是我现在的代码。我认为这是对的,但是运行这个代码会产生一个太高的位置……在飞机顶部的某个地方,随着飞机方向的改变,它会以一种圆形的模式移动。此外,如果我尝试旋转头部向量0度(通过设置phi为0),我得到相同(或至少类似)奇怪的结果,所以我必须设置我的四分位数或错误的东西。
//get the vector to the players head relative to the plane's center of gravity
float headX = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peX"));
float headY = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peY"));
float headZ = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peZ"));
//the planes orientation in euler angles
float theta = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/theta")) * (M_PI / 180.0f);
float psi = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/psi")) * (M_PI / 180.0f);
float phi = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/phi")) * (M_PI / 180.0f);
//convert euler angles into a vector for our axis or rotation
float planeVecX = cos(psi)*cos(theta);
float planeVecY = sin(psi)*cos(theta);
float planeVecZ = sin(theta);
//make some vectors
Vector3<float> *headVector = new Vector3<float>(headX, headY, headZ);
headVector->Normalize();
Vector3<float> *planeVector = new Vector3<float>(planeVecX, planeVecY, planeVecZ);
planeVector->Normalize();
//Make a quaternion for our rotation
Quat<float> *planeQuat = new Quat<float>(*planeVector, phi);
planeQuat->Normalize();
//rotate headVector by plane quat
Vector3<float> rotatedHeadVec = planeQuat->Rotate(*headVector);
//output our final camera position and orientation
outCameraPosition->x = planeX + rotatedHeadVec.x;
outCameraPosition->y = planeY + rotatedHeadVec.y;
outCameraPosition->z = planeZ + rotatedHeadVec.z;
outCameraPosition->pitch = theta * (180.0f / M_PI);
outCameraPosition->heading = psi * (180.0f / M_PI);
outCameraPosition->roll = phi * (180.0f / M_PI);
TIA for the help.
原来x平面和它的坐标系方向不太一致。这段代码的想法是正确的,但是使用X-Plane的数据的方式是错误的。