2011-11-06 17 views
5

Estoy tratando de crear un gráfico de escena para mi juego 3D en el que las transformaciones de cada objeto son relativas a su padre. Cada nodo del gráfico tiene un vector de Rotación, Escala y Traducción.3D Relativo a las Transformaciones Absolutas

¿Cuál es la forma correcta de combinar las matrices de transformación relativa para obtener la transformación absoluta de un objeto? Me gustaría que también pudieras explicar tu solución.


Aquí es un ejemplo de hacerlo mal:
En realidad, esto resultó ser la solución:

Matrix GetAbsoluteTransformation() 
{ 
    if (!this.IsRoot()) 
    { 
     return this.Transformation * this.Parent.GetAbsoluteTransformation(); 
    } 
    else 
    { 
     return this.Transformation; 
    } 
} 

En este caso, cuando se gira el nodo padre, escalado o movido, el niño se transforma la misma cantidad, que es un comportamiento correcto! Pero el niño solo girará alrededor de su propio origen y no se mueve alrededor del origen de los padres.


Aplicaciones:

hay un modelo de automóvil con cuatro ruedas. Las ruedas están colocadas de forma relativa alrededor del origen del automóvil. Las ruedas pueden girar al igual que las ruedas reales. Si ahora giro el auto, las ruedas deberían permanecer unidas a él en todo momento. En este caso, el automóvil es la raíz y las ruedas son los nódulos infantiles.

Otro ejemplo sería un modelo del sistema solar. Los planetas giran alrededor de su propio eje, se mueven alrededor del sol y las lunas se mueven alrededor de los planetas.

+0

Resulta que mi primera idea de cómo hacerlo, que luego consideré como no adecuada, ¡en realidad fue la solución! Pasé las últimas horas tratando de resolver esto. * facepalm * ¡Gracias a todos por la ayuda rápida y precisa! – Lucius

Respuesta

3

Con respecto a su "forma de hacerlo mal", odio decírtelo, pero no está mal; más bien, está incompleto. Necesita hacer ese tipo de trabajo independientemente de la relación padre-hijo.

Aquí hay un ejemplo de eso: la rueda está unida al automóvil tal como lo mencionó. Si traduce o gira el automóvil, no necesita tocar las ruedas: están en la misma ubicación en relación con el automóvil. Sin embargo, cuando tratas de obtener la nueva ubicación de la rueda en el "mundo real", debes atravesar el árbol y aplicar las transformaciones de la matriz sobre la marcha. Eso todo funciona, ¿verdad?

Cuando gira un objeto, gira alrededor de su PROPIO origen. Entonces, una rueda probablemente debería estar girando alrededor de su eje y, y un planeta alrededor de su eje z. Pero ahora si necesitas mover un planeta "alrededor del sol", estás haciendo algo completamente diferente. Esto debe calcularse por separado. Eso no quiere decir que no va a aliviarse usando algunos de los mismos fósforos que ya tienes, (aunque no puedo decirlo con seguridad sin hacer los cálculos yo mismo) pero es completamente diferente.

Estás viendo realmente cambiando el estado del objeto. Esa es la belleza del gráfico de escena! Si no tuvieras un gráfico de escena, tendrías que averiguar todos los diversos valores hasta la escena principal y luego hacer todo tipo de operaciones matemáticas. Aquí, solo tienes que hacer un poco de trigonometría y álgebra para moverte por el planeta (puedes buscar en Google las mecánicas celestes) y mover el planeta en relación con su estrella. La próxima vez que la escena principal pregunte dónde está el planeta, ¡simplemente irá al gráfico de la escena! :-D

+0

Escojo esta como la mejor respuesta. Mi enfoque original era correcto y ahora no sé por qué lo consideré incorrecto (¿demasiado simple?: D) También tienes razón sobre la rotación planetaria: ahora incluí un nodo adicional que maneja la rotación alrededor del sol. ¡Muchas gracias! – Lucius

+0

Si el sol gira, los planetas rotarán también con este álgebra matricial. Cinemática hacia adelante .. – stefan

+0

@Stefan, entonces, obviamente, el sol debería ser simplemente un hijo del sistema solar como el planeta, y centrado en el origen. – corsiKa

1

Creo que este es el comportamiento correcto.

No creo que rotar alrededor del origen de los padres sea algo que pueda lograrse con una simple pila de matriz. Creo que solo puedes propagarte de padres a hijos.

Puede intentar en su lugar establecer la rotación relativa y la transformación en función de los desplazamientos del origen absoluto de los padres, aunque eso es mucho más que simplemente presionar sobre una pila de matriz.

Aquí hay una pregunta similar: Getting absolute position and rotation from inside a scene graph?

+0

¡Gracias! ¡También correcto! :) – Lucius

1

Depende de si está utilizando OpenGL o Direct3D. En OpenGL, las transformaciones se aplican de derecha a izquierda, mientras que en Direct3D, se aplican de izquierda a derecha. Son formas perfectamente válidas de diseñar el sistema de transformación, pero significa que debes pensar de forma diferente.

Me resulta más fácil pensar en el sistema de OpenGL, pero a la inversa. En lugar de pensar en cómo se mueven los vértices de un objeto cuando las transformaciones se aplican de derecha a izquierda, imagino que el sistema de coordenadas del objeto se transforma en un orden de izquierda a derecha. Cada transformación se aplica en relación con el nuevo sistema de coordenadas local, no relativo al mundo.

En el caso de las ruedas del automóvil, hay tres transformaciones involucradas: la posición del automóvil en el espacio, el origen de la rueda con respecto al automóvil y la orientación de la rueda con respecto a su posición neutral. Simplemente aplique estos en orden de izquierda a derecha (o viceversa para Direct3D). Para dibujar cuatro ruedas, primero aplique la transformación del automóvil, luego recuerde la transformación actual, luego aplique la ubicación y la orientación se transforma a su vez, volviendo a la transformación del automóvil que se recuerda después de cada una.

+0

No estoy seguro de si esta respuesta se ajusta por completo a mi pregunta. Pero aun así, aún no sabía acerca de esta diferencia, ¡así que gracias! :) – Lucius

+0

Creo que estos son los valores predeterminados, y puede voltearlos si es necesario. Al menos estoy bastante seguro de que puedes hacerlo en OpenGL. –

+0

@user lo mejor que se puede sacar de la respuesta de Marcelos es que hay muchos marcos que están en uso por cientos de miles (¿quizás millones?) De desarrolladores, y que debería considerar usar uno de esos para hacer el trabajo pesado en tu sistema. No solo le ahorrarán muchas horas de depuración (tenga en cuenta que necesitará muchas más horas de las que le tomaría para crear la suya propia), sino que también tendrá un conjunto de habilidades lucrativas y lucrativas en su currículum. – corsiKa

Cuestiones relacionadas