#pragma once #include "Utils.h" /// /// Affine2D class. /// namespace EmberNs { /// /// Uses matrix composition to handle the /// affine matrix. Taken almost entirely from /// Fractron, but using glm, and in C++. /// Note that the matrix layout differs from flam3 so it's best to use /// the A, B, C, D, E, F wrappers around the underlying matrix indices. But if the matrix must /// be accessed directly, the two are laid out as such: /// flam3: 3 columns of 2 rows each. Accessed col, row. /// [a(0,0)][b(1,0)][c(2,0)] /// [d(0,1)][e(1,1)][f(2,1)] /// Ember: 2 columns of 3 rows each. Accessed col, row. /// [a(0,0)][d(1,0)] /// [b(0,1)][e(1,1)] /// [c(0,2)][f(1,2)] /// Template argument expected to be float or double. /// template class EMBER_API Affine2D { public: Affine2D(); Affine2D(const Affine2D& affine); /// /// Copy constructor to copy an Affine2D object of type U. /// Special case that must be here in the header because it has /// a second template parameter. /// /// The Affine2D object to copy template Affine2D(const Affine2D& affine) { Affine2D::operator=(affine); } Affine2D(v2T& x, v2T& y, v2T& t); Affine2D(T xx, T xy, T yx, T yy, T tx, T ty); Affine2D(m4T& mat); Affine2D& operator = (const Affine2D& affine); /// /// Assignment operator to assign an Affine2D object of type U. /// Special case that must be here in the header because it has /// a second template parameter. /// /// The Affine2D object to copy. /// Reference to updated self template Affine2D& operator = (const Affine2D& affine) { A(T(affine.A())); B(T(affine.B())); C(T(affine.C())); D(T(affine.D())); E(T(affine.E())); F(T(affine.F())); return *this; } bool operator == (const Affine2D& affine); v2T operator * (const v2T& v); Affine2D operator * (const T& t); void MakeID(); bool IsID() const; bool IsZero() const; bool IsEmpty() const; void Scale(T amount); void ScaleXY(T amount); Affine2D ScaleCopy(T amount); void Rotate(T rad); void RotateTrans(T rad); void Translate(const v2T& v); void RotateScaleXTo(const v2T& v); void RotateScaleYTo(const v2T& v); Affine2D Inverse() const; v2T TransformNormal(const v2T& v) const; v2T TransformVector(const v2T& v) const; m2T ToMat2ColMajor() const; m2T ToMat2RowMajor() const; m4T ToMat4ColMajor(bool center = false) const; m4T ToMat4RowMajor(bool center = false) const; m4T TransToMat4ColMajor() const; //Note that returning a copy is actually faster than a const ref&. T A() const; T B() const; T C() const; T D() const; T E() const; T F() const; void A(T a); void B(T b); void C(T c); void D(T d); void E(T e); void F(T f); v2T X() const; v2T Y() const; v2T O() const; void X(const v2T& x); void Y(const v2T& y); void O(const v2T& t); string ToString() const; static Affine2D CalcRotateScale(const v2T& from, const v2T& to); static void CalcRSAC(const v2T& from, const v2T& to, T& a, T& c); m23T m_Mat; }; }