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);
    }
}
Beispiel #2
0
/*!
 * \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
  );
}