javascript orbitcontrols - Gire la cámara en Three.js con el mouse




camera three.orbitcontrols (5)

Tengo bastantes objetos en mi escena, por lo que rotarlos a todos podría ser un dolor. Entonces, ¿cuál es la manera más fácil de mover la cámara alrededor del origen con un clic del mouse y arrastrar? De esta forma, todas las luces, los objetos en la escena están en el mismo lugar, por lo que lo único que cambia es la cámara. Three.js no proporciona una manera de rotar una cámara alrededor de un punto, ¿o sí?

Gracias


Answers

echa un vistazo a los siguientes ejemplos

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

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

hay otros ejemplos para diferentes controles de mouse, pero ambos permiten girar la cámara alrededor de un punto y acercar y alejar con la rueda del mouse, la principal diferencia es OrbitControls refuerza la dirección de la cámara y TrackballControls permite que la cámara gire al alza -abajo.

Todo lo que tienes que hacer es incluir los controles en tu documento html

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

e incluye esta línea en tu fuente

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

Esto podría servir como un buen punto de partida para mover / rotar / acercar una cámara con el mouse / trackpad (en mecanografiado):

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

colocarlo como:

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

Controles:

  • mover mientras [manteniendo el mouse a la izquierda / dedo solo en el trackpad] para mover la cámara en el plano x / y
  • mueva [la rueda del mouse / dos dedos en el trackpad] para mover arriba / abajo en la dirección z
  • mantenga presionada la tecla Mayús + [la rueda del mouse / dos dedos en el panel táctil] para acercar / alejar a través de un campo de visión creciente / decreciente
  • mover mientras mantiene presionado [mouse derecha / dos dedos en el trackpad] para girar la cámara (quaternion)

Adicionalmente:

Si desea acercarse un poco cambiando la "distancia" (a lo largo de yz) en lugar de cambiar el campo de visión, puede subir / bajar la posición yyz de la cámara sin modificar la proporción de yy de la posición como sigue:

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

Aquí hay un proyecto con una cámara giratoria . Al mirar a través de la fuente, parece mover la posición de la cámara en un círculo.

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

}

Aquí hay otra demo y en esta creo que solo crea un nuevo objeto THREE.TrackballControls con la cámara como parámetro, que probablemente sea la mejor manera de hacerlo.

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

Eche un vistazo a THREE.PointerLockControls


Sylvester también puede generar matrices de rotación . Mirando el ejemplo del violín - la función del webkit que parece hacer la rotación:

// Rotate the Matrix around the transformed vector
var newMatrix = m.rotateAxisAngle(vector.x, vector.y, vector.z, angle);

Parece que está más en la línea de la función Matrix.Rotation(angle [, axis]) , creo que proporcionaría axis como un objeto Sylvester Vector, en lugar de los argumentos webkit x, y, z - http://sylvester.jcoglan.com/api/matrix.html#rotation

Multiplicar las matrices x, y, z no funciona demasiado bien porque las transformaciones adicionales se aplicarán en el nuevo contexto. Acabo de caer en esta trampa con esta página js / canvas: http://benjaminbenben.com/projects/twittny_test/





javascript 3d three.js