Patch [15/15]: Implements D3DRMQuaternionSlerp [try 2]
David.Adam at math.cnrs.fr
David.Adam at math.cnrs.fr
Thu Apr 19 14:16:57 CDT 2007
All these patches were done in collaboration with Vijay Kamuju.
David ADAM
-------------- next part --------------
>From ae006c5ed24021200271c8fb2130543cdf1c80cd Mon Sep 17 00:00:00 2001
From: Adam <David.Adam at math.cnrs.fr>
Date: Fri, 20 Apr 2007 03:33:06 +0200
Subject: [PATCH] Implements D3DRMQuaternionSlerp with test.
---
dlls/d3drm/d3drm.spec | 2 +-
dlls/d3drm/math.c | 11 +++++++++++
dlls/d3drm/tests/vector.c | 32 ++++++++++++++++++++++++++++++--
3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/dlls/d3drm/d3drm.spec b/dlls/d3drm/d3drm.spec
index c73b416..45bbd08 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)
diff --git a/dlls/d3drm/math.c b/dlls/d3drm/math.c
index a561e50..cf95773 100644
--- a/dlls/d3drm/math.c
+++ b/dlls/d3drm/math.c
@@ -63,6 +63,17 @@ LPD3DRMQUATERNION WINAPI D3DRMQuaternion
return q;
}
+/* Interpolation between two quaternions */
+LPD3DRMQUATERNION WINAPI D3DRMQuaternionSlerp(LPD3DRMQUATERNION q, LPD3DRMQUATERNION a, LPD3DRMQUATERNION b, D3DVALUE alpha)
+{
+ D3DVALUE epsilon=1.0;
+ D3DVECTOR sca1,sca2;
+ if (a->s*b->s+D3DRMVectorDotProduct(&(a->v),&(b->v))<0.0) epsilon=-1.0;
+ q->s=(1.0-alpha)*a->s+epsilon*alpha*b->s;
+ D3DRMVectorAdd(&(q->v),D3DRMVectorScale(&(sca1),&(a->v),(1.0-alpha)),D3DRMVectorScale(&(sca2),&(b->v),epsilon*alpha));
+ return q;
+}
+
/* Add Two Vectors */
LPD3DVECTOR WINAPI D3DRMVectorAdd(LPD3DVECTOR d, LPD3DVECTOR s1, LPD3DVECTOR s2)
{
diff --git a/dlls/d3drm/tests/vector.c b/dlls/d3drm/tests/vector.c
index 7b5f4ec..485d4a5 100644
--- a/dlls/d3drm/tests/vector.c
+++ b/dlls/d3drm/tests/vector.c
@@ -141,8 +141,8 @@ void MatrixTest(void)
void QuaternionTest(void)
{
D3DVECTOR axis;
- D3DVALUE theta;
- D3DRMQUATERNION q,r;
+ D3DVALUE g,h,epsilon,par,theta;
+ D3DRMQUATERNION q,q1,q2,r;
/*_________________QuaternionFromRotation___________________*/
axis.x=1.0;axis.y=1.0;axis.z=1.0;
@@ -150,6 +150,34 @@ void QuaternionTest(void)
D3DRMQuaternionFromRotation(&r,&axis,theta);
q.s=0.5;q.v.x=0.5;q.v.y=0.5;q.v.z=0.5;
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. */
+ par=0.31;
+ 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;
+ D3DRMQuaternionSlerp(&r,&q1,&q2,par);
+ 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.0;
+ g=1.0-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;
+ D3DRMQuaternionSlerp(&r,&q1,&q2,par);
+ expect_quat(q,r);
}
START_TEST(vector)
--
1.4.2
More information about the wine-patches
mailing list