From 7a4490c06248e03817faf85a49e48c04350bc4c7 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 20 Nov 2007 12:49:38 +0100 Subject: [PATCH] d3dx8: Implement D3DXQuaternionToAxisAngle. --- dlls/d3dx8/d3dx8.spec | 2 +- dlls/d3dx8/math.c | 21 +++++++++++++++++++++ dlls/d3dx8/tests/math.c | 25 +++++++++++++++++++++++-- include/d3dx8math.h | 1 + 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/dlls/d3dx8/d3dx8.spec b/dlls/d3dx8/d3dx8.spec index af78fb26d8b..1c57f53383a 100644 --- a/dlls/d3dx8/d3dx8.spec +++ b/dlls/d3dx8/d3dx8.spec @@ -49,7 +49,7 @@ @ stdcall D3DXMatrixOrthoOffCenterLH(ptr long long long long long long) @ stdcall D3DXMatrixShadow(ptr ptr ptr) @ stdcall D3DXMatrixReflect(ptr ptr) -@ stub D3DXQuaternionToAxisAngle +@ stdcall D3DXQuaternionToAxisAngle(ptr ptr ptr) @ stub D3DXQuaternionRotationMatrix @ stub D3DXQuaternionRotationAxis @ stub D3DXQuaternionRotationYawPitchRoll diff --git a/dlls/d3dx8/math.c b/dlls/d3dx8/math.c index e907be14022..52e580d223c 100644 --- a/dlls/d3dx8/math.c +++ b/dlls/d3dx8/math.c @@ -665,6 +665,27 @@ D3DXQUATERNION* WINAPI D3DXQuaternionSquad(D3DXQUATERNION *pout, CONST D3DXQUATE return pout; } +void WINAPI D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION *pq, D3DXVECTOR3 *paxis, FLOAT *pangle) +{ + FLOAT norm; + + *pangle = 0.0f; + norm = D3DXQuaternionLength(pq); + if ( norm ) + { + paxis->x = pq->x / norm; + paxis->y = pq->y / norm; + paxis->z = pq->z / norm; + if ( fabs( pq->w ) <= 1.0f ) *pangle = 2.0f * acos(pq->w); + } + else + { + paxis->x = 1.0f; + paxis->y = 0.0f; + paxis->z = 0.0f; + } +} + /*_________________D3DXVec2_____________________*/ D3DXVECTOR2* WINAPI D3DXVec2BaryCentric(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT f, FLOAT g) diff --git a/dlls/d3dx8/tests/math.c b/dlls/d3dx8/tests/math.c index 229d0b7dc61..e3c6a28046b 100644 --- a/dlls/d3dx8/tests/math.c +++ b/dlls/d3dx8/tests/math.c @@ -552,9 +552,10 @@ static void D3DXPlaneTest(void) static void D3X8QuaternionTest(void) { - D3DXQUATERNION expectedquat, gotquat, nul, q, r, s, t, u; + D3DXQUATERNION expectedquat, gotquat, Nq, nul, q, r, s, t, u; LPD3DXQUATERNION funcpointer; - FLOAT expected, got, scale, scale2; + D3DXVECTOR3 axis, expectedvec; + FLOAT angle, expected, got, scale, scale2; BOOL expectedbool, gotbool; nul.x = 0.0f; nul.y = 0.0f; nul.z = 0.0f; nul.w = 0.0f; @@ -667,6 +668,26 @@ static void D3X8QuaternionTest(void) expectedquat.x = -156.296f; expectedquat.y = 30.242f; expectedquat.z = -2.5022f; expectedquat.w = 7.3576f; D3DXQuaternionSquad(&gotquat,&q,&r,&t,&u,scale); expect_vec4(expectedquat,gotquat); + +/*_______________D3DXQuaternionToAxisAngle__________________*/ + Nq.x = 1.0f/22.0f; Nq.y = 2.0f/22.0f; Nq.z = 4.0f/22.0f; Nq.w = 10.0f/22.0f; + expectedvec.x = 1.0f/11.0f; expectedvec.y = 2.0f/11.0f; expectedvec.z = 4.0f/11.0f; + expected = 2.197869f; + D3DXQuaternionToAxisAngle(&Nq,&axis,&angle); + expect_vec3(expectedvec,axis); + ok(fabs( angle - expected ) < admitted_error, "Expected: %f, Got: %f\n", expected, angle); + /* Test if |w|>1.0f */ + expectedvec.x = 1.0f/11.0f; expectedvec.y = 2.0f/11.0f; expectedvec.z = 4.0f/11.0f; + expected = 0.0f; + D3DXQuaternionToAxisAngle(&q,&axis,&angle); + expect_vec3(expectedvec,axis); + ok(fabs( angle - expected ) < admitted_error, "Expected: %f, Got: %f\n", expected, angle); + /* Test the null quaternion */ + expectedvec.x = 1.0f; expectedvec.y = 0.0f; expectedvec.z = 0.0f; + expected = 0.0f; + D3DXQuaternionToAxisAngle(&nul,&axis,&angle); + expect_vec3(expectedvec,axis); + ok(fabs( angle - expected ) < admitted_error, "Expected: %f, Got: %f\n", expected, angle); } static void D3X8Vector2Test(void) diff --git a/include/d3dx8math.h b/include/d3dx8math.h index 3e5581ebebe..dd85e3af4fa 100644 --- a/include/d3dx8math.h +++ b/include/d3dx8math.h @@ -308,6 +308,7 @@ D3DXQUATERNION* WINAPI D3DXQuaternionMultiply(D3DXQUATERNION *pout, CONST D3DXQU D3DXQUATERNION* WINAPI D3DXQuaternionNormalize(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq); D3DXQUATERNION* WINAPI D3DXQuaternionSlerp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, FLOAT t); D3DXQUATERNION* WINAPI D3DXQuaternionSquad(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, CONST D3DXQUATERNION *pq4, FLOAT t); +void WINAPI D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION *pq, D3DXVECTOR3 *paxis, FLOAT *pangle); D3DXVECTOR2* WINAPI D3DXVec2BaryCentric(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT f, FLOAT g); D3DXVECTOR2* WINAPI D3DXVec2CatmullRom(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv0, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT s);