2017-10-01 5 views
0

Je me suis demandé comment je peux obtenir ma caméra FPS pour se déplacer essentiellement en fonction vers l'avant et vers l'arrière sur la direction de la caméra, mais j'ai échoue lamentablement, je voudrais connaître la façon de faire au mieux, comme en ce moment mon code est commutateur sens derrière mon triangle (w devient s et s devient w) et généralement fonctionne pas (se déplacer en diagonale au lieu d'avancer, parfois), la rotation fonctionne parfaitement, mais la traduction vis ma matrice ...OpenGL, Caméra première personne Traduction

void glfwCursorCallback(GLFWwindow* window, double x, double y) { 
    camera.rx += (x - camera.lcx) * 0.01f; 
    camera.ry += (y - camera.lcy) * 0.01f; 
    kmMat4RotationYawPitchRoll(&camera.mat, camera.ry , camera.rx, 0.0f); 
    camera.lcx = x; 
    camera.lcy = y; 
} 
... 
kmMat4PerspectiveProjection(&projection, 90.0f, aspect, 0.1f, 1000.f); 
float x = 0.0f, y = 0.0f, z = -1.0f; 
while(!glfwWindowShouldClose(window)) { 
    if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { 
     /* pitch - ry */ 
     x += 0.1*sin(camera.ry)*cos(camera.rx); 
     y += 0.1*sin(camera.ry)*sin(camera.rx); 
     z += 0.1*cos(camera.ry); 
    } 
    if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { 
     x -= 0.1*sin(camera.ry)*cos(camera.rx); 
     y -= 0.1*sin(camera.ry)*sin(camera.rx); 
     z -= 0.1*cos(camera.ry); 
    } 

    glClear(GL_COLOR_BUFFER_BIT); 
    kmMat4Translation(&transform, x, y, z); 
    kmMat4Multiply(&object, &camera.mat, &transform); 
    kmMat4Multiply(&final, &projection, &object); 
    glUniformMatrix4fv(shader.mpm, 1, GL_FALSE, final.mat); 
    ... 

Je ne sais pas comment le faire depuis que je ne l'ai fait auparavant, donc j'aimerais quelques conseils de la gens plus expérimentés ici!

Edit: Le but est d'avoir la caméra aller de l'avant selon l'orientation. En outre, il fonctionne parfaitement si je laisse de côté x, y et juste mis z à + - 0,1 ... il est donc pas un problème de la matrice multiplications

Répondre

0

Alors que dans le monde de l'axe X est dirigé vers la droite, le Y selon l'axe vers l'avant, et l'axe Z vers le haut, sur la zone de visualisation des points de l'axe X vers la gauche, vers le haut de l'axe Y et l'axe Z de la vue (note dans un système de main droite le Z -Axis est le produit croisé de l'axe X et de l'axe Y).

world to view

Chaque point et chaque vecteur à partir du système de référence de la scène doit donc être d'abord converties en coordonnées fenêtre. Ceci peut être facilement traitée par le tableau suivant:

x y z 
-------- 
1 0 0 | x' = x 
0 0 1 | y' = z 
0 -1 0 | z' = -y 


De plus, vous devez changer progressivement la matrice de la caméra et ne pas résumer les mouvements et les rotations. Cela signifie que vous devez calculer le mouvement actuel et la matrice de rotation actuelle. Appliquez le mouvement et la rotation à la caméra et gardez la caméra pour le cycle suivant de la boucle. Au cycle suivant de la boucle, vous devez utiliser la caméra manipulée du cycle précédent et vous devez appliquer le nouveau mouvement et la rotation. Cela provoque des changements incrémentaux de la caméra, toujours en fonction de sa position et de son orientation actuelles.

movement and rotation


Votre code devrait ressembler en quelque sorte comme ceci:

double currenYaw = 0.0; 
double currentPitch = 0.0; 
double currentX  = 0.0; 
double currentY  = 0.0; 

void glfwCursorCallback(GLFWwindow* window, double x, double y) 
{ 
    currenYaw += (x - currentX) * 0.01; 
    currentPitch += (currentY - y) * 0.01; 
    currentX  = x; 
    currentY  = y; 
} 

glfwGetCursorPos(_wnd, &currentX, &currentY); 
while(!glfwWindowShouldClose(window)) { 

    float x = 0.0f, y = 0.0f, z = 0.0f; 
    if (glfwGetKey(_wnd, GLFW_KEY_W) == GLFW_PRESS) 
     y = 0.1f; 
    if (glfwGetKey(_wnd, GLFW_KEY_S) == GLFW_PRESS) { 
     y = -0.1f; 
    if (glfwGetKey(_wnd, GLFW_KEY_D) == GLFW_PRESS) 
     x = 0.1f; 
    if (glfwGetKey(_wnd, GLFW_KEY_A) == GLFW_PRESS) { 
     x = -0.1f; 
    if (glfwGetKey(_wnd, GLFW_KEY_Q) == GLFW_PRESS) 
     z = -0.1f; 
    if (glfwGetKey(_wnd, GLFW_KEY_E) == GLFW_PRESS) { 
     z = 0.1f; 

    // movment 
    kmMat4 yaw_matrix; 
    kmMat4Translation(&transform, x, z, -y); 

    // yaw 
    kmMat4 yaw_matrix; 
    kmMat4RotationY(&yaw_matrix, currenYaw); 
    currenYaw = 0.0; 

    // pitch 
    kmMat4 pitch_matrix; 
    kmMat4RotationX(&pitch_matrix, currentPitch); 
    currentPitch = 0.0; 

    // roatation = pitch_matrix * yaw_matrix 
    kmMat4 roatation; 
    kmMat4Multiply(&roatation, &yaw_matrix, &yaw_matrix); 

    // change the camera matrix incrementally 
    kmMat4Multiply(&camera.mat, &transform, &camera.mat); 
    kmMat4Multiply(&camera.mat, &roatation, &camera.mat); 

    .... 
} 


Seet plus:

+0

Je voudrais aller vers la caméra, et stocker cette valeur pour les temps supplémentaires (x, y, z) Je ne veux juste passer par un montant fixe dans un axe, je le fais déjà bien – Whiteclaws

+0

Votre "solution" fait du triangle le centre du monde et la caméra tournant autour, donc pas vraiment ce que je cherche, je suis à la recherche d'un FP camera – Whiteclaws

+0

Vous devez changer la matrice de la caméra de façon incrémentielle et ne pas faire la somme des mouvements et des rotations. Voir la nouvelle réponse – Rabbid76