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: Left- vs. Right-Handed Coordinate Systems). 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!

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.