# OpenGL OpenGl translating with quaternion based view/camera

## Recommended Posts

Misantes    2092

Alright, first let me promise this will be the last thread on quaternions I will make 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 )

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 . 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 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).

Misantes

Edited by Misantes

##### Share on other sites
Misantes    2092

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.

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

## Create an account

Register a new account

• ### Similar Content

• Hello. I'm Programmer who is in search of 2D game project who preferably uses OpenGL and C++. You can see my projects in GitHub. Project genre doesn't matter (except MMO's :D).

• Hello, My name is Matt. I am a programmer. I mostly use Java, but can use C++ and various other languages. I'm looking for someone to partner up with for random projects, preferably using OpenGL, though I'd be open to just about anything. If you're interested you can contact me on Skype or on here, thank you!
Skype: Mangodoor408
• By tyhender
Hello, my name is Mark. I'm hobby programmer.
So recently,I thought that it's good idea to find people to create a full 3D engine. I'm looking for people experienced in scripting 3D shaders and implementing physics into engine(game)(we are going to use the React physics engine).
And,ye,no money =D I'm just looking for hobbyists that will be proud of their work. If engine(or game) will have financial succes,well,then maybe =D
Sorry for late replies.
I mostly give more information when people PM me,but this post is REALLY short,even for me =D
So here's few more points:
Engine will use openGL and SDL for graphics. It will use React3D physics library for physics simulation. Engine(most probably,atleast for the first part) won't have graphical fron-end,it will be a framework . I think final engine should be enough to set up an FPS in a couple of minutes. A bit about my self:
I've been programming for 7 years total. I learned very slowly it as "secondary interesting thing" for like 3 years, but then began to script more seriously.  My primary language is C++,which we are going to use for the engine. Yes,I did 3D graphics with physics simulation before. No, my portfolio isn't very impressive. I'm working on that No,I wasn't employed officially. If anybody need to know more PM me.

• By Zaphyk
I am developing my engine using the OpenGL 3.3 compatibility profile. It runs as expected on my NVIDIA card and on my Intel Card however when I tried it on an AMD setup it ran 3 times worse than on the other setups. Could this be a AMD driver thing or is this probably a problem with my OGL code? Could a different code standard create such bad performance?

• I'm trying to get some legacy OpenGL code to run with a shader pipeline,
The legacy code uses glVertexPointer(), glColorPointer(), glNormalPointer() and glTexCoordPointer() to supply the vertex information.
I know that it should be using setVertexAttribPointer() etc to clearly define the layout but that is not an option right now since the legacy code can't be modified to that extent.
I've got a version 330 vertex shader to somewhat work:
#version 330 uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; layout(location = 0) in vec4 Vertex; layout(location = 2) in vec4 Normal; // Velocity layout(location = 3) in vec3 TexCoord; // TODO: is this the right layout location? out VertexData { vec4 color; vec3 velocity; float size; } VertexOut; void main(void) { vec4 p0 = Vertex; vec4 p1 = Vertex + vec4(Normal.x, Normal.y, Normal.z, 0.0f); vec3 velocity = (osg_ModelViewProjectionMatrix * p1 - osg_ModelViewProjectionMatrix * p0).xyz; VertexOut.velocity = velocity; VertexOut.size = TexCoord.y; gl_Position = osg_ModelViewMatrix * Vertex; } What works is the Vertex and Normal information that the legacy C++ OpenGL code seem to provide in layout location 0 and 2. This is fine.
What I'm not getting to work is the TexCoord information that is supplied by a glTexCoordPointer() call in C++.
Question:
What layout location is the old standard pipeline using for glTexCoordPointer()? Or is this undefined?

Side note: I'm trying to get an OpenSceneGraph 3.4.0 particle system to use custom vertex, geometry and fragment shaders for rendering the particles.

• 10
• 11
• 24
• 26
• 17