Implementation of mathematical functions for D3DRM

David.Adam at math.cnrs.fr David.Adam at math.cnrs.fr
Sun Apr 15 01:12:35 CDT 2007


Here is the complete implementation of the mathematical functions of  
D3DRM with tests.
Tests work under Windows XP and wine.

This work was done in colloboration with Vijay Kamuju.

Comments are welcome .

David ADAM
-------------- next part --------------
>From 264fb2d006a77c8625df8b534500cfb8cdad6b85 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 12:04:47 +0200
Subject: [PATCH] [1] Header file for D3DRM.

---
 include/d3drmdef.h |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/include/d3drmdef.h b/include/d3drmdef.h
new file mode 100644
index 0000000..2b2bd6a
--- /dev/null
+++ b/include/d3drmdef.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007 Vijay Kiran Kamuju
+ *           2007 David ADAM
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __D3DRMDEFS_H__
+#define __D3DRMDEFS_H__
+
+#include <stddef.h>
+#include <windef.h>
+
+#ifndef DX_SHARED_DEFINES
+
+typedef float D3DVALUE, *LPD3DVALUE;
+
+#ifndef D3DVECTOR_DEFINED
+typedef struct _D3DVECTOR {
+    float x;
+    float y;
+    float z;
+} D3DVECTOR;
+#define D3DVECTOR_DEFINED
+#endif
+
+#ifndef LPD3DVECTOR_DEFINED
+typedef D3DVECTOR *LPD3DVECTOR;
+#define LPD3DVECTOR_DEFINED
+#endif
+
+#define DX_SHARED_DEFINES
+#endif
+
+#ifdef WIN32
+#define D3DRMAPI  __stdcall
+#else
+#define D3DRMAPI
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef D3DVALUE D3DRMMATRIX4D[4][4];
+typedef struct _D3DRMQUATERNION
+{   D3DVALUE s;
+    D3DVECTOR v;
+} D3DRMQUATERNION, *LPD3DRMQUATERNION;
+
+void _D3DRMMatrixFromQuaternion(D3DRMMATRIX4D, LPD3DRMQUATERNION);
+
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionFromRotation(LPD3DRMQUATERNION ,LPD3DVECTOR,D3DVALUE);
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionMultiply(LPD3DRMQUATERNION, LPD3DRMQUATERNION, LPD3DRMQUATERNION);
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionSlerp(LPD3DRMQUATERNION, LPD3DRMQUATERNION, LPD3DRMQUATERNION, D3DVALUE);
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionFromMatrix(LPD3DRMQUATERNION, D3DRMMATRIX4D);
+
+LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR, LPD3DVECTOR, LPD3DVECTOR);
+LPD3DVECTOR D3DRMAPI D3DRMVectorCrossProduct(LPD3DVECTOR, LPD3DVECTOR, LPD3DVECTOR);
+D3DVALUE D3DRMAPI D3DRMVectorDotProduct(LPD3DVECTOR, LPD3DVECTOR);
+LPD3DVECTOR D3DRMAPI D3DRMVectorNormalize(LPD3DVECTOR);
+
+#define D3DRMVectorNormalise D3DRMVectorNormalize
+
+D3DVALUE D3DRMAPI D3DRMVectorModulus(LPD3DVECTOR);
+LPD3DVECTOR D3DRMAPI D3DRMVectorRandom(LPD3DVECTOR);
+LPD3DVECTOR D3DRMAPI D3DRMVectorRotate(LPD3DVECTOR, LPD3DVECTOR, LPD3DVECTOR, D3DVALUE);
+LPD3DVECTOR D3DRMAPI D3DRMVectorScale(LPD3DVECTOR, LPD3DVECTOR, D3DVALUE);
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif
+
+
-- 
1.4.2

-------------- next part --------------
>From 7e76281a0ef2b22c8683ea9d9c67eeb2724687b7 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 12:20:06 +0200
Subject: [PATCH] [2] Implement D3DRMVectorAdd with test.

---
 configure                    |    2 +
 configure.ac                 |    1 +
 dlls/d3drm/Makefile.in       |    4 ++-
 dlls/d3drm/d3drm.spec        |    2 +
 dlls/d3drm/math.c            |   41 +++++++++++++++++++++++++++
 dlls/d3drm/tests/Makefile.in |   13 +++++++++
 dlls/d3drm/tests/vector.c    |   64 ++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 85b24c5..a5fe716 100755
--- a/configure
+++ b/configure
@@ -20277,6 +20277,8 @@ ac_config_files="$ac_config_files dlls/d
 
 ac_config_files="$ac_config_files dlls/d3drm/Makefile"
 
+ac_config_files="$ac_config_files dlls/d3drm/tests/Makefile"
+
 ac_config_files="$ac_config_files dlls/d3dx8/Makefile"
 
 ac_config_files="$ac_config_files dlls/d3dxof/Makefile"
diff --git a/configure.ac b/configure.ac
index c9766dc..cd25a18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1529,6 +1529,7 @@ AC_CONFIG_FILES([dlls/d3d9/Makefile])
 AC_CONFIG_FILES([dlls/d3d9/tests/Makefile])
 AC_CONFIG_FILES([dlls/d3dim/Makefile])
 AC_CONFIG_FILES([dlls/d3drm/Makefile])
+AC_CONFIG_FILES([dlls/d3drm/tests/Makefile])
 AC_CONFIG_FILES([dlls/d3dx8/Makefile])
 AC_CONFIG_FILES([dlls/d3dxof/Makefile])
 AC_CONFIG_FILES([dlls/dbghelp/Makefile])
diff --git a/dlls/d3drm/Makefile.in b/dlls/d3drm/Makefile.in
index 2883af1..f070c1d 100644
--- a/dlls/d3drm/Makefile.in
+++ b/dlls/d3drm/Makefile.in
@@ -6,7 +6,9 @@ MODULE    = d3drm.dll
 IMPORTLIB = libd3drm.$(IMPLIBEXT)
 IMPORTS   = kernel32
 
-C_SRCS = d3drm_main.c
+C_SRCS = \
+	d3drm_main.c \
+	math.c
 
 RC_SRCS = version.rc
 
diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 9964085..f0aa67f 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -8,7 +8,7 @@
 @ stub D3DRMQuaternionFromRotation
 @ stub D3DRMQuaternionMultiply
 @ stub D3DRMQuaternionSlerp
