我有一个数据,以毫秒为单位的时间和对象当时的位置(x,y,z)。

msec    |poz_x  |poz_y  |poz_z
------------------------------
0       |318    |24     |3
25      |318    |24     |3
49      |318    |23     |3
70      |318    |22     |2
91      |318    |22     |2
113     |318    |21     |1
136     |318    |21     |1
e.t.c


问题在于实际数据与下一个数据之间的时间差会有所不同(来自传感器)。
我正在寻找一种实时制作动画的方法。
如果我的数据中有60秒的信息,则需要在60秒内在浏览器中制作动画。
我已经读过requestAnimationFrame( animate );每秒将重复60次此功能,但是如果我的场景很沉重,我想想帧率会下降。无论如何,这不能解决我的问题。

我正在寻找一种不依赖于浏览器当前帧速率的可靠解决方案。
请帮忙。

最佳答案

有和没有库,有两种解决方法。
没错,这并不像仅计算动画循环的滴答数那样简单,因为不能保证每1/60秒发生一次。但是animation-frame回调(下面的代码中的loop)将获得一个时间戳作为第一个参数传递,该时间戳可用于计算animation-progress。

因此,在javascript中,可能是这样的:

// these are your keyframes, in a format compatible with THREE.Vector3.
// Please note that the time `t` is expected in milliseconds here.
// (must have properties named x, y and z - otherwise the copy below doesn't work)
const keyframes = [
  {t: 0, x: 318, y: 24, z: 3},
  {t: 25, x: 318, y: 24, z: 3},
  // ... and so on
];

// find a pair of keyframes [a, b] such that `a.t < t` and `b.t > t`.
// In other words, find the previous and next keyframe given the
// specific time `t`. If no previous or next keyframes is found, null
// is returned instead.
function findNearestKeyframes(t) {
  let prevKeyframe = null;
  for (let i = 0; i < keyframes.length; i++) {
    if (keyframes[i].t > t) {
      return [prevKeyframe, keyframes[i]];
    }
    prevKeyframe = keyframes[i];
  }

  return [prevKeyframe, null];
}

const tmpV3 = new THREE.Vector3();

function loop(t) {
  const [prevKeyframe, nextKeyframe] = findNearestKeyframes(t);

  // (...not handling cases where there is no prev or next here)

  // compute the progress of time between the two keyframes
  // (0 when t === prevKeyframe.t and 1 when t === nextKeyframe.t)
  let progress = (t - prevKeyframe.t) / (nextKeyframe.t - prevKeyframe.t);

  // copy position from previous keyframe, and interpolate towards the
  // next keyframe linearly
  tmpV3.copy(nextKeyframe);
  someObject.position
    .copy(prevKeyframe)
    .lerp(tmpV3, progress);

  // (...render scene)

  requestAnimationFrame(loop);
}

// start the animation-loop
requestAnimationFrame(loop);


编辑:要解决关于优化findNearestKeyframes功能的注释中的一个问题:

一旦获得了数千个关键帧,就可以对其进行一些优化,是的。对于大约几百美元的东西来说,这是不值得的(我将其归类为过早的优化)。

为了进行优化,可以创建索引表以跳过数组的无关部分。例如,您可以将索引每10秒开始存储在keyframes数组中,或者这样的方式-当您搜索t = 12.328s附近的关键帧时,可以根据预先计算的信息。您可能还可以使用许多其他算法和结构来加快速度。

10-04 12:10
查看更多