I want to use the camera like human eyes.
The human being should walk (e.g. also backwards without turning around) in a limited space and also tilt his head.
Although I created a Quaternion data visualization, I could not solve this with this technique.
https://discourse.threejs.org/t/quaternion-axis-angle-visualization/1358
During the search I did not find a suitable solution for me.
With the elements
viewPoint = new THREE.Vector3( … );
camera.lookAt( viewPoint );
I’ve made a simple solution.
http://threejs.hofk.de/fiddle/camera_fiddle.html
(Use w s a d l r t b uparrow down arrow, moving with the mouse can be easily added to.)
Since it’s jerking, TWEEN must be added. For example like there: http://jsfiddle.net/prisoner849/r9vzm1uf/
As a room I took a skybox from Emil Persson.
http://www.humus.name/index.php?page=Textures&start=32
(Creative Commons License Attribution 3.0)
I don’t quite like my solution myself.
Question.
Is there a better solution somewhere,
or what should I change in my solution?
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title> eye camera </title>
<style> </style>
</head>
<body ></body>
<script src="three.min.92.js"></script>
<script src="THREEx.WindowResize.js"></script>
<script> 'use strict'
var scene = new THREE.Scene( );
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.001, 10000 );
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
var container = document.createElement('div');
document.body.appendChild( container );
container.appendChild( renderer.domElement );
THREEx.WindowResize( renderer, camera );
var speed = 0.88; // In this demo constant.
var phi = 0;
var theta = 0;
var viewR0 = 80;
var viewR = viewR0;
var viewDir = new THREE.Vector2( );
var scout = new THREE.Object3D( );
camera.position.set( 0, 1.5 , 0 ); // height of human eyes
var viewPoint = new THREE.Vector3( 0, 1.5, -viewR0 );
camera.lookAt( viewPoint );
document.addEventListener( 'keydown', function( evt ) {
if ( evt.keyCode === 87 ) { if ( withinBorders( moveForward ) ) moveForward( camera ) } // w fast vorward
if ( evt.keyCode === 83 ) { if ( withinBorders( moveBack ) ) moveBack( camera ) } // s backward a little slower
if ( evt.keyCode === 65 ) { if ( withinBorders( moveLeft ) ) moveLeft( camera ) } // a slowly leftwards
if ( evt.keyCode === 68 ) { if ( withinBorders( moveRight ) ) moveRight( camera ) } // d slowly rightwards
if ( evt.keyCode === 76 ) { turnLeft( camera ) } // l turn to the left
if ( evt.keyCode === 82 ) { turnRight( camera ) } // r turn to the right
if ( evt.keyCode === 84 ) { goTop( camera ) } // t upstretch
if ( evt.keyCode === 66 ) { goBottom( camera ) } // b bend down
if ( evt.keyCode === 38 ) { lookUp( camera ) } // up arrow, looking higher
if ( evt.keyCode === 40 ) { lookDown( camera ) } // down arrow, looking deeper
});
var texturArray = [ 'CubeMap/', 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg'];
var skyboxTexture = new THREE.CubeTextureLoader( ).setPath( texturArray[ 0 ] ).load( [
texturArray[ 1 ],
texturArray[ 2 ],
texturArray[ 3 ],
texturArray[ 4 ],
texturArray[ 5 ],
texturArray[ 6 ]
] );
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = skyboxTexture;
var shMaterial = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
side: THREE.BackSide
} );
var surroundings = new THREE.Mesh( new THREE.BoxBufferGeometry( 10 * viewR0, 10 * viewR0, 10 * viewR0 ), shMaterial );
surroundings.position.set( 0 , 10, 0 );
scene.add( surroundings );
animate();
// ...................
function animate( ) {
requestAnimationFrame( animate );
camera.lookAt( viewPoint );
renderer.render( scene, camera );
}
function turnRight( obj ) {
phi -= 0.006 * speed;
viewPoint.x = obj.position.x - Math.sin( phi ) * viewR;
viewPoint.z = obj.position.z - Math.cos( phi ) * viewR;
}
function turnLeft( obj ) {
phi += 0.006 * speed;
viewPoint.x = obj.position.x - Math.sin( phi ) * viewR;
viewPoint.z = obj.position.z - Math.cos( phi ) * viewR;
}
function moveForward( obj ) {
viewDir.x = -Math.sin( phi );
viewDir.z = -Math.cos( phi );
move( obj, viewDir, 4 );
}
function moveRight( obj ) {
viewDir.x = Math.cos( phi );
viewDir.z = -Math.sin( phi );
move( obj, viewDir, 1.2 );
}
function moveLeft( obj ) {
viewDir.x = -Math.cos( phi );
viewDir.z = Math.sin( phi );
move( obj, viewDir, 1.2 );
}
function moveBack( obj ) {
viewDir.x = Math.sin( phi );
viewDir.z = Math.cos( phi );
move( obj, viewDir, 2 );
}
function goTop( obj ) {
if ( obj.position.y < viewR0 / 4) {
obj.position.y += 0.6 * speed;
viewPoint.y = obj.position.y + Math.sin( theta ) * viewR0;
}
}
function goBottom( obj ) {
if ( obj.position.y > 1 ) {
obj.position.y -= 0.6 * speed;
viewPoint.y = obj.position.y + Math.sin( theta ) * viewR0;
}
}
function lookDown( obj ) {
if ( theta > -1.45 ) {
theta -= 0.01 * speed;
viewR = Math.cos( theta ) * viewR0;
viewPoint.x = obj.position.x - Math.sin( phi ) * viewR;
viewPoint.y = obj.position.y + Math.sin( theta ) * viewR0;
viewPoint.z = obj.position.z - Math.cos( phi ) * viewR;
}
}
function lookUp( obj ) {
if ( theta < 1.45 ) {
theta += 0.01 * speed;
viewR = Math.cos( theta ) * viewR0;
viewPoint.x = obj.position.x - Math.sin( phi ) * viewR;
viewPoint.y = obj.position.y + Math.sin( theta ) * viewR0;
viewPoint.z = obj.position.z - Math.cos( phi ) * viewR;
}
}
function move( obj, viewDir, factor ) {
obj.position.x += viewDir.x * factor * speed;
obj.position.z += viewDir.z * factor * speed;
viewPoint.x = obj.position.x - Math.sin( phi ) * viewR;
viewPoint.z = obj.position.z - Math.cos( phi ) * viewR;
}
function withinBorders( moveFunction ) {
scout.position.x = camera.position.x;
scout.position.z = camera.position.z;
moveFunction( scout );
// Here a simple circle. Uniting of figures is possible.
return Math.sqrt( scout.position.x * scout.position.x + scout.position.z * scout.position.z ) < 200;
}
</script>
</html>