-@ stub D3DRMVectorAdd
+@ stdcall D3DRMVectorAdd(ptr ptr ptr)
 @ stub D3DRMVectorCrossProduct
 @ stub D3DRMVectorDotProduct
 @ stub D3DRMVectorModulus
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
new file mode 100644
index 0000000..96af2f0
--- /dev/null
+++ b/dlls/d3drm/math.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007 David Adam
+ *           2007 Vijay Kiran Kamuju
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <math.h>
+#include <time.h>
+#include "windef.h"
+#include "winbase.h"
+#include "d3drmdef.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
+
+/* Add Two Vectors */
+LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
+{
+    d->x=s1->x + s2->x;
+    d->y=s1->y + s2->y;
+    d->z=s1->z + s2->z;
+    return d;
+}
diff --git a/dlls/d3drm/tests/Makefile.in b/dlls/d3drm/tests/Makefile.in
new file mode 100644
index 0000000..1e682e7
--- /dev/null
+++ b/dlls/d3drm/tests/Makefile.in
@@ -0,0 +1,13 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+TESTDLL   = d3drm.dll
+IMPORTS   = d3drm kernel32
+EXTRALIBS = -ldxguid
+
+CTESTS = vector.c
+
+ at MAKE_TEST_RULES@
+
+ at DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
new file mode 100644
index 0000000..c4cbd53
--- /dev/null
+++ b/dlls/d3drm/tests/vector.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Vijay Kiran Kamuju
+ *                David Adam 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+ 
+#include <assert.h>
+#include "wine/test.h"
+#include "d3drmdef.h"
+#include <math.h>
+
+#define expect_vec(expectedvec,gotvec) \
+  ok( ((fabs(expectedvec.x-gotvec.x)<0.000001)&&(fabs(expectedvec.y-gotvec.y)<0.000001)&&(fabs(expectedvec.z-gotvec.z)<0.000001)), \
+  "Expected Vector= (%f, %f, %f)\n , Got Vector= (%f, %f, %f)\n", \
+  expectedvec.x,expectedvec.y,expectedvec.z, gotvec.x, gotvec.y, gotvec.z);
+
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
+
+static void init_function_pointers(void)
+{
+    HMODULE hmod = LoadLibraryA("d3drm.dll");
+
+    if(!hmod)
+    {
+        skip("Could not load d3drm.dll");
+        return;
+    }
+
+    pD3DRMVectorAdd = (void*)GetProcAddress(hmod, "D3DRMVectorAdd");
+}
+
+static void VectorTest(void)
+{
+    D3DVECTOR e,r,u,v;
+
+    u.x=2.0;u.y=2.0;u.z=1.0;
+    v.x=4.0;v.y=4.0;v.z=0.0;
+
+/*______________________VectorAdd_________________________________*/
+    pD3DRMVectorAdd(&r,&u,&v);
+    e.x=6.0;e.y=6.0;e.z=1.0;
+    todo_wine {
+    expect_vec(e,r);
+              }
+}
+
+START_TEST(vector)
+{
+   init_function_pointers();
+   VectorTest();
+}
-- 
1.4.2

-------------- next part --------------
>From 4c2f235c8152259e2b5ac30730f85bc8f71ad015 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 12:23:46 +0200
Subject: [PATCH] [3] Implements D3DRMVectorSubtract with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    9 +++++++++
 dlls/d3drm/tests/vector.c |    9 +++++++++
 3 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index f0aa67f..0041265 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -17,7 +17,7 @@
 @ stub D3DRMVectorReflect
 @ stub D3DRMVectorRotate
 @ stub D3DRMVectorScale
-@ stub D3DRMVectorSubtract
+@ stdcall D3DRMVectorSubtract(ptr ptr ptr)
 @ stub Direct3DRMCreate
 @ stub DllCanUnloadNow
 @ stub DllGetClassObject
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 96af2f0..a4e9da4 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -39,3 +39,12 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3
     d->z=s1->z + s2->z;
     return d;
 }
+
+/* Subtract Two Vectors */
+LPD3DVECTOR D3DRMAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
+{
+    d->x=s1->x - s2->x;
+    d->y=s1->y - s2->y;
+    d->z=s1->z - s2->z;
+    return d;
+}
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index c4cbd53..505d122 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -28,6 +28,7 @@ #define expect_vec(expectedvec,gotvec) \
   expectedvec.x,expectedvec.y,expectedvec.z, gotvec.x, gotvec.y, gotvec.z);
 
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
 static void init_function_pointers(void)
 {
@@ -40,6 +41,7 @@ static void init_function_pointers(void)
     }
 
     pD3DRMVectorAdd = (void*)GetProcAddress(hmod, "D3DRMVectorAdd");
+    pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
 
 static void VectorTest(void)
@@ -55,6 +57,13 @@ static void VectorTest(void)
     todo_wine {
     expect_vec(e,r);
               }
+
+/*_______________________VectorSubtract__________________________*/
+    pD3DRMVectorSubtract(&r,&u,&v);
+    e.x=-2.0;e.y=-2.0;e.z=1.0;
+    todo_wine {
+    expect_vec(e,r);
+              }
 }
 
 START_TEST(vector)
-- 
1.4.2

-------------- next part --------------
>From 8ab90d7c73bd93b98f4c0a88e1fdc2dc75136f53 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 12:28:59 +0200
Subject: [PATCH] [4] Implement D3DRMVectorCrossProduct with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    9 +++++++++
 dlls/d3drm/tests/vector.c |    9 +++++++++
 3 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 0041265..4347160 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -9,7 +9,7 @@
 @ stub D3DRMQuaternionMultiply
 @ stub D3DRMQuaternionSlerp
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
-@ stub D3DRMVectorCrossProduct
+@ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
 @ stub D3DRMVectorDotProduct
 @ stub D3DRMVectorModulus
 @ stub D3DRMVectorNormalize
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index a4e9da4..f15db68 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -40,6 +40,15 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3
     return d;
 }
 
+/* Cross Product of Two Vectors */
+LPD3DVECTOR D3DRMAPI D3DRMVectorCrossProduct(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
+{
+    d->x=s1->y * s2->z - s1->z * s2->y;
+    d->y=s1->z * s2->x - s1->x * s2->z;
+    d->z=s1->x * s2->y - s1->y * s2->x;
+    return d;
+}
+
 /* Subtract Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 505d122..fa7ff9d 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -28,6 +28,7 @@ #define expect_vec(expectedvec,gotvec) \
   expectedvec.x,expectedvec.y,expectedvec.z, gotvec.x, gotvec.y, gotvec.z);
 
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
 static void init_function_pointers(void)
@@ -41,6 +42,7 @@ static void init_function_pointers(void)
     }
 
     pD3DRMVectorAdd = (void*)GetProcAddress(hmod, "D3DRMVectorAdd");
+    pD3DRMVectorCrossProduct = (void*)GetProcAddress(hmod, "D3DRMVectorCrossProduct");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
 
@@ -58,6 +60,13 @@ static void VectorTest(void)
     expect_vec(e,r);
               }
 
+/*_______________________VectorCrossProduct_______________________*/
+    pD3DRMVectorCrossProduct(&r,&u,&v);
+    e.x=-4.0;e.y=4.0;e.z=0.0;
+    todo_wine {
+    expect_vec(e,r);
+              }
+
 /*_______________________VectorSubtract__________________________*/
     pD3DRMVectorSubtract(&r,&u,&v);
     e.x=-2.0;e.y=-2.0;e.z=1.0;
-- 
1.4.2

-------------- next part --------------
>From bb9e1c4d34d87dc41b5501088e1624fa30a446fb Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 12:52:49 +0200
Subject: [PATCH] [5] Implements D3DRMVectorDotProduct with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    8 ++++++++
 dlls/d3drm/tests/vector.c |    7 +++++++
 3 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 4347160..59c1e03 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -10,7 +10,7 @@
 @ stub D3DRMQuaternionSlerp
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
 @ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
-@ stub D3DRMVectorDotProduct
+@ stdcall D3DRMVectorDotProduct(ptr ptr)
 @ stub D3DRMVectorModulus
 @ stub D3DRMVectorNormalize
 @ stub D3DRMVectorRandom
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index f15db68..332f5a5 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -49,6 +49,14 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorCrossPro
     return d;
 }
 
