5
votes

What I am looking to do is to be able to push and pop transform matrices into SpriteBatch. I have 2 sprites, parent and child, and the child should be scaled, rotated, translated relative to the parent.

I currently have an implementation using textured quads but I think this should be possible using the built in SpriteBatch class and using Matrix.Decompose(). I'm not sure how to pass the decomposed values to SpriteBatch once I've decomposed them though.

I understand how to keep the matrix stack, I'm just looking for an example of using values coming from Matrix.Decompose() in conjunction with SpriteBatch.

1

1 Answers

6
votes

Figured this one out myself finally. Most of the credit belongs to this blog post though.

You can use this method to decompose your matrix:

private 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((double)(direction.Y), (double)(direction.X));
    position = new Vector2(position3.X, position3.Y);
    scale = new Vector2(scale3.X, scale3.Y);
}

You can then build a transform matrix your leaf sprites like so:

Matrix transform = 
    Matrix.CreateScale(new Vector3(this.Scale, 1.0f)) *
    Matrix.CreateRotationZ(this.Rotation) *
    Matrix.CreateTranslation(new Vector3(this.Position, 0));

For your parent sprites, include the origin:

Matrix transform = 
    Matrix.CreateTranslation(new Vector3(-this.Origin, 0)) *
    Matrix.CreateScale(new Vector3(this.Scale, 1.0f)) *
    Matrix.CreateRotationZ(this.Rotation) *
    Matrix.CreateTranslation(new Vector3(this.position, 0));

Multiply by all the matrices in the stack in reverse order.