2

I am currently trying to figure out how quaternions multiply and concatenate with each other in glm for opengl, but every thread I find only mentions 1 quaternion rotation.... Basically, how can I combine quaternions such that all the rotations concatenate? For example:

glm::quat quaternions[4]; // how to merge all 4 quaternions?

I have tried 2 approaches so far:

// approach 1:
glm::quat quaternions[4];
glm::quat q = glm::quat(glm::vec3(0));
q *= quaternions[0];
q *= quaternions[1];
q *= quaternions[2];
q *= quaternions[2];
glm::mat4 matrix = glm::toMat4(q);

// approach 2:
glm::quat quaternions[4];
glm::mat4 matrix = glm::mat4(1.0f);
matrix = matrix * glm::toMat4(quaternions[0]);
matrix = matrix * glm::toMat4(quaternions[1]);
matrix = matrix * glm::toMat4(quaternions[2]);
matrix = matrix * glm::toMat4(quaternions[2]);

None of these approaches seem to give me the results I am expecting.

Edit: I should add that I was trying to skin a collada model using assimp and glm. Approach 1 and 2 give me the exact solution I am looking for, so either should work.

Jas
  • 850
  • 7
  • 21
  • 1
    A far better question is... why do you have 4 quaternions to begin with? What do they represent? Also, what results are you expecting? – Nicol Bolas Apr 19 '16 at 14:09
  • How did you test result of quaternions merge? Could you please post example? – Unick Apr 19 '16 at 14:10
  • @NicolBolas assimp uses quaternions to represent bone rotations for skinning. And bones have a parent child hierchy, so I need to combine quaternions for a child's rotation. I didn't add this in the first place because I thought it was unneccessary, sorry. Basically my mesh comes deformed with these quaternions, but fine with my custom matrices. So clearly I am doing something wrong in the quaternion multiplication step – Jas Apr 19 '16 at 14:13
  • @Unick plz see my reply to Nicol Bolas. Well for the example Id have to show you a visual picture of my mesh deformed or something.... But I am 80% positive that I am making some error in quaternions.... – Jas Apr 19 '16 at 14:16
  • 1
    @Jas I can recommend you make small UnitTest. For example you create 2 or 3 quaternions and merge it and output results. I hope you can look final quaternion value and say is it correct or not. How I know quaternion is vector + angel (Or you can convert quaternion Euler degrees). Also you can post this test to question and it will help to find solution. There are many nuances: order of multiplication, method of multiplication and others. – Unick Apr 19 '16 at 14:31
  • @Unick alright will do thx. I would prefer to convert to Euler angles, in fact that was what I wanted to do originally.... For this I can use glm::eularAngles() right? – Jas Apr 19 '16 at 14:41
  • 2
    @Jas: "*And bones have a parent child hierchy, so I need to combine quaternions for a child's rotation.*" No, you need to combine *transformations*, not rotations. Translation, rotation, scaling, *all of them* are accumulated up the hierarchy. You need to compute each object's transformation matrix locally, independently, then compose them to get the full object-to-local transform. This does not require accumulating quaternions, but full matrix transforms. – Nicol Bolas Apr 19 '16 at 14:43
  • @NicolBolas that is what I meant sorry for the confusion. For each bone's animation, I am creating a matrix and then multiplying it by all its parents for the final transform. I am not too familar with the terminology, but my bind pose had a similar process and it worked 100%, so this should too. – Jas Apr 19 '16 at 14:50
  • 1
    @Jas, i think you can use pitch, roll, yaw to get euler angles. – Unick Apr 19 '16 at 15:21
  • 1
    @Jas: So where is this quaternion accumulation stuff coming from? If you are creating a matrix for each bone, and accumulating it with the parent's matrix, why are you trying to multiply a bunch of quaternions together? Each bone's orientation is a *single* quaternion, so where are you getting multiple quaternions per bone from? – Nicol Bolas Apr 19 '16 at 15:22
  • @NicolBolas Quaternions can be multiplied to combine rotations like matrices I believe. I am only using rotation right now so I dont need to build a matrix for translation, rotation, scale, etc. – Jas Apr 23 '16 at 01:50
  • 1
    @Jas: "*I am only using rotation right now*" What kind of skeletal figure does not have translations at all? All of the components would just be rotating on top of each other. The other thing is that the rotations and translations combine to *change* the translations. That is, translations of bones lower in the hierarchy are affected by the orientation of their parents. So you have to have each bones position/orientation be a single unit. A matrix. You don't accumulate orientations and positions *separately* up the hierarchy. – Nicol Bolas Apr 23 '16 at 01:53
  • @NicolBolas Well I do not really know sorry... My mesh is working pretty well right now... I am very new to skinning and collada, and its my first project with this stuff so I am very lost with terminology but it just worked out. – Jas Apr 23 '16 at 01:59

1 Answers1

2

After 3 days of more trial and error I finally figured out what was going on. Turns out some of my bones had a "roll" in blender which was screwing things up. Upside down bones were also a problem in my mesh. So for anyone who is having problems with an assimp loaded animation:

  • Check your bind pose first
  • Make sure you don't have upside down bones, this may cause some problems.
  • Check all bone information (in my case it was "roll" causing problems)

So nothing was wrong with my quaternion code...

Jas
  • 850
  • 7
  • 21