Adding or Concatenating Transforms (Scale, Rotation, Translation)

Started by
21 comments, last by Kwizatz 11 years, 2 months ago

I keep my transformations as a scale vector, a rotation quaternion and a translation vector (SRT) rather than a single matrix, when I need a matrix I do some conversion and get a 4x4 matrix out of the 2 vectors and quaternion.

To add or concatenate 2 transforms what I do is generate the matrices from the 2 SRT transforms and multiply them together, which is fine since I rarely require to convert back from Matrix to SRT.

In the long run I think there are some matrix multiplications that can be shaved off if I could "add transforms", so I am trying to do that, but I ran into some issues.

My basic approach is as follows:

I have 2 SRT structures which I want to concatenate.

I do a element wise multiplication of the scale vector (S = S1[0] * S2[0],S1[1] * S2[1],S1[2] * S2[2]), this seems to work, but for now I have no scaling, so all values are 1, I just need to know if this is correct or if there is something wrong there.

I do a simple quaternion multiplication with R1 * R2, again this works as expected as the 3x3 sub-matrix is the same as when I convert to matrix and multiply matrices.

I to an element wise addition of the translation vectors so T = T1[0]+T2[0],T1[1]+T2[1],T1[2]+T2[2], and this is where it all goes wrong, the values on the matrices are different, and now that I think of it, this may have to do with the last element in the matrix, the 4th element of a position vector....

TL;DR version:

So anyway, long story short I want to concatenate/add transforms in Scale, Rotation, Translation format and then convert the result to a 4x4 matrix rather than convert the SRT's to matrices and then multiply the matrices, but the translation vector addition is giving me trouble.

Any ideas?

Thanks in advance!

Advertisement
You don't add translations when they are 4x4 homogeneous matrices, you (matrix) multiply them, that's the whole point of homogeneous matrices (all affine transforms can be multiplied). Just make sure the rest of the translation matrix is the identity (i.e. the upper 3x3 part).
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Hey, thanks! that makes perfect sense, I though of something like that, but for some reason I kept thinking the 3x3 upper part had to already be populated with rotation and translation data instead of the identity... I am glad I posted. smile.png

Would scale work the way I am doing it though? I would like confirmation on that.

Thanks again!

Yeah, scale works the same way, just make sure the 4th row and column is (0 0 0 1). (So it's diagonal with zeros everywhere except leading diagonal which is (scalex scaley scalez 1).

EDIT: There is always a 1 in the bottom right corner of homogeneous transform matrices.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Hmmmm no, that didn't work, I get the same values.

With identity matrices for the SR part the T part becomes the sum I am already doing, but inverted (IE: T2 + T1 instead of T1 + T2).

The bottom right value does remain as 1, so no real change.

You will only be able to keep the pieces of the transformation separate if you only allow uniform scaling. This is because by appending transforms that don't enforce uniform scaling you can end up with a matrix that skews vertices. Being that you cannot skew vertices with a scale, rotation, then translation. You will not be able to concatenate transformations and keep them in the split representation.
My current game project Platform RPG

I don't think this is going to work. IIRC, if you have a transform matrix that has scaling and/or rotation info as well as translation, the scale and rotation are applied first. So the translation components can't be combined independently, unless the scale and rotation of both SRTs are identical. Matrix multiplication isn't commutative, so you can't really expect to get an accurate result if you change the order inl which you combine the component transforms.

I don't think this is going to work. IIRC, if you have a transform matrix that has scaling and/or rotation info as well as translation, the scale and rotation are applied first. So the translation components can't be combined independently, unless the scale and rotation of both SRTs are identical. Matrix multiplication isn't commutative, so you can't really expect to get an accurate result if you change the order inl which you combine the component transforms.

Yeah, you're right, I found out that if I apply the rotation of the first SRT to the translation of the second SRT before adding the 2 vectors, I do get the same vector as the matrix multiplications, give or take 0.000001 due to floating point error (scale is 1,1,1 so its mute at the moment, but I am sure I would have to take it into account as well).

My "rotate_vector_by_quaternion" packs quite a lot of operations, so now I am just pondering whether its worth it or not. In the end what I may be saving is a temp array of matrices since what OpenGL (and I suspect Direct3D) expects is matrices as well anyway.

Thanks for your help!

I wouldn't worry too much about trying to devise a more efficient way to concatenate transforms unless you've determined empirically through profiling that this bit of code is your bottleneck. Your first priority should be code that you can read and understand after not looking at it for six months. Multiplying matrices is a standard approach to transform concatenation, so let it be your first choice. Otherwise you run the risk of wondering what the hell you were trying to do, how it was supposed to work, and why you were doing it in the first place.

Yckx you just resumed my coding life!

I have been looking for a piece of code I wrote about 8 years ago, and I am still trying to figure out what the hell was I thinking when doing that.

Don't do the same mistakes, if you do change, comment through fully, you never know when you will need to revisit your old code. And believe me, sometimes when I am really sleepy or tired I code extraordinary things that work, do what is supposed, but I have no idea why.

So unless this really is your bottleneck (which I doubt), don't really bother trying to optimize the code.

Check out my new blog: Morphexe

This topic is closed to new replies.

Advertisement