Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Matrix Decomposition

Started by fs1 Sep 15, 2014 at 11:52 AM 12 replies 3k views
Original Post
fs1
fs1
Dear All
It is my first post here.
I have a 4x4 affine matrix transformation and wanted to decompose it by polar decomposition, get the scale/stretch component and modify it - so I can resize my sprites to half of their size, and compose back my transform matrix.
Is this possible?
Thanks
haegarr
haegarr

Decomposing the matrix transform is perhaps not needed; it depends on how you create the original sprite transform matrix. If you just use a rotation and translation, then you can multiply with the scaling matrix, i.e.

M * S( 0.5 ) when using column vectors

S( 0.5 ) * M when using row vectors

should do the job. It works by first scaling the sprite (uniformly) and then applying the original transformation. Have you tried this already?

fs1
fs1
Thanks haegarr!

This doesn't work unfortunately.

Can I do it via polar decomposition?
alvaro
alvaro
What do you mean "doesn't work"?
fs1
fs1
I am hooking a game and getting the world matrix.

If I apply a scale matrix to it, the sprites disappear, they don't do the desire effect which is the scaling I want.

That's why I am looking into decomposition.

Regards,
haegarr
haegarr




If I apply a scale matrix to it, the sprites disappear, they don't do the desire effect which is the scaling I want.

If you put the scale matrix on the wrong side, then you scale also the position and a sprite may disappear due to that. So, have you ensured that you've chosen the correct order of multiplication? What happens if you use scaling factors close to 1?

fs1
fs1
haegarr, thanks. I did some tests.

I applied the scaling to the transform and it does the job. The problem I am having is that there is a group of sprites with a center somewhere, and the scale applies to that center.

How can I do a scale to each individual sprite from each center? This group is drawn in a single draw call.

I guess that math-wise, you need to translate to each center and do the scale for each element of the group?

Thanks!
haegarr
haegarr




I guess that math-wise, you need to translate to each center and do the scale for each element of the group?

Yes: If p is the position of the center, then translate by -p so that the center comes to rest at 0, do the scaling, then translate back by +p.

Is the drawcall done with an own matrix for each sprite, or with a common matrix for all sprites?

fs1
fs1

Thanks haegarr.

The problem is that the draw call is done with a common matrix. Any suggestions? Any changes on the vertices are possible?

Thanks for your help!

Regards,

haegarr
haegarr




The problem is that the draw call is done with a common matrix. Any suggestions? Any changes on the vertices are possible?

I don't know whether you can change the vertices directly, because you just told nothing about how the vertices are passed.

If you have access to them then of course you can use the CPU to do the job. For example, if all sprites are given by quads then each 4-tuple of vertices are to be used. Or if sprites are passed as 2 triangles, then each 6-tuple is to be used. Or if the vertices are passed by index, then the same goes with indices.

You can then compute the center of each sprite by summing the N vertex positions and divide by N. Then subtract those center position from each of the N vertex positions, half the resulting vector, and re-add the center. E.g.


for each sprite
   vec2 center(0, 0);
   for each of the N vertices of the sprite do
      center += vertex.pos;
   center /= N;
   for each of the N vertices of the sprite do
      vertex.pos = ( vertex.pos + center ) * 0.5;
fs1
fs1

Thanks haegarr. I will try your suggestion !

Regards!

fs1
fs1
This bring me to another quick question. Let's say I multiply each xyz primitive coordinates by 1/2, should I expect to get a sprite half the size of the original?
Thanks and Regards.

EDIT: I guess this will need a displacement component as well along with halfing the vertices
Bacterius
Bacterius

This bring me to another quick question. Let's say I multiply each xyz primitive coordinates by 1/2, should I expect to get a sprite half the size of the original?
Thanks and Regards.

EDIT: I guess this will need a displacement component as well along with halfing the vertices


Coordinate scaling is always done relative to the coordinate system's origin. In general that means you probably need to translate your sprite to be centered at the origin, scale it there, and then translate it back to where it was. Then it will be at the same spot, just half the original size.
“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”
fs1
fs1
You can then compute the center of each sprite by summing the N vertex positions and divide by N. Then subtract those center position from each of the N vertex positions, half the resulting vector, and re-add the center. E.g.

for each sprite
   vec2 center(0, 0);
   for each of the N vertices of the sprite do
      center += vertex.pos;
   center /= N;
   for each of the N vertices of the sprite do
      vertex.pos = ( vertex.pos + center ) * 0.5;

haegarr, thanks ! That works perfect !

Thank you all for the help.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.