DirectXMath.h 라이브러리에서 4×4 Matrix를 나타내는 데에는 XMMATRIX라는 클래스가 쓰인다.

struct XMMATRIX;

// Fix-up for (1st) XMMATRIX parameter to pass in-register for ARM64 and vector call; by reference otherwise
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMMATRIX FXMMATRIX;
#else
typedef const XMMATRIX& FXMMATRIX;
#endif

// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX;

#ifdef _XM_NO_INTRINSICS_
struct XMMATRIX
#else
__declspec(align(16)) struct XMMATRIX
#endif
{
#ifdef _XM_NO_INTRINSICS_
    union
    {
        XMVECTOR r[4];
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
            float _41, _42, _43, _44;
        };
        float m[4][4];
    };
#else
    XMVECTOR r[4];
#endif

    XMMATRIX() = default;

    XMMATRIX(const XMMATRIX&) = default;

#if defined(_MSC_VER) && (_MSC_FULL_VER < 191426431)
    XMMATRIX& operator= (const XMMATRIX& M) noexcept { r[0] = M.r[0]; r[1] = M.r[1]; r[2] = M.r[2]; r[3] = M.r[3]; return *this; }
#else
    XMMATRIX& operator=(const XMMATRIX&) = default;

    XMMATRIX(XMMATRIX&&) = default;
    XMMATRIX& operator=(XMMATRIX&&) = default;
#endif

    constexpr XMMATRIX(FXMVECTOR R0, FXMVECTOR R1, FXMVECTOR R2, CXMVECTOR R3) : r{ R0,R1,R2,R3 } {}
    XMMATRIX(float m00, float m01, float m02, float m03,
             float m10, float m11, float m12, float m13,
             float m20, float m21, float m22, float m23,
             float m30, float m31, float m32, float m33);
    explicit XMMATRIX(_In_reads_(16) const float *pArray);

#ifdef _XM_NO_INTRINSICS_
    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
#endif

    XMMATRIX    operator+ () const { return *this; }
    XMMATRIX    operator- () const;

    XMMATRIX&   XM_CALLCONV     operator+= (FXMMATRIX M);
    XMMATRIX&   XM_CALLCONV     operator-= (FXMMATRIX M);
    XMMATRIX&   XM_CALLCONV     operator*= (FXMMATRIX M);
    XMMATRIX&   operator*= (float S);
    XMMATRIX&   operator/= (float S);

    XMMATRIX    XM_CALLCONV     operator+ (FXMMATRIX M) const;
    XMMATRIX    XM_CALLCONV     operator- (FXMMATRIX M) const;
    XMMATRIX    XM_CALLCONV     operator* (FXMMATRIX M) const;
    XMMATRIX    operator* (float S) const;
    XMMATRIX    operator/ (float S) const;

    friend XMMATRIX     XM_CALLCONV     operator* (float S, FXMMATRIX M);
};

XMMATRIX는 SIMD의 장점을 취하기 위해 4개의 XMVECTOR Instance를 사용한다.

또한 Matrix 곱셈을 위한 연산자와 한 성분을 그 Row와 Column의 색인들을 지정해 접근/수정하기 위한 대괄호 연산자를 중복적재하고 있다.

 

또한 XMMATRIX를 이용해 선언된 FXMMATRIX와 CXMMATRIX가 있다.

이 둘의 설명은 주석을 통해 충분히 이해가 가겠지만, 다시 한번 언급을 해두려 한다.

보통 XMMATRIX를 Parameter로 전달 할 때에는 CXMMATRIX를 사용한다.

하지만 특수한 경우에 FXMMATRIX를 사용해야 하기도 하는데

  • 첫번째 XMMATRIX일 것
  • 위 XMMATRIX 변수 앞에 XMVECTOR가 3개 이상 존재하지 않을 것
  • 위 XMMATRIX 변수 뒤에 2개 이상의 float나 double, XMVECTOR가 존재하지 않을 것

 

생성자의 경우에는 항상 CXMMATRIX만 사용하는 것을 권장한다.

 

XMMATRIX에서는 다양한 생성자 외에, XMMatrixSet이라는 함수로도 Instance 생성이 가능하다.

XMMATRIX    XM_CALLCONV     XMMatrixSet(float m00, float m01, float m02, float m03,
                                        float m10, float m11, float m12, float m13,
                                        float m20, float m21, float m22, float m23,
                                        float m30, float m31, float m32, float m33);

Matrix를 클래스 자료 멤버로 저장할 때에는 Vector를 XMFLOAT2나 XMFLOAT3, XMFLOAT4를 사용한 것과 같이 XMFLOAT4X4나 XMFLOAT3X4, XMFLOAT4X3을 사용하는 것이 권장된다.

// 3x3 Matrix: 32 bit floating point components
struct XMFLOAT3X3
{
    union
    {
        struct
        {
            float _11, _12, _13;
            float _21, _22, _23;
            float _31, _32, _33;
        };
        float m[3][3];
    };

    XMFLOAT3X3() = default;

