[GPG 1 글 2.8] GPG1의 쿼터니온과.. DX의 쿼터니온..

GPG 시리즈 관련 질답, 논의 공간.

Moderator: 류광

비회원

GPG1의 쿼터니온과.. DX의 쿼터니온..

Post by 비회원 »

안녕하세요.. 캐릭터 애니메이션을 구현하면서..
쿼터니온을 이용해서 Rotation값을 보간하고 있습니다..
그런데 최종적으로 행렬로 변환하면서 문제가 있는데요..


제가 GPG1에 있는 쿼터니온-행렬 변환을 사용하다가..
DX SDK에 있는 변환함수를 사용하니 문제가 생겨서 이렇게 질문을 드립니다.

Code: Select all

// GPG 쿼터니온 변환
void Quat::MakeRotationMatrix( Matrix4 &_mat ) const
	{
		float xx2 = 2.0f*x*x;
		float yy2 = 2.0f*y*y;
		float zz2 = 2.0f*z*z;
		float xy2 = 2.0f*x*y;
		float xz2 = 2.0f*x*z;
		float yz2 = 2.0f*y*z;
		float wx2 = 2.0f*w*x;
		float wy2 = 2.0f*w*y;
		float wz2 = 2.0f*w*z;
		_mat._11 = 1.0f-(yy2+zz2);	_mat._12 = xy2 - wz2;		_mat._13 = wy2 + xz2;		_mat._14 = 0.0f;
		_mat._21 = xy2 + wz2;		_mat._22 = 1.f - (xx2+zz2);	_mat._23 = yz2 - wx2;		_mat._24 = 0.0f;
		_mat._31 = xz2 - wy2;		_mat._32 = yz2 + wx2;		_mat._33 = 1.f - (xx2+yy2);	_mat._34 = 0.0f;
		_mat._41 = 					_mat._42 =					_mat._43 = 0.0f;			_mat._44 = 1.0f;
	}

// D3D 쿼터니온 변환
	void Quat::MakeRotationMatrix( Matrix4 &_mat ) const
	{
		float xx2 = 2.0f*x*x;
		float yy2 = 2.0f*y*y;
		float zz2 = 2.0f*z*z;
		float xy2 = 2.0f*x*y;
		float xz2 = 2.0f*x*z;
		float yz2 = 2.0f*y*z;
		float sx2 = 2.0f*w*x;
		float sy2 = 2.0f*w*y;
		float sz2 = 2.0f*w*z;
		_mat._11 = 1.0f-yy2-zz2;	_mat._12 = xy2 + sz2;		_mat._13 = xz2 - sy2;			_mat._14 = 0.0f;
		_mat._21 = xy2 - sz2;		_mat._22 = 1.0f-xx2-zz2;	_mat._23 = yz2 + sx2;			_mat._24 = 0.0f;
		_mat._31 = xz2 + sy2;		_mat._32 = yz2 - sx2;		_mat._33 = 1.0f-xx2-yy2;		_mat._34 = 0.0f;
		_mat._41 =					_mat._42 =					_mat._43 = 0.0f;				_mat._44 = 1.0f;
	}
	*/
둘의 차이가.. 왼손 오른손 좌표의 차이인것 같은데.. 둘의 알고리즘이 좀 틀린것 같습니다.
gpg로 하면 잘나오는데 DXSDK로 하면 잘 안나옵니다 (옆으로 기울어서 삐뚤게 나오는것 같습니다.)


3DMax플러그인에서 IGameExporter를 사용하여 D3D좌표로 설정해주고 애니메이션을 뽑는데..
좀 이상하군요..
비회원

Post by 비회원 »

잘은 모르지만, 쿼터니온이 다른게 아니라 행렬이 다를 겁니다.
행렬to 쿼터니온이 아니라 반대로 quatTomatrix를 사용하시어
같은 쿼터니온 값을 님의 코드랑 DX코드랑 적용하여 결과를 비교해보세요.
비회원

Post by 비회원 »

아 코드를 잘못 보았네요.
그냥 매트릭스 결과가 transpose된 관계일거 같은데요.
비회원

그렇군요..

Post by 비회원 »

비회원 wrote:아 코드를 잘못 보았네요.
그냥 매트릭스 결과가 transpose된 관계일거 같은데요.
테스트 해보니 실재로 Transpose된 값이군요 (gpg것이)

그런데 왜 gpg것은 Transpose가 되어있는 것일까요..

D3D는 그렇치 않는데 말이죠...
-_-;


쿼터니온을 행렬로 변환할때 Transpose해서 사용해야 되는 이유가 있는 걸까요?
maru09
Posts: 45
Joined: 2009-03-23 17:21

Re: 그렇군요..

Post by maru09 »

비회원 wrote:
비회원 wrote:아 코드를 잘못 보았네요.
그냥 매트릭스 결과가 transpose된 관계일거 같은데요.
테스트 해보니 실재로 Transpose된 값이군요 (gpg것이)

그런데 왜 gpg것은 Transpose가 되어있는 것일까요..

D3D는 그렇치 않는데 말이죠...
-_-;


쿼터니온을 행렬로 변환할때 Transpose해서 사용해야 되는 이유가 있는 걸까요?
아마... GPG는 OpenGL 계통이라 곱하는 방향이 반대라서 그럴꺼에요
정영구
비회원

Re: 그렇군요..

Post by 비회원 »

비회원 wrote: 쿼터니온을 행렬로 변환할때 Transpose해서 사용해야 되는 이유가 있는 걸까요?
row convention, column convention에 대해 알아보세요. 아마 저 이유일 것으로 생각됩니다. 각각에 대해 장단점이 있는것으로 압니다.(저는 모릅니다. dx방식이 좀더 빠른계산이 된다는데 전혀 이해가 안갑니다.)
tomatowax
Posts: 464
Joined: 2005-01-17 12:22
Contact:

Post by tomatowax »

음.. OpenGL 은 일반적인 수학 좌표계 및 수학 공식들을 기준으로 작성되었습니다.

D3D 는 '자체적으로' 고안한 좌표계와 공식들을 사용합니다.
(우린 OpenGL 과 다르다! 라고 하고 싶었다네요.)

때문에 일반적인 수학 공식으로 제시된 솔루션들은 OpenGL 에서 동일하게 동작하구요.

D3D 같은 경우는 '모든 경우' 에서 D3D 수학계와 맞아야 합니다.

단순히 Matrix 의 좌표계만 바꾼다고 해결될 일이 아니라
쿼터니온의 경우에도 D3D 전용 공식을 사용해야 합니다.

그리고 GPG 는 일반 수학을 다루기 때문에 예제도 OpenGL 로 작성되는 경우가 많죠.

Image
http://www.mindpol.com/Plugins/Technolo ... ?f=36&t=31
Post Reply