+/* Dot Product of Two vectors */
+D3DVALUE D3DRMAPI D3DRMVectorDotProduct(LPD3DVECTOR s1, LPD3DVECTOR s2)
+{
+    D3DVALUE dot_product;
+    dot_product=s1->x * s2->x + s1->y * s2->y + s1->z * s2->z;
+    return dot_product;
+}
+
 /* Subtract Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index fa7ff9d..5eebfd9 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -29,6 +29,7 @@ #define expect_vec(expectedvec,gotvec) \
 
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
+static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
 static void init_function_pointers(void)
@@ -43,11 +44,13 @@ static void init_function_pointers(void)
 
     pD3DRMVectorAdd = (void*)GetProcAddress(hmod, "D3DRMVectorAdd");
     pD3DRMVectorCrossProduct = (void*)GetProcAddress(hmod, "D3DRMVectorCrossProduct");
+    pD3DRMVectorDotProduct = (void*)GetProcAddress(hmod, "D3DRMVectorDotProduct");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
 
 static void VectorTest(void)
 {
+    D3DVALUE mod;
     D3DVECTOR e,r,u,v;
 
     u.x=2.0;u.y=2.0;u.z=1.0;
@@ -67,6 +70,10 @@ static void VectorTest(void)
     expect_vec(e,r);
               }
 
+/*_______________________VectorDotProduct__________________________*/
+    mod=pD3DRMVectorDotProduct(&u,&v);
+    todo_wine ok((mod == 16.0), "Expected 16.0, Got %f",mod); 
+
 /*_______________________VectorSubtract__________________________*/
     pD3DRMVectorSubtract(&r,&u,&v);
     e.x=-2.0;e.y=-2.0;e.z=1.0;
-- 
1.4.2

-------------- next part --------------
>From eb2d0d80562740bd594d66a0234f3ff51ff37e6e Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 13:35:55 +0200
Subject: [PATCH] [6] Implements D3DRMVectorModulus with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    8 ++++++++
 dlls/d3drm/tests/vector.c |    6 ++++++
 3 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 59c1e03..b736405 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -11,7 +11,7 @@
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
 @ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
 @ stdcall D3DRMVectorDotProduct(ptr ptr)
-@ stub D3DRMVectorModulus
+@ stdcall D3DRMVectorModulus(ptr)
 @ stub D3DRMVectorNormalize
 @ stub D3DRMVectorRandom
 @ stub D3DRMVectorReflect
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 332f5a5..daa0ddf 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -57,6 +57,14 @@ D3DVALUE D3DRMAPI D3DRMVectorDotProduct(
     return dot_product;
 }
 
+/* Norm of a vector */
+D3DVALUE D3DRMAPI D3DRMVectorModulus(LPD3DVECTOR v)
+{
+    D3DVALUE result;
+    result=sqrt(v->x * v->x + v->y * v->y + v->z * v->z);
+    return result;
+}
+
 /* Subtract Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 5eebfd9..6fcd9f8 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -30,6 +30,7 @@ #define expect_vec(expectedvec,gotvec) \
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
+static D3DVALUE (D3DRMAPI *pD3DRMVectorModulus)(LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
 static void init_function_pointers(void)
@@ -45,6 +46,7 @@ static void init_function_pointers(void)
     pD3DRMVectorAdd = (void*)GetProcAddress(hmod, "D3DRMVectorAdd");
     pD3DRMVectorCrossProduct = (void*)GetProcAddress(hmod, "D3DRMVectorCrossProduct");
     pD3DRMVectorDotProduct = (void*)GetProcAddress(hmod, "D3DRMVectorDotProduct");
+    pD3DRMVectorModulus = (void*)GetProcAddress(hmod, "D3DRMVectorModulus");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
 
@@ -74,6 +76,10 @@ static void VectorTest(void)
     mod=pD3DRMVectorDotProduct(&u,&v);
     todo_wine ok((mod == 16.0), "Expected 16.0, Got %f",mod); 
 
+/*_______________________VectorModulus_____________________________*/
+    mod=pD3DRMVectorModulus(&u);
+    todo_wine ok((mod == 3.0), "Expected 3.0, Got %f",mod);
+
 /*_______________________VectorSubtract__________________________*/
     pD3DRMVectorSubtract(&r,&u,&v);
     e.x=-2.0;e.y=-2.0;e.z=1.0;
-- 
1.4.2

-------------- next part --------------
>From 0f921553b331dd4c2fb146934dd001ea1c1c3e76 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 13:41:28 +0200
Subject: [PATCH] [7] Implements D3DRMVectorScale with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    9 +++++++++
 dlls/d3drm/tests/vector.c |   12 +++++++++++-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index b736405..1efbfd4 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -16,7 +16,7 @@
 @ stub D3DRMVectorRandom
 @ stub D3DRMVectorReflect
 @ stub D3DRMVectorRotate
-@ stub D3DRMVectorScale
+@ stdcall D3DRMVectorScale(ptr ptr long)
 @ stdcall D3DRMVectorSubtract(ptr ptr ptr)
 @ stub Direct3DRMCreate
 @ stub DllCanUnloadNow
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index daa0ddf..9d794ee 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -65,6 +65,15 @@ D3DVALUE D3DRMAPI D3DRMVectorModulus(LPD
     return result;
 }
 
