message: gltfio: Fix animation by clamping the per-channel interpolant.
  Tested with the model in as well as Fox, BusterDrone, CesiumMan,
  InterpolationTest, and VC.
  Fixes
diff: @@ -224,33 +224,32 @@ void Animator::applyAnimation(size_t animationIndex, float time) const {
  // Find the first keyframe after the given time, or the keyframe that matches it exactly.
  TimeValues::const_iterator iter = times.lower_bound(time);
  - // Find the two values that we will interpolate between.
  - TimeValues::const_iterator prevIter;
  - TimeValues::const_iterator nextIter;
  + // Compute the interpolant (between 0 and 1) and determine the keyframe pair.
  + float t = 0.0f;
  + size_t nextIndex;
  + size_t prevIndex;
  if (iter == times.end()) {
  - continue;
  + nextIndex = times.size() - 1;
  + prevIndex = nextIndex;
  } else if (iter == times.begin()) {
  - prevIter = nextIter = iter;
  + nextIndex = 0;
  + prevIndex = 0;
  } else {
  - nextIter = iter;
  - prevIter = --iter;
  - }
  -
  - // Compute the interpolant between 0 and 1.
  - float prevTime = prevIter->first;
  - float nextTime = nextIter->first;
  + TimeValues::const_iterator prev = iter; --prev;
  + nextIndex = iter->second;
  + prevIndex = prev->second;
  + const float nextTime = iter->first;
  + const float prevTime = prev->first;
  float deltaTime = nextTime - prevTime;
  - if (deltaTime < 0) {
  - deltaTime += anim.duration;
  + assert(deltaTime >= 0);
  + if (deltaTime > 0) {
  + t = (time - prevTime) / deltaTime;
  + }
  }
  - float t = deltaTime == 0 ? 0.0f : ((time - prevTime) / deltaTime);
  // Perform the interpolation. This is a simple but inefficient implementation; Filament
  // stores transforms as mat4's but glTF animation is based on TRS (translation rotation
  // scale).
  - size_t prevIndex = prevIter->second;
  - size_t nextIndex = nextIter->second;
  -
  mat4f xform = transformManager->getTransform(node);
  float3 scale;
  quatf rotation;
  