2013-09-16 5 views
3

J'ai une caméra dans mon application:Three.js Faire pivoter la caméra dans le plan

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); 

Ceux code render fonction doit faire pivoter la caméra pendant que je suis en appuyant sur les touches:

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)); 
} 

Caméra tourne, mais pas de la manière dont j'ai besoin. Je veux que la caméra tourne comme dans FPS (First Person Shooter) dans l'avion. Voir l'image pour comprendre ce que je veux ...
Je suis d'essayer d'utiliser sin(1) et cos(1), mais je ne comprends pas comment fonctionne rotateOnAxis, car translate fonctions fonctionnent comme un charme et déplace la caméra dans la direction de ce qu'elle voit.
P.S.
Voici un docs au three.js peut-être que cela aide.
Pour gérer les événements clavier que j'utilise KeyboardJS
Et voici une fonction degInRad:

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

Lien sur JSFiddle

camera rotation

O - position de la caméra
O-O1 - direction actuelle de la caméra
R1 - direction de rotation actuelle
R - direction ce que je veux
Désolé pour bonne photo.

+0

Tenez compte, au lieu, à l'aide/modification, 'THREE.PointerLockControls'. Voir http://threejs.org/examples/misc_controls_pointerlock.html. Notez dans le code source du pointeur-verrouillage comment la caméra est ajoutée en tant qu'enfant/petit-fils de 2 objets pour obtenir l'effet souhaité. – WestLangley

+0

@WestLangley, c'est sympa, merci, mais je n'ai pas besoin de bouger la caméra avec la souris. Et 'camera' utilise uniquement dans' controls = new THREE.PointerLockControls (camera); scene.add (controls.getObject()); '- son objet interne' PointerLockControls' ajoute à la scène, pas 'camera' elle-même et dans la fonction' onWindowResize' - juste en appliquant de nouvelles propriétés, et dans 'renderer.render (scène, caméra); '- utilise ici la variable' camera' originale. À propos de quoi 'child/petitchild' Vous parlez? Je ne peux vraiment pas comprendre, pouvez-vous expliquer? Merci d'avance. – ostapische

+0

Remarquez comment 'PointerLockControls' fait tourner la caméra comme vous le souhaitez, sauf qu'elle utilise la souris au lieu du clavier. Pour obtenir cet effet, il utilise la technique 'pitchObject' et' yawObject'. Voir le code source. C'est ce que je voulais dire par «enfant/petit-enfant». Vous n'avez pas besoin d'utiliser 'PointerLockControls'; vous pouvez mettre en œuvre une logique similaire. – WestLangley

Répondre

12

Vous pouvez obtenir ce que vous voulez simplement en mettant camera.rotation.order = 'YXZ';

+2

+1. Oui, et simplement incrémenter/décrémenter 'camera.rotation.x' et' .y' directement. – WestLangley

+0

Je pense que c'est une meilleure solution, merci. Maintenant, je vois que 'Object3D.rotation' est un type' Euler', pas 'Vector3' ... – ostapische

4

croyez ce que vous cherchez conceptuellement est une installation de caméra de forage. Dans cette approche, vous construisez d'abord un Object3D pour être le "cou", puis attachez la caméra à cet objet avec la rotation désirée. Ensuite, vous pouvez appliquer les rotations au Object3D pour regarder autour sans l'effet d'oscillation. Pour le porter plus loin, vous pouvez imbriquer cet objet "cou" dans un autre Object3D pour agir comme le "corps" et appliquer les traductions à cet objet pour se déplacer sur la scène. De cette façon, vous avez une base de contrôleur de caméra. J'ai modifié votre violon comme suit:

Éditer: changement de mise en œuvre pour mieux adapter le cas d'utilisation @ostapische. Voici le violon 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(); 
} 

je vais parler de la PointLockControl ou FirstPersonControl, mais je vois WestLangley a été si gentil à suggérer. Quoi qu'il en soit bonne chance,

+0

Vous avez des erreurs dans votre code, mais @WestLangley me donne une bonne idée de voir le code source de PointerLockControls. Pouvez-vous ajouter [this] (http://jsfiddle.net/ostapische/uFwFC/2/) lien à votre réponse ou modifier votre code à l'état de travail et puis-je approuver la réponse. – ostapische

+0

Voilà, le code modifié a été mis à jour. Merci pour votre considération et merci à @WestLangley pour ses conseils avisés. –

Questions connexes