I don't really know exactly what your RelativePosition
and Model.Origin
stand for, so it's hard to say for certain, but usually the origin part should come at the beggining of the world matrix and be negated (i.e. Matrix.CreateTranslation(-player.Model.Origin)
).
Scaling, rotation and translation usually come in SRT order, which you did right.
As for the RelativePosition
I'm not sure what it is. But if that's like the transform of the parent object, then I think it needs to go at the end (at least that's how it worked for me here).
Anyway, for future reference, here's a rundown of what is usually the order for each situation:
Simple Transformations
The order of multiplication for a world matrix is typically:
// World Matrix
Scale * Rotation * Translation
And the order of multiplication for a view matrix is typically:
// View Matrix
-Translation * -Rotation * Zoom
Transformations with Origin
However, especially in 2D games, you frequently need to add an origin displacement to your transformation. That's usually added to the beggining, and must be negated too, so:
// World Matrix with Origin
-OriginTranslation * Scale * Rotation * PositionTranslation
The same thing can also be done with a view matrix, but you add it to the end and this time you don't negate it:
// View Matrix with Origin
-PositionTranslation * -Rotation * Zoom * OriginTranslation
Transformations with Selective Origin
There are also some cases where you want to have an origin displacement, but you want it to affect only your scale and rotation, but not your translation. The way to handle that is to undo the origin transformation before reaching the translation component. For example, with the world matrix:
// World Matrix with Origin for Scale and Rotation
-OriginTranslation * Scale * Rotation * OriginTranslation * PositionTranslation
And the view matrix:
// View Matrix with Origin
-PositionTranslation * -OriginTranslation * -Rotation * Zoom * OriginTranslation
Orbiting around Target
Finally, there's the special case where you want something that orbits around another point. In that situation, you simply switch rotation and translation and it becomes:
// Orbit matrix
Scale * Translation * Rotation
Edit
From your picture I now understand you're trying to create a sort of bone hierarchy where the character is composed by several pieces each with their own transformations, which in turn are grouped together and work as a whole.
In this situation it's easier to understand if you divide the process into two separate matrices, one for the character as a whole, and one for the piece, and then combine them into one as:
Piece Absolute World Matrix = Piece Relative World Matrix * Character World Matrix
So for full flexibility let's say your character has its own Position
, Rotation
, Scale
and Origin
in the world, and each piece has its own Position
, Rotation
, Scale
and Origin
relative to the origin of the character. You would then calculate the actual world matrix as:
Matrix characterMatrix = Matrix.CreateTranslation(-character.Origin) *
Matrix.CreateScale(character.Scale) *
Matrix.CreateRotationY(character.Rotation) *
Matrix.CreateTranslation(character.Position);
foreach(Piece piece in character.Pieces)
{
Matrix pieceMatrix = Matrix.CreateTranslation(-piece.Origin) *
Matrix.CreateScale(piece.Scale) *
Matrix.CreateRotationY(piece.Rotation) *
Matrix.CreateTranslation(piece.Position);
Matrix finalMatrix = pieceMatrix * characterMatrix;
}
Since you only seem to use a small subset of this values, you can remove everything that isn't being used, and if you want you can also inline everything into a single expression (the problem is that you will be recalculating the character's world matrix over and over and again for each piece, which is wasteful).
I think the result would then be, using the values you provided:
effect.Parameters["World"].SetValue(
Matrix.CreateTranslation(component.RelativePosition) * // Piece Matrix
Matrix.CreateTranslation(-player.Model.Origin) * // Character Matrix
Matrix.CreateRotationY(player.Rotation.Y) *
Matrix.CreateTranslation(player.Position) *
Matrix.CreateTranslation(0, 0, -1)
);