From 4f1d5c26d1fc8bbb6dbd8a34699fb80a192ae4e3 Mon Sep 17 00:00:00 2001 From: David Adam Date: Wed, 12 Nov 2008 18:54:50 +0100 Subject: [PATCH] d3dx8: Implement D3DXMatrixAffineTransformation2D. --- dlls/d3dx9_36/d3dx9_36.spec | 2 +- dlls/d3dx9_36/math.c | 47 +++++++++++ dlls/d3dx9_36/tests/math.c | 160 +++++++++++++++++++++++++++++++++++- include/d3dx9math.h | 1 + 4 files changed, 208 insertions(+), 2 deletions(-) diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index 2e68ba2e813..9058dd74647 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -197,7 +197,7 @@ @ stub D3DXLoadVolumeFromResourceW @ stub D3DXLoadVolumeFromVolume @ stdcall D3DXMatrixAffineTransformation(ptr long ptr ptr ptr) d3dx8.D3DXMatrixAffineTransformation -@ stub D3DXMatrixAffineTransformation2D +@ stdcall D3DXMatrixAffineTransformation2D(ptr long ptr long ptr) @ stdcall D3DXMatrixDecompose(ptr ptr ptr ptr) @ stdcall D3DXMatrixDeterminant(ptr) d3dx8.D3DXMatrixfDeterminant @ stdcall D3DXMatrixInverse(ptr ptr ptr) d3dx8.D3DXMatrixInverse diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c index cbfac84fb96..b5cdde2bae1 100644 --- a/dlls/d3dx9_36/math.c +++ b/dlls/d3dx9_36/math.c @@ -28,6 +28,53 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); +/************************************************************************* + * D3DXMatrixAffineTransformation2D + */ +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D( + D3DXMATRIX *pout, FLOAT scaling, + CONST D3DXVECTOR2 *protationcenter, FLOAT rotation, + CONST D3DXVECTOR2 *ptranslation) +{ + D3DXQUATERNION rot; + D3DXVECTOR3 rot_center, trans; + + rot.w=cos(rotation/2.0f); + rot.x=0.0f; + rot.y=0.0f; + rot.z=sin(rotation/2.0f); + + if ( protationcenter ) + { + rot_center.x=protationcenter->x; + rot_center.y=protationcenter->y; + rot_center.z=0.0f; + } + else + { + rot_center.x=0.0f; + rot_center.y=0.0f; + rot_center.z=0.0f; + } + + if ( ptranslation ) + { + trans.x=ptranslation->x; + trans.y=ptranslation->y; + trans.z=0.0f; + } + else + { + trans.x=0.0f; + trans.y=0.0f; + trans.z=0.0f; + } + + D3DXMatrixAffineTransformation(pout, scaling, &rot_center, &rot, &trans); + + return pout; +} + /************************************************************************* * D3DXMatrixDecompose */ diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c index ff5e1102af7..2930d347733 100644 --- a/dlls/d3dx9_36/tests/math.c +++ b/dlls/d3dx9_36/tests/math.c @@ -17,7 +17,7 @@ */ #include "wine/test.h" -#include "d3dx9math.h" +#include "d3dx9.h" #define ARRAY_SIZE 5 @@ -25,6 +25,38 @@ #define relative_error(exp, out) ((exp == out) ? 0.0f : (fabs(out - exp) / fabs(exp))) +static inline BOOL compare_matrix(const D3DXMATRIX *m1, const D3DXMATRIX *m2) +{ + int i, j; + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + if (fabs(U(*m1).m[i][j] - U(*m2).m[i][j]) > admitted_error) + return FALSE; + } + } + + return TRUE; +} + +#define expect_mat(expectedmat, gotmat) \ +do { \ + const D3DXMATRIX *__m1 = (expectedmat); \ + const D3DXMATRIX *__m2 = (gotmat); \ + ok(compare_matrix(__m1, __m2), "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n" \ + "Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n", \ + U(*__m1).m[0][0], U(*__m1).m[0][1], U(*__m1).m[0][2], U(*__m1).m[0][3], \ + U(*__m1).m[1][0], U(*__m1).m[1][1], U(*__m1).m[1][2], U(*__m1).m[1][3], \ + U(*__m1).m[2][0], U(*__m1).m[2][1], U(*__m1).m[2][2], U(*__m1).m[2][3], \ + U(*__m1).m[3][0], U(*__m1).m[3][1], U(*__m1).m[3][2], U(*__m1).m[3][3], \ + U(*__m2).m[0][0], U(*__m2).m[0][1], U(*__m2).m[0][2], U(*__m2).m[0][3], \ + U(*__m2).m[1][0], U(*__m2).m[1][1], U(*__m2).m[1][2], U(*__m2).m[1][3], \ + U(*__m2).m[2][0], U(*__m2).m[2][1], U(*__m2).m[2][2], U(*__m2).m[2][3], \ + U(*__m2).m[3][0], U(*__m2).m[3][1], U(*__m2).m[3][2], U(*__m2).m[3][3]); \ +} while(0) + #define compare_rotation(exp, got) \ ok(fabs(exp.w - got.w) < admitted_error && \ fabs(exp.x - got.x) < admitted_error && \ @@ -88,6 +120,131 @@ * says so too). */ +static void test_Matrix_AffineTransformation2D(void) +{ + D3DXMATRIX exp_mat, got_mat; + D3DXVECTOR2 center, position; + FLOAT angle, scale; + + center.x = 3.0f; + center.y = 4.0f; + + position.x = -6.0f; + position.y = 7.0f; + + angle = D3DX_PI/3.0f; + + scale = 20.0f; + + exp_mat.m[0][0] = 10.0f; + exp_mat.m[1][0] = -17.320507f; + exp_mat.m[2][0] = 0.0f; + exp_mat.m[3][0] = -1.035898f; + exp_mat.m[0][1] = 17.320507f; + exp_mat.m[1][1] = 10.0f; + exp_mat.m[2][1] = 0.0f; + exp_mat.m[3][1] = 6.401924f; + exp_mat.m[0][2] = 0.0f; + exp_mat.m[1][2] = 0.0f; + exp_mat.m[2][2] = 20.0f; + exp_mat.m[3][2] = 0.0f; + exp_mat.m[0][3] = 0.0f; + exp_mat.m[1][3] = 0.0f; + exp_mat.m[2][3] = 0.0f; + exp_mat.m[3][3] = 1.0f; + + D3DXMatrixAffineTransformation2D(&got_mat, scale, ¢er, angle, &position); + + expect_mat(&exp_mat, &got_mat); + +/*______________*/ + + center.x = 3.0f; + center.y = 4.0f; + + angle = D3DX_PI/3.0f; + + scale = 20.0f; + + exp_mat.m[0][0] = 10.0f; + exp_mat.m[1][0] = -17.320507f; + exp_mat.m[2][0] = 0.0f; + exp_mat.m[3][0] = 4.964102f; + exp_mat.m[0][1] = 17.320507f; + exp_mat.m[1][1] = 10.0f; + exp_mat.m[2][1] = 0.0f; + exp_mat.m[3][1] = -0.598076f; + exp_mat.m[0][2] = 0.0f; + exp_mat.m[1][2] = 0.0f; + exp_mat.m[2][2] = 20.0f; + exp_mat.m[3][2] = 0.0f; + exp_mat.m[0][3] = 0.0f; + exp_mat.m[1][3] = 0.0f; + exp_mat.m[2][3] = 0.0f; + exp_mat.m[3][3] = 1.0f; + + D3DXMatrixAffineTransformation2D(&got_mat, scale, ¢er, angle, NULL); + + expect_mat(&exp_mat, &got_mat); + +/*______________*/ + + position.x = -6.0f; + position.y = 7.0f; + + angle = D3DX_PI/3.0f; + + scale = 20.0f; + + exp_mat.m[0][0] = 10.0f; + exp_mat.m[1][0] = -17.320507f; + exp_mat.m[2][0] = 0.0f; + exp_mat.m[3][0] = -6.0f; + exp_mat.m[0][1] = 17.320507f; + exp_mat.m[1][1] = 10.0f; + exp_mat.m[2][1] = 0.0f; + exp_mat.m[3][1] = 7.0f; + exp_mat.m[0][2] = 0.0f; + exp_mat.m[1][2] = 0.0f; + exp_mat.m[2][2] = 20.0f; + exp_mat.m[3][2] = 0.0f; + exp_mat.m[0][3] = 0.0f; + exp_mat.m[1][3] = 0.0f; + exp_mat.m[2][3] = 0.0f; + exp_mat.m[3][3] = 1.0f; + + D3DXMatrixAffineTransformation2D(&got_mat, scale, NULL, angle, &position); + + expect_mat(&exp_mat, &got_mat); + +/*______________*/ + + angle = 5.0f * D3DX_PI/4.0f; + + scale = -20.0f; + + exp_mat.m[0][0] = 14.142133f; + exp_mat.m[1][0] = -14.142133f; + exp_mat.m[2][0] = 0.0f; + exp_mat.m[3][0] = 0.0f; + exp_mat.m[0][1] = 14.142133; + exp_mat.m[1][1] = 14.142133f; + exp_mat.m[2][1] = 0.0f; + exp_mat.m[3][1] = 0.0f; + exp_mat.m[0][2] = 0.0f; + exp_mat.m[1][2] = 0.0f; + exp_mat.m[2][2] = -20.0f; + exp_mat.m[3][2] = 0.0f; + exp_mat.m[0][3] = 0.0f; + exp_mat.m[1][3] = 0.0f; + exp_mat.m[2][3] = 0.0f; + exp_mat.m[3][3] = 1.0f; + + D3DXMatrixAffineTransformation2D(&got_mat, scale, NULL, angle, NULL); + + expect_mat(&exp_mat, &got_mat); +} + static void test_Matrix_Decompose(void) { D3DXMATRIX pm; @@ -566,6 +723,7 @@ static void test_D3DXVec_Array(void) START_TEST(math) { + test_Matrix_AffineTransformation2D(); test_Matrix_Decompose(); test_D3DXVec_Array(); } diff --git a/include/d3dx9math.h b/include/d3dx9math.h index 54e7762fbe2..9992919c3c4 100644 --- a/include/d3dx9math.h +++ b/include/d3dx9math.h @@ -267,6 +267,7 @@ D3DXCOLOR* WINAPI D3DXColorAdjustContrast(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, D3DXCOLOR* WINAPI D3DXColorAdjustSaturation(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s); D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation(D3DXMATRIX *pout, float scaling, D3DXVECTOR3 *rotationcenter, D3DXQUATERNION *rotation, D3DXVECTOR3 *translation); +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D(D3DXMATRIX *pout, FLOAT scaling, CONST D3DXVECTOR2 *protationcenter, FLOAT rotation, CONST D3DXVECTOR2 *ptranslation); HRESULT WINAPI D3DXMatrixDecompose(D3DXVECTOR3 *poutscale, D3DXQUATERNION *poutrotation, D3DXVECTOR3 *pouttranslation, D3DXMATRIX *pm); FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pm); D3DXMATRIX* WINAPI D3DXMatrixInverse(D3DXMATRIX *pout, FLOAT *pdeterminant, CONST D3DXMATRIX *pm);