web-dev-qa-db-fra.com

Faire pivoter la caméra dans Three.js avec la souris

Il y a pas mal d'objets dans ma scène, donc leur rotation pourrait être pénible. Alors, quel est le moyen le plus facile de déplacer la caméra autour d'Origine en cliquant sur la souris et en la faisant glisser? De cette façon, toutes les lumières et les objets de la scène se trouvent au même endroit. La seule chose qui change est donc la caméra. Three.js ne fournit pas un moyen de faire pivoter une caméra autour d’un point.

Je vous remercie

55
miki725

Voici un projet avec une caméra rotative . En regardant à travers la source, il semble simplement déplacer la position de la caméra dans un cercle.

function onDocumentMouseMove( event ) {

    event.preventDefault();

    if ( isMouseDown ) {

        theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 )
                + onMouseDownTheta;
        phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 )
              + onMouseDownPhi;

        phi = Math.min( 180, Math.max( 0, phi ) );

        camera.position.x = radious * Math.sin( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
        camera.position.z = radious * Math.cos( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.updateMatrix();

    }

    mouse3D = projector.unprojectVector(
        new THREE.Vector3(
            ( event.clientX / renderer.domElement.width ) * 2 - 1,
            - ( event.clientY / renderer.domElement.height ) * 2 + 1,
            0.5
        ),
        camera
    );
    ray.direction = mouse3D.subSelf( camera.position ).normalize();

    interact();
    render();

}

Voici une autre démo et dans celle-ci, je pense que cela crée simplement un nouvel objet THREE.TrackballControls avec la caméra en tant que paramètre, ce qui est probablement la meilleure solution.

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )
57
Burt Sampson

jetez un oeil aux exemples suivants

http://threejs.org/examples/#misc_controls_orbit

http://threejs.org/examples/#misc_controls_trackball

il existe d'autres exemples de commandes de souris différentes, mais ces deux options permettent à la caméra de pivoter autour d'un point et d'effectuer un zoom avant et arrière avec la molette de la souris, la différence principale étant OrbitControls force la caméra vers le haut et TrackballControls permet à la caméra de pivoter vers le haut. -vers le bas.

Tout ce que vous avez à faire est d’inclure les contrôles dans votre document HTML.

<script src="js/OrbitControls.js"></script>

et inclure cette ligne dans votre source 

controls = new THREE.OrbitControls( camera, renderer.domElement );
40
ekcrisp

Jetez un coup d’œil à THREE.PointerLockControls

3
Pavel Galaton

Cela peut constituer un bon point de départ pour déplacer / tourner / zoomer une caméra avec une souris/un trackpad (en TypeScript):

class CameraControl {
    zoomMode: boolean = false
    press: boolean = false
    sensitivity: number = 0.02

    constructor(renderer: Three.Renderer, public camera: Three.PerspectiveCamera, updateCallback:() => void){
        renderer.domElement.addEventListener('mousemove', event => {
            if(!this.press){ return }

            if(event.button == 0){
                camera.position.y -= event.movementY * this.sensitivity
                camera.position.x -= event.movementX * this.sensitivity        
            } else if(event.button == 2){
                camera.quaternion.y -= event.movementX * this.sensitivity/10
                camera.quaternion.x -= event.movementY * this.sensitivity/10
            }

            updateCallback()
        })    

        renderer.domElement.addEventListener('mousedown', () => { this.press = true })
        renderer.domElement.addEventListener('mouseup', () => { this.press = false })
        renderer.domElement.addEventListener('mouseleave', () => { this.press = false })

        document.addEventListener('keydown', event => {
            if(event.key == 'Shift'){
                this.zoomMode = true
            }
        })

        document.addEventListener('keyup', event => {
            if(event.key == 'Shift'){
                this.zoomMode = false
            }
        })

        renderer.domElement.addEventListener('mousewheel', event => {
            if(this.zoomMode){ 
                camera.fov += event.wheelDelta * this.sensitivity
                camera.updateProjectionMatrix()
            } else {
                camera.position.z += event.wheelDelta * this.sensitivity
            }

            updateCallback()
        })
    }
}

déposez-le comme:

this.cameraControl = new CameraControl(renderer, camera, () => {
    // you might want to rerender on camera update if you are not rerendering all the time
    window.requestAnimationFrame(() => renderer.render(scene, camera))
})

Les contrôles: 

  • déplacez tout en [en maintenant la souris à gauche/un seul doigt sur le pavé tactile] pour déplacer la caméra dans le plan x/y 
  • move [molette de la souris/deux doigts sur le pavé tactile] pour monter/descendre dans la direction z 
  • maintenez la touche Maj enfoncée + [molette de la souris/deux doigts sur le pavé tactile] pour effectuer un zoom avant/arrière via un champ de vision croissant/décroissant
  • déplacez tout en en maintenant [souris droite/deux doigts sur le pavé tactile] pour faire pivoter la caméra (quaternion)

Aditionellement:

Si vous souhaitez un peu zoomer en modifiant la "distance" (le long de yz) au lieu de modifier le champ de vision, vous pouvez augmenter/réduire la position de la caméra y et z tout en conservant le rapport des positions y et z, comme suit:

// in mousewheel event listener in zoom mode
const ratio = camera.position.y / camera.position.z
camera.position.y += (event.wheelDelta * this.sensitivity * ratio)
camera.position.z += (event.wheelDelta * this.sensitivity)
2
ambientlight

OrbitControls et TrackballControls semblent être bons à cet effet.

controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;

mise à jour en rendu

controls.update();
0
nguyentran