2012-07-20 6 views
27

Istnieje kilka doskonałych pytań dotyczących stosów (1, 2) dotyczących niepublikowania w pliku Three.js, czyli w jaki sposób konwertować (x, y) współrzędne myszy w przeglądarce na Współrzędne (x, y, z) w przestrzeni roboczej Three.js. Przeważnie idą tego wzoru:Konwersja współrzędnych globalnych na współrzędne ekranu w pliku Three.js przy użyciu rzutni

var elem = renderer.domElement, 
     boundingRect = elem.getBoundingClientRect(), 
     x = (event.clientX - boundingRect.left) * (elem.width/boundingRect.width), 
     y = (event.clientY - boundingRect.top) * (elem.height/boundingRect.height); 

    var vector = new THREE.Vector3( 
     (x/WIDTH) * 2 - 1, 
     - (y/HEIGHT) * 2 + 1, 
     0.5 
    ); 

    projector.unprojectVector(vector, camera); 
    var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize()); 
    var intersects = ray.intersectObjects(scene.children); 

I zostały próbuje zrobić odwrotnie - zamiast iść z „ekranu do świata” przestrzeni, aby przejść od „świata na ekranie” przestrzeń. Jeśli znam pozycję obiektu w Three.js, jak mogę określić jego pozycję na ekranie?

Wydaje się, że nie ma żadnego opublikowanego rozwiązania tego problemu. Another question about this just showed up on Stack, ale autor twierdzi, że rozwiązał problem za pomocą funkcji, która nie działa dla mnie. Ich rozwiązanie nie używa rzutowanego Ray'a i jestem całkiem pewien, że ponieważ 2D do 3D używa unprojectVector(), to rozwiązanie 3D do 2D będzie wymagało projectVector().

Na Githubie otwarto także this issue.

Każda pomoc jest doceniana.

+0

Dziękuję za wzór tłumaczenia "ekran do świata". To był ból przez wiele godzin .. – LePhleg

Odpowiedz

31

spróbuj to:

var width = 640, height = 480; 
var widthHalf = width/2, heightHalf = height/2; 

var vector = new THREE.Vector3(); 
var projector = new THREE.Projector(); 
projector.projectVector(vector.setFromMatrixPosition(object.matrixWorld), camera); 

vector.x = (vector.x * widthHalf) + widthHalf; 
vector.y = - (vector.y * heightHalf) + heightHalf; 
+0

op na innym stosie pytań wysłanych ten link, który również ma rozwiązanie. Dzięki jeszcze raz! https://github.com/mrdoob/three.js/issues/78 – BishopZ

+2

Funkcja getPosition() została uznana za przestarzałą. Użyj tego zamiast: var vector = projector.projectVector (new THREE.Vector3(). GetPositionFromMatrix (object.matrixWorld), camera); – imbrizi

+0

Zaktualizowana odpowiedź. Dzięki @imbrizi! – mrdoob

1

Użytkownik nie może przekształcić współrzędnych (x, y) na (x, y, z), ponieważ utracono informacje. To, co cytujesz, to jak znaleźć wszystkie punkty na wszystkich obiektach w scenie, które przecinają promień generowany przez (x, y).

Przejście od "świata do ekranu" zgodnie z żądaniem jest tym, czym jest projekcja, i jest równoważne z renderowaniem pojedynczego punktu (x, y, z). To, co robisz, to zastosowanie macierzy projekcji do swojego punktu (x, y, z). Jest to prawdopodobnie funkcja Projector.projectVector(vector, camera) pod adresem http://mrdoob.github.com/three.js/docs/49/#Projector, ale ze względu na to, że wyprowadza ona wektor 3D, mogę tylko założyć, że jeden z wymiarów to 0 i możesz go zignorować.

3

dla nowoczesnych Three.js (R75), wektor może być rzutowany na ekran z:

var width = window.innerWidth, height = window.innerHeight; 
var widthHalf = width/2, heightHalf = height/2; 

var pos = object.position.clone(); 
pos.project(camera); 
pos.x = (pos.x * widthHalf) + widthHalf; 
pos.y = - (pos.y * heightHalf) + heightHalf; 
2

Na każdy coraz deprecated lub warnings dzienniki, z zaakceptowana odpowiedź dotyczy starszych wersji Three.js. Teraz jest jeszcze łatwiej dzięki:

let pos = new THREE.Vector3(); 
pos = pos.setFromMatrixPosition(object.matrixWorld); 
pos.project(camera); 

let widthHalf = canvasWidth/2; 
let heightHalf = canvasHeight/2; 

pos.x = (pos.x * widthHalf) + widthHalf; 
pos.y = - (pos.y * heightHalf) + heightHalf; 
pos.z = 0; 

console.log(pos); 
+0

"Obiekt" nie jest zdefiniowany –