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);
'내용정리 > DirectX12' 카테고리의 다른 글
07. DirectX12 template 프로젝트 분석 02 - 20.06.05 (0) | 2020.06.05 |
---|---|
07. DirectX12 template 프로젝트 분석 01 - 20.05.29 (0) | 2020.05.29 |
05. DirectXMath.h에서의 Vector 관련 기능 (0) | 2020.05.22 |
04. 기초 필수 수학 - Transform (0) | 2020.05.22 |
03. 기초 필수 수학 - Matrix (0) | 2020.05.15 |