【问题标题】:3D camera X axis rotation3D相机X轴旋转
【发布时间】:2017-07-23 00:11:19
【问题描述】:

我完全不知道如何解释这个问题,因为如果你看一下我制作的以下视频,它是不言自明的。

没有角度 - https://www.youtube.com/watch?v=R_GtaXWpP9c&feature=youtu.be

角度 - https://www.youtube.com/watch?v=RoaZMccGYGo&feature=youtu.be

正如您在无角度版本中看到的,您可以完全正常地旋转 Y 轴,但是当您控制 X 轴(如“角度”视频中所示)时,您会以一种奇怪的方式旋转,这是有道理的。正如您可能已经猜到的那样,我希望 X 轴保持不变,而 Y 轴保持从左到右移动,我不希望 Y 轴从正变为负。

我希望这是有道理的,希望有一个很好的解释,我可能错过了一个包含所有公式的网站,但我不确定“问题”被称为什么。

我的旋转脚本的一些代码:

var pressed = [0,0,0,0,0,0,0,0];
function update() {
    $('#w').html(pressed);
}
setInterval(update, 100);
$(document).keydown(function(evt) {
    if (evt.which == 87) {
        pressed[0] = 1;
    }
    if(evt.which == 68) {
        pressed[1] = 1;
    }
    if(evt.which == 65) {
        pressed[2] = 1;
    }
    if(evt.which == 83) {
        pressed[3] = 1;
    }
    if(evt.which == 39) {
        pressed[4] = 1;
    }
    if(evt.which == 37) {
        pressed[5] = 1;
    }
    if(evt.which == 38) {
        pressed[6] = 1;
    }
    if(evt.which == 40) {
        pressed[7] = 1;
    }
    //console.log(evt.which);
});
$(document).keyup(function(evt) {
    if (evt.which == 87) {
        pressed[0] = 0;
    }
    if(evt.which == 68) {
        pressed[1] = 0;
    }
    if(evt.which == 65) {
        pressed[2] = 0;
    }
    if(evt.which == 83) {
        pressed[3] = 0;
    }
    if(evt.which == 39) {
        pressed[4] = 0;
    }
    if(evt.which == 37) {
        pressed[5] = 0;
    }
    if(evt.which == 38) {
        pressed[6] = 0;
    }
    if(evt.which == 40) {
        pressed[7] = 0;
    }
});
function check_pressed() {
    if(pressed[0] == 1){
        camera.position.z = camera.position.z - 0.1;
    }
    if(pressed[1] == 1){
        camera.position.x = camera.position.x + 0.1;
    }
    if(pressed[2] == 1){
        camera.position.x = camera.position.x - 0.1;
    }
    if(pressed[3] == 1){
        camera.position.z = camera.position.z + 0.1;
    }
    if(pressed[4] == 1){
        if(camera.rotation.y <= Math.PI * -2) {
            camera.rotation.y = 0;
        } else {
            camera.rotation.y -= 0.03;
        }
    }
    if(pressed[5] == 1){
        if(camera.rotation.y >= Math.PI * 2) {
            camera.rotation.y = 0;
        } else {
            camera.rotation.y += 0.03;
        }
    }
    if(pressed[6] == 1){
        if(camera.rotation.x >= 0.5) {
            camera.rotation.x = 0.5;
        } else {
            camera.rotation.x += 0.01;
        }
    }
    if(pressed[7] == 1){
        if(camera.rotation.x <= 0) {
            camera.rotation.x = 0;
        } else {
            camera.rotation.x -= 0.01;
        }
    }

}
setInterval(check_pressed, 20);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
	<head>
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
			canvas { width: 100%; height: 100% }
		</style>
	</head>
	<body>
		<script src="https://threejs.org/build/three.js"></script>
		<script src="js/jquery-3.1.1.min.js"></script>
		<script src="js/movement.js"></script>
		<script>
			var cubes = [];
            var geometry = new THREE.BoxGeometry( 1, 1, 1 );
            //var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );

			var scene = new THREE.Scene();
			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

			var renderer = new THREE.WebGLRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

            for(i = 0; i < 4; i++) {
                if(i == 0) {
                    material = new THREE.MeshBasicMaterial( { color: 0x63AEDB } );
				} else {
                    material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
				}
                cubes[i] = new THREE.Mesh( geometry, material );
                scene.add( cubes[i] );
            }
            cubes[1].position.x = -2;
            cubes[1].position.z = 2;
            cubes[2].position.x = 2;
            cubes[2].position.z = 2;
            cubes[3].position.z = 4;
			camera.position.z = 2;
			camera.rotation.y = 0;
			//console.log(camera.rotation.x);
			var render = function () {
				requestAnimationFrame( render );

				//cubes[1].rotation.x += 0.00;
				//cube.rotation.y += 0.01;

				renderer.render(scene, camera);
				
			};
			render();
		</script>
	</body>
</html>

【问题讨论】:

  • 你如何旋转你的相机?你有一些代码要显示吗?
  • 这里有完整的代码。我做了一个小系统,它可以检查你是否按住按钮,这就是为什么这么小的系统有这么多代码......我还对你能走多远等做了一些限制。
  • stackoverflow.com/questions/32157515/…。进行实验,直到您了解欧拉角在 three.js 中的工作原理。

标签: camera three.js


【解决方案1】:

您正在在自己的坐标系中旋转相机

camera.rotation.x(或z)不为0 时,y 轴被变换,不再指向上方。这就解释了为什么旋转行为异常。

如果您希望您的 y 轴位于世界坐标系中,您可以添加一个 THREE.Object3D 作为 轴心点 作为您的父级camera.

var pivot = new THREE.Object3D();
scene.add(pivot);
pivot.add(camera);

现在,您相机的rotation.ypivot 控制:

pivot.rotation.y += 0.03;

...position 也是如此:

pivot.position.z = 2.0;

我在this fiddle 上更新了你的代码。

【讨论】:

  • 谢谢,很好的解释,您也花时间进行修复,这太棒了!我一定会自己做这个修复,这样我就可以从中学习:D
  • 谢谢,但您应该选择WestLangley 提出的解决方案;)
  • 是的,无论如何感谢您的帮助并花时间编辑代码和制作图片等!
  • 别担心,这是一种享受
【解决方案2】:

不需要枢轴。解决您的问题的简单方法是设置

camera.rotation.order = 'YXZ'; // the default is 'XYZ'

然后,相机的旋转将按照您的预期进行。

更多信息请参见this answer

更新小提琴:https://jsfiddle.net/07g07uLa/1/

注意,小提琴中没有枢轴,也不需要将相机添加到场景中。

three.js r.84

【讨论】:

  • 也谢谢你,我给了你最好的答案(无意冒犯其他人)。
  • 我不知道欧拉角的 order 属性,谢谢! :)
猜你喜欢
  • 2012-07-23
  • 2016-09-22
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
相关资源
最近更新 更多