three.js rotate camera in plane
Solution 1
You might get what you want simply by setting camera.rotation.order = 'YXZ';
Solution 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,
ostapische
Updated on September 18, 2020Comments
-
ostapische over 3 years
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 usesin(1)
andcos(1)
but can't understand howrotateOnAxis
works, causetranslate
functions work like a charm and moves camera in direction in what she sees.
P.S.
Here is a docs to thethree.js
maybe it helps.
To handle keyboard events I use KeyboardJS
And here is adegInRad
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.