Nozomi Kodama : d3dx9: Implement D3DXSHRotate.

Alexandre Julliard julliard at winehq.org
Tue Sep 25 15:13:38 CDT 2012


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

Author: Nozomi Kodama <Nozomi.kodama at yahoo.com>
Date:   Mon Sep 17 19:20:45 2012 +0800

d3dx9: Implement D3DXSHRotate.

---

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

diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index 6e3268d..44956b8 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -287,7 +287,7 @@
 @ stub D3DXSHProjectCubeMap(long ptr ptr ptr ptr)
 @ stub D3DXSHPRTCompSplitMeshSC(ptr long long ptr long ptr long long ptr ptr long ptr ptr ptr ptr ptr)
 @ stub D3DXSHPRTCompSuperCluster(ptr ptr long long ptr ptr)
-@ stub D3DXSHRotate(ptr long ptr ptr)
+@ stdcall D3DXSHRotate(ptr long ptr ptr)
 @ stdcall D3DXSHRotateZ(ptr long float ptr)
 @ stdcall D3DXSHScale(ptr long ptr float)
 @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr)
diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c
index 4285c2a..00cf9c3 100644
--- a/dlls/d3dx9_36/math.c
+++ b/dlls/d3dx9_36/math.c
@@ -2372,6 +2372,100 @@ FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b)
     return out;
 }
 
+static void rotate_X(FLOAT *out, UINT order, FLOAT a, FLOAT *in)
+{
+    out[0] = in[0];
+    if ( order < 2 )
+        return;
+
+    out[1] = a * in[2];
+    out[2] = -a * in[1];
+    out[3] = in[3];
+    if ( order == 2 )
+        return;
+
+    out[4] = a * in[7];
+    out[5] = -in[5];
+    out[6] = -0.5f * in[6] - 0.8660253882f * in[8];
+    out[7] = -a * in[4];
+    out[8] = -0.8660253882f * in[6] + 0.5f * in[8];
+    out[9] = -a * 0.7905694842f * in[12] + a * 0.6123724580f * in[14];
+    if ( order == 3 )
+        return;
+
+    out[10] = -in[10];
+    out[11] = -a * 0.6123724580f * in[12] - a * 0.7905694842f * in[14];
+    out[12] = a * 0.7905694842f * in[9] + a * 0.6123724580f * in[11];
+    out[13] = -0.25f * in[13] - 0.9682458639f * in[15];
+    out[14] = -a * 0.6123724580f * in[9] + a * 0.7905694842f * in[11];
+    out[15] = -0.9682458639f * in[13] + 0.25f * in[15];
+    if ( order == 4 )
+        return;
+
+    out[16] = -a * 0.9354143739f * in[21] + a * 0.3535533845f * in[23];
+    out[17] = -0.75f * in[17] + 0.6614378095f * in[19];
+    out[18] = -a * 0.3535533845f * in[21] - a * 0.9354143739f * in[23];
+    out[19] = 0.6614378095f * in[17] + 0.75f * in[19];
+    out[20] = 0.375f * in[20] + 0.5590170026f * in[22] + 0.7395099998f * in[24];
+    out[21] = a * 0.9354143739f * in[16] + a * 0.3535533845f * in[18];
+    out[22] = 0.5590170026f * in[20] + 0.5f * in[22] - 0.6614378691f * in[24];
+    out[23] = -a * 0.3535533845f * in[16] + a * 0.9354143739f * in[18];
+    out[24] = 0.7395099998f * in[20] - 0.6614378691f * in[22] + 0.125f * in[24];
+    if ( order == 5 )
+        return;
+
+    out[25] = a * 0.7015607357f * in[30] - a * 0.6846531630f * in[32] + a * 0.1976423711f * in[34];
+    out[26] = -0.5f * in[26] + 0.8660253882f * in[28];
+    out[27] = a * 0.5229125023f * in[30] + a * 0.3061861992f * in[32] - a * 0.7954951525 * in[34];
+    out[28] = 0.8660253882f * in[26] + 0.5f * in[28];
+    out[29] = a * 0.4841229022f * in[30] + a * 0.6614378691f * in[32] + a * 0.5728219748f * in[34];
+    out[30] = -a * 0.7015607357f * in[25] - a * 0.5229125023f * in[27] - a * 0.4841229022f * in[29];
+    out[31] = 0.125f * in[31] + 0.4050463140f * in[33] + 0.9057110548f * in[35];
+    out[32] = a * 0.6846531630f * in[25] - a * 0.3061861992f * in[27] - a * 0.6614378691f * in[29];
+    out[33] = 0.4050463140f * in[31] + 0.8125f * in[33] - 0.4192627370f * in[35];
+    out[34] = -a * 0.1976423711f * in[25] + a * 0.7954951525f * in[27] - a * 0.5728219748f * in[29];
+    out[35] = 0.9057110548f * in[31] - 0.4192627370f * in[33] + 0.0624999329f * in[35];
+
+}
+
+FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, CONST D3DXMATRIX *matrix, CONST FLOAT *in)
+{
+    FLOAT alpha, beta, gamma, sinb, temp[36];
+
+    TRACE("out %p, order %u, matrix %p, in %p\n", out, order, matrix, in);
+
+    out[0] = in[0];
+
+    if ( ( order > D3DXSH_MAXORDER ) || ( order < D3DXSH_MINORDER ) )
+        return out;
+
+    /* TODO: Implement handy computations for order <= 3. They are faster than the general algorithm. */
+    if ( order < 4 )
+        WARN("Using general algorithm for order = %u\n", order);
+
+    if ( fabsf( matrix->u.m[2][2] ) != 1.0f )
+    {
+        sinb = sqrtf( 1.0f - matrix->u.m[2][2] * matrix->u.m[2][2] );
+        alpha = atan2f(matrix->u.m[2][1] / sinb, matrix->u.m[2][0] / sinb );
+        beta = atan2f( sinb, matrix->u.m[2][2] );
+        gamma = atan2f( matrix->u.m[1][2] / sinb, -matrix->u.m[0][2] / sinb );
+    }
+    else
+    {
+        alpha = atan2f( matrix->u.m[0][1], matrix->u.m[0][0] );
+        beta = 0.0f;
+        gamma = 0.0f;
+    }
+
+    D3DXSHRotateZ(out, order, gamma, in);
+    rotate_X(temp, order, 1.0f, out);
+    D3DXSHRotateZ(out, order, beta, temp);
+    rotate_X(temp, order, -1.0f, out);
+    D3DXSHRotateZ(out, order, alpha, temp);
+
+    return out;
+}
+
 FLOAT* WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, CONST FLOAT *in)
 {
     FLOAT c1a, c2a, c3a, c4a, c5a, s1a, s2a, s3a, s4a, s5a;
diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c
index 2cb9c52..2cb6a7a 100644
--- a/dlls/d3dx9_36/tests/math.c
+++ b/dlls/d3dx9_36/tests/math.c
@@ -2640,6 +2640,72 @@ static void test_D3DXSHMultiply3(void)
         ok(relative_error(c[i], expected[i]) < admitted_error, "Expected[%d] = %f, received = %f\n", i, expected[i], c[i]);
 }
 
