【问题标题】:Three.js camera rotation order三.js相机旋转顺序
【发布时间】:2013-09-10 09:45:31
【问题描述】:

我正在尝试使用游戏手柄在 Three.js 中旋转相机,使用第一人称射击风格的控件。

浏览器检测到游戏手柄并识别它的输入,但相机的旋转顺序错误。当我在相机的局部 Y 轴上旋转时,它也会考虑到局部 X 旋转,这是不需要的。

看来我和this guy 遇到了同样的问题,但他的问题是使用 Three.js r54 解决的,而我使用的是 r60。他设置了camera.eulerOrder = "YXZ"; 以使其正常工作,但当前等效的camera.rotation.order = "YXZ"; 似乎对我不起作用。

我知道 Three.js 的内置“FirstPersonControls”类,但它不适合我,因为它不接受控制器输入,而且以后在其中塞入其他非移动控件会很麻烦。我也知道 gamepad.js 并且没有兴趣使用它。

谁能帮忙?

我的轮换代码:

function pollGamepad()
{
    gamepad = navigator.webkitGetGamepads()[0];

    //Rotation
    if(gamepad.axes[3] > 0.20)
    {
        camera.rotateX(-gamepad.axes[3] * 0.02);
    }
    if(gamepad.axes[3] < -0.20)
    {
        camera.rotateX(-gamepad.axes[3] * 0.02);
    }

    if(gamepad.axes[2] < -0.20)
    {
        camera.rotateY(-gamepad.axes[2] * 0.02);
    }
    if(gamepad.axes[2] > 0.20)
    {
        camera.rotateY(-gamepad.axes[2] * 0.02);
    }
}

【问题讨论】:

    标签: javascript rotation three.js euler-angles gamepad-api


    【解决方案1】:

    PointerLockControls 使用的方法是创建对象层次结构:yawObject 包含 pitchObject 包含 camera。然后水平鼠标(或操纵杆)移动将改变偏航对象的 Y 轴旋转,垂直鼠标(或操纵杆)移动将改变俯仰对象的 X 轴旋转,并且相机的旋转将保持默认(0, 0, -1) .这只是手动模拟 Euler YXZ 排序,但它可能对您更有效。如果您需要获得整体轮换,它确实会造成一些尴尬。

    在我最近编写的一个自定义控制器中,我通过add()将相机设置为单个父对象并将父对象的欧拉顺序设置为YXZ,实现了相同的结果。我不记得为什么这比直接在相机上设置效果更好,但确实如此。

    【讨论】:

    • 感谢 Icemonster,这帮助很大。
    • 我只是将我的相机放在一个父对象中,并对其应用所有平移和偏航,然后将任何俯仰应用于相机本身,这似乎工作得很好,同时保持一切简单。跨度>
    • 谢谢!!!我正在努力旋转我的 yawObject(自 3 天以来)。我使用了 PointerLockControls,我的相机是一个“锚”对象(一个简单的 3D 对象)的父对象,因此每当我移动鼠标时,对象都会随着我的相机围绕它旋转而旋转。然后我为 WASD 动作添加了按键事件,并在 requestAnimationFrame() 中更新了角色网格的位置。所以现在当我尝试在按下 WASD 键的同时沿 Y 旋转我的角色网格时,我无法旋转超出这个范围(-90 到 90)。我的角色正面临一个万向节锁。所以我改变了我的锚的欧拉顺序
    • 另外,在较新版本的三个js中,object.eulerOrder设置为object.rotation.order
    【解决方案2】:

    我自己也遇到过这个问题,我想出了一个简单的解决方案。在执行 y 旋转之前,始终将相机的 x 旋转重置为零。然后,恢复 x 旋转。所以:

    // Rotate camera Fps style
    function rotateCamera(dx,dy){
        //store previous x rotation
        var x = camera.rotation.x;
    
        //reset camera's x rotation.
        camera.rotateX(-x);
    
        //rotate camera on y axis
        camera.rotateY(dy);
    
        //check if we are trying to look to high or too low
        if ( Math.abs( dx + x ) > Math.Pi/2 - 0.05) {
            camera.rotateX(x);
        else
            camera.rotateX(x+dx);
    
        //reset z rotation. Floating point operations might change z rotation during the above operations.
        camera.rotation.z = 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-22
      • 2015-01-30
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 2021-01-01
      • 2012-10-24
      • 2012-07-24
      相关资源
      最近更新 更多