[PATCH 11/12] d3drm: Implement frame InverseTransformVectors

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


Signed-off-by: Jeff Smith <whydoubt at 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);
-- 
2.14.3




More information about the wine-devel mailing list