+/* Scale a vector */
+LPD3DVECTOR D3DRMAPI D3DRMVectorScale(LPD3DVECTOR d, LPD3DVECTOR s, D3DVALUE factor)
+{
+    d->x=factor * s->x;
+    d->y=factor * s->y;
+    d->z=factor * s->z;
+    return d;
+}
+
 /* Subtract Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorSubtract(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 6fcd9f8..ece51fd 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -31,6 +31,7 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorModulus)(LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorScale)(LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
 static void init_function_pointers(void)
@@ -47,12 +48,13 @@ static void init_function_pointers(void)
     pD3DRMVectorCrossProduct = (void*)GetProcAddress(hmod, "D3DRMVectorCrossProduct");
     pD3DRMVectorDotProduct = (void*)GetProcAddress(hmod, "D3DRMVectorDotProduct");
     pD3DRMVectorModulus = (void*)GetProcAddress(hmod, "D3DRMVectorModulus");
+    pD3DRMVectorScale = (void*)GetProcAddress(hmod, "D3DRMVectorScale");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
 
 static void VectorTest(void)
 {
-    D3DVALUE mod;
+    D3DVALUE mod,par;
     D3DVECTOR e,r,u,v;
 
     u.x=2.0;u.y=2.0;u.z=1.0;
@@ -80,6 +82,14 @@ static void VectorTest(void)
     mod=pD3DRMVectorModulus(&u);
     todo_wine ok((mod == 3.0), "Expected 3.0, Got %f",mod);
 
+/*_______________________VectorScale__________________________*/
+    par=2.5;
+    pD3DRMVectorScale(&r,&u,par);
+    e.x=5.0;e.y=5.0;e.z=2.5;
+    todo_wine {
+    expect_vec(e,r);
+              }
+
 /*_______________________VectorSubtract__________________________*/
     pD3DRMVectorSubtract(&r,&u,&v);
     e.x=-2.0;e.y=-2.0;e.z=1.0;
-- 
1.4.2

-------------- next part --------------
>From 07597494ec96d568824222521638553a0f1d749f Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 13:48:21 +0200
Subject: [PATCH] [8] Implements D3DRMVectorNormalize with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |   16 ++++++++++++++++
 dlls/d3drm/tests/vector.c |   20 +++++++++++++++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 1efbfd4..172f07e 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -12,7 +12,7 @@
 @ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
 @ stdcall D3DRMVectorDotProduct(ptr ptr)
 @ stdcall D3DRMVectorModulus(ptr)
-@ stub D3DRMVectorNormalize
+@ stdcall D3DRMVectorNormalize(ptr)
 @ stub D3DRMVectorRandom
 @ stub D3DRMVectorReflect
 @ stub D3DRMVectorRotate
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 9d794ee..b542584 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -65,6 +65,22 @@ D3DVALUE D3DRMAPI D3DRMVectorModulus(LPD
     return result;
 }
 
+/* Normalize a vector.  Returns (1,0,0) if INPUT is the NULL vector. */
+LPD3DVECTOR D3DRMAPI D3DRMVectorNormalize(LPD3DVECTOR u)
+{
+    D3DVALUE modulus;
+    modulus=D3DRMVectorModulus(u);
+    if(modulus) 
+      {
+       D3DRMVectorScale(u,u,1/modulus);
+      }
+    else
+      {
+       u->x=1; u->y=0; u->z=0;
+      }
+    return u; 
+}
+
 /* Scale a vector */
 LPD3DVECTOR D3DRMAPI D3DRMVectorScale(LPD3DVECTOR d, LPD3DVECTOR s, D3DVALUE factor)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index ece51fd..96c4a3d 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -31,6 +31,7 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorModulus)(LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorNormalize)(LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorScale)(LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
@@ -48,6 +49,7 @@ static void init_function_pointers(void)
     pD3DRMVectorCrossProduct = (void*)GetProcAddress(hmod, "D3DRMVectorCrossProduct");
     pD3DRMVectorDotProduct = (void*)GetProcAddress(hmod, "D3DRMVectorDotProduct");
     pD3DRMVectorModulus = (void*)GetProcAddress(hmod, "D3DRMVectorModulus");
+    pD3DRMVectorNormalize = (void*)GetProcAddress(hmod, "D3DRMVectorNormalize");
     pD3DRMVectorScale = (void*)GetProcAddress(hmod, "D3DRMVectorScale");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
@@ -55,7 +57,7 @@ static void init_function_pointers(void)
 static void VectorTest(void)
 {
     D3DVALUE mod,par;
-    D3DVECTOR e,r,u,v;
+    D3DVECTOR e,r,u,v,casnul;
 
     u.x=2.0;u.y=2.0;u.z=1.0;
     v.x=4.0;v.y=4.0;v.z=0.0;
@@ -82,6 +84,22 @@ static void VectorTest(void)
     mod=pD3DRMVectorModulus(&u);
     todo_wine ok((mod == 3.0), "Expected 3.0, Got %f",mod);
 
+/*_______________________VectorNormalize___________________________*/
+    pD3DRMVectorNormalize(&u);
+    e.x=2.0/3.0;e.y=2.0/3.0;e.z=1.0/3.0;
+    todo_wine {
+    expect_vec(e,u);
+              }
+
+/* If u is the NULL vector, MSDN says that the return vector is NULL. In fact, the returned vector is (1,0,0). The following test case prove it. */
+
+    casnul.x=0; casnul.y=0; casnul.z=0;
+    pD3DRMVectorNormalize(&casnul);
+    e.x=1; e.y=0; e.z=0;
+    todo_wine {
+    expect_vec(e,casnul);
+              }
+
 /*_______________________VectorScale__________________________*/
     par=2.5;
     pD3DRMVectorScale(&r,&u,par);
-- 
1.4.2

-------------- next part --------------
>From 642db309fc058dc0dae3fd6c8e7927ae570e7348 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 13:51:01 +0200
Subject: [PATCH] [9] Implements D3DRMVectorRandom. Test is unuseful.

---
 dlls/d3drm/d3drm.spec |    2 +-
 dlls/d3drm/math.c     |   11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 172f07e..5af714e 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -13,7 +13,7 @@
 @ stdcall D3DRMVectorDotProduct(ptr ptr)
 @ stdcall D3DRMVectorModulus(ptr)
 @ stdcall D3DRMVectorNormalize(ptr)
-@ stub D3DRMVectorRandom
+@ stdcall D3DRMVectorRandom(ptr)
 @ stub D3DRMVectorReflect
 @ stub D3DRMVectorRotate
 @ stdcall D3DRMVectorScale(ptr ptr long)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index b542584..31192e4 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -81,6 +81,17 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorNormaliz
     return u; 
 }
 
+/* Returns a random unit vector */
+LPD3DVECTOR D3DRMAPI D3DRMVectorRandom(LPD3DVECTOR d)
+{
+    srand(time(NULL));
+    d->x=(D3DVALUE)(rand());
+    d->y=(D3DVALUE)(rand());
+    d->z=(D3DVALUE)(rand());
+    D3DRMVectorNormalize(d);
+    return d;
+}
+
 /* Scale a vector */
 LPD3DVECTOR D3DRMAPI D3DRMVectorScale(LPD3DVECTOR d, LPD3DVECTOR s, D3DVALUE factor)
 {
-- 
1.4.2

-------------- next part --------------
>From 61c6879323d78b47ca9a1946323f0350cb87a3dd Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 13:55:40 +0200
Subject: [PATCH] [10] Implements D3DRMVectorReflect with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    8 ++++++++
 dlls/d3drm/tests/vector.c |   13 ++++++++++++-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 5af714e..19361a9 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -14,7 +14,7 @@
 @ stdcall D3DRMVectorModulus(ptr)
 @ stdcall D3DRMVectorNormalize(ptr)
 @ stdcall D3DRMVectorRandom(ptr)
-@ stub D3DRMVectorReflect
+@ stdcall D3DRMVectorReflect(ptr ptr ptr)
 @ stub D3DRMVectorRotate
 @ stdcall D3DRMVectorScale(ptr ptr long)
 @ stdcall D3DRMVectorSubtract(ptr ptr ptr)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 31192e4..9882464 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -92,6 +92,14 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorRandom(L
     return d;
 }
 
+/* Reflection of a vector on a surface */
+LPD3DVECTOR D3DRMAPI D3DRMVectorReflect(LPD3DVECTOR r, LPD3DVECTOR ray, LPD3DVECTOR norm)
+{
+    D3DVECTOR sca;
+    D3DRMVectorSubtract(r,D3DRMVectorScale(&sca,norm,2*D3DRMVectorDotProduct(ray,norm)),ray);
+    return r;
+}
+
 /* Scale a vector */
 LPD3DVECTOR D3DRMAPI D3DRMVectorScale(LPD3DVECTOR d, LPD3DVECTOR s, D3DVALUE factor)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 96c4a3d..0e38b7d 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -32,6 +32,7 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorModulus)(LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorNormalize)(LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorReflect)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorScale)(LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
@@ -50,6 +51,7 @@ static void init_function_pointers(void)
     pD3DRMVectorDotProduct = (void*)GetProcAddress(hmod, "D3DRMVectorDotProduct");
     pD3DRMVectorModulus = (void*)GetProcAddress(hmod, "D3DRMVectorModulus");
     pD3DRMVectorNormalize = (void*)GetProcAddress(hmod, "D3DRMVectorNormalize");
+    pD3DRMVectorReflect = (void*)GetProcAddress(hmod, "D3DRMVectorReflect");
     pD3DRMVectorScale = (void*)GetProcAddress(hmod, "D3DRMVectorScale");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 }
@@ -57,7 +59,7 @@ static void init_function_pointers(void)
 static void VectorTest(void)
 {
     D3DVALUE mod,par;
-    D3DVECTOR e,r,u,v,casnul;
+    D3DVECTOR e,r,u,v,casnul,ray,norm;
 
     u.x=2.0;u.y=2.0;u.z=1.0;
     v.x=4.0;v.y=4.0;v.z=0.0;
@@ -100,6 +102,15 @@ static void VectorTest(void)
     expect_vec(e,casnul);
               }
 
+/*____________________VectorReflect_________________________________*/
+    ray.x=3.0; ray.y=-4.0; ray.z=5.0;
+    norm.x=1.0; norm.y=-2.0; norm.z=6.0;
+    e.x=79.0; e.y=-160.0; e.z=487.0;
+    pD3DRMVectorReflect(&r,&ray,&norm);
+    todo_wine {
+               expect_vec(e,r);
+              }
+
 /*_______________________VectorScale__________________________*/
     par=2.5;
     pD3DRMVectorScale(&r,&u,par);
-- 
1.4.2

-------------- next part --------------
>From 790f65badfa2d353c16a3f72f143b78d115f55ab Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 14:26:27 +0200
Subject: [PATCH] [11] Implements D3DRMMatrixFromQuaternion with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |   12 ++++++++++++
 dlls/d3drm/tests/vector.c |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 19361a9..3b02fa9 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -4,7 +4,7 @@
 @ stub D3DRMColorGetRed
 @ stub D3DRMCreateColorRGB
 @ stub D3DRMCreateColorRGBA
-@ stub D3DRMMatrixFromQuaternion
+@ stdcall D3DRMMatrixFromQuaternion(ptr ptr)
 @ stub D3DRMQuaternionFromRotation
 @ stub D3DRMQuaternionMultiply
 @ stub D3DRMQuaternionSlerp
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 9882464..1fc8b06 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -31,6 +31,18 @@ #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
 
