Jump to content

  • Log In with Google      Sign In   
  • Create Account

OpenGl translating with quaternion based view/camera


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Misantes   GDNet+   -  Reputation: 1218

Like
0Likes
Like

Posted 11 June 2014 - 10:33 PM

Alright, first let me promise this will be the last thread on quaternions I will make tongue.png Also, I would usually post this in the beginners section, but it feels a little out of place there, so mods, please feel free to relocate this if it does indeed belong there. But, that said, I am rather new to OpenGL, so please keep that mind when responding (you're of course welcome to respond however you'd like, but I'm much less likely to understand it smile.png)

 

So, I'm able to successfully rotate the Camera around using quaternions. Where I'm running into difficulties is moving the Camera around the worldspace (or the worldspace around the camera). To clarify, so there is less confusion(I'm rather new and I'll certainly misuse opengl nomenclature in this post, but I'll try to be clear) when I say camera I mean a View matrix in a matrix:

glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

The biggest issue I've had is that translating by the quaterion or quaternion-based matrix seems to not produce the results I'm going for, as often the axis I'm trying to move along will be represented by a zero in the quaternion and therefore translates by zero when multiplied by a vector (if my math is correct, which it may not be). I'm probably explaining this poorly, so to illustrate, imagine I'm "rolling" the view matrix by rotating along the Z axis. If I try translating by glm::vec3(0,0,10) everything will seemingly work and I'll move forward in the world(or the world backward, whichever). However, any time the quaternion is not rotating along the Z axis(say, I'm rotating the camera to the left, along the X axis), if I try translating by the same glm::vec3(0,0,10), it will of course not move forward (I'm assuming again, that it's because it's now multiplying the vector.z by zero).

 

What I've tried doing so far is rotating the view matrix around using the quaternion-based matrix, but translating the models/world in the ModelMatrix. This works great, except of course they will not translate in the direction I'm trying to translate in, as they're being moved in world space rather than the camera space. If I rotate them first, then translate, this works better, but suffers from the same problem mentioned above, where if it's not along the Z axis, it won't translate in the Z axis direction.

 

I've tried, instead of translating by a vector of (0,0,10) to something like (10,10,10), which doesn't work, because it now translates on the axis I'm rotating on (i.e. moving up when I'm rotating left, etc, which makes total sense in hindsight).

 

I've also tried translating instead in the ViewMatrix and then translating and rotating the models in the ModelMatrix, but they rotate around the world center instead of the ViewMatrix center. If I had to guess(and I'm certain you'll correct me if I'm wrong), I think this is probably the direction I need to head in, but I need to rotate them around the location of the "camera." But, I'm having difficulty implementing this.

 

I've tried rotating in the ViewMatrix, and then for the ModelMatrix rotating, translating, then rotating back using the conjugate of the original quaternion, but had really weird outcomes as well. It's possible I'm using the conjugate wrong, or ordering things incorrectly when using it.

 

Anyhow, I've tried dozens of other things which all haven't worked for various (in hindsight, obvious) reasons. I'm feeling a little on the discouraged side, but thought I would ask here at this point.

 

Here is some relevant code. Please forgive any spaghettiness as I've redone it a hundred times, and much of it is just a hacky-workaround to try to debug exactly what it's doing. I've left it in it's current ugly condition, so as to not accidentally delete what may actually be the problem. I'll of course clean it up once it's working.

