How to invert just z axis of incoming quaternion
Hi everyone,
I'm super new to using VR/AR/Unity and have been seriously struggling to figure how to solve this issue. I'm currently using the Vive trackers and a base station and have been plugging the tracker coordinates (as seen by the base station) into unity on a camera object. Unfortunately, the rotational data isn't lining up. When I rotate the tracker on the z axis, everything works well, but when I rotate it either on the x or y axis, the camera angle changes in the opposite direction.
After playing around with things, I figured out that unity and the vive base station share a Y and X axis, but the z axis is inverted (i.e. right-handed vs left-handed coordinate systems: https://www.evl.uic.edu/ralph/508S98/coordinates.html). Knowing this, position is no problem (I can just negate the z values), but I can't figure out rotation.
So far I've thought about:
1 - converting R-handed quaternions from the trackers into a L-handed quaternions in unity – but apparently there are no such thing as left and right handed quaternions. I did read that it can matter which coordinate system you derive your quaternions from, though. So I wasn't really sure what to make of it and a lot of the math was over my head.
2 - converting my 3x3 basis matrix from the trackers into a left-handed system. I've tried negating the Z base vector, which didn't work. I tried switching the Z and Y base vector columns, which also didn't work.
3 - converting to euler angles from my R-handed quaternion, negating the x and y axis rotations, and converting back to quaternion, but when I tried to use euler angles I couldn't even get good results simply converting from quaternion to euler and back (without changing anything). Everything was erratic and unstable (code attempt for that:)
Tracker tr = DataCapture.instance.tracker1;
Vector3 trEulers = tr.rotQuat.eulerAngles;
transform.rotation = Quaternion.Euler(trEulers.y, trEulers.z, trEulers.x); //from documentation: The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).
Does anyone have any good suggestions on getting from my R-handed tracking rotational info to the L-handed system in unity? Thanks!
Answer by HMSMakerspace · Aug 08, 2017 at 01:02 AM
Figured it out! If anyone runs into this problem, the solution was to take the basis matrix and negate the following values:
[ x1 x2 -x3 ]
[ y1 y2 -y3 ]
[-z1 -z2 z3 ]
I honestly don't understand why it works (would love an explanation if someone has one), but I found it in the steamVR libraries when they pull in their tracker data. Looks like it would flip the the first two base vectors over the x-y plane, and then the third one and flip it over both the x-z and y-z planes. Somehow it totally fixes the handedness of the data.
Apparently I didn't actually have to change the coordinate system from R-handed to L-handed at all. Applying the above negative signs to the basis matrix simply results in the inverse of all the rotations applied to the tracker.
Your answer
Follow this Question
Related Questions
Rotate an object to a position only through one axis 1 Answer
Add +1 each time a sphere turns 1 degree on it's axis 0 Answers
Quaternions to EulerAngles weird x-axis interaction 1 Answer
Euler Angles in code / inspector different (both local & global) 1 Answer
How to find the 'longitude' of a collision location on a sphere collider? 0 Answers