Tween相机位置并使用slerp旋转 -- THREE.js

11

我希望在旋转相机的同时,能够缓慢移动相机的位置。

这是我的函数:

function moveAndLookAt(camera, dstpos, dstlookat, options) {
  options || (options = {duration: 300});

  var origpos = new THREE.Vector3().copy(camera.position); // original position
  var origrot = new THREE.Euler().copy(camera.rotation); // original rotation

  camera.position.set(dstpos.x, dstpos.y, dstpos.z);
  camera.lookAt(dstlookat);
  var dstrot = new THREE.Euler().copy(camera.rotation)

  // reset original position and rotation
  camera.position.set(origpos.x, origpos.y, origpos.z);
  camera.rotation.set(origrot.x, origrot.y, origrot.z);

  //
  // Tweening
  //

  // position
  new TWEEN.Tween(camera.position).to({
    x: dstpos.x,
    y: dstpos.y,
    z: dstpos.z
  }, options.duration).start();;

  // rotation (using slerp)
  (function () {
    var qa = camera.quaternion; // src quaternion
    var qb = new THREE.Quaternion().setFromEuler(dstrot); // dst quaternion
    var qm = new THREE.Quaternion();

    var o = {t: 0};
    new TWEEN.Tween(o).to({t: 1}, options.duration).onUpdate(function () {
      THREE.Quaternion.slerp(qa, qb, qm, o.t);
      camera.quaternion.set(qm.x, qm.y, qm.z, qm.w);
    }).start();
  }).call(this);
}

这个代码运行很好:http://codepen.io/abernier/pen/zxzObm


唯一的问题是旋转的缓动效果似乎不是线性的,导致位置的缓动效果(是线性的)和旋转不匹配。

如何将slerp变成线性缓动效果?

谢谢。


我以为球面插值(slerp)会保持恒定速度,但事实并非如此... - abernier
http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/ Slerp应该保持恒定的速度,而nlerp则不需要。 - Brendan Annable
@BrendanAnnable 我不理解的是:如果 slerp 应该保持恒定速度(即线性),而我的位置补间也是线性的(没有缓动),为什么会有这种衰减? - abernier
1个回答

13

在你的代码中

// rotation (using slerp)
(function () {
var qa = camera.quaternion; // src quaternion

将其改为

qa = new THREE.Quaternion().copy(camera.quaternion); // src quaternion

你所做的方式,qa与相机四元数相同,并且在球面线性插值计算中进行反馈。它必须是一个恒定变量。


1
太棒了!!它运行得非常好:http://codepen.io/abernier/pen/LEjPBX,谢谢!这是赏金 :) - abernier
很高兴它能帮到你 :-) - vals

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接