Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 48 +++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 26f01d85dc..10aebb704e 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1145,29 +1145,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_affine(frame->transform, m, m2); + break; + + case D3DRMCOMBINE_AFTER: + memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D)); + rotate_axis(m2, &axis, theta); + matrix_multiply_affine(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 ecf23103a7..71dbe7793c 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2749,6 +2749,20 @@ static void set_transform(IDirect3DRMFrame *frame, IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); }
+static void sanitize_matrix(D3DRMMATRIX4D m) +{ + int i, j; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + if (m[i][j] > -1e-7 && m[i][j] < 1e-7) + m[i][j] = 0.0; + } + } +} + static void test_frame_transform(void) { HRESULT hr; @@ -2833,6 +2847,40 @@ static void test_frame_transform(void) check_matrix(matrix, 2,0,0, 0,2,0, 0,0,2, 6,6,6, 32);
+ 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); + ok(hr == D3DRM_OK, "Cannot add rotation (REPLACE) (hr = %x)", hr); + IDirect3DRMFrame_GetTransform(frame, matrix); + sanitize_matrix(matrix); + check_matrix(matrix, 1,0,0, 0,0,1, 0,-1,0, 0,0,0, 32); + + 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); + ok(hr == D3DRM_OK, "Cannot add rotation (BEFORE) (hr = %x)", hr); + IDirect3DRMFrame_GetTransform(frame, matrix); + sanitize_matrix(matrix); + check_matrix(matrix, 1,0,0, 0,0,1, 0,-1,0, 3,3,3, 32); + + 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); + ok(hr == D3DRM_OK, "Cannot add rotation (AFTER) (hr = %x)", hr); + IDirect3DRMFrame_GetTransform(frame, matrix); + sanitize_matrix(matrix); + check_matrix(matrix, 1,0,0, 0,0,1, 0,-1,0, 3,-3,3, 32); + + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, 1.57079633f); + ok(hr == D3DRM_OK, "Cannot add rotation around Z axis (AFTER) (hr = %x)", hr); + IDirect3DRMFrame_GetTransform(frame, matrix); + sanitize_matrix(matrix); + check_matrix(matrix, 0,1,0, -1,0,0, 0,0,1, 0,0,0, 32); + + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, 1.57079633f); + ok(hr == D3DRM_OK, "Cannot add rotation around null axis (hr = %x)", hr); + IDirect3DRMFrame_GetTransform(frame, matrix); + sanitize_matrix(matrix); + check_matrix(matrix, 1,0,0, 0,0,1, 0,-1,0, 0,0,0, 32); + + IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm); }