[PATCH 07/12] d3drm: Implement frame AddRotation

Jeff Smith whydoubt at gmail.com
Thu Jun 13 23:27:32 CDT 2019


Signed-off-by: Jeff Smith <whydoubt at gmail.com>
---
 dlls/d3drm/frame.c       | 75 +++++++++++++++++++++++++++++++++++++++++++-----
 dlls/d3drm/tests/d3drm.c | 19 ++++++++++++
 2 files changed, 87 insertions(+), 7 deletions(-)

diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c
index 8dbecd5896..ebe09df141 100644
--- a/dlls/d3drm/frame.c
+++ b/dlls/d3drm/frame.c
@@ -1160,29 +1160,90 @@ static HRESULT WINAPI d3drm_frame1_AddScale(IDirect3DRMFrame *iface,
     return d3drm_frame3_AddScale(&frame->IDirect3DRMFrame3_iface, type, sx, sy, sz);
 }
 
+static void rotate_axis(D3DRMMATRIX4D matrix, D3DVECTOR *axis, D3DVALUE theta)
+{
+    D3DVALUE stheta, ctheta, coff;
+
+    D3DRMVectorNormalize(axis);
+    stheta = sinf(theta);
+    ctheta = cosf(theta);
+    coff = 1.0f - ctheta;
+
+    matrix[0][0] = coff * axis->u1.x * axis->u1.x + ctheta;
+    matrix[1][0] = coff * axis->u1.x * axis->u2.y - stheta * axis->u3.z;
+    matrix[2][0] = coff * axis->u1.x * axis->u3.z + stheta * axis->u2.y;
+    matrix[3][0] = 0.0f;
+    matrix[0][1] = coff * axis->u2.y * axis->u1.x + stheta * axis->u3.z;
+    matrix[1][1] = coff * axis->u2.y * axis->u2.y + ctheta;
+    matrix[2][1] = coff * axis->u2.y * axis->u3.z - stheta * axis->u1.x;
+    matrix[3][1] = 0.0f;
+    matrix[0][2] = coff * axis->u3.z * axis->u1.x - stheta * axis->u2.y;
+    matrix[1][2] = coff * axis->u3.z * axis->u2.y + stheta * axis->u1.x;
+    matrix[2][2] = coff * axis->u3.z * axis->u3.z + ctheta;
+    matrix[3][2] = 0.0f;
+    matrix[0][3] = 0.0f;
+    matrix[1][3] = 0.0f;
+    matrix[2][3] = 0.0f;
+    matrix[3][3] = 1.0f;
+}
+
 static HRESULT WINAPI d3drm_frame3_AddRotation(IDirect3DRMFrame3 *iface,
         D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
 {
-    FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n",
-            iface, type, x, y, z, theta);
+    struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
+    D3DVECTOR axis;
+    D3DRMMATRIX4D m, m2;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+    axis.u1.x = x;
+    axis.u2.y = y;
+    axis.u3.z = z;
+
+    switch (type)
+    {
+        case D3DRMCOMBINE_REPLACE:
+            rotate_axis(frame->transform, &axis, theta);
+            break;
+
+        case D3DRMCOMBINE_BEFORE:
+            rotate_axis(m, &axis, theta);
+            memcpy(m2, frame->transform, sizeof(D3DRMMATRIX4D));
+            matrix_multiply(frame->transform, m, m2);
+            break;
+
+        case D3DRMCOMBINE_AFTER:
+            memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D));
+            rotate_axis(m2, &axis, theta);
+            matrix_multiply(frame->transform, m, m2);
+            break;
+
+        default:
+            WARN("Unknown Combine Type %u\n", type);
+            return D3DRMERR_BADVALUE;
+    }
+
+    return D3DRM_OK;
 }
 
 static HRESULT WINAPI d3drm_frame2_AddRotation(IDirect3DRMFrame2 *iface,
         D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
 {
-    FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta);
+    struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+    return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta);
 }
 
 static HRESULT WINAPI d3drm_frame1_AddRotation(IDirect3DRMFrame *iface,
         D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
 {
-    FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta);
+    struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+    return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta);
 }
 
 static HRESULT WINAPI d3drm_frame3_AddVisual(IDirect3DRMFrame3 *iface, IUnknown *visual)
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index e7e3effa7a..fa23ad7795 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -2883,6 +2883,25 @@ static void test_frame_transform(void)
     EXPECT_TRANSFORM("AddScale (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 6,6,6);
 
 
+    SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3);
+    hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 1.0f, 0.0f, 0.0f, 1.57079633f);
+    EXPECT_TRANSFORM("AddRotation (REPLACE)", frame, 1,0,0, 0,0,1, 0,-1,0, 0,0,0);
+
+    SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3);
+    hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_BEFORE, 1.0f, 0.0f, 0.0f, 1.57079633f);
+    EXPECT_TRANSFORM("AddRotation (BEFORE)", frame, 1,0,0, 0,0,1, 0,-1,0, 3,3,3);
+
+    SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3);
+    hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_AFTER, 1.0f, 0.0f, 0.0f, 1.57079633f);
+    EXPECT_TRANSFORM("AddRotation (AFTER)", frame, 1,0,0, 0,0,1, 0,-1,0, 3,-3,3);
+
+    hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, 1.57079633f);
+    EXPECT_TRANSFORM("AddRotation around Z axis", frame, 0,1,0, -1,0,0, 0,0,1, 0,0,0);
+
+    hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, 1.57079633f);
+    EXPECT_TRANSFORM("AddRotation around null axis", frame, 1,0,0, 0,0,1, 0,-1,0, 0,0,0);
+
+
     IDirect3DRMFrame_Release(subframe);
     IDirect3DRMFrame_Release(frame);
     IDirect3DRM_Release(d3drm);
-- 
2.14.3




More information about the wine-devel mailing list