+/* Matrix for the Rotation that a unit quaternion represents */
+void D3DRMAPI D3DRMMatrixFromQuaternion(D3DRMMATRIX4D m, LPD3DRMQUATERNION q)
+{
+    D3DVALUE w,x,y,z;
+    w=q->s; x=(q->v).x; y=(q->v).y; z=(q->v).z;
+    m[0][0]=1-2*(y*y+z*z); m[1][1]=1-2*(x*x+z*z); m[2][2]=1-2*(x*x+y*y);
+    m[1][0]=2*(x*y+z*w); m[0][1]=2*(x*y-z*w);
+    m[2][0]=2*(x*z-y*w); m[0][2]=2*(x*z+y*w);
+    m[2][1]=2*(y*z+x*w); m[1][2]=2*(y*z-x*w);
+    m[3][0]=0; m[3][1]=0; m[3][2]=0; m[0][3]=0; m[1][3]=0; m[2][3]=0; m[3][3]=1;
+}
+
 /* Add Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 0e38b7d..9be0b53 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -27,6 +27,22 @@ #define expect_vec(expectedvec,gotvec) \
   "Expected Vector= (%f, %f, %f)\n , Got Vector= (%f, %f, %f)\n", \
   expectedvec.x,expectedvec.y,expectedvec.z, gotvec.x, gotvec.y, gotvec.z);
 
+#define expect_mat( expectedmat, gotmat)\
+{ \
+   int i,j,equal=1; \
+    for (i=0; i<4; i++)\
+        {\
+         for (j=0; j<4; j++)\
+             {\
+              if (fabs(expectedmat[i][j]-gotmat[i][j])>0.000001)\
+                 {\
+                  equal=0;\
+                 }\
+             }\
+        }\
+    ok(equal, "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n",expectedmat[0][0],expectedmat[0][1],expectedmat[0][2],expectedmat[0][3],expectedmat[1][0],expectedmat[1][1],expectedmat[1][2],expectedmat[1][3],expectedmat[2][0],expectedmat[2][1],expectedmat[2][2],expectedmat[2][3],expectedmat[3][0],expectedmat[3][1],expectedmat[3][2],expectedmat[3][3],gotmat[0][0],gotmat[0][1],gotmat[0][2],gotmat[0][3],gotmat[1][0],gotmat[1][1],gotmat[1][2],gotmat[1][3],gotmat[2][0],gotmat[2][1],gotmat[2][2],gotmat[2][3],gotmat[3][0],gotmat[3][1],gotmat[3][2],gotmat[3][3]);\
+}\
+
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
@@ -36,6 +52,8 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorScale)(LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
+static void (D3DRMAPI *pD3DRMMatrixFromQuaternion)(D3DRMMATRIX4D, LPD3DRMQUATERNION);
+
 static void init_function_pointers(void)
 {
     HMODULE hmod = LoadLibraryA("d3drm.dll");
@@ -54,6 +72,8 @@ static void init_function_pointers(void)
     pD3DRMVectorReflect = (void*)GetProcAddress(hmod, "D3DRMVectorReflect");
     pD3DRMVectorScale = (void*)GetProcAddress(hmod, "D3DRMVectorScale");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
+
+     pD3DRMMatrixFromQuaternion = (void*)GetProcAddress(hmod, "D3DRMMatrixFromQuaternion");
 }
 
 static void VectorTest(void)
@@ -127,8 +147,26 @@ static void VectorTest(void)
               }
 }
 
+static void MatrixTest(void)
+{
+    D3DRMQUATERNION q;
+    D3DRMMATRIX4D exp,mat;
+
+    exp[0][0]=-49; exp[0][1]=4;   exp[0][2]=22;  exp[0][3]=0;
+    exp[1][0]=20;  exp[1][1]=-39; exp[1][2]=20;  exp[1][3]=0;
+    exp[2][0]=10;  exp[2][1]=28;  exp[2][2]=-25; exp[2][3]=0;
+    exp[3][0]=0;   exp[3][1]=0;   exp[3][2]=0;   exp[3][3]=1;
+    q.s=1; q.v.x=2; q.v.y=3; q.v.z=4;
+
+   pD3DRMMatrixFromQuaternion(mat,&q);
+   todo_wine {
+              expect_mat(exp,mat);
+             }
+}
+
 START_TEST(vector)
 {
    init_function_pointers();
    VectorTest();
+   MatrixTest();
 }
-- 
1.4.2

-------------- next part --------------
>From b1d07a3bec22ef46de8be0a6e497c8e1060d94ae Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 14:32:15 +0200
Subject: [PATCH] [12] Implements D3DRMQuaternionFromRotation with test.
[12] Implements D3DRMQuaternionFromRotation with test.
---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |    8 ++++++++
 dlls/d3drm/tests/vector.c |   27 +++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 3b02fa9..fd42527 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -5,7 +5,7 @@
 @ stub D3DRMCreateColorRGB
 @ stub D3DRMCreateColorRGBA
 @ stdcall D3DRMMatrixFromQuaternion(ptr ptr)
-@ stub D3DRMQuaternionFromRotation
+@ stdcall D3DRMQuaternionFromRotation(ptr ptr long)
 @ stub D3DRMQuaternionMultiply
 @ stub D3DRMQuaternionSlerp
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 1fc8b06..912870c 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -43,6 +43,14 @@ void D3DRMAPI D3DRMMatrixFromQuaternion(
     m[3][0]=0; m[3][1]=0; m[3][2]=0; m[0][3]=0; m[1][3]=0; m[2][3]=0; m[3][3]=1;
 }
 
+/* Returns a unit quaternion that represents a rotation of an angle around an axis */
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionFromRotation(LPD3DRMQUATERNION q, LPD3DVECTOR v, D3DVALUE theta)
+{
+    q->s=cos(theta/2);
+    D3DRMVectorScale(&(q->v),D3DRMVectorNormalize(v),sin(theta/2));
+    return q;
+}
+
 /* Add Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 9be0b53..3ea2391 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -22,6 +22,8 @@ #include "wine/test.h"
 #include "d3drmdef.h"
 #include <math.h>
 
+#define PI 4*atan(1.0)
+
 #define expect_vec(expectedvec,gotvec) \
   ok( ((fabs(expectedvec.x-gotvec.x)<0.000001)&&(fabs(expectedvec.y-gotvec.y)<0.000001)&&(fabs(expectedvec.z-gotvec.z)<0.000001)), \
   "Expected Vector= (%f, %f, %f)\n , Got Vector= (%f, %f, %f)\n", \
@@ -43,6 +45,12 @@ #define expect_mat( expectedmat, gotmat)
     ok(equal, "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n",expectedmat[0][0],expectedmat[0][1],expectedmat[0][2],expectedmat[0][3],expectedmat[1][0],expectedmat[1][1],expectedmat[1][2],expectedmat[1][3],expectedmat[2][0],expectedmat[2][1],expectedmat[2][2],expectedmat[2][3],expectedmat[3][0],expectedmat[3][1],expectedmat[3][2],expectedmat[3][3],gotmat[0][0],gotmat[0][1],gotmat[0][2],gotmat[0][3],gotmat[1][0],gotmat[1][1],gotmat[1][2],gotmat[1][3],gotmat[2][0],gotmat[2][1],gotmat[2][2],gotmat[2][3],gotmat[3][0],gotmat[3][1],gotmat[3][2],gotmat[3][3]);\
 }\
 
+#define expect_quat(expectedquat,gotquat) \
+  ok( (fabs(expectedquat.v.x-gotquat.v.x)<0.000001)&&(fabs(expectedquat.v.y-gotquat.v.y)<0.0000001)&&(fabs(expectedquat.v.z-gotquat.v.z)<0.000001)&&(fabs(expectedquat.s-gotquat.s)<0.000001), \
+  "Expected Quaternion %f %f %f %f , Got Quaternion %f %f %f %f\n", \
+  expectedquat.s,expectedquat.v.x,expectedquat.v.y,expectedquat.v.z, \
+  gotquat.s,gotquat.v.x,gotquat.v.y,gotquat.v.z);
+
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
@@ -54,6 +62,8 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 
 static void (D3DRMAPI *pD3DRMMatrixFromQuaternion)(D3DRMMATRIX4D, LPD3DRMQUATERNION);
 
+static LPD3DRMQUATERNION (D3DRMAPI *pD3DRMQuaternionFromRotation)(LPD3DRMQUATERNION,LPD3DVECTOR,D3DVALUE);
+
 static void init_function_pointers(void)
 {
     HMODULE hmod = LoadLibraryA("d3drm.dll");
@@ -164,9 +174,26 @@ static void MatrixTest(void)
              }
 }
 
+static void QuaternionTest(void)
+{
+    D3DVECTOR axis;
+    D3DVALUE theta=2*PI/3;
+    D3DRMQUATERNION q,r;
+
+    axis.x=1.0;axis.y=1.0;axis.z=1.0;
+
+/*_________________QuaternionFromMatrix___________________*/
+    pD3DRMQuaternionFromRotation(&r,&axis,theta);
+    q.s=0.5;q.v.x=0.5;q.v.y=0.5;q.v.z=0.5;
+    todo_wine {
+    expect_quat(q,r);
+              }
+}
+
 START_TEST(vector)
 {
    init_function_pointers();
    VectorTest();
    MatrixTest();
+   QuaternionTest();
 }
-- 
1.4.2

-------------- next part --------------
>From 34ba693025149d5a86ea93f652c4dad70a064a65 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 14:34:11 +0200
Subject: [PATCH] [13] Implements D3DRMQuaternionMultiply.

---
 dlls/d3drm/d3drm.spec |    2 +-
 dlls/d3drm/math.c     |   12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index fd42527..a23caff 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -6,7 +6,7 @@
 @ stub D3DRMCreateColorRGBA
 @ stdcall D3DRMMatrixFromQuaternion(ptr ptr)
 @ stdcall D3DRMQuaternionFromRotation(ptr ptr long)
