Inconsistency between MyAvatar.orientation, MyAvatar.bodyRol/Yaw/Pitch and the way the avatar is drawn on screen


I’m worried about possible consequences of the choice that was made for the default avatar orientation.

With default I mean the orientation of the avatar in world when its rotation relative to the world has the quaternion 0,0,0,1.
Here is why:

When looking at the screen, the coordinate system attached to the screen is as follows:
X: left to right, Y: down to up, Z: far to close. This the openGL / video card coordinates grown historically from the 2D era.

When looking at the screen you look at the world; you expect that ‘up’ in the world is upwards
on your screen. Therefore, upwards in-world is +Y in (3D) screen coordinates. I have to note that
there is absolutely no reason to couple the screen coordinates and the world coordinates. Personally
I’d have made the Z axis of the world “up”, but I understand that for hifi the choice has been made
that also in-world the positive Y axis is up.

It becomes more understandable why the world coordinate system is unrelated to the screen
coordinate system when we try to understand the orientation of the remaining two axis: there
obviously is no preference for any direction in the horizontal plane; you could be looking anywhere.
However, there is a link in terms of the relative rotation between the two coordinates systems:
if this rotation is the unity rotation (0,0,0,1 as quaternion) then the respective axis of the two must be parallel.
So, whatever that rotation is - assume it’s unity and then the world X axis would (also) point to the right and
the world Z axis will point towards you. Below assume your cam is looking in that direction (towards the negative Z axis of the world).

So far so good.

Inside a script we have the MyAvatar object with its position in world coordinates and a quaternion
called MyAvatar.orientation. This object also exposes a bodyRoll, bodyYaw and bodyPitch.

Lets investigate what roll, yaw and pitch really mean.

First of all, they are relative to the object (the avatar in this case) and not relative to the world!
The terms are used intensively for airplanes (the expertise of @SeanDevin) which pretty much defines
their meaning: if the avatar is sitting in an airplane as pilot then the meaning of roll, yaw, pitch
as defined for airplanes should hold for the avatar. The canonical picture is therefore:

See for the correct directions of roll, yaw and pitch.
Although there seems to be a general confusion about the directions. There is no confusion about
which axis (relative to the vehicle) roll, yaw and pitch are linked to;
see for example

Now we can apply the same trick as before: we set the “orientation” (rotation of the avatar relative
to the world) to unity and then see how the avatar should be oriented:
In this case it should be laying down, feet away from the cam, head towards the cam and facing right.

Of course, the normal orientation would be one with its head upwards (to the positive Y axis of the
world), but that just means that MyAvatar.orientation would normally NOT be 0,0,0,1.
But, that is not the case in highfidelity.

Fortunately, it’s possible to define that the avatar stands upright
when MyAvatar.orientation equals 0,0,0,1 (which is the case in hifi currently) - which thus means that the yaw would be around
the Y axis of the coordinate system relative to the avatar - by simply renaming the axis.
This then leads to one the following pictures:

Now the problem that I found:

Empirically I found that

MyAvatar.orientation == Quat.fromVec3Degrees( { x: MyAvatar.bodyRoll, y: MyAvatar.bodyYaw, z: MyAvatar.bodyPitch } );

which corresponds to A.

But, if you set MyAvatar.orientation to 0,0,0,1 (or bodyRoll, bodyYaw and bodyPitch to 0) then the
avatar ends up facing the negative Z axis, which corresponds to B!

So, something must be wrong here :confused:


I know your not discussing Blender but I had some relevent issues to your thread fbx wiki
"Forward / Up Axis
SWITCH-Z Forward, Y Up

Since many applications use a different axis for ‘Up’,
there are axis conversion there settings, Forward and Up axis - By
mapping these to different axis you can convert rotations between
applications default up & forward axis.
Blender uses Y Forward, Z Up (since the front view looks along the +Y direction).
For example, its common for applications to use Y as the up axis, in that case -Z Forward, Y Up is needed."

So I had issues converting from blender to HF as it seems to use Mayas orientation


@Judas I can live with Y being upwards in world. My problem is that Roll (one “wing” up, the other down - or in T-pose, one arm up and the other down :wink: can only be linked to one axis: either the X axis (image A) or the Z axis (image B), because the Y axis is already taken and defined to be vertical.

Note that openGL itself defines Roll to swing X to Y, hence - it links ‘Roll’ to the Z axis (image B above with Roll reversed), which is how the avatar ends up being drawn, as well.

If that is correct - then how on earth can it be that
MyAvatar.orientation == Quat.fromVec3Degrees( { x: MyAvatar.bodyRoll, y: MyAvatar.bodyYaw, z: MyAvatar.bodyPitch } ); ?

Somewhere some confusion must have been made in the code, because this rotates a Roll around the X axis.


Ok big software question.are you using Blender? Because its importer wont import a maya fbx correctly any way using 7.1 or bos fbx plugin.
The rigs I imported correctly had to be entirely created in blender to not bork the bone roll.
If your not using Blender I don’t know.


I am not using blender - but that seems irrelevant.


I’m not sure where you’re getting your conversion between the quaternion orientation and Euler angles. The relation is MyAvatar.orientation == Quat.fromVec3Degrees({ x: MyAvatar.bodyPitch, y: MyAvatar.bodyYaw, z: MyAvatar.bodyRoll}) (you can see this in the C++ code, hifi/libraries/avatars/src/AvatarData.h). The angles follow the right hand rule: if you point the thumb of your right hand in the direction of the axis, then your fingers curl in the direction of positive rotation.


@Andrzej Ah… that would make things be correct after all :blush:
I determined it empirically by calculating Quat.fromVec3Degrees( { x: MyAvatar.bodyRoll, y: MyAvatar.bodyYaw, z: MyAvatar.bodyPitch } ); and printing it - as well as MyAvatar.orientation and saw they were equal. Then I concluded that that must be the relationship. I think I was too hasty; for some reason it didn’t matter that I swapped roll and pitch in my test case. I should have done more tests :/.

Thanks for taking the time to point this out; I’m going to investigate more and might report later, when I really know what is going on :wink: