gpt4 book ai didi

javascript - 第一人称视角旋转不起作用

转载 作者:行者123 更新时间:2023-12-03 01:10:05 25 4
gpt4 key购买 nike

相机无法正常旋转。当我在x轴y轴上移动鼠标时,相机似乎会翻转。我是 two.js 的新手,对该界面不太了解。

Camera rotation

我见过mrdoob的点锁控件,但我不明白如何使用两个单独的对象来控制偏航和俯仰。我认为他为此使用了两个物体。还有其他不同的方法吗?

<!DOCTYPE html>
<html>

<head>
<title>THREEJS</title>
<style>
body {
margin: 0;
}
</style>
</head>

<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.js"></script>
<script type="text/javascript">
let width = innerWidth
let height = innerHeight

let scene = new THREE.Scene()
let camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)

let renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.body.appendChild(renderer.domElement)

let cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({
color: 0xFFFFFF,
wireframe: false
}))
let plane = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10, 10, 10),
new THREE.MeshLambertMaterial({
color: 0x00FF00,
wireframe: false
}))
let light = new THREE.PointLight(0xFFFFFF, 1.5, 15)

plane.rotation.set(-Math.PI / 2, 0, 0)
cube.position.set(0, 1, 0)
light.position.set(0, 10, 0)

scene.add(cube)
scene.add(plane)
scene.add(light)

addEventListener("resize", () => {
width = innerWidth
height = innerHeight
renderer.setSize(width, height)
camera.aspect = width / height
camera.updateProjectionMatrix()
})

camera.position.set(0, 1, 2)

renderer.domElement.onclick = () =>
renderer.domElement.requestPointerLock()
document.addEventListener('pointerlockchange', lockChangeAlert, false);
document.addEventListener('mozpointerlockchange', lockChangeAlert, false);

function updatePosition(event) {
let {
movementX,
movementY
} = event
let rotateSpeed = 0.002
camera.rotation.y -= movementX * rotateSpeed
camera.rotation.x -= movementY * rotateSpeed

camera.rotation.x = Math.max(-Math.PI / 2, Math.min(camera.rotation.x, Math.PI / 2))
}

function lockChangeAlert() {

if (document.pointerLockElement == renderer.domElement) {
document.addEventListener("mousemove", updatePosition, false)
} else {
document.removeEventListener("mousemove", updatePosition, false)
}
}

let keys = {}

function keyDown(event) {
keys[event.key] = true
}

function keyUp(event) {
delete keys[event.key]
}

document.onkeydown = keyDown
document.onkeyup = keyUp

function update() {
let moveSpeed = 0.05

cube.rotation.x += 0.01
cube.rotation.y += 0.01

if (keys["w"]) {
camera.position.x -= Math.sin(camera.rotation.y) * moveSpeed
camera.position.z -= Math.cos(camera.rotation.y) * moveSpeed
}
if (keys["s"]) {
camera.position.x += Math.sin(camera.rotation.y) * moveSpeed
camera.position.z += Math.cos(camera.rotation.y) * moveSpeed
}

if (keys["d"]) {

}
if (keys["a"]) {

}


}

function draw() {
renderer.render(scene, camera)
}

function loop() {
update()
draw()

requestAnimationFrame(loop)
}

loop()
</script>
</body>

</html>

最佳答案

它使用 2 个对象的原因是因为您所描述的问题,称为“万向节锁”。

对于一个对象,根据旋转的串联顺序,您将在一个轴上进行旋转,从而锁定另一个轴上的旋转或导致另一个轴翻转。

有一个rotation.order参数,你可以使用它来解决这个问题(例如rotation.order ='YZX',或'ZYX'而不是标准的'XYZ',但这使得你的旋转有不同的比管道的其余部分“顺序”,因此有时更优雅但效率稍低的方法是仅使用 2 个单独的对象,一个用于俯仰,一个用于偏航。另一种解决方案是使用不继承问题的四元数万向节锁。

万向节锁是一个有趣的问题,有着有趣的历史。

https://en.wikipedia.org/wiki/Gimbal_lock

关于javascript - 第一人称视角旋转不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52235224/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com