XNA Math 라이브러리(벡터)

DirectX11/수학관련 2016. 7. 2. 16:30

* Direct3D 9 과 10에선 그래픽스에 필요한 벡터 및 다른 주요 3차원 수학 형식들을 지원하는 수학 유틸리티 라이브러리가 있지만 Direct11 라이브러리에는 3차원 수학코드가 포함되어 있지 않다.

(물론 d3dx10.h>를 포함시키고 d3dx10.lib를 링크해서 D3DX10 Math함수를 사용하는 것도 가능하다.

* XNA 라이브러리는 Windows와 Xbox360에서 사용가능한 특별한 하드웨어 레지스터들을 활용한다.

SIMD 명령 집합을 사용하기 때문에 float나 int네개를 한번에 처리할 수 있다.

- XNA라이브러리는 모든 코드가 인라인화 되어 있어서 헤더파일만 추가하고 따로 라이브러리를 링크할 필요가 없다.


1. XNA 라이브러리에서 벡터를 사용할 때

typedef __m128 XMVECTOR; XNA 라이브러리에서 벡터는 이렇게 선언되어 있다.

계산을 수행할 때 __m128형식은 SIMD의 장점을 취하게 된다.

하지만 XMVECTOR의 경우 16바이트 경계에 정렬되어야 하는데, 지역변수와 전역변수에서는 정렬이 자동으로 이루어진다. 클래스 자료 멤버의 경우에는 이 대신 XMFLOAT2, XMFLOAT3, XMFLOAT4를 사용하는 것이 바람직 하다.

이 구조체들은 이렇게 정의 된다.

typedef struct_XMFLOAT4{

FLOAT x;

FLOAT y;

FLOAT z;

FLOAT w;

} XMFLOAT4;


하지만 이 형식들은 SIMD의 장점을 취하지 못하므로 XMVECTOR형식으로 변환해서 계산해야 SIMD의 장점을 취할 수 있다.


* 적재 및 저장 함수들


XMFLOAT*를 XMVECTOR로

// XMFLOAT2 를 XMVECTOR2에 적재

XMVECTOR XMLoatFloat2( CONST XMFLOAT2 *pSource);


// XMFLOAT3 를 XMVECTOR3에 적재

XMVECTOR XMLoatFloat3( CONST XMFLOAT3 *pSource);


// XMFLOAT4 를 XMVECTOR4에 적재

XMVECTOR XMLoatFloat4( CONST XMFLOAT4 *pSource);


XMVECTOR를 XMFLOAT*로

VOID XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); // 3,4 도 있음


이 외에도 3원소 UINT, XMCOLOR, XMBYTE4 등 XMVECTOR로 변환하고 적재하는 함수들도 있다.


XMVECTOR 인스턴스의 성분 하나만 읽거나 변경하고 싶은 경우도 있다 그런경우에 사용하는 조회 설정 함수들도 있다.

FLOAT XMVectorGetX(FXMVECTOR V);

XMVECTOR XMVectorSetX(FXMVECTOR V, FLOAT x); // y,z,w까지 다 있다.


2. 매개변수 전달

SIMD의 장점을 취하려면 함수에 XMVECTOR 형식의 매개변수를 전달할 때 지켜야 할 규칙이 몇 가지 있다.

32비트 Windows와 64비트 WIndows, XBox 360의 규칙들이 서로 다르다.

플랫폼에 독립적인 코드를 위해 XMVECTOR형식의 매개변수에 대해 CXMVECTOR 형식과 FXMVECTOR 형식을 사용한다.

이 형식들은 다음과 같이 정의 되어 있다.


// 32비트 Windows

typedef const XMVECTOR FXMVECTOR;

typedef const XMVECTOR& CXMVECTOR;


// 64비트 Windows

typedef const XMVECTOR& FXMVECTOR;

typedef const XMVECTOR& CXMVECTOR;


구체적인 규칙으론 처음 3개의 매개변수는 FXMVECTOR 형식이어야하고 그 외의 매개변수는 반드시 CXMVECTOR 형식이어야 한다.

즉, 매개변수에 있는 XMVECTOR변수 처음 3개는 FXMVECTOR을 쓰고 이후엔 CXMVECTOR을 써야한다.


3. 상수 벡터

상수(const) XMVECTOR 인스턴스에는 반드시 XMVECTORF32 형식을 사용해야 한다.

간단히 말하면, 초기화 구문을 사용하고자 할 때에는 항상 XMVECTORF32를 사용해야 한다. (XMVECTORF32는 16바이트 경계로 정렬된 구조체로, XMVECTOR로의 변환 연산자를 지원한다.


4. 설정 함수

XMVECTOR XMVectorZero();

XMVECTOR XMVectorSplatOne(); // 벡터 (1, 1, 1, 1) 을 돌려준다.

XMVECTOR XMVectorSet( FLOAT x, FLOAT y, FLOAT z, FLOAT w) // 벡터(x, y, z, w)를 돌려준다.

XMVECTOR XMVectorReplicate( FLOAT s); // 벡터 (s, s, s, s)를 돌려준다.

XMVECTOR XMVectorSplatX( FXMVECTOR V); // 벡터 (Vx, Vx, Vx, Vx)를 돌려준다.


* 수학적 결과가 스칼라 값이라도 XMVECTOR변수를 반환한다 그 이후는 SIMD벡터 연산의 전환을 최소화 해서 SIMD로 유지하는 것이 효율적이기 때문이다.


5. 부동 소수점 연산

* 부동 소수점 연산을 할때에는 오차가 누적되서 변수가 근사값이 되는데 그때에 Epsilon을 두어서 상등을 판정할 수 있다. 

XNA라이브러리에는 두 벡터의 상등을 판정하는 XMVector3NearEqual이라는 함수가 있다. 이 함수는 Epsilon을 매개변수로 허용 오차를 받는다.


'DirectX11 > 수학관련' 카테고리의 다른 글

XNA Math 라이브러리 (행렬)  (0) 2016.07.02
posted by 알쿠미