¿Cómo implementar artilugios de traducción, escala y rotación para manipular transformaciones de objetos 3D?


11

Estoy en el proceso de desarrollar un editor 3D básico. Utiliza OpenGL para renderizar un mundo 3D. En este momento, mi escena es solo unas pocas cajas de diferentes tamaños y estoy en la etapa en la que quiero poder seleccionar cada caja y luego moverla / escalarla / rotarla para lograr cualquier transformación que desee.

¿Cómo puedo resolver el problema de implementar tanto el renderizado de los artilugios de estas herramientas (o identificadores, o cómo las personas generalmente los llaman) y también elegirlos en cada eje para realizar el cambio en la transformación con mi mouse? Para mayor claridad: ingrese la descripción de la imagen aquí

Mi investigación hasta ahora sugirió que el enfoque más limpio es tener un cuadro delimitador alineado por eje por flecha en el gizmo y otro por cuadrado (los que mueven el objeto en un plano en lugar de un solo eje) y luego emitir un rayo desde el mouse posición y ver con qué choca. Pero esto todavía es demasiado abstracto para mí, agradecería más orientación sobre cómo funcionaría este algoritmo (el pseudocódigo es más que suficiente)


1
Por lo general, te lanzarás al mundo con la posición del mouse y verás si golpeas un artilugio. También puede transformar el artilugio en el espacio de la pantalla para detectar colisiones allí. Por lo general, aunque solo hace la distancia del tipo de cosa de segmento de rayo a línea. La rotación generalmente se realiza como una bola de seguimiento virtual. Vea Melax en Gemas de programación de juegos 1. La traducción es prácticamente un producto de punto, y también lo es la escala.
RandyGaul

Respuestas:


9

En algún momento de mi tiempo en e-on, he mantenido los artilugios de la línea de productos Vue .
Puedo decirte que te llevará varios días, a tiempo completo.
A menos que encuentre alguna biblioteca o una forma súper inteligente, la forma clásica es obtener la coordenada del mouse en la ventana cuando hace clic, si es una coordenada relativa a la ventana gráfica, simplemente puede dividir x e y por ancho y alto, usted obtener un vector (flotante 2d) en el rango [0,1]. reste (0.5,0.5) para obtener el rango [-0.5, 0.5] para x e y.
Luego, haces un rayo a partir de esta coordenada usando las x e y simplemente como el rayo x e y, y configuras z a la distancia focal. a veces la relación de aspecto es un dolor en el culo en esta operación. Un poco de violín y error de prueba lo solucionarán.
Luego, debe verificar la intersección con sus elementos de gizmos, ya sea que tenga una malla que generó, o que esté modelada en una licuadora u otro DCC, o partes de malla que puedan articularse entre sí ... Solo use esas partes de malla como un rayo / consulta de intersección triangular.
O si lo tiene, rayo / cilindro, rayo / esfera de acuerdo con su apariencia de gizmo y partes.
Debe tener rutinas de intersección que sean capaces de aplicar una matriz de transformación en la primitiva que colisionan . Extremadamente importante porque su artilugio se traducirá con el objeto que sirve para moverse, rotará y se escalará con el inverso de la distancia a la cámara, de modo que mantenga un tamaño proyectado fijo en la pantalla.
Luego tiene la parte de interacción, la más fácil es tomar el delta del punto en que el mouse fue el primer evento de "mouse down" y la posición actual de "Mouse mover", en 2D puro, y usar este delta como el movimiento actual del eje en el espacio mundial, multiplicado por algunos kque tú decides empíricamente. De acuerdo con sus unidades internas versus píxel versus escala actual de zoom, etc.
El paso final es simplemente aplicar la matriz del gizmo al objeto manipulado, para que lo siga.

Te digo que implementarlo es todo un viaje al infierno, y si lo estás haciendo en tu tiempo libre, espera más de una semana. Varias semanas si estás descubriendo completamente el campo. Más de un mes si sus fines de semana están ocupados con otras actividades :)

Le sugiero que descargue Embree 2.0 de Intel para hacer la consulta de intersección de rayos / triángulos por usted, para que no tenga que preocuparse por codificar eso. O podría copiar / pegar sin piedad y adaptar el código de Blender ... ¿Creo que se mudaron a la licencia de Apache? Debería ser posible legalmente.


1
Muchas gracias por tu respuesta. De hecho es útil. Sabía que no estaba loco cuando me sentía abrumado por una tarea aparentemente fácil. Subestimo su dificultad y terminé atrapado en el mismo problema durante días. La próxima vez que vaya y maneje esto, me aseguraré de haber hecho un buen plan. Gracias
Grimshaw

0

Para manipulador-traductor, uso el siguiente algoritmo:

1) Cuando el mouse está presionado, necesitamos verificar si el rayo se cruza con la flecha. Por ejemplo, consideramos la flecha X. Construimos Ray en el espacio mundial (basado en el frustum de la cámara y la posición del mouse). Construimos un plano en el que se encuentra el eje x: su normal es igual V cruz X cruz V, donde V - vector desde el centro a la cámara, X - representa el eje x. Luego intersectamos el rayo con el plano y, por lo tanto, encontramos el punto de intersección en coordenadas mundiales. Luego proyectamos el segmento del eje xy el punto resultante nuevamente en la pantalla, buscamos la distancia entre el segmento proyectado y el punto proyectado en la pantalla. Si tiene menos de unos pocos píxeles, el mouse introduce el eje. También calculamos el vector delta del espacio mundial entre el centro de selección y nuestra intersección.

Este procedimiento lo hacemos para 3 ejes, por lo que encontramos distancias a todos los ejes. Encuentra la distancia mínima. así que encontramos con qué eje se cruza el mouse.

2) Cuando el mouse se mueve. sabemos por qué eje se mueve el objeto (de 1). encontramos la intersección espacial mundial del rayo con el plano (como en 1). además, proyectamos el punto de intersección en la línea a lo largo de la cual se mueve el objeto. posición final del manipulador = intersección + delta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.