This Function handles the rotation, but as you can see, it's mostly empty (i don't know what to do next). What i did is Get the change in mouse position in x and y direction using the WM_INPUT message. I then created 2 long variables that hold the angle which is simply the change in coordinates divided by a factor:

Please note that i want the camera to rotate around the origin and keep a certain distance away from it. (This is for a 3D tetris game)
I know that i can rotate the scene instead of the camera, but i can use the same code to do it, right?

0

Share this post

Link to post

Share on other sites

You need to add to your quaternion a constructor which takes an AxisAngle. Create two quaterions, one for each rotation. Multiply them together and by the current transform to obtain the rotated transform.

Share this post

Link to post

Share on other sites

Original post by WaaayoffThat's what i mean, i don't know how. What do i normalize? what exactly is the conjugate used for? How do i specify around which axis to rotate..

Please tell me what to do step by step or maybe give me the code so i can study it? (a code a beginner can understand)

What graphics API are you using?

Also, is there any particular reason you're using quaternions for this? If you're new to 3-d math, it seems it might make more sense to hold off on using quaternions and just stick with basic matrix and vector math for the time being.

0

Share this post

Link to post

Share on other sites

Well i wanted to use Euler angles, but everyone kept telling me not to because of something called gimbal lock, whatever that is. I don't mind the math, it's not like i don't understand it, it's just that i don't know what the math IS.

Share this post

Link to post

Share on other sites

Well i wanted to use Euler angles, but everyone kept telling me not to because of something called gimbal lock, whatever that is.

Don't listen to 'everyone' :-) There's a lot of misinformation and misunderstanding out there regarding both Euler angles and quaternions, so my advice would be to learn the material yourself so that you can make your own determinations about which tools to use and when.

In any case, based on what you've described, an Euler-angle pair (e.g. pitch and yaw) sounds like an appropriate solution. It sounds to me like what you want is a standard 'orbital' camera that can rotate laterally around the target point and also pitch up and down. For this type of motion, Euler/spherical angles are perfectly appropriate, gimbal lock is not an issue, and quaternions are not needed (well, quaternions aren't really ever *needed*, per se, but they do have some advantages in certain situations).

Although using 'look at' functions such as gluLookAt() or the DirectX equivalent can sometimes add unnecessary confusion and just get in the way (IMO), for an orbital camera I think a look-at function can be a good choice. All you need to do is track the yaw, pitch, and distance to the target, perform a spherical-to-Cartesian coordinate conversion to generate the camera position from these parameters, and then plug the parameters into a DX 'look-at' function to get your view matrix. (Note that if it's possible for the camera to be more or less directly above or below the target point, you may have to handle those cases separately.)

Obviously I glossed over the details there, but I'd recommend maybe searching the forum archives for (e.g.) 'orbital camera' and see if you can find some examples. And if you get stuck, I or someone else should be able to offer some more details on how an orbital camera can be implemented.

All that's been done here is getting the change Mouses position in the x and y directions and I have then passed them into camera->update were the magic will happen.

There are a few maths functions you'll need for this, and they are: Vector crossProduct, create unit Length vector, quaternion conjugate, convert vector to quaternion and a quaternion multiply, I see you have some there already.

void Camera::update(tVector3 *MouseDir){// axis to rotate around will be the normal to the UP vector and// vector between the camera position and lookat. tVector3 UP(0.0f,1.0f,0.0f);// World Space Up Vector tVector3 v = m_lookat - m_position; tVector3 axis = Math::crossProduct(&v, &m_up);

// Turn it into a unit vector axis = Math::unitVector(&axis);

rotateCamera(MouseDir->y, &axis); rotateCamera(MouseDir->x, &UP);}

Here I'm creating the axis that you will want to rotate about.The rotation about the UP vector is fairly straight forward.The 'x-axis' for the other rotation is given by the cross product of the up vector and the vector between the camera's lookat and current position. This is a local x-axis to the camera, not the world x-axis.

Here's a wee diagram to illustrate this.

What we want to do now is rotate the view vector(v = m_lookat - m_position) by an angle(MouseDir.x/y) about an axis(UP and axis). So now we have everything needed to rotate the camera so lets look at the rotateCamera function.

In this case P refers to our view vector (m_lookat - m_position)(note this will only work is q if a unit quaternion which it will be as long as your axis is a unit vector, else you would need to use the inverse or R instead of the conjugate.)

So rotating the vector now boils down to 2 quaternion multiplications.

You can do the quaternion multiplications either (R*V)*R' or R*(V*R') as long as the order is the same.The rotated view vector is now called result. To then convert this into the new position of the camera in world space it will be the camera's lookat + result.

Now the camera class will have the camera position and lookat you can extract and slap into your gluLookat or DirectX equivilent.

Theres 1 extra thing missing here though. The camera can't go past the vertical.To do this you will need to change the local up vector (m_up) this will be done by applying the same rotation to the m_up as you did with view. This will allow the camera to go around in a full sphere..ideal if yer idea is like tetrisSphere!