Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 36 ++++++++++++++++++++++++++++++++++-- dlls/d3drm/tests/d3drm.c | 26 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 9566a799f2..cccd0f9e15 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -3100,9 +3100,41 @@ static HRESULT WINAPI d3drm_frame3_TransformVectors(IDirect3DRMFrame3 *iface, static HRESULT WINAPI d3drm_frame3_InverseTransformVectors(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) + matrix_invert(m, frame->transform); + else if (!ref) + { + D3DRMMATRIX4D m2; + matrix_expand(m2, frame, NULL); + matrix_invert(m, m2); + } + else + { + D3DRMMATRIX4D m2, m3; + matrix_expand(m3, frame, NULL); + matrix_invert(m2, m3); + matrix_expand(m3, ref, 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_SetTraversalOptions(IDirect3DRMFrame3 *iface, DWORD options) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index d0a8c83dae..1e41023f8f 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -3010,6 +3010,32 @@ static void test_frame_transform(void) ok(hr == D3DRMERR_BADVALUE, "TransformVectors: BADVALUE error expected when reference == self\n");
+ 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_InverseTransformVectors(frame3, reference3, 4, dvec, svec); + EXPECT_VECTORS_4("InverseTransformVectors (vs. reference)", + dvec[0], -92.48, -80.04, -62, + dvec[1], -87.12, -73.76, -58, + dvec[2], -97, -85, -65, + dvec[3], -84.68, -73.64, -57); + hr = IDirect3DRMFrame3_InverseTransformVectors(frame3, NULL, 4, dvec, svec); + EXPECT_VECTORS_4("InverseTransformVectors (vs. NULL)", + dvec[0], -1.4, -18.48, 4.64, + dvec[1], -0.6, -18.12, 4.16, + dvec[2], -2, -18, 4, + dvec[3], -1.4, -17.68, 5.24); + hr = IDirect3DRMFrame3_InverseTransformVectors(subframe3, NULL, 4, dvec, svec); + EXPECT_VECTORS_4("InverseTransformVectors (sub-frame vs. NULL)", + dvec[0], 8/3.0-0.6, 160/9.0+0.64, -400/9.0-0.48, + dvec[1], 8/3.0-1.4, 160/9.0+0.16, -400/9.0-0.12, + dvec[2], 8/3.0, 160/9.0, -400/9.0, + dvec[3], 8/3.0-0.6, 160/9.0+1.24, -400/9.0+0.32); + hr = IDirect3DRMFrame3_InverseTransformVectors(frame3, frame3, 4, dvec, svec); + ok(hr == D3DRMERR_BADVALUE, "InverseTransformVectors: BADVALUE error expected when reference == self\n"); + + IDirect3DRMFrame3_Release(reference3); IDirect3DRMFrame3_Release(subframe3); IDirect3DRMFrame3_Release(frame3);