//generation of the quaternion. axisX, axisY etc are passed in on keypresses. For clarity, this is always
//a "1.f" on keypress. I.e. on keypress "A", the axisY would be "1". They're reset to zero at the beginning of this function if key isn't still pressed.
    
   if(axisZ != 0 ||  axisX != 0 || axisY != 0 )//workaround to be able to move forward for debugging purposes
    {
        rotQuat = glm::quat(angleIn, axisX, axisY, axisZ);
    }
    else
    {
        rotQuat = glm::quat(angleIn, axisX, axisY, 1);
    }
     /*below is workaround to handle multiple axis rotation. There's probably a better way, but
    I'm still in  the process of learning/implementing that*/

    glm::quat quatx = glm::quat(angleInx, axisX, 0, 0);
    glm::quat quaty = glm::quat(angleInx, 0, axisY, 0);
    glm::quat quatz = glm::quat(angleInx, 0, 0, axisZ);

    if(axisY != 0 && axisX != 0)
      {
       rotQuat = glm::mix(quatx, quaty, .5f);
      }
    else if(axisZ != 0 && axisY != 0)
      {
       rotQuat = glm::mix(quaty, quatz, .5f);
      }
    else if(axisZ != 0 && axisX != 0)
      {
       rotQuat = glm::mix(quatx, quatz, .5f);
      }

    glm::mat4 RotationMatrix = mat4_cast(rotQuat);
    //movement below is a glm::vec3(0,0,1), usually.
    ViewMatrix =  glm::translate(movement)*RotationMatrix* ViewMatrix;
   //ModelMatrix = glm::RotationMatrix * ModelMatrix; //this and viewmatrix above are often changed trying to solve this. Don't take them too literally here, as they're the likely culprit.
    SkyboxViewMatrix = RotationMatrix * SkyboxViewMatrix;

With the above workarounds, I can rotate, then move, but, I can't rotate and move. This makes for a pretty unpleasant control scheme.

 

Anyhow, I'm certainly going about this the wrong way, but I'm uncertain where. It's possible in multiple places tongue.png. It's likely I learned how to translate things about incorrectly in the first place, and it's just now biting me. I had no difficulty in translating things when using Euler angles, but my rotations were wrong (I'm building a silly space sim). But, now using quaternions, things are rotating better, but I'm having this current problem.

 

Let me know if you need any other information. And, to those of you who helped me with my initial quaternion mess, feel free to sit this one out smile.png You're welcome to contribute, but I don't want to overtax anyone. I'm new here, and you've been a great community, and I don't want to overstep with too many inane questions (I think this is number 3 in the last two months).

 

Thanks in advance, and cheers smile.png

 

Misantes


Edited by Misantes, 11 June 2014 - 11:02 PM.

Beginner here <- please take any opinions with grain of salt :P


Sponsor:

#2 Misantes   GDNet+   -  Reputation: 1218

Like
0Likes
Like

Posted 12 June 2014 - 05:32 PM

Alright, so I've found that multiplying a quaternion-based matrix before the rotation matrix and then the translation afterward the RotationMatrix will make it so that the camera keeps translating while rotating, but this seems like a very inelegant solution, and I'm guessing still not the correct way to be going about this. So, technically, things seem to be working, but I'm still open to learning the proper way if anyone has some insights to this.

 

Here's what the workaround looks like now:

    if(glfwGetKey( window, GLFW_KEY_A ) == GLFW_PRESS || glfwGetKey( window, GLFW_KEY_D ) == GLFW_PRESS)
    {
        glm::quat movequat = glm::quat(0,0,1,0);
        glm::mat4 movequatM = mat4_cast(movequat);
        ViewMatrix = translationMatrix * RotationMatrix * movequatM * ViewMatrix;
    }


    else if(glfwGetKey( window, GLFW_KEY_W ) == GLFW_PRESS || glfwGetKey( window, GLFW_KEY_S ) == GLFW_PRESS)
    {
        glm::quat movequat = glm::quat(0,1,0,0);
        glm::mat4 movequatM = mat4_cast(movequat);
        ViewMatrix = translationMatrix * RotationMatrix * movequatM * ViewMatrix;
    }

    else
    {
        glm::quat movequat = glm::quat(0,0,0,1);
        glm::mat4 movequatM = mat4_cast(movequat);
        ViewMatrix = translationMatrix * RotationMatrix * movequatM * ViewMatrix;
    }

 

This seems to fix the multiplying by zero, but again, doesn't feel right (I seem to just be multiplying the rotation matrix by itself, but with no angle). Am I creating the RotationMatrix incorrectly, perhaps, and that's why this workaround is necessary? Anyhow, I'm going wrong somewhere in here, but uncertain where. I'd welcome any help.

Thanks again in advance, smile.png

 

edit* ack, and I didn't mean to bump my own thread, my first post just seemed so long, it felt weird adding to it, and I forgot it would bump it >,< won't happen again.


Edited by Misantes, 12 June 2014 - 09:50 PM.

Beginner here <- please take any opinions with grain of salt :P





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS