2016-01-13 77 views
0

我在創建THREE.js中的相機Tween時遇到了一些麻煩,特別是在動畫結束和開始時,總會出現相機「跳躍」,這意味着一旦動畫開始並且一次相機閃爍動畫結束。作爲參考,我正在做的是:如何在Tween /動畫播放期間/之後避免攝像機跳躍?

  1. 相機俯視從上面的情景。

  2. 當用戶點擊場景中的某個元素時,攝像頭會對其進行放大(通過TWEEN),當距離足夠近時,OrbitControls目標將變爲所選元素的質心,並且自動旋轉開始,所以用戶看到元素在屏幕中心旋轉。

  3. 當用戶再次單擊時,相機會縮小到其初始位置(通過TWEEN)並返回到原始控件。

我在每個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); 

回答

0

OK,看來這個問題本身就是有我用旋轉的攝像頭,採用四元數和球面線性插值方法。

我發現,最好的方法(更容易,沒有閃爍/跳躍)將插入camera.rotation的參數,而不是插值四元數。

因此,一個補間的camera.rotation.the_axis_where_you_want_to_rotate完美地工作,並與位置上的吐溫同時完成,達到我期待的效果。