我目前正在开发一个X-Plane 插件以添加对 Oculus Rift 的支持,但我在使用四元数进行旋转时遇到了问题。我以前用旋转矩阵或欧拉角做过这种事情,但由于四元数似乎是现在要走的路,我借此机会学习它们。四元数也是 Oculus SDK 似乎在本地使用的,因此使用它们是阻力最小的路径。
我要解决的问题是将相机放置在哪里,以便在飞机本身在飞行中改变其方向时,它位于飞行员头部的位置。这对我来说似乎很简单。我有一个向量表示飞行员头到飞机重心的相对位置,我想围绕飞机z向量旋转滚动度数。
这是我现在拥有的代码。我认为这是正确的,但是运行此代码会产生一个太高的位置......在飞机屋顶上方的某个地方,并且随着飞机方向的变化以圆形模式移动。此外,如果我尝试将头部矢量旋转 0 度(通过将phi设置为 0),我会得到相同(或至少相似)的奇怪结果,所以我必须设置我的 quat 或有什么问题。
//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 的帮助。