javascript Three.js相机旋转顺序

py49o6xq  于 2023-11-15  发布在  Java
关注(0)|答案(3)|浏览(136)

我正在尝试使用游戏手柄在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);
    }
}

字符串

bvjxkvbb

bvjxkvbb1#

PointerLockControls使用的方法是创建对象的层次结构:yawObject包含pitchObject包含camera。然后水平鼠标(或操纵杆)移动将改变偏航对象的Y旋转,垂直鼠标(或操纵杆)移动将改变俯仰对象的X旋转,相机的旋转将保持固定在默认的(0, 0, -1)。这只是手动模拟Euler YXZ排序,但它可能更适合你。如果你需要获得整体旋转,它确实会产生一些尴尬。
在我最近编写的一个自定义控制器中,我通过将相机add()设置为单个父对象并将父对象的Euler阶数设置为YXZ来实现相同的结果。我不记得为什么这比直接在相机上设置更好,但确实如此。

30byixjq

30byixjq2#

我自己也遇到了这个问题,我想出了一个简单的解决方案。在执行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;
}

字符串

hlswsv35

hlswsv353#

我按了每个按钮直到它工作这是它弹出的代码

var controlers = [];
controlers[0] = 0;
controlers[1] = 0;
controlers[2] = 0;
controlers[3] = 0;
controlers[4] = 0;
controlers[5] = 0;
controlers[6] = 0;
controlers[7] = 0;      
let controllerIndex = null;

window.addEventListener("gamepadconnected", (event) => {
  const gamepad = event.gamepad;
  controllerIndex = gamepad.index;
  console.log("connected");
});

window.addEventListener("gamepaddisconnected", (event) => {
  controllerIndex = null;
  console.log("disconnected");
});

function handleButtons(buttons) {
  for (let i = 0; i < buttons.length; i++) {
    const button = buttons[i];
    const buttonElement = document.getElementById(`controller-b${i}`);
    const selectedButtonClass = "selected-button";

    if (buttonElement) {
      if (button.value > 0) {
        buttonElement.classList.add(selectedButtonClass);
        buttonElement.style.filter = `contrast(${button.value * 150}%)`;
      } else {
        buttonElement.classList.remove(selectedButtonClass);
        buttonElement.style.filter = `contrast(100%)`;
      }
    }
  }
}


function updateStick(elementId, leftRightAxis, upDownAxis) {
  const multiplier = 25; 
  const stickLeftRight = leftRightAxis;
  const stickUpDown = upDownAxis;

 


camera.object = camera;
    camera.target = new THREE.Vector3( 0, 0, 0  );

    

    camera.mouseX = 0;
    camera.mouseY = 0;

    camera.lat =  0;
    camera.lon =  360;
    camera.phi = 0;
    camera.theta = 0;

    

        
    



            controlers[4] =  (stickLeftRight   )  ;
            controlers[5] = (stickUpDown ) ;


camera.lon += stickLeftRight * 10 ;
              camera.lat -= stickUpDown * 10  ; // * this.invertVertical?-1:1;

            camera.lat = Math.max( -15, Math.min( 15, camera.lat ) );
            camera.phi = ( 90 - camera.lat ) * Math.PI / 180;
            camera.theta = camera.lon * Math.PI / 360;

            var targetPosition = camera.target,
            position = camera.object.position;

        targetPosition.x = position.x + 100 * Math.cos( camera.theta );
        targetPosition.y = position.y + 200 * Math.cos( camera.phi );
        targetPosition.z = position.z + 100 * Math.sin( camera.phi ) * Math.sin( camera.theta );

var stickLeftRight_a = ( (stickLeftRight) * 100);

var stickUpDown_a = ( (stickUpDown) * 100);

if( stickLeftRight_a < -87 || stickLeftRight_a > 87 || stickUpDown_a < -87 || stickUpDown_a > 87  ){ 
    

if( stickLeftRight_a > -87 && stickLeftRight_a < 87 ){
camera.lon += stickLeftRight  ;
              camera.lat -= stickUpDown ; // * tstickLeftRight_as.invertVertical?-1:1;

            camera.lat = Math.max( -15, Math.min( 15, camera.lat ) );
            camera.phi = ( 90 - camera.lat ) * Math.PI / 180;
            camera.theta = camera.lon * Math.PI / 360;

            var targetPosition = camera.target,
            position = camera.object.position;

        targetPosition.x = position.x + 100 * Math.cos( camera.theta );
        targetPosition.y = position.y + 200 * Math.cos( camera.phi );
        targetPosition.z = position.z + 100 * Math.sin( camera.phi ) * Math.sin( camera.theta );
camera.lookAt(targetPosition);

}



if(  stickLeftRight_a > 87 ){
controlers[6] = controlers[6] + 0.01;

if( controlers[6] > 360 ){
 controlers[6] = 0;

}
camera.rotation.y -= controlers[6];

camera.rotation.z = 0 ;

camera.rotation.x = 0 ;
}
if( stickLeftRight_a < -87 ){

controlers[6] = controlers[6] - 0.01;
if( controlers[6] < 0 ){
 controlers[6] = 360;

}
camera.rotation.y += controlers[6];
camera.rotation.z = 0 ;

camera.rotation.x = 0 ;

}
}
}                       
}
}

function handleSticks(axes) {
  updateStick("controller-b10", axes[0], axes[1]);
  updateStick("controller-b11", axes[2], axes[3]);
}

function gameLoop() {
  if (controllerIndex !== null) {
    const gamepad = navigator.getGamepads()[controllerIndex];
    handleButtons(gamepad.buttons);
    handleSticks(gamepad.axes);
  }
  requestAnimationFrame(gameLoop);
}

gameLoop();

字符串

相关问题