Question

I'm currently working on an X-Plane plugin to add support for the Oculus Rift and I'm having problems with using quaternions for rotation. I've done this kind of thing before with rotation matrices, or Euler angles, but since quaternions seem to be the way to go now, I'm taking the chance to learn them. Quaternions are also what the Oculus SDK seem to use natively so using them is the path of least resistance.

The problem i'm trying to solve is where to position the camera so it is in the location of the pilots head as the plane itself changes its orientation in flight. It seems pretty straightforward to me. I have a vector that represents the relative position of the pilots head to the planes center of gravity, and i want to rotate around the planes z vector by roll degrees.

Here's the code i have right now. I think this is right but running this code yeilds a position that's too high... somewhere above the planes roof and moves around in kind of a circular pattern as the planes orientation changes. Also, if i try rotating the head vector by 0 degrees (by setting phi to 0) I get the same (or similar at least) wierd results, so I must be setting up my quat or something wrong.

    //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.

Was it helpful?

Solution

Turns out that x-plane isn't very consistent with it's coordinate system orientations. This code had the right idea, but was using the data it got from X-Plane the wrong way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top