void lib3ds_track_eval_quat(Lib3dsTrack *track, float q[4], float t) { lib3ds_quat_identity(q); if (track) { Lib3dsKey pp, p0, p1, pn; float u; int index; float ap[4], bp[4], an[4], bn[4]; assert(track->type == LIB3DS_TRACK_QUAT); if (!track->nkeys) { return; } index = find_index(track, t, &u); if (index < 0) { lib3ds_quat_axis_angle(q, track->keys[0].value, track->keys[0].value[3]); return; } if (index >= track->nkeys) { quat_for_index(track, track->nkeys - 1, q); return; } setup_segment(track, index, &pp, &p0, &p1, &pn); rot_key_setup(pp.frame>=0? &pp : NULL, &p0, &p1, ap, bp); rot_key_setup(&p0, &p1, pn.frame>=0? &pn : NULL, an, bn); lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u); } }
/*! * \ingroup tracks */ void lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat q, Lib3dsFloat t) { Lib3dsQuatKey *k; Lib3dsFloat nt; Lib3dsFloat u; if (!track->keyL) { lib3ds_quat_identity(q); return; } if (!track->keyL->next) { lib3ds_quat_copy(q, track->keyL->q); return; } for (k=track->keyL; k->next!=0; k=k->next) { if ((t>=k->tcb.frame) && (t<k->next->tcb.frame)) { break; } } if (!k->next) { if (track->flags&LIB3DS_REPEAT) { nt=(Lib3dsFloat)fmod(t, k->tcb.frame); for (k=track->keyL; k->next!=0; k=k->next) { if ((nt>=k->tcb.frame) && (nt<k->next->tcb.frame)) { break; } } ASSERT(k->next); } else { lib3ds_quat_copy(q, k->q); return; } } else { nt=t; } u=nt - k->tcb.frame; u/=(k->next->tcb.frame - k->tcb.frame); lib3ds_quat_squad( q, k->q, k->dd, k->next->ds, k->next->q, u ); }