Nozomi Kodama : d3dx9_36: Implementation of D3DXSHEvalDirection.

Alexandre Julliard julliard at winehq.org
Mon Jul 16 14:14:29 CDT 2012


Module: wine
Branch: master
Commit: c957f8a921154c293f1dda53595f45a396477d1f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c957f8a921154c293f1dda53595f45a396477d1f

Author: Nozomi Kodama <Nozomi.Kodama at yahoo.com>
Date:   Sun Jul 15 10:18:50 2012 +0200

d3dx9_36: Implementation of D3DXSHEvalDirection.

---

 dlls/d3dx9_36/d3dx9_36.spec |    2 +-
 dlls/d3dx9_36/math.c        |   60 +++++++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/tests/math.c  |   37 ++++++++++++++++++++++++++
 include/d3dx9math.h         |    1 +
 4 files changed, 99 insertions(+), 1 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index 9230d55..b59c8a9 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -275,7 +275,7 @@
 @ stdcall D3DXSHAdd(ptr long ptr ptr)
 @ stdcall D3DXSHDot(long 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 D3DXSHEvalHemisphereLight(long ptr long long ptr ptr ptr)
 @ stub D3DXSHEvalSphericalLight(long ptr long long long long ptr ptr ptr)
diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c
index 79a0bca..89a19af 100644
--- a/dlls/d3dx9_36/math.c
+++ b/dlls/d3dx9_36/math.c
@@ -1995,6 +1995,66 @@ FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b)
     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 ta, tb;
diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c
index 66d4689..fecb413 100644
--- a/dlls/d3dx9_36/tests/math.c
+++ b/dlls/d3dx9_36/tests/math.c
@@ -2422,6 +2422,42 @@ static void test_D3DXSHDot(void)
     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)
 {
     unsigned int i;
@@ -2512,6 +2548,7 @@ START_TEST(math)
     test_D3DXFloat_Array();
     test_D3DXSHAdd();
     test_D3DXSHDot();
+    test_D3DXSHEvalDirection();
     test_D3DXSHMultiply2();
     test_D3DXSHMultiply3();
     test_D3DXSHScale();
diff --git a/include/d3dx9math.h b/include/d3dx9math.h
index ab3e2b0..602c2a4 100644
--- a/include/d3dx9math.h
+++ b/include/d3dx9math.h
@@ -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 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 D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b);
 FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale);




More information about the wine-cvs mailing list