Reputation: 1573
I've got a quaternion that represents the rotation of a cube. This cube can sequentially be rotated left, up, right and down, only 90 degrees at a time, so that one is always looking at one of the faces directly. Using OpenGL's right-hand coordinate system, this is the surface facing +z, looking at the screen.
I want to retrieve the 'roll' of the cube. That is, how much the face currently facing world +z is rotated around this absolute z-axis.
Could someone explain what would be the best way to go about this? Convert to Euler angles (this seems hardly to be the right option)? Do some fancy quaternion math? I've tried all sorts of code snippets, but am at my last straw here.
Upvotes: 0
Views: 723
Reputation: 41474
Each face has a normal (the vector, relative to the cube's local space, which points straight out from the face). That's mathematically unambiguous. It sounds, though, like you also want each face to have an "upright" orientation -- as though the cube were a die, and each face had a number with a particular this-way-up -- which is not intrinsically a property of a face, but you can go ahead and define one. Consider the "upright" vector for a particular face to be the vector which, in the cube's local space, points from the bottom to the top of the die's numeral.
So now you have six face normals, and their corresponding six upright vectors. You also have the world-space "backwards vector" and "upright vector" of the viewer, which are +Z and (probably) +Y respectively. From here on it's easy:
atan2(dot(+Z, cross(+Y, faceUprightWS)), dot(+Y, faceUprightWS))
.Upvotes: 1