# Restore object right vector to horizontal position using quaternions

I'm fairly new in gamedev mathematics and i have a problem i cannot solve on my own.

I'm working on L-System tree generation engine and i'm having serious difficulities while trying to work out certain quaternion manipulation.

Every generated tree is a group of segments, growing from its parent starting from root. Every segments rotation is represented by quaternion. When child segment grows from its parent, i just multiply quaternion representing child rotation relative to parent by parent rotation quaternion. It works fine, however i need to implement another type of rotation to the child branch: bringing back segments right vector back to horizontal position. Is there any way i can solve this problem using quaternions?

I've tried manipulating quaternion converted to rotation matrix (extract quaternions front vector, recalculate right and up, modify rotation matrix and convert it to new quaternion) but i see that extracted informations about segment rotation are somehow corrupted, as it can be seen on screenshots ('tree' is at position (0,0,0), camera facing direction (0,-1,0)). Second one presents segment rotated 90 degrees about z axis (yaw). Expected vectors should be:
Right: 0 1 0
Front: 1 0 0
Up: 0 0 1

Is there something i do/understand wrong?

Edit:
I've checked again my vectors-to-matrix code part and turns out i've messed up vector rows with columns, that's why i was getting those strange results while trying different approaches!

I'm posting my working \$ operation:

...
mat4 rotationMatrix = mat4_cast(transform.rotation);
vec3 front(rotationMatrix[0][1], rotationMatrix[1][1], rotationMatrix[2][1]);
vec3 worldDown = vec3(0, -1, 0);

vec3 right = normalize(cross(front, worldDown));
vec3 up = normalize(cross(front, right));

float matrix[16] = {
right.x, front.x, up.x, 0,
right.y, front.y, up.y, 0,
right.z, front.z, up.z, 0,
0,      0,       0,    0
};

mat4 newMatrix = make_mat4(matrix);
transform.rotation = quat(newMatrix);
...


Your code is missing. Did you do something like:

matrix44 mat = mat( q );
vec4 x = mat.getRow( 0 )
vec4 y = mat.getRow( 1 )
vec4 z = mat.getRow( 2 )
vec4 p = mat.getRow( 3 )

x.z = 0;
x.normalize()
y = z.cross( x )
z = x.cross( y )

matrix44 newmat;
newmat.setRow( 0,x );
newmat.setRow( 1,y );
newmat.setRow( 2,z );
newmat.setRow( 3,p );

quat newq = quat( newmat );


Note that this code will fail in edge case where x-axis points straight up (0,0,1).

• Thank you for helping me out, everything works fine now. :) Jan 8, 2018 at 21:00