Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 32 ++++++++++++++++++++++++++++++-- dlls/d3drm/tests/d3drm.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 7162b8323f..9566a799f2 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -3064,9 +3064,37 @@ static HRESULT WINAPI d3drm_frame3_Save(IDirect3DRMFrame3 *iface, static HRESULT WINAPI d3drm_frame3_TransformVectors(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, DWORD num, D3DVECTOR *dst, D3DVECTOR *src) { - FIXME("iface %p, reference %p, num %u, dst %p, src %p stub!\n", iface, reference, num, dst, src); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference); + D3DRMMATRIX4D m; + unsigned int i;
- return E_NOTIMPL; + TRACE("iface %p, reference %p, num %u, dst %p, src %p.\n", iface, reference, num, dst, src); + + if (ref == frame) + return D3DRMERR_BADVALUE; + + if (ref == frame->parent) + memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D)); + else if (!ref) + matrix_expand(m, frame, NULL); + else + { + D3DRMMATRIX4D m2, m3; + matrix_expand(m3, ref, NULL); + matrix_invert(m2, m3); + matrix_expand(m3, frame, NULL); + matrix_multiply(m, m2, m3); + } + + for (i = 0; i < num; ++i) + { + dst[i].u1.x = src[i].u1.x * m[0][0] + src[i].u2.y * m[1][0] + src[i].u3.z * m[2][0] + m[3][0]; + dst[i].u2.y = src[i].u1.x * m[0][1] + src[i].u2.y * m[1][1] + src[i].u3.z * m[2][1] + m[3][1]; + dst[i].u3.z = src[i].u1.x * m[0][2] + src[i].u2.y * m[1][2] + src[i].u3.z * m[2][2] + m[3][2]; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame3_InverseTransformVectors(IDirect3DRMFrame3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index dbff1bac82..d0a8c83dae 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2810,6 +2810,16 @@ cleanup: EXPECT_VECTOR_(test_description, vector2, vx2,vy2,vz2); \ }
+#define EXPECT_VECTORS_4(test_description, vector1, vx1,vy1,vz1, vector2, vx2,vy2,vz2, \ + vector3, vx3,vy3,vz3, vector4, vx4,vy4,vz4) \ + { \ + ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \ + EXPECT_VECTOR_(test_description, vector1, vx1,vy1,vz1); \ + EXPECT_VECTOR_(test_description, vector2, vx2,vy2,vz2); \ + EXPECT_VECTOR_(test_description, vector3, vx3,vy3,vz3); \ + EXPECT_VECTOR_(test_description, vector4, vx4,vy4,vz4); \ + } + static void test_frame_transform(void) { HRESULT hr; @@ -2818,6 +2828,7 @@ static void test_frame_transform(void) IDirect3DRMFrame3 *frame3, *subframe3, *reference3; D3DRMMATRIX4D matrix; D3DVECTOR v1, v2; + D3DVECTOR svec[4], dvec[4];
hr = Direct3DRMCreate(&d3drm); ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); @@ -2973,6 +2984,32 @@ static void test_frame_transform(void) -0.8,0.6,0, -0.48,-0.64,0.6, 0.36,0.48,0.8, 80/3.0,289/9.0,224/9.0);
+ SET_VECTOR(svec[0], 0,0,0); + SET_VECTOR(svec[1], 1,0,0); + SET_VECTOR(svec[2], 0,1,0); + SET_VECTOR(svec[3], 0,0,1); + hr = IDirect3DRMFrame3_TransformVectors(frame3, reference3, 4, dvec, svec); + EXPECT_VECTORS_4("TransformVectors (vs. reference)", + dvec[0], 5.8, 5.4, 11, + dvec[1], 5.8-1.4, 5.4-1.45, 11+0.25, + dvec[2], 5.8-0.2, 5.4-1.1, 11-0.5, + dvec[3], 5.8+2.44, 5.4+3.67, 11+0.45); + hr = IDirect3DRMFrame3_TransformVectors(frame3, NULL, 4, dvec, svec); + EXPECT_VECTORS_4("TransformVectors (vs. NULL)", + dvec[0], 10, 11, 12, + dvec[1], 10+0.8, 11-0.6, 12, + dvec[2], 10+0.36, 11+0.48, 12+0.8, + dvec[3], 10-0.48, 11-0.64, 12+0.6); + hr = IDirect3DRMFrame3_TransformVectors(subframe3, NULL, 4, dvec, svec); + EXPECT_VECTORS_4("TransformVectors (sub-frame vs. NULL)", + dvec[0], 80/3.0, 289/9.0, 224/9.0, + dvec[1], 80/3.0-0.8, 289/9.0+0.6, 224/9.0, + dvec[2], 80/3.0-0.48, 289/9.0-0.64, 224/9.0+0.6, + dvec[3], 80/3.0+0.36, 289/9.0+0.48, 224/9.0+0.8); + hr = IDirect3DRMFrame3_TransformVectors(frame3, frame3, 4, dvec, svec); + ok(hr == D3DRMERR_BADVALUE, "TransformVectors: BADVALUE error expected when reference == self\n"); + + IDirect3DRMFrame3_Release(reference3); IDirect3DRMFrame3_Release(subframe3); IDirect3DRMFrame3_Release(frame3);