d3drm: Implement D3DRMQuaternionSlerp.
This commit is contained in:
parent
909b502360
commit
d53d7c9ea2
|
@ -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)
|
||||
|
|
|
@ -78,6 +78,18 @@ LPD3DRMQUATERNION WINAPI D3DRMQuaternionFromRotation(LPD3DRMQUATERNION q, LPD3DV
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -153,8 +153,8 @@ static void MatrixTest(void)
|
|||
static 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;
|
||||
|
@ -162,6 +162,37 @@ static 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)
|
||||
|
|
Loading…
Reference in New Issue