THREE.js:需要帮助旋转四元数

时间:2014-01-24 08:26:17

标签: javascript camera rotation three.js quaternions

我希望了解three.js的四元数,但对于所有教程,我无法将它们转换为我需要的应用程序。这就是问题所在:

给定一个以(0,0,0)为中心的球体,我想在球体表面上对一个物体进行角度,该物体充当相机的焦点。使用键盘输入在曲面上移动和旋转此点。 将焦点设置到选定的轨道当然很容易,但是保持垂直于表面的正确旋转逃离了我。我知道四元数对于平滑运动和任意轴旋转是必要的,但我不知道从哪里开始。

然后第二部分用焦点旋转相机偏移。我找到的片段不再具有所需的效果,因为cameraOffset不会继承旋转:

var cameraOffset = relativeCameraOffset.clone().applyMatrix4( focalPoint.matrixWorld );
camera.position.copy( focalPoint.position.clone().add(cameraOffset) );
camera.lookAt( focalPoint.position );

更新1:在杆上使用固定摄像头尝试并旋转行星。但除非我遗漏了一些重要的东西,否则这也会失败,因为朝向赤道的方向完全倾斜。 (左边变成前锋)。更新中的代码是:

        acceleration.set(0,0,0);

        if (keyboard.pressed("w")) acceleration.x = 1 * accelerationSpeed;
        if (keyboard.pressed("s")) acceleration.x = -1 * accelerationSpeed;
        if (keyboard.pressed("a")) acceleration.z = 1 * accelerationSpeed;
        if (keyboard.pressed("d")) acceleration.z = -1 * accelerationSpeed;
        if (keyboard.pressed("q")) acceleration.y = 1 * accelerationSpeed;
        if (keyboard.pressed("e")) acceleration.y = -1 * accelerationSpeed;

        velocity.add(acceleration);
        velocity.multiplyScalar(dropOff);
        velocity.max(minV);
        velocity.min(maxV);

        planet.mesh.rotation.x += velocity.x;
        planet.mesh.rotation.y += velocity.y;
        planet.mesh.rotation.z += velocity.z;

所以我仍然愿意接受建议。

2 个答案:

答案 0 :(得分:4)

最后从矩阵和四元数的混合物中找到了解决方案:

    //Setup
    var ux = new THREE.Vector3(1,0,0);
    var uy = new THREE.Vector3(0,1,0);
    var uz = new THREE.Vector3(0,0,1);

    var direction = ux.clone();
    var m4 = new THREE.Matrix4();
    var dq = new THREE.Quaternion(); //direction quad base
    var dqq;   //final direction quad
    var dq2 = new THREE.Quaternion();
    dq2.setFromAxisAngle(uz,Math.PI/2); //direction perpendicular rot

        //Update
        if (velocity.length() < 0.1) return;
        if (velocity.x) { focalPoint.translateY( velocity.x ); }
        if (velocity.y) { focalPoint.translateX( velocity.y ); }
        //create new direction from focalPoint quat, but perpendicular
        dqq = dq.clone().multiply(focalPoint.quaternion).multiply(dq2);

        velocity.multiplyScalar(dropOff);
        //forward direction vector          
        direction = ux.clone().applyQuaternion(dqq).normalize();
        //use Matrix4.lookAt to align focalPoint with the direction
        m4.lookAt(focalPoint.position, planet.mesh.position, direction);
        focalPoint.quaternion.setFromRotationMatrix(m4);

        var cameraOffset = relativeCameraOffset.clone();
        cameraOffset.z = cameraDistance;

        cameraOffset.applyQuaternion(focalPoint.quaternion);

        camera.position = focalPoint.position.clone().add(cameraOffset) ;
        //use direction for camera rotation as well
        camera.up = direction;
        camera.lookAt( focalPoint.position );

这是它的核心。它围绕地球平移(并且有一些延伸旋转),而不存在极点问题。

答案 1 :(得分:1)

我不确定你的问题。 但是为了获得帮助,我在一个球体上画了一条船,下面是代码。

var geometry = new THREE.ShapeGeometry(shape);
var translation = new THREE.Matrix4().makeTranslation(boat.position.x, boat.position.y, boat.position.z);
var rotationZ = new THREE.Matrix4().makeRotationZ(-THREE.Math.degToRad(boat.cap));
var rotationX = new THREE.Matrix4().makeRotationX(-THREE.Math.degToRad(boat.latitude));
var rotationY = new THREE.Matrix4().makeRotationY(Math.PI / 2 + THREE.Math.degToRad(boat.longitude));
var roationXY = rotationY.multiply(rotationX);
geometry.applyMatrix(rotationZ);
geometry.applyMatrix(roationXY );
geometry.applyMatrix(translation);
  1. 首先,我在Z上应用旋转来定义船首
  2. 然后,我申请 旋转在Y,X上以使船垂直于表面 球体
  3. 最后我申请翻译将船放在船上 球体的surafce
  4. 轮换顺序很重要