X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=share%2Fvec3.c;h=60daf3c83d2c454cd3f9b630dece4d78446167c6;hb=4483dfdacd29073b37a6429ca8e123c80deac75a;hp=bb125d9ff4a7dbb310a572b5ad330d9702c0b57f;hpb=aebb66151b2b5f3b14ea1c51f7af89e8a4879a4d;p=neverball diff --git a/share/vec3.c b/share/vec3.c index bb125d9..60daf3c 100644 --- a/share/vec3.c +++ b/share/vec3.c @@ -299,7 +299,7 @@ void m_view(float *M, void q_as_axisangle(const float q[4], float u[3], float *a) { - *a = V_DEG(2.0f * facosf(q[0])); + *a = 2.0f * facosf(q[0]); v_nrm(u, q + 1); } @@ -381,4 +381,66 @@ void q_euler(float v[3], const float q[4]) v[2] = fatan2f(m23, m33); } +/* + * Spherical linear interpolation + */ +void q_slerp(float q[4], const float a[4], const float b[4], float t) +{ + float c, r, s, u, v; + int i = +1; + + if (t <= 0.0f) + { + q_cpy(q, a); + return; + } + + if (1.0f <= t) + { + q_cpy(q, b); + return; + } + + /* + * a . b = |a||b| cos A + * |a| = |b| = 1 + */ + + c = q_dot(a, b); + + /* Ensure the shortest path. */ + + if (c < 0) + { + c = -c; + i = -1; + } + + /* Fall back to normalized lerp for very similar orientations. */ + + if (1.0f - c < TINY) + { + u = 1.0f - t; + v = t; + + i = 1; + } + else + { + r = facosf(c); + s = fsinf(r); + u = fsinf((1.0f - t) * r) / s; + v = fsinf((t) * r) / s * i; + + i = 0; + } + + q[0] = a[0] * u + b[0] * v; + q[1] = a[1] * u + b[1] * v; + q[2] = a[2] * u + b[2] * v; + q[3] = a[3] * u + b[3] * v; + + if (i) q_nrm(q, q); +} + /*---------------------------------------------------------------------------*/