Sprite Rotation
#1 Members - Reputation: 100
Posted 11 January 2009 - 04:59 AM
#2 Moderators - Reputation: 5418
Posted 11 January 2009 - 06:15 AM
#3 Members - Reputation: 100
Posted 11 January 2009 - 06:27 AM
Well my texture has a size of 128x128, so 64x64 is the centre right :). Well if that's true... then the centre part ain't got nothing to do with it, most likely. I guess I should go check out more tutorials but they are getting harder to find, if you guys can help out please do so :).
I can't believe so many of you old guys are still here, LOL, I still remember you lot. Must be dedicated, good for you ;).
Thanks,
Fissure.
#4 Members - Reputation: 120
Posted 11 January 2009 - 09:34 PM
here is a sample of how I'm doing a rotation with Sprite (in C#):
Matrix finalMatrix;
finalMatrix = Matrix.Multiply(Matrix.RotationZ(angle), Matrix.Translation(pos));
then when drawing the sprite,
public void DrawSprite(Sprite sp)
{
if (isRotate)
{
sp.Transform = finalMatrix;
sp.Draw(texture, ctr, Vector3.Empty, unchecked((int)spcolor));
isRotate = false;
}
else
{
sp.Draw(texture, ctr, pos, unchecked((int)spcolor));
}
}
#5 Members - Reputation: 100
Posted 17 January 2009 - 07:50 AM
If possible could someone please provide me with a detailed tutorial? Of fourse there are tutorials online... but most of them do not get in to enough detail for me to understand.
EDIT - I wouldn't mind being recommended a book either :).
Thank you and sorry for the late reply.
#7 Members - Reputation: 120
Posted 21 January 2009 - 07:19 PM
Quote:
Original post by GameFissure
I'm sorry geekman1009, I don't understand what you mean :(. What do you mean when you say don't use rotate in Sprite->Draw?
If possible could someone please provide me with a detailed tutorial? Of fourse there are tutorials online... but most of them do not get in to enough detail for me to understand.
EDIT - I wouldn't mind being recommended a book either :).
Thank you and sorry for the late reply.
What I mean is, don't use
D3DXMatrixTransformation2D(&SpriteM, NULL, 0.0f, NULL, &D3DXVECTOR2(SpriteFocus.x, SpriteFocus.y), Index, NULL);
(I didn't read your original post carefully, and since I'm using XNA Game Studio which, the SpriteBatch have incorporated the transformations into the Draw() method, hence the confusion)
since this function always rotate you sprite around the origin (top left of the screen), regardless of how you set your Sprite Center and Position. The bug I mentioned earlier is, D3D will Translate your sprite to its Position BEFORE the Rotation, resulting in what you have been seeing in your current situation - the sprite is rotating around the screen origin. To avoid this bug, multiply 2 transformation matrices together to achieve the effect of rotating a sprite around it's center at given position, in one matrix, you then apply this composition matrix to the sprite.
In other words, rotate the sprite first (regardless of its position, since D3D will rotate the sprite at the world origin or top left of the screen), then translate the rotated sprite to the desired location. This can be achieved by Multiplying a Rotation-around-Z-axis Matrix (the LEFT matrix) and Translation Matrix (the RIGHT matrix). Apply the resulting Matrix from the multiply above and you will get what you want.
#8 Moderators - Reputation: 5418
Posted 22 January 2009 - 03:07 AM
Quote:
Original post by geekman1009
What I mean is, don't use
D3DXMatrixTransformation2D(&SpriteM, NULL, 0.0f, NULL, &D3DXVECTOR2(SpriteFocus.x, SpriteFocus.y), Index, NULL);
(I didn't read your original post carefully, and since I'm using XNA Game Studio which, the SpriteBatch have incorporated the transformations into the Draw() method, hence the confusion)
since this function always rotate you sprite around the origin (top left of the screen), regardless of how you set your Sprite Center and Position. The bug I mentioned earlier is, D3D will Translate your sprite to its Position BEFORE the Rotation, resulting in what you have been seeing in your current situation - the sprite is rotating around the screen origin. To avoid this bug, multiply 2 transformation matrices together to achieve the effect of rotating a sprite around it's center at given position, in one matrix, you then apply this composition matrix to the sprite.
In other words, rotate the sprite first (regardless of its position, since D3D will rotate the sprite at the world origin or top left of the screen), then translate the rotated sprite to the desired location. This can be achieved by Multiplying a Rotation-around-Z-axis Matrix (the LEFT matrix) and Translation Matrix (the RIGHT matrix). Apply the resulting Matrix from the multiply above and you will get what you want.
No that functions is fine. It will apply scaling first, then rotation, then translation (as indicated in the documentation).
I think the problem might be that he's setting the position in ID3DXSprite::Draw...try setting your position as the pTranslation parameter of D3DXMatrixTransformation2D instead of the pPosition parameter of ID3DXSprite::Draw.
#9 Members - Reputation: 163
Posted 10 July 2011 - 01:14 AM
No that functions is fine. It will apply scaling first, then rotation, then translation (as indicated in the documentation).
I think the problem might be that he's setting the position in ID3DXSprite::Draw...try setting your position as the pTranslation parameter of D3DXMatrixTransformation2D instead of the pPosition parameter of ID3DXSprite::Draw.
Like the above poster, I am using D3DXMatrixTransformation2D(...) to rotate my sprite, but I am only performing the translation with the ID3DXSprite::Draw() function. Both D3DXMatrixTransformation2D() and Draw() take translation parameters, but only D3DXMatrixTransformation2D() takes a rotation parameter. Since Draw(...) takes the matrix created by D3DXMatrixTransformation2D(...), I figure I can pass it that matrix for the rotation, and restrict rotation to the Draw() function.
That way, I only need to recalculate a new rotation matrix whenever my sprite rotates (instead of when it rotates OR translates), which should be good because I rotate rarely, but I translate every frame (either the sprite moves or the camera moves). If my sprite hasn't rotated last frame, I can use the previously stored matrix from the last time I called D3DXMatrixTransformation2D(), which was the last time it rotated.
Of course, doing that resulted in the error the OP had - it appeared as if the translation would occur before the rotation. Because rotation is supposed to happen around the origin, this means the sprite rotates around a fixed point and "swings" outward.
My question is - why is this? And can this be avoided somehow (so that I can go with my original plan to only calculate new matrices upon rotations)? My inference is that the Draw(...) function, which takes both a transform matrix and a translation vector, will apply the translation vector (if it's not NULL) before applying the transform matrix.
Is this true? If so, why bother accepting both transform matrices and translation vectors? I can't think of any practical scenarios where you would want both, given how they interfere with one another in such a non-intuitive way.
And what exactly is going on under the hood, when I pass both a transform matrix and a translation vector to Draw()? Is it calculating a translation transform matrix from my translation vector, multiplying that against the transform matrix I passed it, and then using that for the final sprite? Or is it managing some optimized shortcut (which would make it faster than manually calculating each transform matrix - INCLUDING the translation - myself using D3DXMatrixTransformation2D() during every frame?)
And again, is there any way to achieve the effect I desired? The only way that comes to mind is to calculate both rotation and translation matrices independently, and then multiply them when either one changes. That way I'm only calculating rotation matrices when it rotates (which is rare), and translation matrices when it translates (which is every frame) and multiplying them when either changes (which is every frame) - but again, if that's all going on under the hood via D3DXMatrixTransformation2D() and Draw() anyway, I suppose I might as well, right? The only cost is extra storage for the independent rotation and translation matrices.
#10 Members - Reputation: 100
Posted 11 July 2011 - 08:10 AM
I have used many times, with Rotations, Translation and Scaling and it works well.
You have to pay attention to sequence of trasformations... See Mout formula at http://msdn.microsoft.com/en-us/library/bb205366(v=vs.85).aspx
How you can see Traslation is last trasformation ( Mt ).
Mout = (Msc)-1* (Msr)-1* Ms * Msr * Msc * (Mrc)-1* Mr * Mrc * Mt
Remember that Scaling is before Rotation that is before Translation
Regards,
Max.
#11 Members - Reputation: 163
Posted 12 July 2011 - 12:18 AM
Draw is not bugged.
I have used many times, with Rotations, Translation and Scaling and it works well.
You have to pay attention to sequence of trasformations... See Mout formula at http://msdn.microsof...6(v=vs.85).aspx
How you can see Traslation is last trasformation ( Mt ).
Mout = (Msc)-1* (Msr)-1* Ms * Msr * Msc * (Mrc)-1* Mr * Mrc * Mt
Remember that Scaling is before Rotation that is before Translation
Regards,
Max.
Did you read all the posts before yours? The issue is not that D3DXMatrixTransformation2D() translates before rotating. The issue is, if you rotate using a matrix generated by D3DXMatrixTransformation2D(), but leave the translation for Draw() (as opposed to also incorporating it in the matrix generated by D3DXMatrixTransformation2D() with your rotation), then Draw() will apply the translation BEFORE the rotation.
I can show you example code if you want, but I think it has now been well established by the previous posts.
The reasons I bumped this 2-year old thread was not to have the exact same conclusion repeated. It was because I have a number of questions I would like to know the answers to, in my previous post.