    XMFLOAT3X3(const XMFLOAT3X3&) = default;
    XMFLOAT3X3& operator=(const XMFLOAT3X3&) = default;

    XMFLOAT3X3(XMFLOAT3X3&&) = default;
    XMFLOAT3X3& operator=(XMFLOAT3X3&&) = default;

    XM_CONSTEXPR XMFLOAT3X3(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22)
        : _11(m00), _12(m01), _13(m02),
          _21(m10), _22(m11), _23(m12),
          _31(m20), _32(m21), _33(m22) {}
    explicit XMFLOAT3X3(_In_reads_(9) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

//------------------------------------------------------------------------------
// 4x3 Row-major Matrix: 32 bit floating point components
struct XMFLOAT4X3
{
    union
    {
        struct
        {
            float _11, _12, _13;
            float _21, _22, _23;
            float _31, _32, _33;
            float _41, _42, _43;
        };
        float m[4][3];
        float f[12];
    };

    XMFLOAT4X3() = default;

    XMFLOAT4X3(const XMFLOAT4X3&) = default;
    XMFLOAT4X3& operator=(const XMFLOAT4X3&) = default;

    XMFLOAT4X3(XMFLOAT4X3&&) = default;
    XMFLOAT4X3& operator=(XMFLOAT4X3&&) = default;

    XM_CONSTEXPR XMFLOAT4X3(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22,
                            float m30, float m31, float m32)
        : _11(m00), _12(m01), _13(m02),
          _21(m10), _22(m11), _23(m12),
          _31(m20), _32(m21), _33(m22),
          _41(m30), _42(m31), _43(m32) {}
    explicit XMFLOAT4X3(_In_reads_(12) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 4x3 Row-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT4X3A : public XMFLOAT4X3
{
    XMFLOAT4X3A() = default;

    XMFLOAT4X3A(const XMFLOAT4X3A&) = default;
    XMFLOAT4X3A& operator=(const XMFLOAT4X3A&) = default;

    XMFLOAT4X3A(XMFLOAT4X3A&&) = default;
    XMFLOAT4X3A& operator=(XMFLOAT4X3A&&) = default;

    XM_CONSTEXPR XMFLOAT4X3A(float m00, float m01, float m02,
                            float m10, float m11, float m12,
                            float m20, float m21, float m22,
                            float m30, float m31, float m32) :
        XMFLOAT4X3(m00,m01,m02,m10,m11,m12,m20,m21,m22,m30,m31,m32) {}
    explicit XMFLOAT4X3A(_In_reads_(12) const float *pArray) : XMFLOAT4X3(pArray) {}
};

//------------------------------------------------------------------------------
// 3x4 Column-major Matrix: 32 bit floating point components
struct XMFLOAT3X4
{
    union
    {
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
        };
        float m[3][4];
        float f[12];
    };

    XMFLOAT3X4() = default;

    XMFLOAT3X4(const XMFLOAT3X4&) = default;
    XMFLOAT3X4& operator=(const XMFLOAT3X4&) = default;

    XMFLOAT3X4(XMFLOAT3X4&&) = default;
    XMFLOAT3X4& operator=(XMFLOAT3X4&&) = default;

    XM_CONSTEXPR XMFLOAT3X4(float m00, float m01, float m02, float m03,
                            float m10, float m11, float m12, float m13,
                            float m20, float m21, float m22, float m23)
        : _11(m00), _12(m01), _13(m02), _14(m03),
          _21(m10), _22(m11), _23(m12), _24(m13),
          _31(m20), _32(m21), _33(m22), _34(m23) {}
    explicit XMFLOAT3X4(_In_reads_(12) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 3x4 Column-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT3X4A : public XMFLOAT3X4
{
    XMFLOAT3X4A() = default;

    XMFLOAT3X4A(const XMFLOAT3X4A&) = default;
    XMFLOAT3X4A& operator=(const XMFLOAT3X4A&) = default;

    XMFLOAT3X4A(XMFLOAT3X4A&&) = default;
    XMFLOAT3X4A& operator=(XMFLOAT3X4A&&) = default;

    XM_CONSTEXPR XMFLOAT3X4A(float m00, float m01, float m02, float m03,
                             float m10, float m11, float m12, float m13,
                             float m20, float m21, float m22, float m23) :
        XMFLOAT3X4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23) {}
    explicit XMFLOAT3X4A(_In_reads_(12) const float *pArray) : XMFLOAT3X4(pArray) {}
};

//------------------------------------------------------------------------------
// 4x4 Matrix: 32 bit floating point components
struct XMFLOAT4X4
{
    union
    {
        struct
        {
            float _11, _12, _13, _14;
            float _21, _22, _23, _24;
            float _31, _32, _33, _34;
            float _41, _42, _43, _44;
        };
        float m[4][4];
    };

    XMFLOAT4X4() = default;

    XMFLOAT4X4(const XMFLOAT4X4&) = default;
    XMFLOAT4X4& operator=(const XMFLOAT4X4&) = default;

    XMFLOAT4X4(XMFLOAT4X4&&) = default;
    XMFLOAT4X4& operator=(XMFLOAT4X4&&) = default;

    XM_CONSTEXPR XMFLOAT4X4(float m00, float m01, float m02, float m03,
                            float m10, float m11, float m12, float m13,
                            float m20, float m21, float m22, float m23,
                            float m30, float m31, float m32, float m33)
        : _11(m00), _12(m01), _13(m02), _14(m03),
          _21(m10), _22(m11), _23(m12), _24(m13),
          _31(m20), _32(m21), _33(m22), _34(m23),
          _41(m30), _42(m31), _43(m32), _44(m33) {}
    explicit XMFLOAT4X4(_In_reads_(16) const float *pArray);

    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
};

// 4x4 Matrix: 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT4X4A : public XMFLOAT4X4
{
    XMFLOAT4X4A() = default;

    XMFLOAT4X4A(const XMFLOAT4X4A&) = default;
    XMFLOAT4X4A& operator=(const XMFLOAT4X4A&) = default;

    XMFLOAT4X4A(XMFLOAT4X4A&&) = default;
    XMFLOAT4X4A& operator=(XMFLOAT4X4A&&) = default;

    XM_CONSTEXPR XMFLOAT4X4A(float m00, float m01, float m02, float m03,
                             float m10, float m11, float m12, float m13,
                             float m20, float m21, float m22, float m23,
                             float m30, float m31, float m32, float m33)
        : XMFLOAT4X4(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33) {}
    explicit XMFLOAT4X4A(_In_reads_(16) const float *pArray) : XMFLOAT4X4(pArray) {}
};

 

또한 Matrix와 관련된 여러 기능들에 대한 함수도 지원을 한다.

bool        XM_CALLCONV     XMMatrixIsNaN(FXMMATRIX M);
bool        XM_CALLCONV     XMMatrixIsInfinite(FXMMATRIX M);
bool        XM_CALLCONV     XMMatrixIsIdentity(FXMMATRIX M);

XMMATRIX    XM_CALLCONV     XMMatrixMultiply(FXMMATRIX M1, CXMMATRIX M2);
XMMATRIX    XM_CALLCONV     XMMatrixMultiplyTranspose(FXMMATRIX M1, CXMMATRIX M2);
XMMATRIX    XM_CALLCONV     XMMatrixTranspose(FXMMATRIX M);
XMMATRIX    XM_CALLCONV     XMMatrixInverse(_Out_opt_ XMVECTOR* pDeterminant, _In_ FXMMATRIX M);
XMVECTOR    XM_CALLCONV     XMMatrixDeterminant(FXMMATRIX M);
_Success_(return)
bool        XM_CALLCONV     XMMatrixDecompose(_Out_ XMVECTOR *outScale, _Out_ XMVECTOR *outRotQuat, _Out_ XMVECTOR *outTrans, _In_ FXMMATRIX M);

XMMATRIX    XM_CALLCONV     XMMatrixIdentity();

물론 이런 함수에는 Transformation 함수도 포함되어 있다.

XMMATRIX    XM_CALLCONV     XMMatrixTranslation(float OffsetX, float OffsetY, float OffsetZ);
XMMATRIX    XM_CALLCONV     XMMatrixTranslationFromVector(FXMVECTOR Offset);
XMMATRIX    XM_CALLCONV     XMMatrixScaling(float ScaleX, float ScaleY, float ScaleZ);
XMMATRIX    XM_CALLCONV     XMMatrixScalingFromVector(FXMVECTOR Scale);
XMMATRIX    XM_CALLCONV     XMMatrixRotationX(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationY(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationZ(float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationRollPitchYaw(float Pitch, float Yaw, float Roll);
XMMATRIX    XM_CALLCONV     XMMatrixRotationRollPitchYawFromVector(FXMVECTOR Angles);
XMMATRIX    XM_CALLCONV     XMMatrixRotationNormal(FXMVECTOR NormalAxis, float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationAxis(FXMVECTOR Axis, float Angle);
XMMATRIX    XM_CALLCONV     XMMatrixRotationQuaternion(FXMVECTOR Quaternion);
XMMATRIX    XM_CALLCONV     XMMatrixTransformation2D(FXMVECTOR ScalingOrigin, float ScalingOrientation, FXMVECTOR Scaling,
                                                     FXMVECTOR RotationOrigin, float Rotation, GXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixTransformation(FXMVECTOR ScalingOrigin, FXMVECTOR ScalingOrientationQuaternion, FXMVECTOR Scaling,
                                                   GXMVECTOR RotationOrigin, HXMVECTOR RotationQuaternion, HXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixAffineTransformation2D(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, float Rotation, FXMVECTOR Translation);
XMMATRIX    XM_CALLCONV     XMMatrixAffineTransformation(FXMVECTOR Scaling, FXMVECTOR RotationOrigin, FXMVECTOR RotationQuaternion, GXMVECTOR Translation);

 

+ Recent posts