2012-06-30 12 views
5

Ho una CubeGeometry che la fotocamera sta guardando e voglio che la fotocamera ingrandisca in modo che il cubo sia interamente visibile, ma non più grande.Regolazione della fotocamera per la forma Three.js visibile

Il mio primo tentativo è stato quello di convertire i verticies cubo alla telecamera sistema di coordinate,

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

Ho pensato che questo avrebbe funzionato, ma a volte è troppo piccolo, e altre volte troppo grande (a seconda della posizione del telecamera).

Ho anche bisogno di fare questo per macchina ortografica.

Edit: So come fare questo quando il cubo si trova di fronte alla telecamera, sto cercando un modo per farlo quando la fotocamera viene spostata a qualche arbitraria (r, theta, phi) posizione (coordinate polari sferiche; r è in realtà costante per i miei scopi).

risposta

2

Moltiplicando per camera.matrixWorldInverse si ottiene un vettore nelle coordinate della telecamera, ma, soprattutto, non si applica la prospettiva.

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

Possiamo quindi trovare l'angolo più piccolo che si adatta a tutti gli angoli del riquadro nella scena. arctan (D.x/D.z) dà l'angolo BCD dove B è ciò che la fotocamera sta guardando, C è la posizione della fotocamera, e D la posizione di un oggetto che si desidera essere visibile nelle coordinate della telecamera.

Nel mio caso, il seguente assicura che la casella del cubo sia completamente visibile.

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

Telecamera prospettiva. Se la fotocamera è centrato e la visualizzazione del cubo a testa alta, definire

dist = distanza dalla telecamera alla faccia anteriore (importante!) Del cubo

e

height = altezza il cubo.

Se si imposta il campo di vista della macchina fotografica come segue

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

quindi l'altezza cubo abbinare l'altezza visibile.

Telecamera ortografica. Se la fotocamera è centrato e visualizzazione del cubo frontale, definire

aspect = le proporzioni della finestra (cioè, larghezza/altezza)

e

height = altezza del cubo.

Poi costruire la vostra macchina fotografica in questo modo:

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

L'altezza Cube abbinare l'altezza visibile.

In entrambi i casi, se la fotocamera non è al centro o in altro modo osserva il cubo ad angolo, il problema è più complicato.

Inoltre, se la finestra è più stretta di quanto non sia alta, la larghezza è il fattore di limitazione e il problema è più complicato.

+0

Avrei dovuto essere più chiaro nella mia domanda iniziale. Quello che sto cercando di fare è ingrandire o ridurre automaticamente quando la telecamera gira attorno al cubo. Cioè, quando guarda il cubo da un angolo. Ho modificato la domanda per chiarire questo. – sn6uv

+0

Come si trova l'altezza del cubo. È questo calcolando il rettangolo di selezione? Otterremo il rettangolo di selezione del modello dopo l'inizializzazione della telecamera. –

Problemi correlati