Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about order of operation when using a Matrix in XNA, C#

Here are two different pieces of code

This is what I started with

Vector2 hold = Vector2.Transform(pos1, mat1);
Matrix inv = Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(hold, inv);

And this is what i'm told is the simplified version

Matrix matrix1to2 = mat1 * Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(pos1, matrix1to2);

What I don't understand is, why isn't the first line in the simpilifed version

Matrix matrix1to2 = Matrix.Invert(mat2)*mat1;

Since in matrix order the thing on the right would take effect first and in the original we have mat1 being multiplied in first

Edit: The following image shows the order of operations desired

http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/mat1.png

The tutorial says that to create this transformation you use;

Matrix carriageMat = Matrix.CreateTranslation(0, -carriage.Height, 0) * Matrix.CreateScale(playerScaling) 
* Matrix.CreateTranslation(xPos, yPos, 0) * Matrix.Identity;

Why does this work if the order is left to right?

like image 675
Alxander Avatar asked Oct 24 '22 11:10

Alxander


1 Answers

Since in matrix order the thing on the right would take effect first and in the original we have mat1 being multiplied in first

Actually, the "thing on the left" takes effect first. Matrices are applied to the vertex in the same order in which you'd read them (assuming you're used to a Latin language).

In XNA, you typically perform transformations in SRT (Scale, Rotate, Translate) order. That way, the object will be scaled and rotated about its own origin (rotating on is own axis) before being moved into world space.

For example: if I wanted to rotate an object by Pi / 2, the move it 100 units along the X axis, I might use:

var rotate = Matrix.CreateRotationY(MathHelper.PiOver2);
var translate = Matrix.CreateTranslation(new Vector3(100,0,0));

var worldMatrix = rotate * translate;

If, instead, I wanted to move the object 100 units to the right, then rotate it about the world origin (0,0,0) to get a sort of orbiting effect (instead of spinning as is done in the first example), I'd use

var worldMatrix = translate * rotate;

You could also spin the object on its on axis, move it 100 units along the world X axis, the orbit it about the world origin by:

var worldMatrix = rotateSpin * translate * rotateOrbit;

where rotateSpin and rotateOrbit are rotation matrices defining your spin (rotation about object's origin) and orbit (rotation about the world origin following translation), respectively. Note that the order in which the operations effect your service vertices is left - to - right.

like image 103
3Dave Avatar answered Oct 30 '22 12:10

3Dave