简体   繁体   English

如何在 three.js 中的相机 object 的四元数之间来回切换?

[英]How do I slerp back and forth between quaternions for camera object in three.js?

I don't understand why my camera doesn't slerp back.我不明白为什么我的相机不向后倾斜。 When I refresh the page, it slerps once.当我刷新页面时,它会出现一次。 Then after that, it doesn't do anything if I move my mousewheel.然后在那之后,如果我移动鼠标滚轮它什么也不会做。 I expect it to slerp back forward (as I scroll up and down) between the x quaternions.我希望它会在 x 四元数之间向后倾斜(当我上下滚动时)。

export default class Experience {
    constructor(options = {}) {
    //...
        this.camera = new Camera();
        this.renderer = new Renderer(this.canvas);
        this.scrollTargetPosition = new THREE.Quaternion();
        this.scrollTargetPosition.setFromAxisAngle(new THREE.Vector3(0, 0, 1),0);


        this.onMouseScroll();
        this.animate();
    }

    onMouseScroll() {
        window.addEventListener("wheel", (event) => {
            if (event.wheelDelta > 0) {
                this.scrollTargetPosition.x = 0;
            } else {
                this.scrollTargetPosition.x = Math.PI / 2;
            }
        console.log("Target: " + this.scrollTargetPosition.x); //Pictures below
        console.log("Camera: " + this.camera.quaternion.x);
        });
    }

    animate() {
        this.camera.quaternion.slerp(this.scrollTargetPosition, 0.9);
        requestAnimationFrame(this.animate.bind(this));
        this.renderer.render(this.scene, this.camera);

    }
}

Here's what the console.log's look like if I scroll up a bunch of times:如果我向上滚动很多次,这就是 console.log 的样子: 在此处输入图像描述

and if I scroll down:如果我向下滚动:

在此处输入图像描述

The main problem is that you're treating a Quaternion as if it were Euler angles , and they are hugely different.主要问题是您将四元数视为欧拉角,它们有很大的不同。

Quaternion.x is not the x-axis rotation in radians. Quaternion.x不是以弧度表示的 x 轴旋转。 Quaternions are made up of a 4-dimensional combination of imaginary and real numbers , so its x, y, z, w properties are better left alone.四元数由虚数和实数的 4 维组合组成,因此最好不要管它的x, y, z, w属性。 Instead, use the utility methods that performs the task you need.相反,请使用执行所需任务的实用程序方法。 The method below sets the x-axis rotation to 0 or 90 degrees:下面的方法将 x 轴旋转设置为 0 或 90 度:

onMouseScroll() {
    let xAxis = new THREE.Vector3(1, 0, 0);

    window.addEventListener("wheel", (event) => {
        if (event.wheelDelta > 0) {
            this.scrollTargetPosition.setFromAxisAngle(xAxis, 0);
        } else {
            this.scrollTargetPosition.setFromAxisAngle(xAxis, Math.PI / 2);
        }
    });
}

After that, you should be able to perform your spherical interpolation as expected, however I recommend you replace the 0.9 with a smaller number like 0.1 , otherwise it'll pop into place too quickly:之后,您应该能够按预期执行球面插值,但是我建议您将0.9替换为较小的数字,例如0.1 ,否则它会很快就位:

this.camera.quaternion.slerp(this.scrollTargetPosition, 0.9);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM