如何在Tween /动画期间/之后避免相机跳转?

时间:2016-01-13 16:38:28

标签: camera three.js quaternions tween

我在THREE.js中创建相机Tween时遇到了一些麻烦,特别是在动画的结尾和开头,似乎总是有一个相机“跳跃”,这意味着一旦动画开始并且动画结束,相机就会闪烁。作为参考,我正在做的是:

  1. 相机可以俯瞰上面的情景。

  2. 当用户点击场景的元素时,相机会放大它(通过TWEEN),当它足够接近时,OrbitControls目标会更改为所选元素的质心,并自动旋转开始,所以用户看到元素在屏幕中心旋转。

  3. 当用户再次点击时,相机会缩小到其初始位置(通过TWEEN)并返回原始控件。

  4. 我经历过跳跃/闪烁'在每个TWEEN的开头和结尾。

    这是我的补间功能:

          var origpos = new THREE.Vector3().copy(camera.position); // original position
          var origrot = new THREE.Euler().copy(camera.rotation); // original rotation
    
          camera.position.set(x, y+500, z+variation);
          camera.lookAt(new THREE.Vector3(x,y,z));
          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);
    
         options = {duration: 3000};
    
          //
          // Tweening
          //
    
          // position
          new TWEEN.Tween(camera.position).to({
            x: x,
            y: y+500,
            z: z
          }, options.duration).easing(TWEEN.Easing.Cubic.Out).onUpdate(function () {
                camera.lookAt(new THREE.Vector3(x,y,z));
            }).onComplete(function () {
                controls.autoRotate = true;
                controls.autoRotateSpeed = 5.0;
                controls.target = new THREE.Vector3(x, y, z);
            }).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);
    

1 个答案:

答案 0 :(得分:0)

好吧,似乎这个问题本身就是我用来旋转相机的方法,使用四元数和SLERP。

我发现最好的方法(更简单,没有闪烁/跳转)是插入camera.rotation的参数而不是插入四元数。

因此,camera.rotation.the_axis_where_you_want_to_rotate的Tween非常有效,并且与位置上的Tween同时完成,可以达到我想要的效果。