2015-09-22 385 views
0

我刚刚开始学习three.js,并且遇到了一些麻烦,需要编写一个函数,该函数以参数的形式获取对象位置(Vector3)和时间(以毫秒为单位),然后逐渐旋转相机在那个时候面对它。基本上是内置lookAt方法的一个lerp版本。threejs:顺利地将相机朝一个物体旋转

首先我试着使用tweenjs来获得平滑的旋转过渡。对于开始和结束参数,我创建了一个虚拟对象并将其位置,旋转和四元数设置为与摄影机相同,然后我使用lookAt函数面向对象,并将其四元数存储在新变量“targetQuaternion”。然后我使用这个变量作为TWEEN.Tween方法中的目标参数来更新camera.quaternion。我已经尝试过用四元数来避免gymbal锁,然后旋转,但没有任何工作正常。

function rotateCameraToObject(object3D, time) { 

var cameraPosition = camera.position.clone();    // camera original position 
var cameraRotation = camera.rotation.clone();    // camera original rotation 
var cameraQuaternion = camera.quaternion.clone();   // camera original quaternion 

var dummyObject = new THREE.Object3D();      // dummy object 


// set dummyObject's position, rotation and quaternion the same as the camera 
dummyObject.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z); 
dummyObject.rotation.set(cameraRotation.x, cameraRotation.y, cameraRotation.z); 
dummyObject.quaternion.set(cameraQuaternion.x, cameraQuaternion.y, cameraQuaternion.z); 


// lookAt object3D 
dummyObject.lookAt(object3D); 

// store its quaternion in a variable 
var targetQuaternion = dummyObject.quaternion.clone(); 


// tween start object 
var tweenStart = { 
    x: cameraQuaternion.x, 
    y: cameraQuaternion.y, 
    z: cameraQuaternion.z, 
    w: cameraQuaternion.w 
}; 

//tween target object 
var tweenTarget = { 
    x: targetQuaternion.x, 
    y: targetQuaternion.y, 
    z: targetQuaternion.z, 
    w: targetQuaternion.w 
}; 

// tween stuff 
var tween = new TWEEN.Tween(tweenStart).to(tweenTarget, time); 

tween.onUpdate(function() { 
    camera.quaternion.x = tweenStart.x; 
    camera.quaternion.y = tweenStart.y; 
    camera.quaternion.z = tweenStart.z; 
    camera.quaternion.w = tweenStart.w; 
}); 

tween.start(); 

}

所以这是行不通的。

我也尝试另一种方法,计算相机矢量和目标矢量和使用角度旋转目标之间的角度:

function rotateCameraToObject(object3D, time) { 

// camera original position 
var cameraPosition = camera.position.clone(); 

// object3D position 
var objectPosition = object3D.position.clone(); 

// direction vector from camera towards object3D 
var direction = objectPosition.sub(cameraPosition); 

// compute Euler angle 
var angle = new THREE.Euler(); 
angle.setFromVector3(direction); 


/* 
* tween stuff  
*/ 
var start = { 
    x: camera.rotation.clone().x, 
    y: camera.rotation.clone().y, 
    z: camera.rotation.clone().z, 
} 

var end = { 
    x: angle._x, 
    y: angle._y, 
    z: angle._z, 
} 

var tween = new TWEEN.Tween(start).to(end, time); 

tween.onUpdate(function() { 
    camera.rotation.y = start.x; 
    camera.rotation.y = start.y; 
    camera.rotation.y = start.z; 
}); 

tween.start();  

}

这不起作用都不是,最终的相机向物体旋转但旋转不正确。

任何帮助?相机具有lerp旋转功能的正确方法是什么?

在此先感谢!

回答

0

你是否更新过动画循环中的补间?

function animate() { 
    requestAnimationFrame(animate); 

    TWEEN.update(); 

    render(); 
} 

但是它可能会更好使用四元数,而不是旋转转对象 - 防止万向节锁定。 THREE.js提供了一个方便的函数来使用球面线性插值(slerp),而不是使用补间(lerp),它可以给你不希望的结果,最显着的是在180度转弯处。把它放在你的动画循环中。

camera.quaternion.slerp(targetQuaternion,t); //t = normalized value 0 to 1 

然后,您可以吐温牛逼给你你想要的宽松政策。