RE: Do I need to use/do glm::quat things or do I need rotX, rotY, rotZ, for some code where the camera spins around on a sphere centred on the model?
You can use either strategy (i.e. quaternions or euler angles ala degrees). Some people argue about the pros and cons of each too (there is always arguing going on somewhere [mostly?] in the world so we'll leave that alone).
I just so happen to have been playing around with an FPS and Orbit cameras recently, so this might help: It's one in a zillion! ..I mean It's one of those zillion.
glm can be a great tool. You can save yourself a smidge of code by calling something like:
glm::mat4 R = glm::yawPitchRoll(yawf,pitchf,0.0f);
to rotate using quaternions euler angles as input.
Then you could do the following to Update() a camera transformation:
glm::vec3 T = glm::vec3(0,0,dist);
T = glm::vec3(R*glm::vec4(T,0.0f));
*position = *target + T;
*look = glm::normalize(*target-*position);
*up = glm::vec3(R*glm::vec4(*UP,0.0f));
*right = glm::cross(*look,*up);
*V = glm::lookAt(*position, *target, *up);
That was easy! A Spam of code!
Now we just have to translate that into english. anyone?
But lets back up a bit. As far as I can tell you are describing an orbit camera! Let me try and paraphrase your stated goal:
The orbit camera works the opposite way to FPS, ...yeah?. Rather than the position of the camera
staying fixed, the target remains fixed, while the camera moves or rotates around the target.
How does that sound? That's an orbit camera. An obviously good analogy so let's use it?
Since you don't seem very sure about it, I suggest we just stick with that analogy. Sound OK?
Then think about this:
Say we have a target position (the centre of a model..say)
We get the distance(dist) between the target position(target) and the camera position(position) and
turn it into a vector:
glm::vec3 T = glm::vec3(0,0,dist); // turn it into a vector
Then translate this vector by the current rotation matrix:
T = glm::vec3(R*glm::vec4(T,0.0f));
Then adding this translation vector to the target position gives us the new camera position:
*position = *target + T;
That's it.. well almost. So far, we have the new position for the camera to moved to. All we do next is update the camera look, up and right vectors(re-orientate the camera) and view matrix or to be really dry we can say "Recalculate the orthonormal basis and then the view matrix" and its done (ready for the next frame).
The problem with giving code examples is that sometimes there are diminishing returns from explanations of them.. or maybe not... if you can figure it out yourself ... like a puzzle. Trying to figure out what a piece of code does is all part of programming (and lets me off the hook for being lazy!).
You might ask some interesting questions like " What is T or V or UP"? No,.. just kidding!
They are obvious questions, with hopefully obvious answers.
Something a little more interesting you might ask is:
* How do we get the distance(dist) between the target position(target) and the camera position(position) ?
//First set the position then the target and use glm::distance():
void SetPosition(const glm::vec3& p)
{ *position = p; }
void SetTarget(const glm::vec3& tgt)
{ *target = tgt;
distance = glm::distance(*position, *target);
}
glm::distance() is like most bits of code: you can do internals of them yourself instead of using glm if you wish.
So, most of this (I think) comes from The targetcamera section of an Opengl Cookbook: http://www.packtpub.com/opengl-development-cookbook/book
Nothing particularly new in there, Mainly fairly neat code examples using glm that is good to play with. Not sure if I remember it being very "beginner friendly" though. But it does spell out the full code per class that is very easy to modify and to drop into something suitable. Among other things it contains an (FPS) free camera and (orbit/turntable/arcball?) target camera both derived from a base camera class: just what you seem to be starting on, it seems, from your post.
*Another question: What if you wanted to use good ol' fashion degrees (euler angles) ? (that, I assume is your mention of rotX, rotY, rotZ?).
Just replace the quaternion form with the euler form at this line:
An alternative to using glm::yawPitchRoll() is to do it ourselves using glm::rotate():
// correction: this is not quaternions. This is a euler angles version also..sorry
//glm::mat4 R = glm::yawPitchRoll(yawf,pitchf,0.0f);
// produce equivalent effect using glm::rotate()
float xr = pitchDegrees;
float yr = yawDegrees;
glm::mat4 ViewTranslate = glm::mat4(1.0f);
glm::mat4 RY = glm::rotate(ViewTranslate,yr,glm::vec3(0.0f,1.0f,0.0f));//yaw
glm::mat4 RX = glm::rotate(RY,xr,glm::vec3(1.0f,0.0f,0.0f));//pitch
glm::mat4 R = glm::rotate(RX,0.0f,glm::vec3(0.0f,0.0f,1.0f));//no roll, currently redundant but exists anyway
Both methods depend on how you get your input angles with something like camera->Rotate() method like so:
Rotate(const float yaw, const float pitch, const float roll)
{
yawf=glm::radians(y);
pitchf=glm::radians(p);
rollf=glm::radians(r);
// and/or you can store angles in degrees.
yawDegrees = yaw;
pitchDegrees = pitch;
rollDegrees = roll;
Update();
}
What is passed to Rotate can be the mouse Delta positions i.e.The position relative to its last position (or some filtered value thereof).
Getting you hands on the Cookbook may help. A source code download comes with this bit of leisurely reading. With this target camera you have the added bonus of setting the target to any position you desire (a staple of any good 3D model editor I imagine). Hence the authors' emphasis on this orbit camera being a target camera.
Cameras are fun.
The hard part might be figuring out how to build this into your achitecture?