如何使用Three JS实现相机的lookAt动画

16

我有一个场景,可以呈现带有几个对象的棋盘。点击其中一个对象并使用对象拾取技术,我可以获取该对象并将摄像机位置动画到该对象的“俯视图”。然后,使用camera.lookAt方法可以强制摄像机直接看向该对象。

我注意到在onUpdate方法中调用camera.lookAt时,初始动画会出现快速跳动,因为它最初需要旋转大距离才能看向所选对象。相比之下,每个后续的camera.lookAt调用都很小,并且动画效果很好。

// Position the camera to fit
var tween = new TWEEN.Tween(camera.position).to({
    x: selectedObject.position.x,
    y: selectedObject.position.y,
    z: 1
}).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(function() {
    camera.lookAt(selectedObject.position);
}).onComplete(function() {
    camera.lookAt(selectedObject.position);
}).start();

有没有办法对这种方法进行动画处理,或者我必须手动转换相机矩阵的值来查看我的选择对象?

这里是一个带有示例的fiddle。它使用WebGLRenderer,所以请使用适当的浏览器。

http://jsfiddle.net/fungus1487/SMLwa/

感谢任何帮助。


截至今天,我们现在有三个适合的浏览器,三年时间带来了很大的变化。 - Neil
2个回答

20

你可以做的一件事情是同时对相机位置和相机目标进行缓动(需要先定义相机目标)。

var tween = new TWEEN.Tween( camera.position )
    .to( {
        x: selectedObject.position.x,
        y: selectedObject.position.y,
        z: 1
    } )
    .easing( TWEEN.Easing.Linear.None ).onUpdate( function () {

        camera.lookAt( camera.target );

    } )
    .onComplete( function () {

        camera.lookAt( selectedObject.position );

    } )
    .start();

var tween = new TWEEN.Tween( camera.target )
    .to( {
        x: selectedObject.position.x,
        y: selectedObject.position.y,
        z: 0
    } )
    .easing( TWEEN.Easing.Linear.None )
    .onUpdate( function () {

    } )
    .onComplete( function () {

        camera.lookAt( selectedObject.position );

    } )
    .start();

这有点棘手,因为tween需要精确同时运行,而且它们不会... 这就是第二个tween中调用camera.lookAt()的原因。


请问如何定义camera.target?在THREE.js中没有定义。 - pkout
1
正如答案第一行所述,这是您必须定义的内容。但它不一定是“camera”的属性。 - WestLangley
啊,抱歉。我不知道我怎么错过了那个。谢谢! - pkout

7

WestLangley的回答可以,但是似乎过于冗长。我使用了以下代码,其中已经预定义了相机位置(xyz)和目标(xyz)。使用透视相机和轨迹球控件。

new TWEEN.Tween( camera.position ).to( {
    x: position.x,
    y: position.y,
    z: position.z}, 600 )
  .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();
new TWEEN.Tween( controls.target ).to( {
    x: target.x,
    y: target.y,
    z: target.z}, 600 )
  .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();

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