2012-08-18 10 views
6

Potrzebuję pomocy w uporaniu się z obiektem TRÓJ.Frustum.Oblicz wierzchołki płaszczyzny zbliżonej/dalekiej za pomocą TRZECIE.Frustum

Mój problem:

muszę obliczyć blisko/daleko płaskie wierzchołki; Wziąłem spojrzeć na tych tutoriali

  1. http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/
  2. http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/

a ja naszkicował tę funkcję wykonawczą dokładnie (mam taką nadzieję) procedura wyjaśnia (tak aby lewy górny/prawy wierzchołki, zakładając, że aparat może wyglądać tylko lewy i prawy):

 // Near Plane dimensions 
     hNear = 2 * Math.tan(camera.fov/2) * camera.near; // height 
     wNear = hNear * camera.aspect; // width 

     // Far Plane dimensions 
     hFar = 2 * Math.tan(camera.fov/2) * camera.far; // height 
     wFar = hFar * camera.aspect; // width 

getVertices : function() { 
     var p = camera.position.clone(); 
     var l = getCurrentTarget(); // see below 
     var u = new THREE.Vector3(0, 1, 0); 

     var d = new THREE.Vector3(); 
     d.sub(l, p); 
     d.normalize(); 

     var r = new THREE.Vector3(); 
     r.cross(u, d); 
     r.normalize(); 

     // Near Plane center 
     var dTmp = d.clone(); 
     var nc = new THREE.Vector3(); 
     nc.add(p, dTmp.multiplyScalar(camera.near)); 

     // Near Plane top-right and top-left vertices 
     var uTmp = u.clone(); 
     var rTmp = r.clone(); 
     var ntr = new THREE.Vector3(); 
     ntr.add(nc, uTmp.multiplyScalar(hNear/2)); 
     ntr.subSelf(rTmp.multiplyScalar(wNear/2)); 

     uTmp.copy(u); 
     rTmp.copy(r); 
     var ntl = new THREE.Vector3(); 
     ntl.add(nc, uTmp.multiplyScalar(hNear/2)); 
     ntl.addSelf(rTmp.multiplyScalar(wNear/2)); 

     // Far Plane center 
     dTmp.copy(d); 
     var fc = new THREE.Vector3(); 
     fc.add(p, dTmp.multiplyScalar(camera.far)); 

     // Far Plane top-right and top-left vertices 
     uTmp.copy(u); 
     rTmp.copy(r); 
     var ftr = new THREE.Vector3(); 
     ftr.add(fc, uTmp.multiplyScalar(hFar/2)); 
     ftr.subSelf(rTmp.multiplyScalar(wFar/2)); 

     uTmp.copy(u); 
     rTmp.copy(r); 
     var ftl = new THREE.Vector3(); 
     ftl.add(fc, uTmp.multiplyScalar(hFar/2)); 
     ftl.addSelf(rTmp.multiplyScalar(wFar/2)); 

getCurrentTarget : function() { 
     var l = new THREE.Vector3(0, 0, -100); 
     this.camera.updateMatrixWorld(); 
     this.camera.matrixWorld.multiplyVector3(l); 
     return l; 
    } 

To wydaje się działać, ale ...

Moje pytanie:

Czy mogę uzyskać ten sam wynik w bardziej elegancki (może bardziej poprawny) sposób, używając obiektu TRÓJ.Frustum?

Odpowiedz

5

Three.Frustum tak naprawdę nie pomoże ci - to zestaw samolotów. Dobrą wiadomością jest to, że twoje rozwiązanie wydaje się poprawne, ale jest łatwiejszy sposób na przemyślenie tego.

W prawym górnym rogu najbliższej płaszczyźnie jest to punkt w przestrzeni kamery z tymi współrzędnymi:

var ntr = new THREE.Vector3(wNear/2, hNear/2, -camera.near); 

używając definicji wNear i hNear, które są poprawne.

Teraz, upewniając się, że camera.matrixWorld jest aktualizowana, konwertowanie, że punkt na świecie koordynuje tak:

camera.updateMatrixWorld(); 
ntr.applyMatrix4(camera.matrixWorld); 

Teraz odwrócić oznaki dostać pozostałe trzy rogi, a następnie powtórzyć obliczenia dla skrajnej samolot.

Widzisz, miałeś rację; po prostu wziąłeś bardziej skomplikowaną trasę. :-)

EDYCJA: zaktualizowano do three.js r.66

+0

Dziękuję bardzo! Komplikowałem życie na próżno :-) To rozwiązanie jest prostsze i działa lepiej! – Skarafaz

+0

Próbuję zrobić to samo, aby uniknąć umieszczania cząstek poza widoczną przestrzenią, ale nie wygląda to tak, jak należy. http://jsfiddle.net/cZb66/ jest przykładem tego, co mam na myśli. Spodziewałem się, że narożne kwadraty znajdą się w rogach ekranu, ale nie są .... –

+0

@ChrisMorgan Musisz napisać nowy post, jeśli masz pytanie. – WestLangley

Powiązane problemy