This answer will help if you want to use a textured quad, but not if you want to use a series of pre-rotated sprites.
First, determine the pivot point of your sprite. If your sprite is 32x32
and you want to spin the sprite around its center, then its pivot point will be (16, 16)
. Simple.
const tb::Vec2& pivot = m_Sprite->GetPivot();
const tb::Vec2& dim = m_Sprite->GetDimensions();
Then, create a 2D matrix. In your case, you want:
tb::Mat3x3 transform;
transform.Identity();
transform.AddRotation(angle);
transform.AddTranslation(m_Position);
2D matrices are really easy. Here's what the final matrix looks like from the inside:
float rads = tb::Math::DegToRad(m_Rotation);
values[X1] = -tb::Math::Sin(rads);
values[Y1] = tb::Math::Cos(rads);
values[WX] = 0.f;
values[X2] = tb::Math::Cos(rads);
values[Y2] = tb::Math::Sin(rads);
values[WY] = 0.f;
values[TX] = m_Position.x;
values[TY] = m_Position.y;
values[CZ] = 1.f;
Construct four corner points in object space. That sounds difficult, but it looks like this:
tb::Vec2 pos_ul = tb::Vec2(m_Position.x - pivot.x, m_Position.y - pivot.y );
tb::Vec2 pos_ur = tb::Vec2(m_Position.x - pivot.x + dim.x, m_Position.y - pivot.y );
tb::Vec2 pos_ll = tb::Vec2(m_Position.x - pivot.x , m_Position.y - pivot.y + dim.y);
tb::Vec2 pos_lr = tb::Vec2(m_Position.x - pivot.x + dim.x, m_Position.y - pivot.y + dim.y);
Using your matrix, you can transform those corner points:
pos_ul = transform * pos_ul;
pos_ur = transform * pos_ur;
pos_ll = transform * pos_ll;
pos_lr = transform * pos_lr;
And now you can use those coordinates for a textured quad.
For future reference:
- Any transformation can be done with a matrix.
- Try getting the end result you want without a matrix first and then try to turn it into a single matrix.
- Math is your friend!