2010-01-13 16 views
5

Estoy programando un juego en C# usando el motor XNA3.1. Sin embargo, tengo un pequeño problema con mi cámara, básicamente, mi cámara tiende a "voltearse" cuando gira más de 180 grados en su giro (cuando la cámara alcanza los 180 grados, parece voltearse a 0 grados). El código para la obtención de la matriz de vista es el siguiente:Problema al voltear la cámara

Globals.g_GameProcessingInfo.camera.viewMat = Matrix.CreateLookAt(Globals.g_GameProcessingInfo.camera.target.pos, Globals.g_GameProcessingInfo.camera.LookAt, up);    //Calculate the view matrix 

La variable Globals.g_GameProcessingInfo.camera.LookAt la unidad de posición 1 directamente en frente de la cámara, con relación a la rotación de la cámara, y el "arriba" variable se obtiene con el siguiente función:

static Vector3 GetUp()  //Get the up Vector of the camera 
{ 
    Vector3 up = Vector3.Zero; 
    Quaternion quat = Quaternion.Identity; 
    Quaternion.CreateFromYawPitchRoll(Globals.g_GameProcessingInfo.camera.target.rot.Y, Globals.g_GameProcessingInfo.camera.target.rot.X, Globals.g_GameProcessingInfo.camera.target.rot.Z, out quat); 

    up.X = 2 * quat.X * quat.Y - 2 * quat.W * quat.Z;  //Set the up x-value based on the orientation of the camera 
    up.Y = 1 - 2 * quat.X * quat.Z - 2 * quat.Z * quat.Z; //Set the up y-value based on the orientation of the camera 
    up.Z = 2 * quat.Z * quat.Y + 2 * quat.W * quat.X;  //Set the up z-value based on the orientation of the camera 
    return up;  //Return the up Vector3 
} 
+0

Solo para actualizar, implementé la función para transformar el vector ascendente basado en la rotación de la cámara mediante el uso de "Vector.Transform()". Entonces pensé que el problema podría estar causado cuando el vector "arriba" es igual al vector "mirar" y es por eso que se volteó (como ese ha sido el problema en juegos anteriores). Después de volver a codificar la función para actualizar la posición de observación, la cámara todavía tiende a voltearse en la misma área, y no hay nada dramático que ocurra con la rotación o mirar las variables de la cámara. –

+0

Intenta editar la pregunta en lugar de agregar un comentario a tu pregunta al agregar información adicional. Los comentarios son un método aquí para discutir o comentar las respuestas de los demás o los comentarios de los demás. – Manish

Respuesta

1

Tengo los mismos problemas en OpenGL con gluLookAt. Solucioné ese problema con mi propia clase de cámara:

void Camera::ComputeVectors() 
{ 
    Matrix4x4 rotX, rotZ; 
    Quaternion q_x, q_y, q_z; 
    Quaternion q_yx, q_yz; 
    q_x.FromAngleAxis(radians.x, startAxisX); 
    q_y.FromAngleAxis(radians.y, startAxisY); 
    q_z.FromAngleAxis(radians.z, startAxisZ); 
    q_yx = q_y * q_x; 
    q_yx.ToMatrix(rotZ); 
    q_yz = q_y * q_z; 
    q_yz.ToMatrix(rotX); 
    axisX = startAxisX; 
    axisZ = startAxisZ; 
    axisX.Transform(rotX); 
    axisZ.Transform(rotZ); 
    axisY = axisX.Cross(axisZ); 

    position = startPosition; 
    position -= center; 
    position.Transform(q_yx); 
    position += center; 
} 

Es quizás demasiado complicado, pero funciona. axisY es su vector ascendente. El listado completo del código está en: http://github.com/filipkunc/opengl-editor-cocoa/blob/master/PureCpp/MathCore/Camera.cpp

Hope it helps.

+0

Hola amigo, gracias a montones por eso, definitivamente me ayudó y ahora el problema está resuelto, no sé qué pudo haber ido mal, pero esta función ha resuelto el problema: D. –

0

meh esperaba ver un bronceado en alguna parte.

¿Puede vincular a dónde obtuvo su ecuación de por favor? (estoy en el trabajo y realmente no; yo quiero sentarme y derivarlo)

¿cómo estás configurando la rotación de la cámara? ¿estás seguro de que nada está pasando allí?

+0

Obtuve la ecuación de algunas diapositivas de conferencias antiguas que vi al completar mi grado de programación. Es la forma matemática pura de calcular el vector ascendente basado en una rotación de cuaternión. Estoy configurando la rotación de la cámara en varias áreas a lo largo del juego mediante el uso de un Vector3 (pitch, yaw, roll) y no puedo ver nada divertido allí. –

0

Estoy un poco inseguro sobre las matemáticas en su método GetUp. ¿Podrías explicar las matemáticas detrás de esto?

En mi cámara lookat Inicializo mi vector ascendente una vez y luego giro ese vector usando un cuaternión. Esto elimina la posibilidad de intentar hacer un producto cruzado en vectores paralelos para calcular el vector ascendente.

Algunos SEMICODE para aclarar tal vez:

var up = Vector3.Up; 
var target = <some point in space>; 
var rotation = <current rotation quaternion>; 

var forward = target - position; 
forward = Vector3.Transform(forward, rotation); 

var updatedPosition = target - forward; 
var updatedUp = Vector3.Transform(up, rotation); 

var view = Matrix.CreateLookAt(updatedPosition, target, updatedUp); 
+0

El código en el método GetUp es un fragmento del código de la cámara que normalmente uso, que originalmente obtuve de las diapositivas de mi grado de programación. Ha pasado un tiempo desde que analicé las matemáticas reales detrás de esto, pero básicamente nos dijeron "esto te dará la dirección ascendente basada en una orientación" (y ha funcionado en proyectos anteriores en los que he trabajado). Veo la forma en que lo estás explicando y trataré de probarlo, ya que es menos complicado y descartaría cualquier error matemático. –

+0

Acepto, Up.z siente que necesita un "-" en algún lugar. –

1

Ésta es probablemente más lento, pero la única forma que conozco que ver con sería el de la matriz de rotación para 3D. Wikipedia Link

alt text

Dónde

alt text

y U = (Camera.position - Camera.lookat) .norm

... Ahora, yo creo que le daría la parte de rotación de la matriz de vista. Sin embargo, no estoy 100% en eso. Todavía estoy investigando esto sin embargo.

+0

hmmm parece interesante, voy a echarle un vistazo, pero estoy bastante seguro de que estoy recibiendo la dirección correcta. Gracias por la información, –

0

Ya que no estaba satisfecho con las respuestas aquí, tuve que resolver esto yo mismo.

Lo que descubrí es que es bastante simple. Haga esto:

Matrix ypr = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll); 
Vector3 up = Vector3.Transform(Vector3.Up, ypr); 

"arriba" es la dirección que desea.

Cuestiones relacionadas