2012-06-30 5 views
5

J'ai une CubeGeometry que la caméra regarde, et je veux que la caméra fasse un zoom pour que le cube soit entièrement visible, mais pas plus grand.Ajustement de la caméra pour la forme Three.js visible

Ma première tentative a été de convertir le cube vertices à la caméra système de coordonnées,

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

Je pensais que cela fonctionnerait, mais parfois il est trop petit, et d'autres fois trop grand (en fonction de la position du caméra). Je dois également faire ceci pour la caméra orthographique.

Edit: Je sais comment faire lorsque le cube est face à la caméra, je suis à la recherche d'une façon de le faire lorsque l'appareil est déplacé dans une certaine position arbitraire (r, thêta, phi) (coordonnées polaires sphériques; r est réellement constant pour mes fins).

Répondre

2

Multiplier par camera.matrixWorldInverse donne un vecteur dans les coordonnées de la caméra, mais surtout ne pas appliquer de perspective.

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

Nous pouvons alors trouver le plus petit angle qui conviendra à tous les coins de boîte de la scène. Arctan (D.x/D.z) donne l'angle BCD où B est ce que la caméra regarde, C est la position de la caméra et D la position d'un objet que vous voulez voir dans les coordonnées de la caméra.

Dans mon cas, ce qui suit garantit que la boîte à lettres du cube est entièrement 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

Caméra perspective. Si la caméra est centrée et la visualisation de la tête sur le cube, définir

dist = distance de la caméra à la face avant (important!) Du cube

et

height = hauteur Le cube.

Si vous réglez l'appareil photo champ de vue comme suit

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

alors la hauteur du cube correspondra à la hauteur visible.

Appareil photo orthographique. Si la caméra est centrée et la visualisation de la tête sur le cube, définir

aspect = le rapport d'aspect de la fenêtre (à savoir, la largeur/hauteur)

et

height = hauteur du cube.

Ensuite, construire votre appareil photo ainsi:

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

La hauteur du cube correspondra à la hauteur visible. Dans les deux cas, si la caméra n'est pas centrée ou si elle ne voit pas le cube en biais, le problème est plus compliqué. De plus, si la fenêtre est plus étroite que haute, alors la largeur est le facteur contraignant, et le problème est plus compliqué.

+0

J'aurais dû être plus clair dans ma question originale. Ce que j'essaie de faire, c'est automatiquement zoomer ou dézoomer lorsque la caméra tourne autour du cube. C'est-à-dire, quand il regarde le cube sous un angle. J'ai édité la question pour clarifier ceci. – sn6uv

+0

Comment allez-vous trouver la hauteur du cube.Si en calculant la boîte englobante? Nous obtiendrons la boîte de délimitation du modèle après l'initialisation de la caméra. –

Questions connexes