void quat_slerp(const Quat qa, const Quat qb, float t, Quat r) { log_assert(t>=0); log_assert(t<=1); float flip = 1.0; double cosine = qa[3]*qb[3] + qa[0]*qb[0] + qa[1]*qb[1] + qa[2]*qb[2]; if( cosine < 0 ) { cosine = -cosine; flip = -1.0; } Quat ua,ub; if( (1.0 - cosine) < CUTE_EPSILON ) { quat_mul1f(qa, t*flip, ua); quat_mul1f(qb, 1-t, ub); quat_add(ua, ub, r); return; } float theta = (float)acos(cosine); float sine = (float)sin(theta); float beta = (float)sin((1-t)*theta) / sine; float alpha = (float)sin(t*theta) / sine * flip; quat_mul1f(qa, alpha, ua); quat_mul1f(qb, beta, ub); quat_add(ua, ub, r); }
QuatP* qmul1f(Quat qa, float b) { quat_mul1f(qa,b,qa); return qa; }