Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 38 +++++++++++++++++++---- dlls/d3drm/tests/d3drm.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 7 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 8bed50b57e..14a524ea7d 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -2416,23 +2416,49 @@ static HRESULT WINAPI d3drm_frame1_SetZbufferMode(IDirect3DRMFrame *iface, D3DRM
static HRESULT WINAPI d3drm_frame3_Transform(IDirect3DRMFrame3 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + d->u1.x = s->u1.x * frame->transform[0][0] + s->u2.y * frame->transform[1][0] + + s->u3.z * frame->transform[2][0] + frame->transform[3][0]; + d->u2.y = s->u1.x * frame->transform[0][1] + s->u2.y * frame->transform[1][1] + + s->u3.z * frame->transform[2][1] + frame->transform[3][1]; + d->u3.z = s->u1.x * frame->transform[0][2] + s->u2.y * frame->transform[1][2] + + s->u3.z * frame->transform[2][2] + frame->transform[3][2]; + + while ((frame = frame->parent)) + { + D3DVALUE x = d->u1.x; + D3DVALUE y = d->u2.y; + D3DVALUE z = d->u3.z; + d->u1.x = x * frame->transform[0][0] + y * frame->transform[1][0] + + z * frame->transform[2][0] + frame->transform[3][0]; + d->u2.y = x * frame->transform[0][1] + y * frame->transform[1][1] + + z * frame->transform[2][1] + frame->transform[3][1]; + d->u3.z = x * frame->transform[0][2] + y * frame->transform[1][2] + + z * frame->transform[2][2] + frame->transform[3][2]; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_Transform(IDirect3DRMFrame2 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_Transform(&frame->IDirect3DRMFrame3_iface, d, s); }
static HRESULT WINAPI d3drm_frame1_Transform(IDirect3DRMFrame *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_Transform(&frame->IDirect3DRMFrame3_iface, d, s); }
static HRESULT WINAPI d3drm_frame2_AddMoveCallback2(IDirect3DRMFrame2 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index cc4f8fe16a..76e0ec19fb 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -20,6 +20,7 @@ */
#include <limits.h> +#include <math.h>
#define COBJMACROS #include <d3d.h> @@ -2709,12 +2710,75 @@ cleanup: DestroyWindow(window); }
+#define SET_TRANSFORM(frame, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43) \ + { \ + D3DRMMATRIX4D matrix; \ + matrix[0][0] = D3DVAL(m11); \ + matrix[0][1] = D3DVAL(m12); \ + matrix[0][2] = D3DVAL(m13); \ + matrix[0][3] = D3DVAL(0); \ + matrix[1][0] = D3DVAL(m21); \ + matrix[1][1] = D3DVAL(m22); \ + matrix[1][2] = D3DVAL(m23); \ + matrix[1][3] = D3DVAL(0); \ + matrix[2][0] = D3DVAL(m31); \ + matrix[2][1] = D3DVAL(m32); \ + matrix[2][2] = D3DVAL(m33); \ + matrix[2][3] = D3DVAL(0); \ + matrix[3][0] = D3DVAL(m41); \ + matrix[3][1] = D3DVAL(m42); \ + matrix[3][2] = D3DVAL(m43); \ + matrix[3][3] = D3DVAL(1); \ + IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); \ + } + +#define SET_VECTOR(vector, vx,vy,vz) \ + { \ + (vector).x = D3DVAL(vx); \ + (vector).y = D3DVAL(vy); \ + (vector).z = D3DVAL(vz); \ + } + +#define MAXERROR_ABS 0.000001 +#define MAXERROR_REL 0.000001 +#define CHECK(a, b) \ + { \ + if (pass) \ + { \ + if ((a < 1 && a > -1) || (b < 1 && b > -1)) \ + { \ + if (fabs((a) - (b)) > MAXERROR_ABS) \ + { \ + pass = 0; \ + } \ + } \ + else \ + { \ + if (fabs((a) - (b)) > fabs(MAXERROR_REL * (b))) \ + { \ + pass = 0; \ + } \ + } \ + } \ + } + +#define EXPECT_VECTOR(test_description, vector, vx,vy,vz) \ + { \ + int pass = 1; \ + ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \ + CHECK((vector).x, vx); \ + CHECK((vector).y, vy); \ + CHECK((vector).z, vz); \ + ok(pass, test_description ": vector result is not correct\n"); \ + } + static void test_frame_transform(void) { HRESULT hr; IDirect3DRM *d3drm; - IDirect3DRMFrame *frame; + IDirect3DRMFrame *frame, *subframe; D3DRMMATRIX4D matrix; + D3DVECTOR v1, v2;
hr = Direct3DRMCreate(&d3drm); ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); @@ -2726,6 +2790,19 @@ static void test_frame_transform(void) ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetTransform returned hr = %x\n", hr); ok(!memcmp(matrix, identity, sizeof(D3DRMMATRIX4D)), "Returned matrix is not identity\n");
+ + IDirect3DRM_CreateFrame(d3drm, frame, &subframe); + + SET_TRANSFORM(frame, 2,0,0, 0,4,0, 0,0,8, 64,64,64); + SET_TRANSFORM(subframe, 1,0,0, 0,1,0, 0,0,1, 11,11,11); + SET_VECTOR(v1, 3,5,7); + hr = IDirect3DRMFrame_Transform(frame, &v2, &v1); + EXPECT_VECTOR("Transform", v2, 70,84,120); + hr = IDirect3DRMFrame_Transform(subframe, &v2, &v1); + EXPECT_VECTOR("Transform (subframe)", v2, 92,128,208); + + + IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm); }
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 96 +++++++++++++++++++++++++++++++++++++++++++++--- dlls/d3drm/tests/d3drm.c | 7 ++++ 2 files changed, 97 insertions(+), 6 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 14a524ea7d..f5e24efb6f 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -937,6 +937,41 @@ static HRESULT WINAPI d3drm_frame1_AddMoveCallback(IDirect3DRMFrame *iface, return E_NOTIMPL; }
+static void matrix_multiply(D3DRMMATRIX4D d, D3DRMMATRIX4D s1, D3DRMMATRIX4D s2) +{ + d[0][0] = s1[0][0] * s2[0][0] + s1[0][1] * s2[1][0] + s1[0][2] * s2[2][0]; + d[0][1] = s1[0][0] * s2[0][1] + s1[0][1] * s2[1][1] + s1[0][2] * s2[2][1]; + d[0][2] = s1[0][0] * s2[0][2] + s1[0][1] * s2[1][2] + s1[0][2] * s2[2][2]; + d[0][3] = 0.0f; + d[1][0] = s1[1][0] * s2[0][0] + s1[1][1] * s2[1][0] + s1[1][2] * s2[2][0]; + d[1][1] = s1[1][0] * s2[0][1] + s1[1][1] * s2[1][1] + s1[1][2] * s2[2][1]; + d[1][2] = s1[1][0] * s2[0][2] + s1[1][1] * s2[1][2] + s1[1][2] * s2[2][2]; + d[1][3] = 0.0f; + d[2][0] = s1[2][0] * s2[0][0] + s1[2][1] * s2[1][0] + s1[2][2] * s2[2][0]; + d[2][1] = s1[2][0] * s2[0][1] + s1[2][1] * s2[1][1] + s1[2][2] * s2[2][1]; + d[2][2] = s1[2][0] * s2[0][2] + s1[2][1] * s2[1][2] + s1[2][2] * s2[2][2]; + d[2][3] = 0.0f; + d[3][0] = s1[3][0] * s2[0][0] + s1[3][1] * s2[1][0] + s1[3][2] * s2[2][0] + s2[3][0]; + d[3][1] = s1[3][0] * s2[0][1] + s1[3][1] * s2[1][1] + s1[3][2] * s2[2][1] + s2[3][1]; + d[3][2] = s1[3][0] * s2[0][2] + s1[3][1] * s2[1][2] + s1[3][2] * s2[2][2] + s2[3][2]; + d[3][3] = 1.0f; +} + +static struct d3drm_frame *matrix_expand(D3DRMMATRIX4D d, struct d3drm_frame *s, + struct d3drm_frame *shortcut) +{ + D3DRMMATRIX4D m; + memcpy(d, s->transform, sizeof(D3DRMMATRIX4D)); + while ((s = s->parent)) + { + if (s == shortcut) + return NULL; + memcpy(m, d, sizeof(D3DRMMATRIX4D)); + matrix_multiply(d, m, s->transform); + } + return shortcut; +} + static HRESULT WINAPI d3drm_frame3_AddTransform(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DRMMATRIX4D matrix) { @@ -1269,6 +1304,41 @@ static HRESULT WINAPI d3drm_frame1_GetParent(IDirect3DRMFrame *iface, IDirect3DR return d3drm_frame2_GetParent(&frame->IDirect3DRMFrame2_iface, parent); }
+static void matrix_invert(D3DRMMATRIX4D d, D3DRMMATRIX4D s) +{ + D3DVALUE determinant; + D3DVALUE cofac[3]; + + cofac[0] = s[1][1] * s[2][2] - s[1][2] * s[2][1]; + cofac[1] = s[1][2] * s[2][0] - s[1][0] * s[2][2]; + cofac[2] = s[1][0] * s[2][1] - s[1][1] * s[2][0]; + + determinant = s[0][0] * cofac[0] + s[0][1] * cofac[1] + s[0][2] * cofac[2]; + + if (determinant == 0.0f) + { + memcpy(d, identity, sizeof(D3DRMMATRIX4D)); + return; + } + + d[0][0] = cofac[0] / determinant; + d[0][1] = (s[2][1] * s[0][2] - s[2][2] * s[0][1]) / determinant; + d[0][2] = (s[0][1] * s[1][2] - s[0][2] * s[1][1]) / determinant; + d[0][3] = 0.0f; + d[1][0] = cofac[1] / determinant; + d[1][1] = (s[2][2] * s[0][0] - s[2][0] * s[0][2]) / determinant; + d[1][2] = (s[0][2] * s[1][0] - s[0][0] * s[1][2]) / determinant; + d[1][3] = 0.0f; + d[2][0] = cofac[2] / determinant; + d[2][1] = (s[2][0] * s[0][1] - s[2][1] * s[0][0]) / determinant; + d[2][2] = (s[0][0] * s[1][1] - s[0][1] * s[1][0]) / determinant; + d[2][3] = 0.0f; + d[3][0] = -(d[0][0] * s[3][0] + d[1][0] * s[3][1] + d[2][0] * s[3][2]); + d[3][1] = -(d[0][1] * s[3][0] + d[1][1] * s[3][1] + d[2][1] * s[3][2]); + d[3][2] = -(d[0][2] * s[3][0] + d[1][2] * s[3][1] + d[2][2] * s[3][2]); + d[3][3] = 1.0f; +} + static HRESULT WINAPI d3drm_frame3_GetPosition(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DVECTOR *position) { @@ -1547,23 +1617,37 @@ static HRESULT WINAPI d3drm_frame1_GetTextureTopology(IDirect3DRMFrame *iface, B
static HRESULT WINAPI d3drm_frame3_InverseTransform(IDirect3DRMFrame3 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + D3DRMMATRIX4D m, m2;
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + matrix_expand(m2, frame, NULL); + matrix_invert(m, m2); + + d->u1.x = s->u1.x * m[0][0] + s->u2.y * m[1][0] + s->u3.z * m[2][0] + m[3][0]; + d->u2.y = s->u1.x * m[0][1] + s->u2.y * m[1][1] + s->u3.z * m[2][1] + m[3][1]; + d->u3.z = s->u1.x * m[0][2] + s->u2.y * m[1][2] + s->u3.z * m[2][2] + m[3][2]; + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_InverseTransform(IDirect3DRMFrame2 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_InverseTransform(&frame->IDirect3DRMFrame3_iface, d, s); }
static HRESULT WINAPI d3drm_frame1_InverseTransform(IDirect3DRMFrame *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
- return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_InverseTransform(&frame->IDirect3DRMFrame3_iface, d, s); }
static HRESULT WINAPI d3drm_frame3_Load(IDirect3DRMFrame3 *iface, void *filename, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 76e0ec19fb..1c02d639a0 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2801,6 +2801,13 @@ static void test_frame_transform(void) hr = IDirect3DRMFrame_Transform(subframe, &v2, &v1); EXPECT_VECTOR("Transform (subframe)", v2, 92,128,208);
+ SET_VECTOR(v1, 70,84,120); + hr = IDirect3DRMFrame_InverseTransform(frame, &v2, &v1); + EXPECT_VECTOR("InverseTransform", v2, 3,5,7); + SET_VECTOR(v1, 92,128,208); + hr = IDirect3DRMFrame_InverseTransform(subframe, &v2, &v1); + EXPECT_VECTOR("InverseTransform (subframe)", v2, 3,5,7); +
IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame);
On Fri, 14 Jun 2019 at 09:00, Jeff Smith whydoubt@gmail.com wrote:
+static void matrix_multiply(D3DRMMATRIX4D d, D3DRMMATRIX4D s1, D3DRMMATRIX4D s2) +{
- d[0][0] = s1[0][0] * s2[0][0] + s1[0][1] * s2[1][0] + s1[0][2] * s2[2][0];
- d[0][1] = s1[0][0] * s2[0][1] + s1[0][1] * s2[1][1] + s1[0][2] * s2[2][1];
- d[0][2] = s1[0][0] * s2[0][2] + s1[0][1] * s2[1][2] + s1[0][2] * s2[2][2];
- d[0][3] = 0.0f;
- d[1][0] = s1[1][0] * s2[0][0] + s1[1][1] * s2[1][0] + s1[1][2] * s2[2][0];
- d[1][1] = s1[1][0] * s2[0][1] + s1[1][1] * s2[1][1] + s1[1][2] * s2[2][1];
- d[1][2] = s1[1][0] * s2[0][2] + s1[1][1] * s2[1][2] + s1[1][2] * s2[2][2];
- d[1][3] = 0.0f;
- d[2][0] = s1[2][0] * s2[0][0] + s1[2][1] * s2[1][0] + s1[2][2] * s2[2][0];
- d[2][1] = s1[2][0] * s2[0][1] + s1[2][1] * s2[1][1] + s1[2][2] * s2[2][1];
- d[2][2] = s1[2][0] * s2[0][2] + s1[2][1] * s2[1][2] + s1[2][2] * s2[2][2];
- d[2][3] = 0.0f;
- d[3][0] = s1[3][0] * s2[0][0] + s1[3][1] * s2[1][0] + s1[3][2] * s2[2][0] + s2[3][0];
- d[3][1] = s1[3][0] * s2[0][1] + s1[3][1] * s2[1][1] + s1[3][2] * s2[2][1] + s2[3][1];
- d[3][2] = s1[3][0] * s2[0][2] + s1[3][1] * s2[1][2] + s1[3][2] * s2[2][2] + s2[3][2];
- d[3][3] = 1.0f;
+}
That's not a regular 4x4 matrix multiplication. (Which may be fine, but the function name should make that obvious.)
+static struct d3drm_frame *matrix_expand(D3DRMMATRIX4D d, struct d3drm_frame *s,
struct d3drm_frame *shortcut)
+{
- D3DRMMATRIX4D m;
- memcpy(d, s->transform, sizeof(D3DRMMATRIX4D));
- while ((s = s->parent))
- {
if (s == shortcut)
return NULL;
memcpy(m, d, sizeof(D3DRMMATRIX4D));
matrix_multiply(d, m, s->transform);
- }
- return shortcut;
+}
You're always calling this with NULL "shortcut", i.e., the "shortcut" handling is effectively dead code.
+static void matrix_invert(D3DRMMATRIX4D d, D3DRMMATRIX4D s) +{
- D3DVALUE determinant;
- D3DVALUE cofac[3];
- cofac[0] = s[1][1] * s[2][2] - s[1][2] * s[2][1];
- cofac[1] = s[1][2] * s[2][0] - s[1][0] * s[2][2];
- cofac[2] = s[1][0] * s[2][1] - s[1][1] * s[2][0];
- determinant = s[0][0] * cofac[0] + s[0][1] * cofac[1] + s[0][2] * cofac[2];
- if (determinant == 0.0f)
- {
memcpy(d, identity, sizeof(D3DRMMATRIX4D));
return;
- }
- d[0][0] = cofac[0] / determinant;
- d[0][1] = (s[2][1] * s[0][2] - s[2][2] * s[0][1]) / determinant;
- d[0][2] = (s[0][1] * s[1][2] - s[0][2] * s[1][1]) / determinant;
- d[0][3] = 0.0f;
- d[1][0] = cofac[1] / determinant;
- d[1][1] = (s[2][2] * s[0][0] - s[2][0] * s[0][2]) / determinant;
- d[1][2] = (s[0][2] * s[1][0] - s[0][0] * s[1][2]) / determinant;
- d[1][3] = 0.0f;
- d[2][0] = cofac[2] / determinant;
- d[2][1] = (s[2][0] * s[0][1] - s[2][1] * s[0][0]) / determinant;
- d[2][2] = (s[0][0] * s[1][1] - s[0][1] * s[1][0]) / determinant;
- d[2][3] = 0.0f;
- d[3][0] = -(d[0][0] * s[3][0] + d[1][0] * s[3][1] + d[2][0] * s[3][2]);
- d[3][1] = -(d[0][1] * s[3][0] + d[1][1] * s[3][1] + d[2][1] * s[3][2]);
- d[3][2] = -(d[0][2] * s[3][0] + d[1][2] * s[3][1] + d[2][2] * s[3][2]);
- d[3][3] = 1.0f;
+}
While this approach has the advantage of being relatively straightforward, it has the disadvantage of not being the most numerically stable approach. Note that you don't actually need to invert the matrix to get the inverse transform though; it probably makes more sense to decompose it instead.
This is also one of the harder patches in the series, you may want to consider moving the easier ones to the front instead.
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 7 +++++-- dlls/d3drm/tests/d3drm.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index f5e24efb6f..545010caec 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -976,6 +976,7 @@ static HRESULT WINAPI d3drm_frame3_AddTransform(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DRMMATRIX4D matrix) { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + D3DRMMATRIX4D m;
TRACE("iface %p, type %#x, matrix %p.\n", iface, type, matrix);
@@ -986,11 +987,13 @@ static HRESULT WINAPI d3drm_frame3_AddTransform(IDirect3DRMFrame3 *iface, break;
case D3DRMCOMBINE_BEFORE: - FIXME("D3DRMCOMBINE_BEFORE not supported yet\n"); + memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D)); + matrix_multiply(frame->transform, matrix, m); break;
case D3DRMCOMBINE_AFTER: - FIXME("D3DRMCOMBINE_AFTER not supported yet\n"); + memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D)); + matrix_multiply(frame->transform, m, matrix); break;
default: diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 1c02d639a0..51099dc58a 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2762,6 +2762,32 @@ cleanup: } \ }
+#define EXPECT_TRANSFORM_MATRIX(test_description, matrix, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43) \ + { \ + int pass = 1; \ + ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \ + CHECK(matrix[0][0], m11); \ + CHECK(matrix[0][1], m12); \ + CHECK(matrix[0][2], m13); \ + CHECK(matrix[1][0], m21); \ + CHECK(matrix[1][1], m22); \ + CHECK(matrix[1][2], m23); \ + CHECK(matrix[2][0], m31); \ + CHECK(matrix[2][1], m32); \ + CHECK(matrix[2][2], m33); \ + CHECK(matrix[3][0], m41); \ + CHECK(matrix[3][1], m42); \ + CHECK(matrix[3][2], m43); \ + ok(pass, test_description ": returned matrix is not correct\n"); \ + } + +#define EXPECT_TRANSFORM(test_description, frame, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43) \ + { \ + D3DRMMATRIX4D matrix; \ + IDirect3DRMFrame_GetTransform(frame, matrix); \ + EXPECT_TRANSFORM_MATRIX(test_description, matrix, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43); \ + } + #define EXPECT_VECTOR(test_description, vector, vx,vy,vz) \ { \ int pass = 1; \ @@ -2809,6 +2835,24 @@ static void test_frame_transform(void) EXPECT_VECTOR("InverseTransform (subframe)", v2, 3,5,7);
+ memcpy(matrix, identity, sizeof(D3DRMMATRIX4D)); + matrix[3][0] = 3.0f; + matrix[3][1] = 3.0f; + matrix[3][2] = 3.0f; + + SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); + EXPECT_TRANSFORM("AddTransform (REPLACE)", frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3); + + SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_BEFORE, matrix); + EXPECT_TRANSFORM("AddTransform (BEFORE)", frame, 2,0,0, 0,2,0, 0,0,2, 6,6,6); + + SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_AFTER, matrix); + EXPECT_TRANSFORM("AddTransform (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 3,3,3); + + IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 3 +++ dlls/d3drm/tests/d3drm.c | 4 ++++ 2 files changed, 7 insertions(+)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 545010caec..5df85e4fe2 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -980,6 +980,9 @@ static HRESULT WINAPI d3drm_frame3_AddTransform(IDirect3DRMFrame3 *iface,
TRACE("iface %p, type %#x, matrix %p.\n", iface, type, matrix);
+ if (matrix[0][3] != 0.0f || matrix[1][3] != 0.0f || matrix[2][3] != 0.0f || matrix[3][3] != 1.0f) + return D3DRMERR_BADVALUE; + switch (type) { case D3DRMCOMBINE_REPLACE: diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 51099dc58a..e9e789823c 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2852,6 +2852,10 @@ static void test_frame_transform(void) hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_AFTER, matrix); EXPECT_TRANSFORM("AddTransform (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 3,3,3);
+ matrix[3][3] = 2.0f; + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); + ok(hr == D3DRMERR_BADVALUE, "AddTransform: BADVALUE error expected when last column != [0 0 0 1]\n"); +
IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 50 ++++++++++++++++++++++++++++++++++++++++++------ dlls/d3drm/tests/d3drm.c | 13 +++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 5df85e4fe2..df8bd9b78b 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1030,25 +1030,63 @@ static HRESULT WINAPI d3drm_frame1_AddTransform(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_AddTranslation(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + switch (type) + { + case D3DRMCOMBINE_REPLACE: + memcpy(frame->transform, identity, sizeof(D3DRMMATRIX4D)); + frame->transform[3][0] = x; + frame->transform[3][1] = y; + frame->transform[3][2] = z; + break; + + case D3DRMCOMBINE_BEFORE: + frame->transform[3][0] += frame->transform[0][0] * x + + frame->transform[1][0] * y + + frame->transform[2][0] * z; + frame->transform[3][1] += frame->transform[0][1] * x + + frame->transform[1][1] * y + + frame->transform[2][1] * z; + frame->transform[3][2] += frame->transform[0][2] * x + + frame->transform[1][2] * y + + frame->transform[2][2] * z; + break; + + case D3DRMCOMBINE_AFTER: + frame->transform[3][0] += x; + frame->transform[3][1] += y; + frame->transform[3][2] += z; + break; + + default: + WARN("Unknown Combine Type %u\n", type); + return D3DRMERR_BADVALUE; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_AddTranslation(IDirect3DRMFrame2 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + return d3drm_frame3_AddTranslation(&frame->IDirect3DRMFrame3_iface, type, x, y, z); }
static HRESULT WINAPI d3drm_frame1_AddTranslation(IDirect3DRMFrame *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + return d3drm_frame3_AddTranslation(&frame->IDirect3DRMFrame3_iface, type, x, y, z); }
static HRESULT WINAPI d3drm_frame3_AddScale(IDirect3DRMFrame3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index e9e789823c..335e0a4f2d 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2857,6 +2857,19 @@ static void test_frame_transform(void) ok(hr == D3DRMERR_BADVALUE, "AddTransform: BADVALUE error expected when last column != [0 0 0 1]\n");
+ SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_REPLACE, 3.0f, 3.0f, 3.0f); + EXPECT_TRANSFORM("AddTranslation (REPLACE)", frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3); + + SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_BEFORE, 3.0f, 3.0f, 3.0f); + EXPECT_TRANSFORM("AddTranslation (BEFORE)", frame, 2,0,0, 0,2,0, 0,0,2, 6,6,6); + + SET_TRANSFORM(frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_AFTER, 3.0f, 3.0f, 3.0f); + EXPECT_TRANSFORM("AddTranslation (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 3,3,3); + + IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 59 +++++++++++++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 13 +++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index df8bd9b78b..8dbecd5896 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1092,25 +1092,72 @@ static HRESULT WINAPI d3drm_frame1_AddTranslation(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_AddScale(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + switch (type) + { + case D3DRMCOMBINE_REPLACE: + memcpy(frame->transform, identity, sizeof(D3DRMMATRIX4D)); + frame->transform[0][0] = sx; + frame->transform[1][1] = sy; + frame->transform[2][2] = sz; + break; + + case D3DRMCOMBINE_BEFORE: + frame->transform[0][0] *= sx; + frame->transform[0][1] *= sx; + frame->transform[0][2] *= sx; + frame->transform[1][0] *= sy; + frame->transform[1][1] *= sy; + frame->transform[1][2] *= sy; + frame->transform[2][0] *= sz; + frame->transform[2][1] *= sz; + frame->transform[2][2] *= sz; + break; + + case D3DRMCOMBINE_AFTER: + frame->transform[0][0] *= sx; + frame->transform[0][1] *= sy; + frame->transform[0][2] *= sz; + frame->transform[1][0] *= sx; + frame->transform[1][1] *= sy; + frame->transform[1][2] *= sz; + frame->transform[2][0] *= sx; + frame->transform[2][1] *= sy; + frame->transform[2][2] *= sz; + frame->transform[3][0] *= sx; + frame->transform[3][1] *= sy; + frame->transform[3][2] *= sz; + break; + + default: + WARN("Unknown Combine Type %u\n", type); + return D3DRMERR_BADVALUE; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_AddScale(IDirect3DRMFrame2 *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + return d3drm_frame3_AddScale(&frame->IDirect3DRMFrame3_iface, type, sx, sy, sz); }
static HRESULT WINAPI d3drm_frame1_AddScale(IDirect3DRMFrame *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
- return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + return d3drm_frame3_AddScale(&frame->IDirect3DRMFrame3_iface, type, sx, sy, sz); }
static HRESULT WINAPI d3drm_frame3_AddRotation(IDirect3DRMFrame3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 335e0a4f2d..e7e3effa7a 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2870,6 +2870,19 @@ static void test_frame_transform(void) EXPECT_TRANSFORM("AddTranslation (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 3,3,3);
+ SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_REPLACE, 2.0f, 2.0f, 2.0f); + EXPECT_TRANSFORM("AddScale (REPLACE)", frame, 2,0,0, 0,2,0, 0,0,2, 0,0,0); + + SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_BEFORE, 2.0f, 2.0f, 2.0f); + EXPECT_TRANSFORM("AddScale (BEFORE)", frame, 2,0,0, 0,2,0, 0,0,2, 3,3,3); + + SET_TRANSFORM(frame, 1,0,0, 0,1,0, 0,0,1, 3,3,3); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_AFTER, 2.0f, 2.0f, 2.0f); + EXPECT_TRANSFORM("AddScale (AFTER)", frame, 2,0,0, 0,2,0, 0,0,2, 6,6,6); + + IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm);
Signed-off-by: Jeff Smith whydoubt@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);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 248 ++++++++++++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 60 +++++++++++- 2 files changed, 281 insertions(+), 27 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index ebe09df141..4de488575c 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -957,6 +957,19 @@ static void matrix_multiply(D3DRMMATRIX4D d, D3DRMMATRIX4D s1, D3DRMMATRIX4D s2) d[3][3] = 1.0f; }
+static void matrix_multiply_orient(D3DRMMATRIX4D d, D3DRMMATRIX4D s1, D3DRMMATRIX4D s2) +{ + d[0][0] = s1[0][0] * s2[0][0] + s1[0][1] * s2[1][0] + s1[0][2] * s2[2][0]; + d[0][1] = s1[0][0] * s2[0][1] + s1[0][1] * s2[1][1] + s1[0][2] * s2[2][1]; + d[0][2] = s1[0][0] * s2[0][2] + s1[0][1] * s2[1][2] + s1[0][2] * s2[2][2]; + d[1][0] = s1[1][0] * s2[0][0] + s1[1][1] * s2[1][0] + s1[1][2] * s2[2][0]; + d[1][1] = s1[1][0] * s2[0][1] + s1[1][1] * s2[1][1] + s1[1][2] * s2[2][1]; + d[1][2] = s1[1][0] * s2[0][2] + s1[1][1] * s2[1][2] + s1[1][2] * s2[2][2]; + d[2][0] = s1[2][0] * s2[0][0] + s1[2][1] * s2[1][0] + s1[2][2] * s2[2][0]; + d[2][1] = s1[2][0] * s2[0][1] + s1[2][1] * s2[1][1] + s1[2][2] * s2[2][1]; + d[2][2] = s1[2][0] * s2[0][2] + s1[2][1] * s2[1][2] + s1[2][2] * s2[2][2]; +} + static struct d3drm_frame *matrix_expand(D3DRMMATRIX4D d, struct d3drm_frame *s, struct d3drm_frame *shortcut) { @@ -1491,28 +1504,82 @@ static void matrix_invert(D3DRMMATRIX4D d, D3DRMMATRIX4D s) d[3][3] = 1.0f; }
+static void matrix_compare(struct d3drm_frame *frame, struct d3drm_frame *reference, + D3DRMMATRIX4D matrix) +{ + if (frame) + reference = matrix_expand(matrix, frame, reference); + + if (reference) + { + D3DRMMATRIX4D m; + frame = matrix_expand(m, reference, frame); + + if (frame) + { + D3DRMMATRIX4D inverse; + matrix_invert(inverse, m); + memcpy(m, matrix, sizeof(D3DRMMATRIX4D)); + matrix_multiply(matrix, m, inverse); + } + else + matrix_invert(matrix, m); + } +} + static HRESULT WINAPI d3drm_frame3_GetPosition(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DVECTOR *position) { - FIXME("iface %p, reference %p, position %p stub!\n", iface, reference, position); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, position %p.\n", iface, reference, position); + + if (!position) + return D3DRMERR_BADVALUE; + + if (frame == ref) + { + position->u1.x = 0.0f; + position->u2.y = 0.0f; + position->u3.z = 0.0f; + } + else + { + D3DRMMATRIX4D m; + matrix_compare(frame, ref, m); + position->u1.x = m[3][0]; + position->u2.y = m[3][1]; + position->u3.z = m[3][2]; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_GetPosition(IDirect3DRMFrame2 *iface, IDirect3DRMFrame *reference, D3DVECTOR *position) { - FIXME("iface %p, reference %p, position %p stub!\n", iface, reference, position); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, position %p.\n", iface, reference, position); + + return d3drm_frame3_GetPosition(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + position); }
static HRESULT WINAPI d3drm_frame1_GetPosition(IDirect3DRMFrame *iface, IDirect3DRMFrame *reference, D3DVECTOR *position) { - FIXME("iface %p, reference %p, position %p stub!\n", iface, reference, position); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, position %p.\n", iface, reference, position); + + return d3drm_frame3_GetPosition(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + position); }
@@ -1698,25 +1765,62 @@ static HRESULT WINAPI d3drm_frame1_GetVelocity(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_GetOrientation(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DVECTOR *dir, D3DVECTOR *up) { - FIXME("iface %p, reference %p, dir %p, up %p stub!\n", iface, reference, dir, up); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, dir %p, up %p.\n", iface, reference, dir, up); + + if (!dir || !up) + return D3DRMERR_BADVALUE; + + if (frame == ref) + { + dir->u1.x = 0.0f; + dir->u2.y = 0.0f; + dir->u3.z = 1.0f; + up->u1.x = 0.0f; + up->u2.y = 1.0f; + up->u3.z = 0.0f; + } + else + { + D3DRMMATRIX4D m; + matrix_compare(frame, ref, m); + dir->u1.x = m[2][0]; + dir->u2.y = m[2][1]; + dir->u3.z = m[2][2]; + up->u1.x = m[1][0]; + up->u2.y = m[1][1]; + up->u3.z = m[1][2]; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_GetOrientation(IDirect3DRMFrame2 *iface, IDirect3DRMFrame *reference, D3DVECTOR *dir, D3DVECTOR *up) { - FIXME("iface %p, reference %p, dir %p, up %p stub!\n", iface, reference, dir, up); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, dir %p, up %p.\n", iface, reference, dir, up); + + return d3drm_frame3_GetOrientation(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + dir, up); }
static HRESULT WINAPI d3drm_frame1_GetOrientation(IDirect3DRMFrame *iface, IDirect3DRMFrame *reference, D3DVECTOR *dir, D3DVECTOR *up) { - FIXME("iface %p, reference %p, dir %p, up %p stub!\n", iface, reference, dir, up); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, dir %p, up %p.\n", iface, reference, dir, up); + + return d3drm_frame3_GetOrientation(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + dir, up); }
static HRESULT WINAPI d3drm_frame3_GetVisuals(IDirect3DRMFrame3 *iface, DWORD *count, IUnknown **visuals) @@ -2471,52 +2575,148 @@ static HRESULT WINAPI d3drm_frame1_SetMaterialMode(IDirect3DRMFrame *iface, D3DR static HRESULT WINAPI d3drm_frame3_SetOrientation(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz, D3DVALUE ux, D3DVALUE uy, D3DVALUE uz) { - FIXME("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e stub!\n", + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference); + D3DVECTOR dir, up, right; + + TRACE("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e.\n", iface, reference, dx, dy, dz, ux, uy, uz);
- return E_NOTIMPL; + if (dx == ux && dy == uy && dz == uz) + return D3DRMERR_BADVALUE; + + dir.u1.x = dx; + dir.u2.y = dy; + dir.u3.z = dz; + D3DRMVectorNormalize(&dir); + if (ux == 0.0f && uy == 0.0f && uz == 0.0f) + { + up.u1.x = 1.0f; + up.u2.y = 0.0f; + up.u3.z = 0.0f; + D3DRMVectorCrossProduct(&right, &up, &dir); + } + else + { + up.u1.x = ux; + up.u2.y = uy; + up.u3.z = uz; + D3DRMVectorCrossProduct(&right, &up, &dir); + D3DRMVectorNormalize(&right); + D3DRMVectorCrossProduct(&up, &dir, &right); + } + + frame->transform[0][0] = right.u1.x; + frame->transform[0][1] = right.u2.y; + frame->transform[0][2] = right.u3.z; + frame->transform[1][0] = up.u1.x; + frame->transform[1][1] = up.u2.y; + frame->transform[1][2] = up.u3.z; + frame->transform[2][0] = dir.u1.x; + frame->transform[2][1] = dir.u2.y; + frame->transform[2][2] = dir.u3.z; + + if (ref == frame->parent) + return D3DRM_OK; + + if (ref) + { + D3DRMMATRIX4D frame_copy, ref_matrix; + memcpy(frame_copy, frame->transform, sizeof(D3DRMMATRIX4D)); + matrix_expand(ref_matrix, ref, NULL); + matrix_multiply_orient(frame->transform, ref_matrix, frame_copy); + } + + if (frame->parent) + { + D3DRMMATRIX4D inverse, frame_copy, parent; + memcpy(frame_copy, frame->transform, sizeof(D3DRMMATRIX4D)); + matrix_expand(parent, frame->parent, NULL); + matrix_invert(inverse, parent); + matrix_multiply_orient(frame->transform, frame_copy, inverse); + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_SetOrientation(IDirect3DRMFrame2 *iface, IDirect3DRMFrame *reference, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz, D3DVALUE ux, D3DVALUE uy, D3DVALUE uz) { - FIXME("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e stub!\n", + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference); + + TRACE("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e.\n", iface, reference, dx, dy, dz, ux, uy, uz);
- return E_NOTIMPL; + return d3drm_frame3_SetOrientation(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + dx, dy, dz, ux, uy, uz); }
static HRESULT WINAPI d3drm_frame1_SetOrientation(IDirect3DRMFrame *iface, IDirect3DRMFrame *reference, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz, D3DVALUE ux, D3DVALUE uy, D3DVALUE uz) { - FIXME("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e stub!\n", + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference); + + TRACE("iface %p, reference %p, dx %.8e, dy %.8e, dz %.8e, ux %.8e, uy %.8e, uz %.8e.\n", iface, reference, dx, dy, dz, ux, uy, uz);
- return E_NOTIMPL; + return d3drm_frame3_SetOrientation(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + dx, dy, dz, ux, uy, uz); }
static HRESULT WINAPI d3drm_frame3_SetPosition(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, reference %p, x %.8e, y %.8e, z %.8e stub!\n", iface, reference, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, x %.8e, y %.8e, z %.8e.\n", iface, reference, x, y, z); + + if (ref == frame->parent) + { + frame->transform[3][0] = x; + frame->transform[3][1] = y; + frame->transform[3][2] = z; + } + else + { + D3DRMMATRIX4D m; + matrix_compare(ref, frame->parent, m); + frame->transform[3][0] = x * m[0][0] + y * m[1][0] + z * m[2][0] + m[3][0]; + frame->transform[3][1] = x * m[0][1] + y * m[1][1] + z * m[2][1] + m[3][1]; + frame->transform[3][2] = x * m[0][2] + y * m[1][2] + z * m[2][2] + m[3][2]; + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_SetPosition(IDirect3DRMFrame2 *iface, IDirect3DRMFrame *reference, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, reference %p, x %.8e, y %.8e, z %.8e stub!\n", iface, reference, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, x %.8e, y %.8e, z %.8e.\n", iface, reference, x, y, z); + + return d3drm_frame3_SetPosition(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + x, y, z); }
static HRESULT WINAPI d3drm_frame1_SetPosition(IDirect3DRMFrame *iface, IDirect3DRMFrame *reference, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, reference %p, x %.8e, y %.8e, z %.8e stub!\n", iface, reference, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, reference %p, x %.8e, y %.8e, z %.8e.\n", iface, reference, x, y, z); + + return d3drm_frame3_SetPosition(&frame->IDirect3DRMFrame3_iface, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + x, y, z); }
static HRESULT WINAPI d3drm_frame3_SetRotation(IDirect3DRMFrame3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index fa23ad7795..16fd6ae7a6 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2788,21 +2788,33 @@ cleanup: EXPECT_TRANSFORM_MATRIX(test_description, matrix, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43); \ }
-#define EXPECT_VECTOR(test_description, vector, vx,vy,vz) \ +#define EXPECT_VECTOR_(test_description, vector, vx,vy,vz) \ { \ int pass = 1; \ - ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \ CHECK((vector).x, vx); \ CHECK((vector).y, vy); \ CHECK((vector).z, vz); \ ok(pass, test_description ": vector result is not correct\n"); \ }
+#define EXPECT_VECTOR(test_description, vector, vx,vy,vz) \ + { \ + ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \ + EXPECT_VECTOR_(test_description, vector, vx,vy,vz); \ + } + +#define EXPECT_VECTORS_2(test_description, vector1, vx1,vy1,vz1, vector2, vx2,vy2,vz2) \ + { \ + 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); \ + } + static void test_frame_transform(void) { HRESULT hr; IDirect3DRM *d3drm; - IDirect3DRMFrame *frame, *subframe; + IDirect3DRMFrame *frame, *subframe, *reference; D3DRMMATRIX4D matrix; D3DVECTOR v1, v2;
@@ -2902,6 +2914,48 @@ static void test_frame_transform(void) EXPECT_TRANSFORM("AddRotation around null axis", frame, 1,0,0, 0,0,1, 0,-1,0, 0,0,0);
+ SET_TRANSFORM(frame, 1,3,2, 4,5,6, 7,8,9, 2,4,3); + IDirect3DRM_CreateFrame(d3drm, NULL, &reference); + SET_TRANSFORM(reference, 7,8,5, 6,5,4, 5,4,3, 5,5,5); + + hr = IDirect3DRMFrame_SetPosition(frame, reference, 10.0f,11.0f,12.0f); + EXPECT_TRANSFORM("SetPosition (vs. reference)", frame, 1,3,2, 4,5,6, 7,8,9, 201,188,135); + + hr = IDirect3DRMFrame_SetPosition(frame, NULL, 10.0f,11.0f,12.0f); + EXPECT_TRANSFORM("SetPosition (vs. NULL)", frame, 1,3,2, 4,5,6, 7,8,9, 10,11,12); + + hr = IDirect3DRMFrame_SetPosition(subframe, NULL, 20.0f,35.0f,48.0f); + EXPECT_TRANSFORM("SetPosition (sub-frame vs. NULL)", subframe, 1,0,0, 0,1,0, 0,0,1, 2/3.0,238/9.0,-124/9.0); + + hr = IDirect3DRMFrame_SetOrientation(frame, reference, -12.0f,-16.0f,15.0f, 9.0f,12.0f,20.0f); + EXPECT_TRANSFORM("SetOrientation (vs. reference)", frame, 6.08,-3.56,9.4, 4.68,-3.76,6.4, 4,-3,5, 10,11,12); + + hr = IDirect3DRMFrame_SetOrientation(frame, NULL, -12.0f,-16.0f,15.0f, 9.0f,12.0f,20.0f); + EXPECT_TRANSFORM("SetOrientation (vs. NULL)", frame, 0.8,-0.6,0, 0.36,0.48,0.8, -0.48,-0.64,0.6, 10,11,12); + + hr = IDirect3DRMFrame_SetOrientation(subframe, NULL, 9.0f,12.0f,20.0f, -12.0f,-16.0f,15.0f); + EXPECT_TRANSFORM("SetOrientation (sub-frame vs. NULL)", subframe, -1,0,0, 0,0,1, 0,1,0, 2/3.0,238/9.0,-124/9.0); + + hr = IDirect3DRMFrame_GetPosition(frame, reference, &v1); + EXPECT_VECTOR("GetPosition (vs. reference)", v1, 0,10,-11); + + hr = IDirect3DRMFrame_GetPosition(frame, NULL, &v1); + EXPECT_VECTOR("GetPosition (vs. NULL)", v1, 10,11,12); + + hr = IDirect3DRMFrame_GetPosition(subframe, NULL, &v1); + EXPECT_VECTOR("GetPosition (sub-frame vs. NULL)", v1, 80/3.0,289/9.0,224/9.0); + + hr = IDirect3DRMFrame_GetOrientation(frame, reference, &v1, &v2); + EXPECT_VECTORS_2("GetOrientation (vs. reference)", v1, -0.35,2.92,-3.11, v2, -0.05,1.56,-1.73); + + hr = IDirect3DRMFrame_GetOrientation(frame, NULL, &v1, &v2); + EXPECT_VECTORS_2("GetOrientation (vs. NULL)", v1, -0.48,-0.64,0.6, v2, 0.36,0.48,0.8); + + hr = IDirect3DRMFrame_GetOrientation(subframe, NULL, &v1, &v2); + EXPECT_VECTORS_2("GetOrientation (sub-frame vs. NULL)", v1, 0.36,0.48,0.8, v2, -0.48,-0.64,0.6); + + + IDirect3DRMFrame_Release(reference); IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 17 +++++++++++++---- dlls/d3drm/tests/d3drm.c | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 4de488575c..7162b8323f 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1704,13 +1704,22 @@ static HRESULT WINAPI d3drm_frame3_GetTransform(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DRMMATRIX4D matrix) { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference);
TRACE("iface %p, reference %p, matrix %p.\n", iface, reference, matrix);
- if (reference) - FIXME("Specifying a frame as the root of the scene different from the current root frame is not supported yet\n"); - - memcpy(matrix, frame->transform, sizeof(D3DRMMATRIX4D)); + if (ref == frame->parent) + memcpy(matrix, frame->transform, sizeof(D3DRMMATRIX4D)); + else if (!ref) + matrix_expand(matrix, frame, NULL); + else + { + D3DRMMATRIX4D m, m2; + matrix_expand(m, ref, NULL); + matrix_invert(m2, m); + matrix_expand(m, frame, NULL); + matrix_multiply(matrix, m2, m); + }
return D3DRM_OK; } diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 16fd6ae7a6..dbff1bac82 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2815,6 +2815,7 @@ static void test_frame_transform(void) HRESULT hr; IDirect3DRM *d3drm; IDirect3DRMFrame *frame, *subframe, *reference; + IDirect3DRMFrame3 *frame3, *subframe3, *reference3; D3DRMMATRIX4D matrix; D3DVECTOR v1, v2;
@@ -2955,6 +2956,26 @@ static void test_frame_transform(void) EXPECT_VECTORS_2("GetOrientation (sub-frame vs. NULL)", v1, 0.36,0.48,0.8, v2, -0.48,-0.64,0.6);
+ IDirect3DRMFrame_QueryInterface(frame, &IID_IDirect3DRMFrame3, (void**)&frame3); + IDirect3DRMFrame_QueryInterface(subframe, &IID_IDirect3DRMFrame3, (void**)&subframe3); + IDirect3DRMFrame_QueryInterface(reference, &IID_IDirect3DRMFrame3, (void**)&reference3); + + hr = IDirect3DRMFrame3_GetTransform(frame3, reference3, matrix); + EXPECT_TRANSFORM_MATRIX("GetTransform (vs. reference)", matrix, + -1.4,-1.45,0.25, -0.2,-1.1,-0.5, 2.44,3.67,0.45, 5.8,5.4,11); + + hr = IDirect3DRMFrame3_GetTransform(frame3, NULL, matrix); + EXPECT_TRANSFORM_MATRIX("GetTransform (vs. NULL)", matrix, + 0.8,-0.6,0, 0.36,0.48,0.8, -0.48,-0.64,0.6, 10,11,12); + + hr = IDirect3DRMFrame3_GetTransform(subframe3, NULL, matrix); + EXPECT_TRANSFORM_MATRIX("GetTransform (sub-frame vs. NULL)", matrix, + -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); + + + IDirect3DRMFrame3_Release(reference3); + IDirect3DRMFrame3_Release(subframe3); + IDirect3DRMFrame3_Release(frame3); IDirect3DRMFrame_Release(reference); IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame);
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);
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);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/d3drm/frame.c | 97 +++++++++++++++++++++++++++++++++++++++++++++--- dlls/d3drm/tests/d3drm.c | 32 +++++++++++++++- 2 files changed, 122 insertions(+), 7 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index cccd0f9e15..9ca32916fe 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1945,25 +1945,110 @@ static HRESULT WINAPI d3drm_frame1_Load(IDirect3DRMFrame *iface, void *filename, static HRESULT WINAPI d3drm_frame3_LookAt(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *target, IDirect3DRMFrame3 *reference, D3DRMFRAMECONSTRAINT constraint) { - FIXME("iface %p, target %p, reference %p, constraint %#x stub!\n", iface, target, reference, constraint); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_frame *tar = unsafe_impl_from_IDirect3DRMFrame3(target); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame3(reference); + D3DVECTOR dir, up, right;
- return E_NOTIMPL; + TRACE("iface %p, target %p, reference %p, constraint %#x.\n", iface, target, reference, constraint); + + if (!tar) + return D3DRMERR_BADOBJECT; + + dir.u1.x = tar->transform[3][0] - frame->transform[3][0]; + dir.u2.y = tar->transform[3][1] - frame->transform[3][1]; + dir.u3.z = tar->transform[3][2] - frame->transform[3][2]; + + if (ref) + { + D3DRMMATRIX4D m; + D3DVECTOR v; + + matrix_invert(m, ref->transform); + memcpy(&v, &dir, sizeof(D3DVECTOR)); + dir.u1.x = m[0][0] * v.u1.x + m[1][0] * v.u2.y + m[2][0] * v.u3.z; + dir.u2.y = m[0][1] * v.u1.x + m[1][1] * v.u2.y + m[2][1] * v.u3.z; + dir.u3.z = m[0][2] * v.u1.x + m[1][2] * v.u2.y + m[2][2] * v.u3.z; + } + + D3DRMVectorNormalize(&dir); + + switch (constraint) + { + case D3DRMCONSTRAIN_Z: + right.u1.x = dir.u3.z; + right.u2.y = 0.0f; + right.u3.z = -dir.u1.x; + D3DRMVectorNormalize(&right); + D3DRMVectorCrossProduct(&up, &dir, &right); + break; + case D3DRMCONSTRAIN_Y: + right.u1.x = dir.u2.y; + right.u2.y = -dir.u1.x; + right.u3.z = 0.0f; + D3DRMVectorNormalize(&right); + D3DRMVectorCrossProduct(&up, &dir, &right); + break; + case D3DRMCONSTRAIN_X: + up.u1.x = -dir.u2.y; + up.u2.y = dir.u1.x; + up.u3.z = 0.0f; + D3DRMVectorNormalize(&up); + D3DRMVectorCrossProduct(&right, &up, &dir); + break; + default: + WARN("Unknown Constraint %u\n", constraint); + return D3DRMERR_BADVALUE; + } + + frame->transform[0][0] = right.u1.x; + frame->transform[0][1] = right.u2.y; + frame->transform[0][2] = right.u3.z; + frame->transform[1][0] = up.u1.x; + frame->transform[1][1] = up.u2.y; + frame->transform[1][2] = up.u3.z; + frame->transform[2][0] = dir.u1.x; + frame->transform[2][1] = dir.u2.y; + frame->transform[2][2] = dir.u3.z; + + if (ref) + { + D3DRMMATRIX4D m; + memcpy(m, frame->transform, sizeof(D3DRMMATRIX4D)); + matrix_multiply_orient(frame->transform, ref->transform, m); + } + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_frame2_LookAt(IDirect3DRMFrame2 *iface, IDirect3DRMFrame *target, IDirect3DRMFrame *reference, D3DRMFRAMECONSTRAINT constraint) { - FIXME("iface %p, target %p, reference %p, constraint %#x stub!\n", iface, target, reference, constraint); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_frame *tar = unsafe_impl_from_IDirect3DRMFrame(target); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, target %p, reference %p, constraint %#x.\n", iface, target, reference, constraint); + + return d3drm_frame3_LookAt(&frame->IDirect3DRMFrame3_iface, + (tar) ? &tar->IDirect3DRMFrame3_iface : NULL, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + constraint); }
static HRESULT WINAPI d3drm_frame1_LookAt(IDirect3DRMFrame *iface, IDirect3DRMFrame *target, IDirect3DRMFrame *reference, D3DRMFRAMECONSTRAINT constraint) { - FIXME("iface %p, target %p, reference %p, constraint %#x stub!\n", iface, target, reference, constraint); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); + struct d3drm_frame *tar = unsafe_impl_from_IDirect3DRMFrame(target); + struct d3drm_frame *ref = unsafe_impl_from_IDirect3DRMFrame(reference);
- return E_NOTIMPL; + TRACE("iface %p, target %p, reference %p, constraint %#x.\n", iface, target, reference, constraint); + + return d3drm_frame3_LookAt(&frame->IDirect3DRMFrame3_iface, + (tar) ? &tar->IDirect3DRMFrame3_iface : NULL, + (ref) ? &ref->IDirect3DRMFrame3_iface : NULL, + constraint); }
static HRESULT WINAPI d3drm_frame3_Move(IDirect3DRMFrame3 *iface, D3DVALUE delta) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 1e41023f8f..60f0da8001 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2824,7 +2824,7 @@ static void test_frame_transform(void) { HRESULT hr; IDirect3DRM *d3drm; - IDirect3DRMFrame *frame, *subframe, *reference; + IDirect3DRMFrame *frame, *subframe, *reference, *target; IDirect3DRMFrame3 *frame3, *subframe3, *reference3; D3DRMMATRIX4D matrix; D3DVECTOR v1, v2; @@ -3036,9 +3036,39 @@ static void test_frame_transform(void) ok(hr == D3DRMERR_BADVALUE, "InverseTransformVectors: BADVALUE error expected when reference == self\n");
+ hr = IDirect3DRM_CreateFrame(d3drm, frame, &target); + IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, identity); + IDirect3DRMFrame_AddTranslation(target, D3DRMCOMBINE_REPLACE, 0.0f, 3.0f, 2.0f); + IDirect3DRMFrame_AddTranslation(subframe, D3DRMCOMBINE_REPLACE, 3.0f, 6.0f, 4.0f); + SET_TRANSFORM(reference, 1,3,2, 4,5,6, 7,8,9, 2,4,3); + + hr = IDirect3DRMFrame_LookAt(subframe, target, reference, D3DRMCONSTRAIN_Z); + EXPECT_TRANSFORM("GetTransform (constrain Z)", subframe, + -0.757679,3.39217,1.385316, -3.848481,7.797251,1.179861, -6.681523,11.993283,2.349128, 3,6,4); + + hr = IDirect3DRMFrame_LookAt(subframe, target, reference, D3DRMCONSTRAIN_Y); + EXPECT_TRANSFORM("GetTransform (constrain Y)", subframe, + 1.008568,0.005039,-3.603161, 3.700569,2.467296,-7.564274, 6.581180,3.546424,-11.752062, 3,6,4); + + hr = IDirect3DRMFrame_LookAt(subframe, target, reference, D3DRMCONSTRAIN_X); + EXPECT_TRANSFORM("GetTransform (constrain X)", subframe, + -3.112735,0.623119,-1.980556, -5.295893,1.830544,-6.752972, -8.360264,2.098992,-10.94076, 3,6,4); + + hr = IDirect3DRMFrame_LookAt(subframe, target, NULL, D3DRMCONSTRAIN_Z); + EXPECT_TRANSFORM("GetTransform (vs. NULL)", subframe, + -0.5547,0,0.83205, -0.532181,0.768706,-0.354787, -0.639602,-0.639602,-0.426401, 3,6,4); + + hr = IDirect3DRMFrame_LookAt(subframe, NULL, reference, D3DRMCONSTRAIN_Z); + ok(hr == D3DRMERR_BADOBJECT, "InverseTransformVectors: BADOBJECT error expected when target is null\n"); + + hr = IDirect3DRMFrame_LookAt(subframe, target, reference, (D3DRMFRAMECONSTRAINT)-1); + ok(hr == D3DRMERR_BADVALUE, "InverseTransformVectors: BADVALUE error expected when constraint invalid\n"); + + IDirect3DRMFrame3_Release(reference3); IDirect3DRMFrame3_Release(subframe3); IDirect3DRMFrame3_Release(frame3); + IDirect3DRMFrame_Release(target); IDirect3DRMFrame_Release(reference); IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame);
Hi Jeff,
On Fri, 14 Jun 2019 at 09:00, Jeff Smith whydoubt@gmail.com wrote:
static HRESULT WINAPI d3drm_frame3_Transform(IDirect3DRMFrame3 *iface, D3DVECTOR *d, D3DVECTOR *s) {
- FIXME("iface %p, d %p, s %p stub!\n", iface, d, s);
- struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
- return E_NOTIMPL;
- TRACE("iface %p, d %p, s %p.\n", iface, d, s);
- d->u1.x = s->u1.x * frame->transform[0][0] + s->u2.y * frame->transform[1][0]
+ s->u3.z * frame->transform[2][0] + frame->transform[3][0];
- d->u2.y = s->u1.x * frame->transform[0][1] + s->u2.y * frame->transform[1][1]
+ s->u3.z * frame->transform[2][1] + frame->transform[3][1];
- d->u3.z = s->u1.x * frame->transform[0][2] + s->u2.y * frame->transform[1][2]
+ s->u3.z * frame->transform[2][2] + frame->transform[3][2];
- while ((frame = frame->parent))
- {
D3DVALUE x = d->u1.x;
D3DVALUE y = d->u2.y;
D3DVALUE z = d->u3.z;
d->u1.x = x * frame->transform[0][0] + y * frame->transform[1][0]
+ z * frame->transform[2][0] + frame->transform[3][0];
d->u2.y = x * frame->transform[0][1] + y * frame->transform[1][1]
+ z * frame->transform[2][1] + frame->transform[3][1];
d->u3.z = x * frame->transform[0][2] + y * frame->transform[1][2]
+ z * frame->transform[2][2] + frame->transform[3][2];
- }
- return D3DRM_OK;
}
This would probably benefit from a helper function along the lines of wined3d_vec4_transform() in wined3d.
+#define SET_TRANSFORM(frame, m11,m12,m13, m21,m22,m23, m31,m32,m33, m41,m42,m43) \
- { \
D3DRMMATRIX4D matrix; \
matrix[0][0] = D3DVAL(m11); \
matrix[0][1] = D3DVAL(m12); \
matrix[0][2] = D3DVAL(m13); \
matrix[0][3] = D3DVAL(0); \
matrix[1][0] = D3DVAL(m21); \
matrix[1][1] = D3DVAL(m22); \
matrix[1][2] = D3DVAL(m23); \
matrix[1][3] = D3DVAL(0); \
matrix[2][0] = D3DVAL(m31); \
matrix[2][1] = D3DVAL(m32); \
matrix[2][2] = D3DVAL(m33); \
matrix[2][3] = D3DVAL(0); \
matrix[3][0] = D3DVAL(m41); \
matrix[3][1] = D3DVAL(m42); \
matrix[3][2] = D3DVAL(m43); \
matrix[3][3] = D3DVAL(1); \
IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); \
- }
+#define SET_VECTOR(vector, vx,vy,vz) \
- { \
(vector).x = D3DVAL(vx); \
(vector).y = D3DVAL(vy); \
(vector).z = D3DVAL(vz); \
- }
+#define MAXERROR_ABS 0.000001 +#define MAXERROR_REL 0.000001 +#define CHECK(a, b) \
- { \
if (pass) \
{ \
if ((a < 1 && a > -1) || (b < 1 && b > -1)) \
{ \
if (fabs((a) - (b)) > MAXERROR_ABS) \
{ \
pass = 0; \
} \
} \
else \
{ \
if (fabs((a) - (b)) > fabs(MAXERROR_REL * (b))) \
{ \
pass = 0; \
} \
} \
} \
- }
+#define EXPECT_VECTOR(test_description, vector, vx,vy,vz) \
- { \
int pass = 1; \
ok(hr == D3DRM_OK, test_description ": returned hr = %x\n", hr); \
CHECK((vector).x, vx); \
CHECK((vector).y, vy); \
CHECK((vector).z, vz); \
ok(pass, test_description ": vector result is not correct\n"); \
- }
I don't think any of these need to be macros. You may want to take a look at e.g. the compare_point() helper in dlls/d2d1/tests/d2d1.c as an example.
As an aside, I'd recommend sending smaller series of patches, especially when you're new to a module. Although I don't mind, it's not necessary to send patches to my codeweavers.com address, I see them here.
Thanks for working on this,
Henri