Tournez la caméra en trois.js avec la souris

J'ai pas mal d'objets dans ma scène, donc la rotation de tous pourrait être une douleur. Alors, quel est le moyen le plus facile de déplacer la caméra autour d'origine sur le clic de la souris et faites glisser? De cette façon, toutes les lumières, les objets de la scène sont au même endroit, donc la seule chose qui change est la caméra. Trois.js ne fournit pas un moyen de faire pivoter une caméra autour d'un point, ou le fait-il?

Merci

53
demandé sur miki725 2011-12-08 09:57:56

5 réponses

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 qu'elle crée juste un nouvel objet THREE.TrackballControls avec la caméra comme paramètre, ce qui est probablement la meilleure façon d'aller.

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )
54
répondu Burt Sampson 2012-06-04 18:09:14

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 pour différents contrôles de la souris, mais les deux permettent à la caméra de tourner autour d'un point et de zoomer et dézoomer avec la molette de la souris, la principale différence est OrbitControls applique la direction de la caméra vers le haut, et TrackballControls permet à la caméra de tourner la tête en bas.

Tout ce que vous avez à faire est d'inclure les contrôles dans votre document html

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

Et incluez cette ligne dans votre source

controls = new THREE.OrbitControls( camera, renderer.domElement );
40
répondu ekcrisp 2013-10-10 21:31:28

Jetez un oeil à trois.PointerLockControls

3
répondu Pavel Galaton 2013-05-14 14:51:56

Cela pourrait servir de bon point de départ pour déplacer/tourner / zoomer une caméra avec la souris / 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))
})

Contrôles:

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

En outre:

Si vous voulez zoomer un peu en changeant la' distance ' (le long de yz) au lieu de changer le champ de vision, vous pouvez augmenter / descendre la position de la caméra y et z tout en gardant le rapport de position Y et z inchangé comme:

// 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
répondu ambientlight 2018-04-17 16:40:35

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 dans le rendu

controls.update();
0
répondu nguyentran 2018-09-13 03:07:59