-@ stub D3DRMQuaternionMultiply
+@ stdcall D3DRMQuaternionMultiply(ptr ptr ptr)
 @ stub D3DRMQuaternionSlerp
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
 @ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index 912870c..b89796f 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -51,6 +51,18 @@ LPD3DRMQUATERNION D3DRMAPI D3DRMQuaterni
     return q;
 }
 
+/* Product of 2 quaternions */
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionMultiply(LPD3DRMQUATERNION q, LPD3DRMQUATERNION a, LPD3DRMQUATERNION b)
+{
+    D3DVECTOR cross_product;
+    D3DRMVectorCrossProduct(&(cross_product),&(a->v),&(b->v));
+    q->s=a->s * b->s-D3DRMVectorDotProduct(&(a->v),&(b->v));
+    q->v.x=a->s * (b->v).x + b->s * (a->v).x + cross_product.x;
+    q->v.y=a->s * (b->v).y + b->s * (a->v).y + cross_product.y;
+    q->v.z=a->s * (b->v).z + b->s * (a->v).z + cross_product.z;
+    return q;
+}
+
 /* Add Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
-- 
1.4.2

-------------- next part --------------
>From 71e939c9825b906f03566df14823441a7f2f6adc Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 14:20:44 +0200
Subject: [PATCH] [14] Implements D3DRMQuaternionSlerp with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |   11 ++++++++++
 dlls/d3drm/tests/vector.c |   49 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index ed8c2d2..f194f5a 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -7,7 +7,7 @@
 @ stub D3DRMMatrixFromQuaternion(ptr ptr)
 @ stub D3DRMQuaternionFromRotation(ptr ptr) 
 @ stub D3DRMQuaternionMultiply(ptr ptr ptr)
-@ stub D3DRMQuaternionSlerp
+@ stub D3DRMQuaternionSlerp(ptr ptr ptr long)
 @ stdcall D3DRMVectorAdd(ptr ptr ptr)
 @ stdcall D3DRMVectorCrossProduct(ptr ptr ptr)
 @ stdcall D3DRMVectorDotProduct(ptr ptr)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index b89796f..d54b8c5 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -63,6 +63,17 @@ LPD3DRMQUATERNION D3DRMAPI D3DRMQuaterni
     return q;
 }
 
+/* Interpolation between two quaternions */
+LPD3DRMQUATERNION D3DRMAPI D3DRMQuaternionSlerp(LPD3DRMQUATERNION q, LPD3DRMQUATERNION a, LPD3DRMQUATERNION b, D3DVALUE alpha)
+{
+    D3DVALUE epsilon=1;
+    D3DVECTOR sca1,sca2;
+    if (a->s*b->s+D3DRMVectorDotProduct(&(a->v),&(b->v))<0) epsilon=-1;
+    q->s=(1-alpha)*a->s+epsilon*alpha*b->s;
+    D3DRMVectorAdd(&(q->v),D3DRMVectorScale(&(sca1),&(a->v),(1-alpha)),D3DRMVectorScale(&(sca2),&(b->v),epsilon*alpha));
+    return q;
+}
+
 /* Add Two Vectors */
 LPD3DVECTOR D3DRMAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 8e5fc66..eea02a3 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -43,6 +43,12 @@ #define expect_mat( expectedmat, gotmat)
     ok(equal, "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n",expectedmat[0][0],expectedmat[0][1],expectedmat[0][2],expectedmat[0][3],expectedmat[1][0],expectedmat[1][1],expectedmat[1][2],expectedmat[1][3],expectedmat[2][0],expectedmat[2][1],expectedmat[2][2],expectedmat[2][3],expectedmat[3][0],expectedmat[3][1],expectedmat[3][2],expectedmat[3][3],gotmat[0][0],gotmat[0][1],gotmat[0][2],gotmat[0][3],gotmat[1][0],gotmat[1][1],gotmat[1][2],gotmat[1][3],gotmat[2][0],gotmat[2][1],gotmat[2][2],gotmat[2][3],gotmat[3][0],gotmat[3][1],gotmat[3][2],gotmat[3][3]);\
 }\
 
+#define expect_quat(expectedquat,gotquat) \
+  ok( (fabs(expectedquat.v.x-gotquat.v.x)<0.000001)&&(fabs(expectedquat.v.y-gotquat.v.y)<0.0000001)&&(fabs(expectedquat.v.z-gotquat.v.z)<0.000001)&&(fabs(expectedquat.s-gotquat.s)<0.000001), \
+  "Expected Quaternion %f %f %f %f , Got Quaternion %f %f %f %f\n", \
+  expectedquat.s,expectedquat.v.x,expectedquat.v.y,expectedquat.v.z, \
+  gotquat.s,gotquat.v.x,gotquat.v.y,gotquat.v.z);
+
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorAdd)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorCrossProduct)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 static D3DVALUE (D3DRMAPI *pD3DRMVectorDotProduct)(LPD3DVECTOR,LPD3DVECTOR);
@@ -54,6 +60,8 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 
 static void (D3DRMAPI *pD3DRMMatrixFromQuaternion)(D3DRMMATRIX4D, LPD3DRMQUATERNION);
 
+static LPD3DRMQUATERNION (D3DRMAPI *pD3DRMQuaternionSlerp)(LPD3DRMQUATERNION,LPD3DRMQUATERNION,LPD3DRMQUATERNION, D3DVALUE);
+
 static void init_function_pointers(void)
 {
     HMODULE hmod = LoadLibraryA("d3drm.dll");
@@ -74,6 +82,8 @@ static void init_function_pointers(void)
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 
     pD3DRMMatrixFromQuaternion = (void*)GetProcAddress(hmod, "D3DRMMatrixFromQuaternion");
+
+    pD3DRMQuaternionSlerp = (void*)GetProcAddress(hmod, "D3DRMQuaternionSlerp");
 }
 
 static void VectorTest(void)
@@ -164,9 +174,48 @@ static void MatrixTest(void)
               }
 }
 