+static void test_D3DXSHRotate(void)
+{
+    D3DXMATRIX m[4];
+    FLOAT expected, in[49], out[49], *received_ptr;
+    static const FLOAT table[]=
+    { /* Rotation around X-axis Pi/2 */
+        1.01f, -3.01f, 2.01f, 4.01f, -8.01f, -6.01f,
+        -11.307890f, 5.01f, -1.565839f, 1.093598f, -11.01f, 19.833414f,
+        -15.268191f, -19.004118f, -3.364889f, -9.562627f, 12.099654f, -0.272131f,
+        30.241013f, 26.919991f, 39.236877f, -22.632446f, 6.707388f, -11.768282f,
+        3.443672f, -6.07445f, 11.61839f, 1.527561f, 37.89633f, -56.9012f,
+        47.42289f, 50.39153f, 10.61819f, 25.50101f, 0.049241f, 16.98330f,
+      /* Rotation around X-axis -Pi/2 */
+        1.01f, 3.01f, -2.01f, 4.01f, 8.01f, -6.01f,
+        -11.307890f, -5.01f, -1.565839f, -1.093598f, -11.01f, -19.833414f,
+        15.268191f, -19.004118f, 3.364889f, -9.562627f, -12.099654f, -0.272131f,
+        -30.241013f, 26.919991f, 39.236877f, 22.632446f, 6.707388f, 11.768282f,
+        3.443672f, 6.07445f, 11.61839f, -1.527561f, 37.89633f, 56.9012f,
+        -47.42289f, 50.39153f, -10.61819f, 25.50101f, -0.049248f, 16.98330f,
+      /* Yaw Pi/3, Pitch Pi/4, Roll Pi/5 */
+        1.01f, 4.944899f, 1.442301f, 1.627281f, 0.219220f, 10.540824f,
+        -9.136903f, 2.763750f, -7.30904f,  -5.875721f, 5.303124f,  -8.682154f,
+        -25.683384f, 1.680279f, -18.808388f, 7.653656f, 16.939133f, -17.328018f,
+        14.629795f, -54.467102f, -12.231035f, -4.089857f, -9.444222f, 3.056035f,
+        0.179257f, -10.041875f, 23.090092f, -23.188709f, 11.727098f, -65.183090f,
+        48.671577f, -15.073209f, 38.793171f, -26.039536f, 6.192769f, -17.672247f,
+      /* Rotation around Z-axis Pi/6 */
+        1.01f, 3.745711f, 3.01f, 2.467762f, 10.307889f, 9.209813f,
+        7.01f, 3.931864f, 0.166212f, 16.01f, 18.504042f, 17.405966f,
+        13.01f, 6.128016f, -2.029941f, -10.01f, 13.154292f, 24.01f,
+        29.432245f, 28.334167f, 21.01f, 9.056221f, -4.958143f, -18.01f,
+        -27.236094f, -4.520332f, 16.814543f, 34.01f, 43.092495f, 41.994423f,
+        31.01f, 12.716471f, -8.618400f, -28.01f, -40.896347f, -44.190571,};
+    unsigned int i, j, order;
+
+    D3DXMatrixRotationX(&m[0], -D3DX_PI / 2.0f);
+    D3DXMatrixRotationX(&m[1], D3DX_PI / 2.0f);
+    D3DXMatrixRotationYawPitchRoll(&m[2], D3DX_PI / 3.0f, D3DX_PI / 4.0f, D3DX_PI / 5.0f);
+    D3DXMatrixRotationZ(&m[3], D3DX_PI / 6.0f);
+
+    for (i = 0; i < 49; i++)
+        in[i] = i + 1.01f;
+
+    for (j = 0; j < 4; j++)
+    {
+        for (order = 0; order <= D3DXSH_MAXORDER; order++)
+        {
+            for (i = 0; i < 49; i++)
+                out[i] = ( i + 1.0f ) * ( i + 1.0f );
+
+            received_ptr = D3DXSHRotate(out, order, &m[j], in);
+            ok(received_ptr == out, "Order %u, expected %p, received %p\n", order, out, received_ptr);
+
+            for (i = 0; i < 49; i++)
+            {
+                if ( ( i > 0 ) && ( ( i >= order * order ) || ( order > D3DXSH_MAXORDER ) ) )
+                    expected = ( i + 1.0f ) * ( i + 1.0f );
+                else
+                    expected = table[36 * j + i];
+
+                ok(relative_error(out[i], expected) < admitted_error, "Order %u index %u, expected %f, received %f\n", order, i, expected, out[i]);
+            }
+        }
+    }
+}
+
 static void test_D3DXSHRotateZ(void)
 {
     unsigned int i, j, order, square;
@@ -2740,6 +2806,7 @@ START_TEST(math)
     test_D3DXSHEvalDirectionalLight();
     test_D3DXSHMultiply2();
     test_D3DXSHMultiply3();
+    test_D3DXSHRotate();
     test_D3DXSHRotateZ();
     test_D3DXSHScale();
 }
diff --git a/include/d3dx9math.h b/include/d3dx9math.h
index bcf8c17..971ec53 100644
--- a/include/d3dx9math.h
+++ b/include/d3dx9math.h
@@ -383,6 +383,7 @@ FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir
 HRESULT WINAPI D3DXSHEvalDirectionalLight(UINT order, CONST D3DXVECTOR3 *dir, FLOAT Rintensity, FLOAT Gintensity, FLOAT Bintensity, FLOAT *rout, FLOAT *gout, FLOAT *bout);
 FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b);
 FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b);
+FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, CONST D3DXMATRIX *matrix, CONST FLOAT *in);
 FLOAT* WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, CONST FLOAT *in);
 FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale);
 




More information about the wine-cvs mailing list