openclonk/src/graphics/C4BltTransform.h

72 lines
2.5 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#ifndef INC_C4BltTransform
#define INC_C4BltTransform
// rotation info class
class C4BltTransform
{
public:
float mat[9]; // transformation matrix
public:
C4BltTransform() = default; // default: don't init fields
void Set(float fA, float fB, float fC, float fD, float fE, float fF, float fG, float fH, float fI)
{ mat[0]=fA; mat[1]=fB; mat[2]=fC; mat[3]=fD; mat[4]=fE; mat[5]=fF; mat[6]=fG; mat[7]=fH; mat[8]=fI; }
void SetRotate(float iAngle, float fOffX, float fOffY); // set by angle and rotation offset
bool SetAsInv(C4BltTransform &rOfTransform);
void Rotate(float Angle, float fOffX, float fOffY) // rotate by angle around rotation offset
{
// multiply matrix as seen in SetRotate by own matrix
C4BltTransform rot; rot.SetRotate(Angle, fOffX, fOffY);
(*this) *= rot;
}
void SetMoveScale(float dx, float dy, float sx, float sy)
{
mat[0] = sx; mat[1] = 0; mat[2] = dx;
mat[3] = 0; mat[4] = sy; mat[5] = dy;
mat[6] = 0; mat[7] = 0; mat[8] = 1;
}
void MoveScale(float dx, float dy, float sx, float sy)
{
// multiply matrix by movescale matrix
C4BltTransform move; move.SetMoveScale(dx,dy,sx,sy);
(*this) *= move;
}
void ScaleAt(float sx, float sy, float tx, float ty)
{
// scale and move back so tx and ty remain fixpoints
MoveScale(-tx*(sx-1), -ty*(sy-1), sx, sy);
}
C4BltTransform &operator *= (const C4BltTransform &r)
{
// transform transformation
Set(mat[0]*r.mat[0] + mat[3]*r.mat[1] + mat[6]*r.mat[2],
mat[1]*r.mat[0] + mat[4]*r.mat[1] + mat[7]*r.mat[2],
mat[2]*r.mat[0] + mat[5]*r.mat[1] + mat[8]*r.mat[2],
mat[0]*r.mat[3] + mat[3]*r.mat[4] + mat[6]*r.mat[5],
mat[1]*r.mat[3] + mat[4]*r.mat[4] + mat[7]*r.mat[5],
mat[2]*r.mat[3] + mat[5]*r.mat[4] + mat[8]*r.mat[5],
mat[0]*r.mat[6] + mat[3]*r.mat[7] + mat[6]*r.mat[8],
mat[1]*r.mat[6] + mat[4]*r.mat[7] + mat[7]*r.mat[8],
mat[2]*r.mat[6] + mat[5]*r.mat[7] + mat[8]*r.mat[8]);
return *this;
}
void TransformPoint(float &rX, float &rY) const; // rotate point by angle
};
#endif