Three.js如何使用四元数旋转相机

13
在Three.js中,我想使用THREE.quaternion使相机对象旋转到所选对象。
我搜索了网络,但找不到关于如何使用这个四元数类的示例/演示或文档。
我尝试用以下代码来运行:
    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.y = 10;
    camera.position.z = 0;
    camera.position.x = radious;
    camera.useQuaternion = true;

   // I did use the TrackballTrackballControls. Maybe it causes the problem so I put it here
    controls = new THREE.TrackballControls( camera, document.getElementById(_canvasElement) );

    // function to make the camera rotate to the object
    function focusOn3DObject(obj){  
        obj.useQuaternion = true;
        obj.quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

        var newQuaternion = new THREE.Quaternion();
        THREE.Quaternion.slerp(camera.quaternion, obj.quaternion, newQuaternion, 0.07);
        camera.quaternion = newQuaternion;
    }

但是它没有起作用。我错过了什么吗? 请帮忙。谢谢。


2
请注意,在较新的THREE.js版本中,useQuaternion已被移除。该库现在默认使用四元数。 - Drew Noakes
还要注意的是,今天(2015年8月)THREE的相机对象有一个方法.lookAt(vector3) - 它接收一个Vector3,其中包含要查看的对象的位置。您可以将任何object3d.position作为参数传递,以便相机查看它。请查看:http://threejs.org/docs/index.html#Reference/Cameras/Camera - Tiago
5个回答

18

Slerp很容易。它需要4个参数:

  • targetRotation 实际相机旋转
  • destinationRotation 物体旋转
  • destinationRotation 新的四元数将成为新的相机旋转
  • percentOfRotation 这个参数是玩具,我现在使用0.07,可以是0(0%)到1(100%)之间的值

这是我的旋转方法:

var qm = new THREE.Quaternion();
THREE.Quaternion.slerp(camera.quaternion, destRotation, qm, 0.07);
camera.quaternion = qm;
camera.quaternion.normalize();

希望这能帮到你。不用担心,我也花了几个星期来完善相机跟随的效果。


嗨,在文档中,.slerp 只有 2 个参数... https://threejs.org/docs/#Reference/Math/Quaternion...我有什么误解吗? - TOPKAT
@SébastienGarcia-Roméo,Quaternion中有两种slerp方法--此答案中使用的是静态方法。这两种方法都列在quaternion文档页面上,但静态方法在底部。 - Matthias

3
您可以使用ThreeJs中的applyQuaternion方法。
 const quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

 camera.applyQuaternion(quaternion); // Apply Quaternion

 camera.quaternion.normalize();  // Normalize Quaternion

2
我认为这行代码不起作用:
obj.quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

您需要设置。
obj.useQuaternion = true

将对象添加到场景后,旋转时会自动应用于obj.quaternion

第二点是应该将对象应用于控制器而不是相机。因为您想控制的是对象而不是相机?


我想让摄像头旋转并聚焦于物体上。摄像头将围绕着这个物体移动。所以我认为摄像头会被控制。我的理解是否正确? - user1533481
似乎我在黑暗中寻找,因为没有关于这个的文档或示例 :(。能否请您解释一下函数slerp?它的参数是什么?我尝试了您的建议,但没有成功。 - user1533481
6
请注意,在较新的THREE.js版本中,useQuaternion已被移除。该库现在默认使用四元数。 - Drew Noakes

1
这是我的做法:
  1. 获取摄像机的当前四元数(initialQuaternion)
  2. 创建摄像机的克隆
  3. 使用lookAt方法使克隆朝向目标
  4. 问题在于,摄像机的lookAt方法实际上会使其背离目标,因此您有两个选择:
  • 直接使用lookAt方法,然后反转旋转
  • 或计算目标应该具有的位置,以便当从其背面观看时,您实际上朝向正确的方向
  1. 获取克隆的新四元数(targetQuaternion)
  2. 通过使用动画循环,在initialQuaternion和targetQuaternion之间进行slerp插值

0

我已经尝试使用它:

    var newQuaternion = new THREE.Quaternion();
        THREE.Quaternion.slerp(camera.quaternion, obj.quaternion, newQuaternion, 0.01);
        camera.quaternion = newQuaternion;
        camera.quaternion.normalize();
        camera.matrixAutoUpdate();

然而,我未能获得期望的结果。我知道这是一个相当旧的帖子,但如果有人能回应,我会很高兴。除了这篇文章,我没有看到其他相关的帖子,所以真的希望有人能回应。

以下是我的问题详细描述:在three.js中旋转相机以查看所选对象


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