+static void QuaternionTest(void)
+{
+    D3DVALUE par=0.5,g,h,epsilon;
+    D3DRMQUATERNION q,q1,q2,r;
+
+/*_________________QuaternionSlerp_________________________*/
+/* Interpolation slerp is in fact a linear interpolation, not a spherical linear interpolation. Moreover, if the angle of the two quaternions is in ]PI/2;3PI/2[, QuaternionSlerp interpolates between the first quaternion and the opposite of the second one. The test proves these two facts. */
+
+    q1.s=1.0; q1.v.x=2.0; q1.v.y=3.0; q1.v.z=50.0;
+    q2.s=-4.0; q2.v.x=6.0; q2.v.y=7.0; q2.v.z=8.0; 
+/* The angle between q1 and q2 is in [-PI/2,PI/2]. So, one interpolates between q1 and q2. */
+    epsilon=1.0;
+    g=1.0-par; h=epsilon*par;
+/* Part of the test proving that the interpolation is linear. */
+    q.s=g*q1.s+h*q2.s;
+    q.v.x=g*q1.v.x+h*q2.v.x;
+    q.v.y=g*q1.v.y+h*q2.v.y;
+    q.v.z=g*q1.v.z+h*q2.v.z;
+    pD3DRMQuaternionSlerp(&r,&q1,&q2,par);
+    todo_wine {
+    expect_quat(q,r);
+              }
+
+    q1.s=1.0; q1.v.x=2.0; q1.v.y=3.0; q1.v.z=50.0;
+    q2.s=-94.0; q2.v.x=6.0; q2.v.y=7.0; q2.v.z=-8.0; 
+/* The angle between q1 and q2 is not in [-PI/2,PI/2]. So, one interpolates between q1 and -q2. */
+    epsilon=-1;
+    g=1-par; h=epsilon*par;
+    q.s=g*q1.s+h*q2.s;
+    q.v.x=g*q1.v.x+h*q2.v.x;
+    q.v.y=g*q1.v.y+h*q2.v.y;
+    q.v.z=g*q1.v.z+h*q2.v.z;
+    pD3DRMQuaternionSlerp(&r,&q1,&q2,par);
+    todo_wine {
+    expect_quat(q,r);
+              }
+}
+
 START_TEST(vector)
 {
    init_function_pointers();
    VectorTest();
    MatrixTest();
+   QuaternionTest();
 }
-- 
1.4.2

-------------- next part --------------
>From c39cbaceba4ff5032de8200e580133e838bd9d88 Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Sun, 15 Apr 2007 14:56:28 +0200
Subject: [PATCH] [15] Implement D3DRMVectorRotate with test.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |   18 ++++++++++++++++++
 dlls/d3drm/tests/vector.c |   22 ++++++++++++++++++++--
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index 8d79f86..4499211 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -15,7 +15,7 @@
 @ stdcall D3DRMVectorNormalize(ptr)
 @ stdcall D3DRMVectorRandom(ptr)
 @ stdcall D3DRMVectorReflect(ptr ptr ptr)
-@ stub D3DRMVectorRotate
+@ stdcall D3DRMVectorRotate(ptr ptr ptr long)
 @ stdcall D3DRMVectorScale(ptr ptr long)
 @ stdcall D3DRMVectorSubtract(ptr ptr ptr)
 @ stub Direct3DRMCreate
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index d54b8c5..ebba91b 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -135,6 +135,24 @@ LPD3DVECTOR D3DRMAPI D3DRMVectorRandom(L
     return d;
 }
 
+/* Rotation of a vector */
+LPD3DVECTOR D3DRMAPI D3DRMVectorRotate(LPD3DVECTOR r, LPD3DVECTOR v, LPD3DVECTOR axis, D3DVALUE theta)
+{
+    D3DRMQUATERNION quaternion,quaternion1, quaternion2, quaternion3, resultq;
+    D3DVECTOR NORM;
+
+    quaternion1.s=cos(theta*.5);
+    quaternion2.s=cos(theta*.5);
+    NORM=*D3DRMVectorNormalize(axis);
+    D3DRMVectorScale(&(quaternion1.v),&NORM,sin(theta * .5));
+    D3DRMVectorScale(&(quaternion2.v),&NORM,-sin(theta * .5));
+    quaternion3.s=0; quaternion3.v=*v;
+    D3DRMQuaternionMultiply(&quaternion,&quaternion1,&quaternion3);
+    D3DRMQuaternionMultiply(&resultq,&quaternion,&quaternion2);
+    r=D3DRMVectorNormalize(&(resultq.v));
+    return r;
+}
+
 /* Reflection of a vector on a surface */
 LPD3DVECTOR D3DRMAPI D3DRMVectorReflect(LPD3DVECTOR r, LPD3DVECTOR ray, LPD3DVECTOR norm)
 {
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 66f3c43..60ae555 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -57,6 +57,7 @@ static D3DVALUE (D3DRMAPI *pD3DRMVectorD
 static D3DVALUE (D3DRMAPI *pD3DRMVectorModulus)(LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorNormalize)(LPD3DVECTOR);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorReflect)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
+static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorRotate)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorScale)(LPD3DVECTOR,LPD3DVECTOR,D3DVALUE);
 static LPD3DVECTOR (D3DRMAPI *pD3DRMVectorSubtract)(LPD3DVECTOR,LPD3DVECTOR,LPD3DVECTOR);
 
@@ -81,6 +82,7 @@ static void init_function_pointers(void)
     pD3DRMVectorModulus = (void*)GetProcAddress(hmod, "D3DRMVectorModulus");
     pD3DRMVectorNormalize = (void*)GetProcAddress(hmod, "D3DRMVectorNormalize");
     pD3DRMVectorReflect = (void*)GetProcAddress(hmod, "D3DRMVectorReflect");
+    pD3DRMVectorRotate = (void*)GetProcAddress(hmod, "D3DRMVectorRotate");
     pD3DRMVectorScale = (void*)GetProcAddress(hmod, "D3DRMVectorScale");
     pD3DRMVectorSubtract = (void*)GetProcAddress(hmod, "D3DRMVectorSubtract");
 
@@ -92,11 +94,13 @@ static void init_function_pointers(void)
 
 static void VectorTest(void)
 {
-    D3DVALUE mod,par;
-    D3DVECTOR e,r,u,v,casnul,ray,norm;
+    D3DVALUE mod,par,theta=2*PI/3;;
+    D3DVECTOR e,r,u,v,w,axis,casnul,ray,norm;
 
     u.x=2.0;u.y=2.0;u.z=1.0;
     v.x=4.0;v.y=4.0;v.z=0.0;
+    w.x=3.0;w.y=4.0;w.z=0.0;
+    axis.x=0.0;axis.y=0.0;axis.z=1.0;
 
 /*______________________VectorAdd_________________________________*/
     pD3DRMVectorAdd(&r,&u,&v);
@@ -145,6 +149,20 @@ static void VectorTest(void)
                expect_vec(e,r);
               }
 
+/*_______________________VectorRotate_______________________________*/
+   pD3DRMVectorRotate(&r,&w,&axis,theta);
+    e.x=-0.3-0.4*sqrt(3);e.y=0.3*sqrt(3)-0.4;e.z=0;
+    todo_wine {
+               expect_vec(e,r);
+              }
+
+/* The same formula gives D3DRMVectorRotate, for theta in [-PI/2;+PI/2] or not. The following test proves this fact.*/
+    pD3DRMVectorRotate(&r,&w,&axis,-PI/4);
+    e.x=1.4/sqrt(2); e.y=0.2/sqrt(2); e.z=0;
+    todo_wine {
+               expect_vec(e,r);
+              }
+
 /*_______________________VectorScale__________________________*/
     par=2.5;
     pD3DRMVectorScale(&r,&u,par);
-- 
1.4.2



More information about the wine-patches mailing list