Implements D3DRMQuaternion Slerp

David.Adam at math.cnrs.fr David.Adam at math.cnrs.fr
Sun Apr 15 18:40:02 CDT 2007


-------------- next part --------------
>From 81295f0f3f67b12b20aeb4cad1fa9ccefd1d46ab Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Mon, 16 Apr 2007 08:17:26 +0200
Subject: [PATCH] [14] Implemnents D3DRMQuaternionSlerp with tests.

---
 dlls/d3drm/d3drm.spec     |    2 +-
 dlls/d3drm/math.c         |   11 +++++++++++
 dlls/d3drm/tests/vector.c |   41 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index a23caff..8d79f86 100644
--- a/dlls/d3drm/d3drm.spec
+++ b/dlls/d3drm/d3drm.spec
@@ -7,7 +7,7 @@
 @ stdcall D3DRMMatrixFromQuaternion(ptr ptr)
 @ stdcall D3DRMQuaternionFromRotation(ptr ptr long)
 @ stdcall D3DRMQuaternionMultiply(ptr ptr ptr)
-@ stub D3DRMQuaternionSlerp
+@ stdcall 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..7dbfffa 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -62,6 +62,17 @@ LPD3DRMQUATERNION D3DRMAPI D3DRMQuaterni
     q->v.z=a->s * (b->v).z + b->s * (a->v).z + cross_product.z;
     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 7e0f856..5c8855b 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -63,7 +63,8 @@ static LPD3DVECTOR (D3DRMAPI *pD3DRMVect
 static void (D3DRMAPI *pD3DRMMatrixFromQuaternion)(D3DRMMATRIX4D, LPD3DRMQUATERNION);
 
 static LPD3DRMQUATERNION (D3DRMAPI *pD3DRMQuaternionFromRotation)(LPD3DRMQUATERNION,LPD3DVECTOR,D3DVALUE);
-
+static LPD3DRMQUATERNION (D3DRMAPI *pD3DRMQuaternionSlerp)(LPD3DRMQUATERNION,LPD3DRMQUATERNION,LPD3DRMQUATERNION, D3DVALUE);
++
 static void init_function_pointers(void)
 {
     HMODULE hmod = LoadLibraryA("d3drm.dll");
@@ -86,6 +87,8 @@ static void init_function_pointers(void)
      pD3DRMMatrixFromQuaternion = (void*)GetProcAddress(hmod, "D3DRMMatrixFromQuaternion");
 
     pD3DRMQuaternionFromRotation = (void*)GetProcAddress(hmod, "D3DRMQuaternionFromRotation");
+    pD3DRMQuaternionSlerp = (void*)GetProcAddress(hmod, "D3DRMQuaternionSlerp");
+
 }
 
 static void VectorTest(void)
@@ -179,8 +182,8 @@ static void MatrixTest(void)
 static void QuaternionTest(void)
 {
     D3DVECTOR axis;
-    D3DVALUE theta=2*PI/3;
-    D3DRMQUATERNION q,r;
+    D3DVALUE theta=2*PI/3,par=0.5,g,h,epsilon;
+    D3DRMQUATERNION q,q1,q2,r;
 
     axis.x=1.0;axis.y=1.0;axis.z=1.0;
 
@@ -190,6 +193,38 @@ static void QuaternionTest(void)
     todo_wine {
     expect_quat(q,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)
-- 
1.4.2



More information about the wine-patches mailing list