2012-07-20 34 views
27

Hay varias preguntas de pila excelente (1, 2) sobre desproyecto en Three.js, que es cómo convertir (x, y) las coordenadas del mouse en el navegador al (x, y, z) las coordenadas en el espacio del lienzo Three.js. La mayoría de ellos siguen este patrón:Conversión de Coordenadas mundiales a Coordenadas de pantalla en Three.js utilizando Proyección

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

he estado tratando de hacer lo contrario - en lugar de pasar de "pantalla para el mundo" espacio, para pasar de "mundo a la pantalla" espacio. Si conozco la posición del objeto en Three.js, ¿cómo determino su posición en la pantalla?

No parece haber ninguna solución publicada para este problema. Another question about this just showed up on Stack, pero el autor afirma haber resuelto el problema con una función que no funciona para mí. Su solución no usa un Rayo proyectado, y estoy bastante seguro de que, dado que 2D a 3D usa unprojectVector(), que la solución 3D a 2D requerirá projectVector().

También hay this issue abierto en Github.

Cualquier ayuda es apreciada.

+0

Muchas gracias por el patrón de traducción "pantalla-mundo". Fue un dolor durante muchas horas ... – LePhleg

Respuesta

31

intento con esto:

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

y otras preguntas sobre la pila publicaron este enlace que también tiene la solución. ¡Gracias de nuevo! https://github.com/mrdoob/three.js/issues/78 – BishopZ

+2

getPosition() ha quedado en desuso. Use esto en su lugar: var vector = projector.projectVector (new THREE.Vector3(). GetPositionFromMatrix (object.matrixWorld), camera); – imbrizi

+0

Respuesta actualizada. Gracias @imbrizi! – mrdoob

1

Usted no puede convertir (x, y) las coordenadas a (x, y, z) coordina porque pierde información. Lo que ha citado es cómo encontrar todos los puntos en todos los objetos de la escena que se cruzan con el rayo generado por (x, y).

El pasar de "mundo a pantalla" como usted solicita es de lo que se trata la proyección, y es equivalente a representar un solo punto (x, y, z). Lo que haces es aplicar la matriz de proyección a tu punto (x, y, z). Presumiblemente es la función Projector.projectVector(vector, camera) en http://mrdoob.github.com/three.js/docs/49/#Projector, pero debido a que produce un vector 3d, solo puedo suponer que una de las dimensiones es 0 y puede ignorarla.

3

Para moderna Three.js (R75), un vector puede ser proyectada sobre la pantalla con:

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

Por todo el mundo tuvo deprecatedwarnings o registros, las la respuesta aceptada es para las versiones anteriores de Three.js. Ahora es aún más fácil con:

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

"objeto" no está definido –

Cuestiones relacionadas