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

Two segments with no rotation applied

Second segment turned right by 90 degrees

Is there something i do/understand wrong?

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;
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).

  • \$\begingroup\$ Thank you for helping me out, everything works fine now. :) \$\endgroup\$ – Blamad Jan 8 '18 at 21:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.