Forum Discussion
genetransfer
12 years agoExplorer
Orientation for left handed coordinate system
Hi I was just looking through the docs and api, and noticed the rift returns only quaternion for right handed coordinate system. There doesn't seem to be a matrix of the orientation so I can build a left handed quaternion. I don't want to use euler angles as they produce gimbal lock in certain situations. any chance of getting a matrix of the orientations instead of just quats in the next sdk update or patch.
or, as I might have missed something does anyone know another way to get a left handed quaternion currently from the sdk?
or, as I might have missed something does anyone know another way to get a left handed quaternion currently from the sdk?
5 Replies
- genetransferExplorernevermind found it...operator OVR::Matrix4f() didn't see it.
- jhericoAdventurer
"genetransfer" wrote:
does anyone know another way to get a left handed quaternion currently from the sdk?
Simply converting the quaternion to a matrix won't change the handed-ness of the resulting matrix.
However, the Quaternion type in the SDK has a method for extracting the Euler angles in an arbitrary coordinate system:template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
void GetEulerAngles(T *a, T *b, T *c)
You can call it like this:glm::vec3 eulerAngles;
sensorFusion.GetOrientation().GetEulerAngles<
OVR::Axis_X, OVR::Axis_Y, OVR::Axis_Z,
OVR::Rotate_CW, OVR::Handed_R
>
(&eulerAngles.x, &eulerAngles.y, &eulerAngles.z);
In your cases you'd want to change Handed_R to Handed_L.
You can then reconstruct a type in your preferred coordinate system using the Euler angles.glm::quat quaternion(getEulerAngles(sensorFusion));
glm::mat4 matrix(glm::mat4_cast(quaternion)) - genetransferExplorerthanks but from the matrix data I can rebuild it as left handed and convert to quaternion whereas rebuilding the quat from euler angles can cause gimbal lock in some situations, which is why I was wanting to avoid that.
- genetransferExplorerIf anyone is using directx left handed coord system and want the hmd orientation with +Z Direction and no gimbal lock,
this might help you...
function to convert matrix right to left (used with following function)
D3DXMATRIX iOddityEngine_MatrixRightHandedToLeft(Matrix4f* matrix)
{
//-------------------------------------------------------------
D3DXMATRIX m1,m2;
//-------------------------------------------------------------
//convert row major to column major
m2.m[0][0] = matrix->M[0][0];
m2.m[1][0] = matrix->M[0][1];
m2.m[2][0] = matrix->M[0][2];
m2.m[3][0] = matrix->M[0][3];
m2.m[0][1] = matrix->M[1][0];
m2.m[1][1] = matrix->M[1][1];
m2.m[2][1] = matrix->M[1][2];
m2.m[3][1] = matrix->M[1][3];
m2.m[0][2] = matrix->M[2][0];
m2.m[1][2] = matrix->M[2][1];
m2.m[2][2] = matrix->M[2][2];
m2.m[3][2] = matrix->M[2][3];
m2.m[0][3] = matrix->M[3][0];
m2.m[1][3] = matrix->M[3][1];
m2.m[2][3] = matrix->M[3][2];
m2.m[3][3] = matrix->M[3][3];
//-------------------------------------------------------------
//convert right handed to left handed as row major
m1.m[0][0] = -m2.m[0][0];
m1.m[0][1] = m2.m[0][1];
m1.m[0][2] = m2.m[0][2];
m1.m[0][3] = 0.0f;
m1.m[1][0] = -m2.m[1][0];
m1.m[1][1] = m2.m[1][1];
m1.m[1][2] = m2.m[1][2];
m1.m[1][3] = 0.0f;
m1.m[2][0] = m2.m[2][0];
m1.m[2][1] = -m2.m[2][1];
m1.m[2][2] = -m2.m[2][2];
m1.m[2][3] = 0.0f;
m1.m[3][0] = 0.0f;
m1.m[3][1] = 0.0f;
m1.m[3][2] = 0.0f;
m1.m[3][3] = 1.0f;
return m1;
//-------------------------------------------------------------
}
The function to return the HMD orientation as quaternion...
void iOculusRiftHMDOrientation(D3DXQUATERNION* q1,bool bUsePrediction)
{
//-------------------------------------------------------------
if (pOculusRift.pSensor)
{
Quatf qf1;
if(bUsePrediction)
{
qf1 = pOculusRift.SFusion->GetPredictedOrientation();
}
else
{
qf1 = pOculusRift.SFusion->GetOrientation();
}
Matrix4f matrix = qf1.operator OVR::Matrix4f();
D3DXMATRIX m1 = iOddityEngine_MatrixRightHandedToLeft(&matrix);
D3DXQUATERNION q2 = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
D3DXQUATERNION q3 = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
//----below function uses "D3DXQuaternionRotationMatrix()"
iRotationMatrixToQuaternion(&q2,&m1);
//----below function uses "D3DXQuaternionRotationYawPitchRoll()"
iQuaternionFromEulerAngles(&q3,0.0f,180.0f,0.0f);
//to face +z
iQuaternionMultiply(&q2,&q2,&q3);
q1->x = q2.x;
q1->y = q2.y;
q1->z = q2.z;
q1->w = q2.w;
}
return;
//-------------------------------------------------------------
} - geekmasterProtegeOr just swap and negate terms to change coordinate systems, which is equivalent to swapping a rotation matrix between column major and row major order.
With 12 sets of Cartesian coordinate systems to choose from (all easily interchangeable) it can be a bit confusing at times...
And the names of the axes can change too, especially when using non-Cartesian (e.g. cylindrical or spherical) coordinates:
http://www.spenvis.oma.be/help/background/coortran/coortran.html
Cartesian handedness:
http://en.wikipedia.org/wiki/Cartesian_coordinates#Orientation_and_handedness
More info about the how and why of coordinate swapping:
http://blog.safe.com/2011/06/fmeevangelist81/
And even more fun stuff:
http://www.mathsisfun.com/geometry/solid-geometry.html
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
- 7 months ago
- 3 years ago
- 7 months ago
- 1 year ago