three.js rotate camera in plane

倖福魔咒の 提交于 2019-12-21 20:01:31

问题


I have a camera in my app:

camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.z = 1;
camera.position.y = -5;
camera.rotateOnAxis(new THREE.Vector3(1, 0, 0), degInRad(90));
camera.up = new THREE.Vector3(0, 0, 1);  

Those code in render function must rotate the camera while I'm pressing the keys:

if (leftPressed) {
    camera.rotateOnAxis((new THREE.Vector3(0, 1, 0)).normalize(), degInRad(1));
} else if (rightPressed) {
    camera.rotateOnAxis((new THREE.Vector3(0, 1, 0)).normalize(), degInRad(-1));
}
if (upPressed) {
    camera.rotateOnAxis((new THREE.Vector3(1, 0, 0)).normalize(), degInRad(1));
} else if (downPressed) {
    camera.rotateOnAxis((new THREE.Vector3(1, 0, 0)).normalize(), degInRad(-1));
}  

Camera rotates, but not in way I need. I want that camera rotates like in FPS (first person shooter) on plane. See picture to understand what I want...
I'm try to use sin(1) and cos(1) but can't understand how rotateOnAxis works, cause translate functions work like a charm and moves camera in direction in what she sees.
P.S.
Here is a docs to the three.js maybe it helps.
To handle keyboard events I use KeyboardJS
And here is a degInRad function:

function degInRad(deg) {
    return deg * Math.PI / 180;
}  

Link on JSFiddle

O - position of camera
O-O1 - current camera direction
R1 - current rotation direction
R - direction what I want
Sorry for good picture.


回答1:


You might get what you want simply by setting camera.rotation.order = 'YXZ';




回答2:


believe what your looking for conceptually is a camera rig setup. In this approach you first build an Object3D to be the "neck", then attach the camera to that object with your desired rotation. Then you can apply the rotations to the Object3D to look around without the wobble effect. To carry it further you could nest that "neck" object in another Object3D to act as the "body" and apply the translations to that object to move about the scene. In this way you have a basic camera controller rig. I modified your fiddle like so:

Edit: implementation change to better suit @ostapische use case. Here's the fiddle link

function degInRad(deg) {
    return deg * Math.PI / 180;
}
/////////////////////////////////
function render() {
    requestAnimationFrame(render);
    if (leftPressed) {
        neck.rotation.y += degInRad(1);
    } else if (rightPressed) {
        neck.rotation.y -= degInRad(1);
    }
    if (upPressed) {
        camera.rotation.x += degInRad(1);
    } else if (downPressed) {
        camera.rotation.x -= degInRad(1);
    }
    renderer.render(scene, camera);
}
/////////////////////////////////
var scene, camera, renderer, grass, neck;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
/////////////////////////////////
window.onload = function() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    cameraHolder = new THREE.Object3D();
    cameraHolder.add( camera );
    renderer = new THREE.WebGLRenderer();
    renderer.rendererSize = {width: window.innerWidth, height: window.innerHeight, quality: 100, maxQuality: 400, minQuality: 20};
    renderer.setSize( renderer.rendererSize.width, renderer.rendererSize.height );
    document.body.appendChild( renderer.domElement );

    var texture, material, geometry, element;

    material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    material.side = THREE.DoubleSide;
    geometry = new THREE.PlaneGeometry(24, 24);   
    grass = new THREE.Mesh( geometry, material );
    grass.name = "grass";
    scene.add( grass );

    neck = new THREE.Object3D();
    neck.rotateOnAxis(new THREE.Vector3(1, 0, 0), degInRad(90));
    neck.up = new THREE.Vector3(0, 0, 1);
    neck.position.z = 1;
    neck.position.y = -5;


    neck.add(camera);
    scene.add(neck);    

    KeyboardJS.on('left', function() { leftPressed = true; }, function() { leftPressed = false; });
    KeyboardJS.on('right', function() { rightPressed = true; }, function() { rightPressed = false; });
    KeyboardJS.on('up', function() { upPressed = true; }, function() { upPressed = false; });
    KeyboardJS.on('down', function() { downPressed = true; }, function() { downPressed = false; });

    render();
}

I was going to mention the PointLockControl or FirstPersonControl, but I see WestLangley has been so kind to suggest. Anyway good luck,



来源:https://stackoverflow.com/questions/18834178/three-js-rotate-camera-in-plane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!