Con ejemplos, sabía que había alguna forma de proyectar un punto en la pantalla (x, y) a los puntos de '3d'. Pero no sé cómo traducirlo. Gracias por cualquier pista.
Probablemente usando el proyector, pero MrDoob obviamente sabe más sobre esto :)
Uhm, ¿quizás deberíamos tener un object3d.screen
que sería un Vector2
y actualizarlo en cada render?
Si ese object3D.screen Vector solo se usa para traducir la object3D.position de cada object3D a 2D, ¿object3D.screen no sería de muy poco valor? Quiero decir: creo que sería más útil poder trasladar cualquier punto x, y, z de cualquier malla en la posición x, y, z a coordenadas 2D.
Eso, a su vez, significa que nunca sería posible calcular previamente cada posición 3D de cada objeto.
En mi humilde opinión, sería útil tener, por ejemplo, una función THREE.3dto2d()
que tome un Vector3 (que representa un punto en la escena) o un Vector3 y un objeto (donde el Vector3 representa un punto en el objeto).
Luego, la función calcula la posición 3D en la escena.
Por último, toma la cámara, su posición, rotación, la matriz de proyección, etc., y vuelve a traducir el punto a 2D.
Supongo que la cámara también debería ser un parámetro de la función ...
Bueno ... Projector.projectScene
ya hace eso;)
Mira, sabía que era el Proyector ... ;-)
¿Hay algún ejemplo que lo use?
Hmm ... todavía no ... esas funciones están diseñadas para ser utilizadas con el Renderer ... devuelven una lista de elementos para renderizar sin relación con los objetos originales. Tal vez debería poner un enlace a los objetos originales y eso servirá ... Hmmm, necesito pensar un poco más.
Actualmente estoy de vacaciones, pero haré una demostración de destello de lente (o algo) tan pronto como regrese (la semana que viene).
Seguro, disfruta de tus vacaciones y espero con ansias la nueva demostración. :-)
Hmm, esto solía funcionar para mí (r32), ya no en r35 ..
toScreenXY: function(position, camera, jqdiv) {
// converts 3D position to screen coords
var pos = position.clone();
projScreenMat = new THREE.Matrix4();
projScreenMat.multiply( camera.projectionMatrix, camera.matrix);
projScreenMat.multiplyVector3(pos);
return { x: (pos.x+1)*jqdiv.width()/2 + jqdiv.offset().left,
y:(-pos.y+1)*jqdiv.height()/2 +jqdiv.offset().top };
},
pos después de projScreenMat.multiplyVector3(pos);
solía tener un límite entre -1 y 1 ((0,0) en el centro de la vista.), pero ahora parece variar inesperadamente.
Sí, camera.matrix
debe reemplazarse ahora con camera.matrixWorldInverse
.
Prueba con esto:
toScreenXY: function ( position, camera, jqdiv ) {
var pos = position.clone();
projScreenMat = new THREE.Matrix4();
projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
projScreenMat.multiplyVector3( pos );
return { x: ( pos.x + 1 ) * jqdiv.width() / 2 + jqdiv.offset().left,
y: ( - pos.y + 1) * jqdiv.height() / 2 + jqdiv.offset().top };
}
Sí, eso funcionó, no sabía sobre los cambios de matrices. Espero que esta función de proyección responda a la pregunta de alivedise.
Creo que es el hilo adecuado para hacer mi pregunta sobre 3D Cube. Tengo un cubo dibujado en lienzo con caras en las que se puede hacer clic. El cubo gira libremente sobre el eje X y el eje Y. Lo que quiero es sacar la mayor parte de la cara frontal cuando el usuario suelte el mouse y hacerlo completamente visible girando automáticamente. Cualquier ayuda en este contexto sería muy agradecida.
Gracias.
@ imrantariq2011 : Eso no está realmente relacionado con este tema, ¿te importaría abrir uno nuevo? Gracias.
Para propósitos de mapeo de texturas, me gustaría poder obtener las coordenadas de pantalla x, y para cada vértice de una cara determinada.
Puedo ver cómo se puede hacer esto usando lo anterior (toScreenXY: function), pero primero se requieren los vértices transformados (escalados, traducidos y rotados) del mundo para una cara determinada. Pasé algún tiempo mirando Projector.projectScene y me pregunto si hay una forma más sencilla de lograr el objetivo anterior y parece que object.matrixWorld.getPosition () podría obtener el centroide del objeto en lugar de los vértices de la cara.
Sí, el código anterior era para uno de. Si necesita proyectar muchos puntos, lo mejor es extraer los bits de código de .projectScene()
.
las personas que llegan hasta aquí pueden querer saber sobre esto:
Yo uso esto, funciona:
función toScreenXY (pos3D)
{
var proyector = nuevo THREE.Projector ();
var v = projector.projectVector (pos3D, cámara);
var percX = (vx + 1) / 2;
var percY = (-vy + 1) / 2;
var left = percX * window.innerWidth;
var top = percY * window.innerHeight;
return new THREE.Vector2 (izquierda, arriba);
}
El viernes 1 de agosto de 2014 a las 11:24 a.m., Artem Fitiskin [email protected] escribió:
Cuando uso toScreenXY, obtengo valores muy grandes.
console.log (pos): // x: -1474.1436403989792, y: -730.829023361206, z: 3.0004000663757324
y después de multiplicarlo con jqdiv, la función devuelve x e y muy grandes.
¿Qué estoy haciendo mal?
-
Responda a este correo electrónico directamente o véalo en GitHub.
@arieljake
Como se indica en las pautas , las solicitudes de ayuda deben dirigirse a stackoverflow . Esta placa es para errores y solicitudes de funciones.
bien ... sin embargo, el propio señor doob puso código, entonces, ¿qué pasa?
@arieljake # 1979
En caso de que alguien todavía necesite esto después de actualizar ...
function screenXY(obj){
var vector = obj.clone();
var windowWidth = window.innerWidth;
var minWidth = 1280;
if(windowWidth < minWidth) {
windowWidth = minWidth;
}
var widthHalf = (windowWidth/2);
var heightHalf = (window.innerHeight/2);
vector.project(camera);
vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;
vector.z = 0;
return vector;
};
Ok, problema muy antiguo, pero tenía un objeto anidado, que no funcionaba con el código anterior.
Mi caso fue: quería la posición x-e-y (y z) real para un objeto anidado después de la renderización, así que adapté los ejemplos anteriores.
Tenga en cuenta:
scene.updateMatrixWorld();
y
parent.updateMatrixWorld();
`` js
función nestedObjecttoScreenXYZ (obj, cámara, ancho, alto)
{
vector var = nuevo TRES.Vector3 ();
vector.setFromMatrixPosition (obj.matrixWorld);
var widthHalf = (ancho / 2);
var heightHalf = (altura / 2);
vector.project (cámara);
vector.x = (vector.x * widthHalf) + widthHalf;
vector.y = - (vector.y * heightHalf) + heightHalf;
vector de retorno;
};
typical call:
```js
var screenpos=NestedObjecttoScreenXY(object,camera,renderer.domElement.width,renderer.domElement.height,true);
En caso de que alguien se encuentre con el mismo problema.
Comentario más útil
En caso de que alguien todavía necesite esto después de actualizar ...