d3dx9_36: Implementation of D3DXSHEvalDirection.

This commit is contained in:
Nozomi Kodama 2012-07-15 10:18:50 +02:00 committed by Alexandre Julliard
parent 8b97ff3278
commit c957f8a921
4 changed files with 99 additions and 1 deletions

View File

@ -275,7 +275,7 @@
@ stdcall D3DXSHAdd(ptr long ptr ptr) @ stdcall D3DXSHAdd(ptr long ptr ptr)
@ stdcall D3DXSHDot(long ptr ptr) @ stdcall D3DXSHDot(long ptr ptr)
@ stub D3DXSHEvalConeLight(long ptr long long long long ptr ptr ptr) @ stub D3DXSHEvalConeLight(long ptr long long long long ptr ptr ptr)
@ stub D3DXSHEvalDirection(ptr long ptr) @ stdcall D3DXSHEvalDirection(ptr long ptr)
@ stub D3DXSHEvalDirectionalLight(long ptr long long long long ptr ptr ptr) @ stub D3DXSHEvalDirectionalLight(long ptr long long long long ptr ptr ptr)
@ stub D3DXSHEvalHemisphereLight(long ptr long long ptr ptr ptr) @ stub D3DXSHEvalHemisphereLight(long ptr long long ptr ptr ptr)
@ stub D3DXSHEvalSphericalLight(long ptr long long long long ptr ptr ptr) @ stub D3DXSHEvalSphericalLight(long ptr long long long long ptr ptr ptr)

View File

