2

I am following a tutorial series about skeletal animation on Youtube (https://www.youtube.com/watch?v=f3Cr8Yx3GGA) and have ran into a problem – everything works fine, except when I rotate one of the bones (or "joints"), they get rotated around the scene origin, meaning they do not stay in place but are translated. The following image illustrates the problem: Object is moved in addition to being rotated

How can I make it so that the translation doesn't happen? I have been going over the tutorial series multiple times now, but cannot identify which step would prevent this from happening.

The code is very large, split into around a dozen files, and I don't know which section might be causing the issue, so I do not think there's much point in posting it all here (it should be similar to the code in the tutorial, even though I am using C++ while he's working in Java. The tutorial code can be found here: https://github.com/TheThinMatrix/OpenGL-Animation). If you could give me even general advice on how this issue is normally solved in skeletal animation, it should hopefully be enough for me to at least identify the part that's wrong and try moving from there.

Gweddry
  • 159
  • 8
  • How are you calculating the bone matrices? You need to walk along the skeleton and accumulate all the transforms that you meet. Usually, you have a rotation per bone, followed by a translation along the bone to get to the next joint. – Nico Schertler Apr 07 '19 at 18:55
  • @NicoSchertler that's pretty much what I'm doing. – Gweddry Apr 08 '19 at 08:05

2 Answers2

0

Rotation matrices on their own can only describe rotations around the origin (Wikipedia). However, rotations can be used in conjunction with translations to change where the origin is to get the desired effect. For example, you could:

  1. Translate the object so that it is centered around the origin
  2. Rotate the object to the desired orientation
  3. Translate the object back to the original position

Or, to phrase it in a different, but functionally equivalent way:

  1. Move the origin to the object's position
  2. Rotate the object to the desired orientation
  3. Reset the origin back to its original position

Related question: Rotating an object around a fixed point in opengl

RedRuin
  • 122
  • 7
  • I am aware of this approach in normal object rotation, but from what I've seen in Skeletal animation tutorials, this is not how it is normally done there. You send one matrix to the shader for each bone, which you then multiply the vertexes (based on their weights and assigned bones) with; at no point is the object translated to origin. For example, observe this vertex shader: https://github.com/TheThinMatrix/OpenGL-Animation/blob/master/Animation/renderer/animatedEntityVertex.glsl – Gweddry Apr 07 '19 at 14:41
  • The rotation and translation matrices could be multiplied together into one general matrix before being sent to the vertex shader. Are you editing the model through your program, or other external software? The github code from what I see seems to read the matrices directly from an input file. – RedRuin Apr 07 '19 at 15:08
  • They are multiplied together, yes. And I am not using any input files, I am creating the data by hand inside the code itself. – Gweddry Apr 07 '19 at 16:38
  • 1
    Well, if the matrix you are sending is the multiplication between a rotation and translation matrix, my only other suggestion would be maybe switch the order of the multiplication. Matrix multiplication is not commutative, so `rotation * translation` is not the same as `translation * rotation`. See if switching them gives the desired result. – RedRuin Apr 07 '19 at 17:36
  • Well, the result changes and turns around a different point, but it breaks the translation (which worked up until now). For example, if parent is at (3.0, 0.0, 0.0), and I wanted to rotate the child, I would need to also translate the child to (3.0, 0.0, 0.0) if I wanted it to stay in the same spot, as opposed to the correct (0.0, 0.0, 0.0) (as the child's position should be relative to parent). – Gweddry Apr 08 '19 at 08:21
  • Its going to be hard for me to suggest further meaningful changes without seeing your code firsthand. Can you edit your question to include the code of your vertex shader and the parts of the code that interact with the transformation matrix uniforms? A test case including a sample input, the expected output, and the unexpected output would also make the question much clearer. – RedRuin Apr 08 '19 at 15:42
  • I figured it out. It was what you said with reversing the multiplication order, combined with me misunderstanding one of the concepts of skeletal animation. – Gweddry Apr 09 '19 at 15:37
  • @Gweddry I know this is a year old now, but I'm curious what concept you were misunderstanding. I'm having the exact same issue - I pass my bone transformations as matrices, and the rotations are all done around the origin. I've looked at the code you linked and I still don't understand how the shader applies these transformations around the joint instead of the origin. Do you remember how you got it working? – Exudes May 26 '20 at 04:23
0

You just need to pay attention to what you are rotating around.

A way to fix this: Rotate it first and then translate it. Rotate the object while it is at the origin and then translate the object to where you want it.

Repeatedly do this when things change throughout your program. Start the object at the origin, do the desired rotation, and then translate out to it's final resting position.

clocksw
  • 68
  • 5