Forum Discussion
AndyTheBald
11 years agoHonored Guest
The eye pose, and left-handed game engines
Hi there
I'm struggling at the moment combining the pose's orientation with our view matrix, in our left-handed game engine.
If I convert the quat as-is to a matrix, and then multiply it by our view matrix, then if I Pitch down the view pitches up, roll left, the view rolls right, yaw left and the view yaws right.
If I invert the quat, then for simple movements from the reference pose, then everything moves in the correct direction. However if I pitch the hmd 90deg down, and then roll the hmd 90deg left, it produced the wrong transform. It's as if it has rolled, and then pitched.
Logically, this makes sense, as internally you could consider the pose quat as the combination of the 3 axis rotations (I'm not sure which order you actually apply heading/pitch/roll, but I believe that's irrelevant). Inverting it, will be the inverse of the 3 individual rotations applied in the opposite order - which matches what I see.
So what I've been struggling with is coming up with a transform, which I can apply to the pose, that gets everything working right. I feel there ought to be a simple transform which corrects this, but everything I've tried hasn't worked.
How do you solve this?
Cheers
Andy
I'm struggling at the moment combining the pose's orientation with our view matrix, in our left-handed game engine.
If I convert the quat as-is to a matrix, and then multiply it by our view matrix, then if I Pitch down the view pitches up, roll left, the view rolls right, yaw left and the view yaws right.
If I invert the quat, then for simple movements from the reference pose, then everything moves in the correct direction. However if I pitch the hmd 90deg down, and then roll the hmd 90deg left, it produced the wrong transform. It's as if it has rolled, and then pitched.
Logically, this makes sense, as internally you could consider the pose quat as the combination of the 3 axis rotations (I'm not sure which order you actually apply heading/pitch/roll, but I believe that's irrelevant). Inverting it, will be the inverse of the 3 individual rotations applied in the opposite order - which matches what I see.
So what I've been struggling with is coming up with a transform, which I can apply to the pose, that gets everything working right. I feel there ought to be a simple transform which corrects this, but everything I've tried hasn't worked.
How do you solve this?
Cheers
Andy
13 Replies
- jhericoAdventurer
"owenwp" wrote:
To be clear, for anyone else with similar problems, quaternions absolutely do have a handedness.
No, they don't."owenwp" wrote:
The imaginary part (x,y,z) is a vector in the same coordinate space as any other vector in your engine, pointing along the axis of rotation.
By thinking of it that way you're essentially performing a mental conversion from rotation space into vector space, which does have a handedness. A spatial rotation quaternion is a point on a 4 dimensional hyper-surface. Trying to apply a 3D concept like handedness to it will only give you nightmares. - lamour42Expert ProtegeHere is the complete head tracking/camera movement code from my DX 12 engine. (details on this project see here: https://forums.oculus.com/viewtopic.php?f=20&t=27502). Code is based on Oculus SDK 8
My coordinate system is left-handed, positive y goes up, positive x to the right, positive z into the screen.
If you want to tweak to another orientation, you probably have to adapt the two lines with the line comment: The scaling matrix and forward transform.
void VR::nextTracking()
{
// Get both eye poses simultaneously, with IPD offset already included.
ovrVector3f useHmdToEyeViewOffset[2] = {
eyeRenderDesc[0].HmdToEyeViewOffset, eyeRenderDesc[1].HmdToEyeViewOffset };
//ovrPosef temp_EyeRenderPose[2];
ovrTrackingState ts = ovr_GetTrackingState(session, ovr_GetTimeInSeconds(), false);
ovr_CalcEyePoses(ts.HeadPose.ThePose, useHmdToEyeViewOffset, layer.RenderPose);
for (int eye = 0; eye < 2; eye++)
{
ovrPosef * useEyePose = &EyeRenderPose[eye];
float * useYaw = &YawAtRender[eye];
float Yaw = XM_PI;
*useEyePose = layer.RenderPose[eye];
*useYaw = Yaw;
// Get view and projection matrices (note near Z to reduce eye strain)
Matrix4f rollPitchYaw = Matrix4f::RotationY(Yaw);
Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f(useEyePose->Orientation);
// fix finalRollPitchYaw for LH coordinate system:
Matrix4f s = Matrix4f::Scaling(1.0f, -1.0f, -1.0f); // 1 1 -1
finalRollPitchYaw = s * finalRollPitchYaw * s;
Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0, 1, 0));
Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0, 0, -1));//0 0 1
Vector3f Posf;
Posf.x = xapp->camera.pos.x;
Posf.y = xapp->camera.pos.y;
Posf.z = xapp->camera.pos.z;
Vector3f diff = rollPitchYaw.Transform(useEyePose->Position);
Vector3f shiftedEyePos;
shiftedEyePos.x = Posf.x - diff.x;
shiftedEyePos.y = Posf.y + diff.y;
shiftedEyePos.z = Posf.z + diff.z;
xapp->camera.look.x = finalForward.x;
xapp->camera.look.y = finalForward.y;
xapp->camera.look.z = finalForward.z;
Matrix4f view = Matrix4f::LookAtLH(shiftedEyePos, shiftedEyePos + finalForward, finalUp);
Matrix4f projO = ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.2f, 2000.0f, false);
Matrix4fToXM(this->viewOVR[eye], view.Transposed());
Matrix4fToXM(this->projOVR[eye], projO.Transposed());
}
} "jherico" wrote:
"owenwp" wrote:
To be clear, for anyone else with similar problems, quaternions absolutely do have a handedness.
No, they don't.
While quaternions themselves might not have a handedness, the rotation they perform (whether it is clockwise or anticlockwise around an axis) is affected by the handedness of the coordinate system used.
(For example: in a right handed coordinate system a positive quaternion pitch around X looks up, while in a left handed system it looks down)
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 6 months ago
- 1 year ago
- 2 years ago
- 9 months ago