@ -1995,6 +1995,66 @@ FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b)
return s; return s;
} }
FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir)
{
TRACE("(%p, %u, %p)\n", out, order, dir);
if ( (order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) )
return out;
out[0] = 0.5f / sqrt(D3DX_PI);
out[1] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->y;
out[2] = 0.5f / sqrt(D3DX_PI / 3.0f) * dir->z;
out[3] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->x;
if ( order == 2 )
return out;
out[4] = 0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->y;
out[5] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->y * dir->z;
out[6] = 0.25f / sqrt(D3DX_PI / 5.0f) * ( 3.0f * dir->z * dir->z - 1.0f );
out[7] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->z;
out[8] = 0.25f / sqrt(D3DX_PI / 15.0f) * ( dir->x * dir->x - dir->y * dir->y );
if ( order == 3 )
return out;
out[9] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->y * (3.0f * dir->x * dir->x - dir->y * dir->y );
out[10] = sqrt(105.0f / D3DX_PI) / 2.0f * dir->x * dir->y * dir->z;
out[11] = -sqrt(42.0 / D3DX_PI) / 8.0f * dir->y * ( -1.0f + 5.0f * dir->z * dir->z );
out[12] = sqrt(7.0f / D3DX_PI) / 4.0f * dir->z * ( 5.0f * dir->z * dir->z - 3.0f );
out[13] = sqrt(42.0 / D3DX_PI) / 8.0f * dir->x * ( 1.0f - 5.0f * dir->z * dir->z );
out[14] = sqrt(105.0f / D3DX_PI) / 4.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y );
out[15] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y );
if ( order == 4 )
return out;
out[16] = 0.75f * sqrt(35.0f / D3DX_PI) * dir->x * dir->y * (dir->x * dir->x - dir->y * dir->y );
out[17] = 3.0f * dir->z * out[9];
out[18] = 0.75f * sqrt(5.0f / D3DX_PI) * dir->x * dir->y * ( 7.0f * dir->z * dir->z - 1.0f );
out[19] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->y * dir->z * ( 3.0f - 7.0f * dir->z * dir->z );
out[20] = 3.0f / ( 16.0f * sqrt(D3DX_PI) ) * ( 35.0f * dir->z * dir->z * dir->z * dir->z - 30.f * dir->z * dir->z + 3.0f );
out[21] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->x * dir->z * ( 3.0f - 7.0f * dir->z * dir->z );
out[22] = 0.375f * sqrt(5.0f / D3DX_PI) * ( dir->x * dir->x - dir->y * dir->y ) * ( 7.0f * dir->z * dir->z - 1.0f);
out[23] = 3.0 * dir->z * out[15];
out[24] = 3.0f / 16.0f * sqrt(35.0f / D3DX_PI) * ( dir->x * dir->x * dir->x * dir->x- 6.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
if ( order == 5 )
return out;
out[25] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->y * ( 5.0f * dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
out[26] = 0.75f * sqrt(385.0f / D3DX_PI) * dir->x * dir->y * dir->z * ( dir->x * dir->x - dir->y * dir->y );
out[27] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->y * ( 3.0f * dir->x * dir->x - dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z );
out[28] = sqrt(1155.0f / D3DX_PI) / 4.0f * dir->x * dir->y * dir->z * ( 3.0f * dir->z * dir->z - 1.0f);
out[29] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->y * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f );
out[30] = sqrt(11.0f / D3DX_PI) / 16.0f * dir->z * ( 63.0f * dir->z * dir->z * dir->z * dir->z - 70.0f * dir->z * dir->z + 15.0f );
out[31] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->x * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f );
out[32] = sqrt(1155.0f / D3DX_PI) / 8.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y ) * ( 3.0f * dir->z * dir->z - 1.0f );
out[33] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z );
out[34] = 3.0f / 16.0f * sqrt(385.0f / D3DX_PI) * dir->z * ( dir->x * dir->x * dir->x * dir->x - 6.0 * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
out[35] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->x * ( dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + 5.0f * dir->y * dir->y * dir->y * dir->y );
return out;
}
FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b) FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b)
{ {
FLOAT ta, tb; FLOAT ta, tb;

View File

@ -2422,6 +2422,42 @@ static void test_D3DXSHDot(void)
return; return;
} }
static void test_D3DXSHEvalDirection(void)
{
unsigned int i, order;
D3DXVECTOR3 d;
FLOAT a[100], expected[100], *received_ptr;
CONST FLOAT table[36] =
{ 0.282095f, -0.977205f, 1.465808f, -0.488603f, 2.185097f, -6.555291f,
8.200181f, -3.277646f, -1.638823f, 1.180087f, 17.343668f, -40.220032f,
47.020218f, -20.110016f, -13.007751f, 6.490479f, -15.020058f, 10.620785f,
117.325661f, -240.856750f, 271.657288f, -120.428375f, -87.994247f, 58.414314f,
-4.380850f, 24.942520f, -149.447693f, 78.278130f, 747.791748f, -1427.687866f,
1574.619141, -713.843933f, -560.843811f, 430.529724, -43.588909, -26.911665, };
d.x = 1.0; d.y = 2.0f; d.z = 3.0f;
for(order = 0; order < 10; order++)
{
for(i = 0; i < 100; i++)
a[i] = 1.5f + i;
received_ptr = D3DXSHEvalDirection(a, order, &d);
ok(received_ptr == a, "Expected %p, received %p\n", a, received_ptr);
for(i = 0; i < 100; i++)
{
/* if the order is < D3DXSH_MINORDER or order > D3DXSH_MAXORDER or the index of the element is greater than order * order - 1, D3DXSHEvalDirection does not modify the output */
if ( (order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) || (i >= order * order) )
expected[i] = 1.5f + i;
else
expected[i] = table[i];
ok(relative_error(a[i], expected[i]) < admitted_error, "order %u, index %u: expected %f, received %f\n", order, i, expected[i], a[i]);
}
}
}
static void test_D3DXSHMultiply2(void) static void test_D3DXSHMultiply2(void)
{ {
unsigned int i; unsigned int i;
@ -2512,6 +2548,7 @@ START_TEST(math)
test_D3DXFloat_Array(); test_D3DXFloat_Array();
test_D3DXSHAdd(); test_D3DXSHAdd();
test_D3DXSHDot(); test_D3DXSHDot();
test_D3DXSHEvalDirection();
test_D3DXSHMultiply2(); test_D3DXSHMultiply2();
test_D3DXSHMultiply3(); test_D3DXSHMultiply3();
test_D3DXSHScale(); test_D3DXSHScale();

View File

@ -379,6 +379,7 @@ FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, CONST D3DXFLOAT16 *pin, UINT n);
FLOAT* WINAPI D3DXSHAdd(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT *b); FLOAT* WINAPI D3DXSHAdd(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT *b);
FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b); FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b);
FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir);
FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b); FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b);
FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b); FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b);
FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale); FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale);