#include <windows.h> // XMVerifyCPUSupport
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <iostream>
typedef __m128 XMVECTOR;
/*
컴파일러에 따라 SSE/SSE2 레지스터를 통해서 전달될 수 있는 인수의 형식이 다르다.
플랫폼/컴파일러 에 대한 의존성을 없애기 위해 FXMVECTOR, GXMVECTOR, HXMVECTOR, CXMVECTOR 형식을 사용해야 하며,
호출규약 역시 컴파일러에 따라서 다를 수 있는데, 그러한 의존성을 없애기 위해서 XM_CALLCONV 라는 호출규약지시자를 붙여야 한다.
win32 __fastcall 지원하는 컴파일러에서 형식 정의
XMVECTOR FXMVECTOR; // 레지스터 전달 ( 첫 3개 )
XMVECTOR& GXMVECTOR, HXMVECTOR, CXMVECTOR; // 스택 사용
win32 __vectorcall 지원하는 컴파일러에서의 형식정의
XMVECTOR FXMVECTOR, GXMVECTOR, HXMVECTOR; // 레지스터 전달 ( 첫 6개 )
XMVECTOR& CXMVECTOR; // 스택사용
함수에 전달되는 XMVECTOR 형식의 인수 순번에 따라 사용되는 형식이 다르다.
XMVECTOR XM_CALLCONV FunctionName ( FXMVECTOR, FXMVECTOR, FXMVECTOR, GXMVECTOR, HXMVECOTR, HXMVECTOR, CXMVECTOR, .... );
생성자 함수의 경우 다른 규칙이 적용된다.
XM_CALLCONV 사용금지, 처음 3개 FXMVECTOR, 나머지 CXMVECTOR 사용
XMVECTOR ConstructorName ( FXMVECTOR, FXMVECTOR, FXMVECTOR, CXMVECTOR, ... )
*/
typedef const XMVECTOR FXMVECTOR;
typedef const XMVECTOR GXMVECTOR;
typedef const XMVECTOR HXMVECTOR;
typedef const XMVECTOR CXMVECTOR;
struct XMFLOAT2;
struct XMFLOAT3;
struct XMFLOAT4;
struct XMVECTORF32; // 상수 벡터
struct XMVECTORV32; // 정수형 상수 벡터
struct XMMATRIX{
XMVECTOR r[4];
}
/**
컴파일러가 지원하는 호출 규약에 따라서 형식이 다르다.
win32 에서 __fastcall 만 지원하는 컴파일러로는 XMMATRIX 매개변수를 SSE/SSE2 레지스터들을 통해서 함수에 전달할 수 없다.
이 경우 XMMATRIX 인스턴스는 스택을 통해서 참조로 전달된다.
win32 __fastcall 지원하는 컴파일러에서의 형식 정의
XMMATRIX& FXMMATRIX;
XMMATRIX& CXMMATRIX;
win32 __vectorcall 지원하는 컴파일러에서의 형식 정의
XMMATRIX FXMMATRIX;
XMMATRIX& CXMMATRIX;
생성자에서는 XM_CALLCONV 호출규약지시자를 사용하지 말아야 하며, 항상 CXMMATRIX 를 사용하라 권한다.
*/
typedef const XMMATRIX FXMMATRIX;
typedef const XMMATRIX CXMMATRIX;
struct XMVFLOAT4X4{
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];
}
};
const float XM_PI = 3.141592654f;
const float XM_2PI = 6.283185307f;
const float XM_1DIVPI = 0.318309886f; // 1/π
const float XM_2DIVPI = 0.159154943f; // 2/π
const float XM_PIDIV2 = 1.570796327f; // π/2
const float XM_PIDIV4 = 0.785398163f; // π/4
float XMConvertToRadians(float fDegrees); // return XM_PI / 180.0f; (π/180°)
float XMConvertToDegrees(float fRadians); // return 180.0f / XM_PI; (180°/π)
using namespace DirectX;
using namespace DirectX::PackedVector;
XMVECTOR XM_CALLCONV XMLoadFloat2(const XMFLOAT2* pSource);
XMVECTOR XM_CALLCONV XMLoadFloat3(const XMFLOAT3* pSource);
XMVECTOR XM_CALLCONV XMLoadFloat4(const XMFLOAT4* pSource);
void XM_CALLCONV XMStoreFloat2(XMFLOAT2* pDestination, FXMVECTOR V);
void XM_CALLCONV XMStoreFloat3(XMFLOAT3* pDestination, FXMVECTOR V);
void XM_CALLCONV XMStoreFloat4(XMFLOAT4* pDestination, FXMVECTOR V);
float XM_CALLCONV XMVectorGetX(FXMVECTOR V);
float XM_CALLCONV XMVectorGetY(FXMVECTOR V);
float XM_CALLCONV XMVectorGetZ(FXMVECTOR V);
float XM_CALLCONV XMVectorGetW(FXMVECTOR V);
XMVECTOR XM_CALLCONV XMVectorSetX(FXMVECTOR V, float x);
XMVECTOR XM_CALLCONV XMVectorSetY(FXMVECTOR V, float y);
XMVECTOR XM_CALLCONV XMVectorSetZ(FXMVECTOR V, float z);
XMVECTOR XM_CALLCONV XMVectorSetW(FXMVECTOR V, float w);
/** 0 벡터 반환 */
XMVECTOR XM_CALLCONV XMVectorZero();
/** 벡터 (1,1,1,1) 반환 */
XMVECTOR XM_CALLCONV XMVectorSplatOne();
/** 벡터 (x,y,z,w) 반환 */
XMVECTOR XM_CALLCONV XMVectorSet(float x, float y, float z, float w);
/** 벡터 (s,s,s,s) 반환 */
XMVECTOR XM_CALLCONV XMVectorReplicate(float Value);
/** 벡터 (Vx, Vx, Vx, Vx) 반환 */
XMVECTOR XM_CALLCONV XMVectorSplatX(FXMVECTOR V);
/** 벡터 (Vy, Vy, Vy, Vy) 반환 */
XMVECTOR XM_CALLCONV XMVectorSplatY(FXMVECTOR V);
/** 벡터 (Vz, Vz, Vz, Vz) 반환 */
XMVECTOR XM_CALLCONV XMVectorSplatZ(FXMVECTOR V);
/** 벡터 (Vw, Vw, Vw, Vw) 반환 */
XMVECTOR XM_CALLCONV XMVectorSplatW(FXMVECTOR V);
/** ‖V‖ 반환 */
XMVECTOR XM_CALLCONV XMVector3Length(FXMVECTOR V);
/** ‖V‖² 반환 */
XMVECTOR XM_CALLCONV XMVector3LengthSq(FXMVECTOR V);
/** 내적 V₁∙V₂ */
XMVECTOR XM_CALLCONV XMVector3Dot(FXMVECTOR V1, FXMVECTOR V2);
/** 외적 V₁×V₂ */
XMVECTOR XM_CALLCONV XMVector3Cross(FXMVECTOR V1, FXMVECTOR V2);
/** 정규화. 단위벡터 반환 V/‖V‖ */
XMVECTOR XM_CALLCONV XMVector3Normalize(FXMVECTOR V);
/** 수직벡터 반환 */
XMVECTOR XM_CALLCONV XMVector3Othogonal(FXMVECTOR V);
/** 두 벡터 사이의 각도 반환 */
XMVECTOR XM_CALLCONV XMVector3AngleBetweenVector(FXMVECTOR V1, FXMVECTOR V2);
/** 벡터의 구성요소 반환 */
void XM_CALLCONV XMVector3ComponentsFromNormal(
XMVECTOR* pParallel, // Projn(V) 를 돌려준다.
XMVECTOR* pPerpendicular, // Propn(V) 를 돌려준다.
FXMVECTOR V, // 입력 V
FXMVECTOR Normal // 입력 n
);
/** V1 == V2 ? */
bool XM_CALLCONV XMVector3Equal(FXMVECTOR V1, FXMVECTOR V2);
/** V1 != V2 ? */
bool XM_CALLCONV XMVector3NotEqual(FXMVECTOR V1, FXMVECTOR V2);
/** V1 == V2 Near ? */
bool XM_CALLCONV XMVector3NearEqual(FXMVECTOR V1, FXMVECTOR V2);
/** 벡터의 각 요소를 절대값 한다. */
XMVECTOR XM_CALLCONV XMVectorAbs(FXMVECTOR V);
/** 벡터의 각 요소를 라디안으로 하여 코사인 계산 한다. */
XMVECTOR XM_CALLCONV XMVectorCos(FXMVECTOR V);
/** 벡터의 각 요소를 라디안으로 하여 사인계산 한다. */
XMVECTOR XM_CALLCONV XMVectorSin(FXMVECTOR V);
/** 벡터의 각 요소를 2ⁿ 한다. */
XMVECTOR XM_CALLCONV XMVectorExp(FXMVECTOR V);
/** 벡터의 각 요소에 제곱근을 적용한다. */
XMVECTOR XM_CALLCONV XMVectorSqrt(FXMVECTOR V);
/** 벡터의 각 요소를 밑이 2인 로그 계산 */
XMVECTOR XM_CALLCONV XMVectorLog(FXMVECTOR V);
/** 벡터의 각 요소를 밑이 자연로그 e인 로그 계산 */
XMVECTOR XM_CALLCONV XMVectorLogE(FXMVECTOR V);
/** 두개 벡터의 각 요소를 가지고 제곱계산 한다. 첫번째 벡터의 요소는 밑으로, 두번째 벡터의 요소는 지수로 계산한다 */
XMVECTOR XM_CALLCONV XMVectorPow(FXMVECTOR V1, FXMVECTOR V2);
/** 두개 벡터의 각 요소중 작은 값만 가지고 벡터를 반환한다 */
XMVECTOR XM_CALLCONV XMVectorMin(FXMVECTOR V1, FXMVECTOR V2);
/** 두개 벡터의 각 요소중 큰 값만 가지고 벡터를 반환한다. */
XMVECTOR XM_CALLCONV XMVectorMax(FXMVECTOR V1, FXMVECTOR V2);
/** 벡터의 각 요소의 순서를 재배치 합니다. 배치순서는 0~3 의 값만 넣어야 합니다. */
XMVECTOR XM_CALLCONV XMVectorSwizzle(FXMVECTOR V, uint32_t E0, uint32_t E1, uint32_t E2, uint32_t E3);
/** 벡터의 각 요소를 0~1 사이 값으로 제한합니다. */
XMVECTOR XM_CALLCONV XMVectorSaturate(FXMVECTOR V);
/** XMMatrix 인스턴스 생성함수 */
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
)
/** XMFLOAT4X4 의 데이터를 XMMATRIX 에 적재 */
XMMATRIX XM_CALLCONV XMLoadFloat4x4(const XMFLOAT4X4* pSource);
/** XMMATRIX 의 데이터를 XMFLOAT4X4 에 저장 */
void XM_CALLCONV XMStoreFloat4x4(XMFLOAT4X4* pDestination, FXMMATRIX M);
/** 단위행렬 반환 */
XMMATRIX XM_CALLCONV XMMatrixIdentity();
/** 단위행렬인지 여부 반환 */
bool XM_CALLCONV XMMatrixIsIdentity(FXMMATRIX M);
/** 행렬 곱 반환 */
XMMATRIX XM_CALLCONV XMMatrixMultiply(FXMMATRIX A, FXMMATRIX B);
/** 전치행렬 반환 */
XMMATRIX XM_CALLCONV XMMatrixTranspose(FXMMATRIX M);
/** 행렬식 반환 */
XMVECTOR XM_CALLCONV XMMatrixDeterminant(FXMMATRIX M);
/** 역행렬 반환 */
XMVECTOR XM_CALLCONV XMMatrixInverse(XMVECTOR* pDeterminant, FXMMATRIX M);
/** 비례행렬 생성 */
XMMATRIX XM_CALLCONV XMMatrixScaling(
float ScaleX; // 비례계수
float ScaleY; // 비례계수
float ScaleZ; // 비례계수
)
/** 벡터의 성분들로 비례행렬 생성. 비례계수가 (Sx, Sy, Sz) 가 된다. */
XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(FXMVECTOR Scale);
/** x 축에 대한 회전행렬 Rx 생성. 시계방향 회전각을 라디안값으로 입력받는다. */
XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle);
/** y 축에 대한 회전행렬 Ry 생성. 시계방향 회전각을 라디안값으로 입력받는다. */
XMMATRIX XM_CALLCONV XMMatrixRotationY(float Angle);
/** z 축에 대한 회전행렬 Rz 생성. 시계방향 회전각을 라디안값으로 입력받는다. */
XMMATRIX XM_CALLCONV XMMatrixRotationZ(float Angle);
/** 임의의 축에대한 회전행렬 Rn 생성. 축으로 활용될 벡터와, 시계방향 회전각을 라디안값으로 입력받는다. */
XMMATRIX XM_CALLCONV XMMatrixRotationAxis(FXMVECTOR Axis, float Angle);
/** 이동행렬 생성 */
XMMATRIX XM_CALLCONV XMMatrixTranslation(float OffsetX, float OffsetY, float OffsetZ);
/** 벡터의 성분들로 이동행렬 생성 */
XMMATRIX XM_CALLCONV XMMatrixTranslationFromVector(FXMVECTOR Offset);
/** 벡터 대 행렬 곱 vM, 점 변환을 위해 Vw = 1 로 둔다.*/
XMVECTOR XM_CALLCONV XMVector3TransformCoord(FXMVECTOR V, CXMMATRIX M)
/** 벡터 대 행렬 곱 vM, 벡터 변환을 위해 Vw = 0 로 둔다 */
XMVECTOR XM_CALLCONV XMVector3TransfromNormal(FXMVECTOR V, CXMMATRIX M);
/** XMVECTOR 객체를 cout 으로 출력할 수 있도록 << 연산자 중복 적재 */
ostream& XM_CALLCONV operator << (ostream& os, FXMVECTOR v){
XMFLOAT4 dest;
XMStoreFloat4(&dest, v);
os << "(" << dest.x << "," << dest.y << "," << dest.z << ")";
return os;
}
/** XMMATRIX 객체를 cout 으로 출력할 수 있도록 << 연산자 중복 적재 */
ostream& XM_CALLCONV operator << (ostream& os, FXMMATRIX m){
for(int i = 0 ; i < 4 ; ++i)
{
os << XMVectorGetX(m.r[i]) << "\t";
os << XMVectorGetY(m.r[i]) << "\t";
os << XMVectorGetZ(m.r[i]) << "\t";
os << XMVectorGetW(m.r[i]);
os << endl;
}
return os;
}
/** SSE2 를 지원하는지(Pentium4, AMD K8 이상) 확인한다 */
if(!XMVerifyCPUSupport())
{
cout << "DirectXMath를 지원하지 않음" << endl;
return 0;
}