Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

i am currently in the process of implementing a render engine that works like flash's. Where a sprite is drawn inside another sprite and reflects all transformation (rotation, scale, etc) on the parent.

I have my transformation setup like so.

    public Matrix transform
    {
        get
        {
            Matrix m_transform =
                Matrix.CreateTranslation(new Vector3(x, y, z)) *
                Matrix.CreateRotationZ(rotation) *
                Matrix.CreateScale(scale)
                ;
            return m_transform;
        }

    }

But i cannot use spritebatch to render the sprite with a matrix. Is there a way to properly do this ?

Thanks alot ;)

share|improve this question
    
Besides what I wrote in my answer, you should invert the order of the transformations, which for a world matrix should be Scale-Rotation-Translation. Also if your scale is just a float value, you'll probably want to change the call to Matrix.CreateScale(scale, scale, 1) because you do not want the Z coordinate to be scaled or it might mess up the SpriteBatch sorting. And you probably should leave the Z component of the translation at 0 too. If you need to change the depth, use the layerDepth SpriteBatch.Draw() parameter. –  David Gouveia Aug 5 '12 at 17:30

2 Answers 2

up vote 0 down vote accepted

Use the following helper method which decomposes any Matrix into a set of position, rotation and scale that can be used directly with a SpriteBatch. It's basically a wrapper around the existing Matrix.Decompose method but making it SpriteBatch friendly:

public 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);
}

It should be pretty straightforward, but here's an example of how to use the method above:

Matrix transform = /* The transform of your sprite */

Vector2 position, scale;
float rotation;
DecomposeMatrix(ref transform, out position, out rotation, out scale);

spriteBatch.Draw(texture, position, null, Color.White, rotation, Vector2.Zero, scale, SpriteEffects.None, 0.0f);

Notice how the origin parameter is left as Vector2.Zero in the example. This is because I usually already embed the origin transformation into the matrix, so the resulting position already includes it.

For more information on the subject of implementing a sprite hierarchy in XNA, I will simply leave two links to related answers of mine:

share|improve this answer

Shawn Hargreaves write this http://blogs.msdn.com/b/shawnhar/archive/2011/01/12/spritebatch-billboards-in-a-3d-world.aspx article on his blog about it. Create BasicEffect instance, set transforms and draw:

spriteBatch.Begin(0, null, null, null, null, basicEffect);
//draw something
spriteBatch.End();
share|improve this answer
    
I think with this approach, you'd need to call Begin/End for each sprite in order to set a new transform, or use Immediate mode, both of which get rid of the benefits of batching. –  David Gouveia Aug 5 '12 at 17:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.