2012-06-30 19 views
5

Tengo un CubeGeometry que la cámara está mirando, y quiero que la cámara haga un zoom para que el cubo sea completamente visible, pero no más grande.Cámara de ajuste para la forma visible Three.js

Mi intento inicial era convertir los vértices del cubo de la cámara sistema de coordenadas,

function toScreenXY(position, camera) { 
    var pos = position.clone(); 
    var projScreenMat = new THREE.Matrix4(); 
    projScreenMat.multiply(camera.projectionMatrix, camera.matrixWorldInverse); 
    projScreenMat.multiplyVector3(pos); 

    return pos; 
} 
function ScaleInView() { 
    camera.fov = 0.0; 
    for (var i=0; i<8; i++) { 
    proj2d = toScreenXY(cube.geometry.vertices[i],camera); 
    angle = 57.296 * Math.max(Math.atan(proj2d.x/proj2d.z), Math.atan(proj2d.y/proj2d.z)); 
    camera.fov = Math.max(camera.fov,angle); 
    } 
    camera.updateProjectionMatrix(); 
} 

pensé que esto iba a funcionar, pero a veces es demasiado pequeño, y otras veces demasiado grande (dependiendo de la posición de la cámara).

También necesito hacer esto para la cámara ortográfica.

Editar: Yo sé cómo hacer esto cuando el cubo está frente a la cámara, yo estoy buscando una manera de hacerlo cuando la cámara se mueve a algunos arbitraria (r, theta, phi) posición (coordenadas polares esféricas; r es realmente constante para mis propósitos).

Respuesta

2

Multiplicando por camera.matrixWorldInverse da un vector en las coordenadas de la cámara, pero lo más importante es que no aplica perspectiva.

function toCameraCoords(position) { 
    return camera.matrixWorldInverse.multiplyVector3(position.clone()); 
} 

Podemos encontrar el ángulo más pequeño que se ajuste a todas las esquinas de la escena. arctan (D.x/D.z) proporciona el ángulo BCD donde B es lo que la cámara está mirando, C es la posición de la cámara y D la posición de un objeto que desea que sea visible en las coordenadas de la cámara.

En mi caso, lo siguiente asegura que el cubo boundbox es completamente visible.

function ScaleInView() { 
    var tmp_fov = 0.0; 

    for (var i=0; i<8; i++) { 
    proj2d = toCameraCoords(boundbox.geometry.vertices[i]); 

    angle = 114.59 * Math.max(// 2 * (Pi/180) 
     Math.abs(Math.atan(proj2d.x/proj2d.z)/camera.aspect), 
     Math.abs(Math.atan(proj2d.y/proj2d.z)) 
    ); 
    tmp_fov = Math.max(tmp_fov, angle); 
} 

camera.fov = tmp_fov + 5; // An extra 5 degrees keeps all lines visible 
camera.updateProjectionMatrix(); 
} 
3

Perspectiva Cámara. Si la cámara está centrada y la visualización de la cabeza en el cubo, definir

dist = distancia desde la cámara a la cara frontal (¡importante!) Del cubo

y

height = altura de el cubo.

Si establece el campo de visión de la cámara del siguiente

fov = 2 * Math.atan(height/(2 * dist)) * (180/Math.PI); 

entonces la altura del cubo coincidirá con la altura visible.

Cámara ortográfica. Si la cámara está centrado y la visualización de la cabeza en el cubo, definir

aspect = la relación de aspecto de la ventana (es decir, anchura/altura)

y

height = altura del cubo.

luego construir la cámara de esta manera:

camera = new THREE.OrthographicCamera(-aspect * height/2, aspect * height/2, height/2, -height/2, near, far); 

La altura del cubo coincidirá con la altura visible.

En cualquier caso, si la cámara no está centrada, o está mirando el cubo en ángulo, entonces el problema es más complicado.

Además, si la ventana es más estrecha que alta, entonces el ancho es el factor restrictivo, y el problema es más complicado.

+0

Debería haber sido más claro en mi pregunta original. Lo que intento hacer es acercar o alejar automáticamente cuando la cámara gira alrededor del cubo. Es decir, cuando se ve el cubo en un ángulo. He editado la pregunta para aclarar esto. – sn6uv

+0

¿Cómo va a encontrar la altura del cubo? ¿Es eso al calcular el cuadro delimitador? Obtendremos el cuadro delimitador del modelo después de la inicialización de la cámara. –

Cuestiones relacionadas