I'm trying to implement a parent child relationship between Sprites and draw them to the screen. I'm calculating transforms by chaining transform matrices.
I'm using code from here:
private void Draw(Texture2D texture, Matrix transform)
{
Vector2 p, s;
float r;
DecomposeMatrix(ref transform, out p, out r, out s);
spriteBatch.Draw(texture, p, null, Color.White, r, new Vector2(texture.Width / 2, texture.Height / 2), s, SpriteEffects.None, 0.0f);
}
private static Matrix GetMatrix(Vector2 position, Vector2 scale, float rotation)
{
return Matrix.CreateScale(scale.X, scale.Y, 1f) * Matrix.CreateRotationZ(rotation) * Matrix.CreateTranslation(position.X, position.Y, 0f);
}
private static void DecomposeMatrix(ref Matrix matrix, out Vector2 position, out float rotation, out Vector2 scale)
{
Vector3 position3, scale3;
Quaternion rotationQ;
matrix.Decompose(out scale3, out rotationQ, out position3);
Vector2 direction = Vector2.Transform(Vector2.UnitX, rotationQ);
rotation = (float)Math.Atan2(direction.Y, direction.X);
position = new Vector2(position3.X, position3.Y);
scale = new Vector2(scale3.X, scale3.Y);
}
And I'm drawing things like this:
Matrix parentT = GetMatrix(parentPosition, parentScale, parentRotation);
Matrix childT = GetMatrix(childPosition, childScale, childRotation);
childT = childT * parentT;
Draw(parent, parentT);
Draw(child, childT);
This seems to be working fine except when the parent has a different scale than [1, 1]. For example, when the scale is [2, 1] and the child is rotating - the child gets scaled along the world X axis which causes it to look deformed:
The result I actually want is:
I still want the child to be affected by the parent's scale while taking the rotation into the account. I guess I could temper with the scale and apply it manually but that doesn't feel right. How to achieve this behaviour using matrices?