Jump to content
  • Advertisement
Sign in to follow this  
Vast

Rotations using quaternions

This topic is 4550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone. Basically, right now I am writing a camera, but I will need the code later to rotate all of my objects. So, my problem is that I wish to rotate my objects arbitrarily, without any constraints (such as if I drag the mouse up, I wish to have my camera rotate more and more until I can make a 360). Right now, it doesn't seem to work. Ok, what I am doing now is this: - Rotation around the Y axis (left and right) I rotate a quaternion qA around the (0,1,0) axis, by given degree, and store it. - Rotation around the X axis (up and down) (quaternion qB) I calculate the view vector (camView - camPos), normalize that, then I take a cross product of the view vector with my up vector, and use that as my axis to rotate around the X axis. That works, but when I look all the way down my view flips to go to the reverse, instead of continuing to rotate (I hope you know what i mean). Yes and I want to keep rotation so that if I keep dragging my mouse down eventually the world would be upside down. - Rotation around the Z axis (tilting) (quaternion qC) I didn't even get that to work :( Stupid stupid stupid. At the end, I multiply qA * qB (i ignore qC because it just doesn't work as i want) and then i do something that looks like this
CVector3 CQuaternion::Rotate (const CVector3& v) const
{
	CQuaternion vec2 = (*this) * CQuaternion(0, v.x, v.y, v.z) * CQuaternion (r, -x, -y, -z);

	return CVector3 (vec2.x, vec2.y, vec2.z);
}
(I forgot where I ripped that from. Code's not mine). the passed parameter is actually the viewVector calculated earlier. So, I get the result from that function taking the view vector, I set the camView to camPos + result, and voila! It works like a normal camera, but not what I want. If anyone could please give me a heads up on what I should do to make my unconstrained camera, I'd be highly grateful. Btw, I really don't want to use Matricies, or anything else (like OpenGL axis rotations). Thanks. - Tima

Share this post


Link to post
Share on other sites
Advertisement
Looks like you have got your order of multiplication incorrect. To rotate a vector by a quaternion, do the following multiplication (after embedding the vector in quat space, i.e. create quat from vector with w = 0 and x,y,z the vector)

q * v * q'

where v = vector embedded in quat space
q = quat representing the rotation
q' = quat conjugate (multiply x, y, z components by -1)

... the result is the x,y,z part of the quaternion multiplication.

EDIT: Looking at it again, that fuction you posted is correct since *this is a quaternion, the middle bit of the multiplication is the embedding of the vector in quat space, and the 3rd multiplicand is the quat conjugate of *this.

Share this post


Link to post
Share on other sites
A few comments:
  • Even though you say you don't want to use a matrix, I recommend that you do. Matrices are easier to learn and understand, and a matrix is better suited for a camera than a quaternion (for various practical reasons). Once you have implemented your camera using a matrix and you have figured out how cameras work, then you might look at using a quaternion.
  • Your camera flips around when looking up or looking down because it is pointing in a direction parallel to your up vector. You need to use you camera's local up vector rather than the world up vector if you want the camera to point up or down.
  • Look up Euler-angle-to-matrix (or Euler-angle-to-quaternion, if you insist) conversion. Compare to yours.

Share this post


Link to post
Share on other sites
Hmm. I see, I already have an implementation of Euler to Quat, and it works the same way. Still not going the way I want it to though.

Could you please elaborate on the concept of a "local" vector? would that be the vector perpendicular to my current view vector? I think I see where you are going with this... at least it is sort of making sense in my head.

What about rotation around the Z axis? Any ideas how I would go about doing that?

Thanks guys, you're being very helpful.

- Tima

Share this post


Link to post
Share on other sites
Something like this:
    camera.direction = normalize( target - camera.position );
camera.right = normalize( cross( camera.direction, camera.up ) ); // camera.up instead of world.up
camera.up = cross( camera.right, camera.direction )

Share this post


Link to post
Share on other sites
hmm, I see.

I have a couple of questions though.

First, would the initial value of camera.up be 0,1,0 (considering I use Y axis as up)?

Second, what is the difference between the target and camera.direction? Sorry, this should be obvious but I just don't see it, and then as addition how should target be updated in relation to the general camera set up?

I think thats all for now.
Thanks!


Regards,
- Tima

Share this post


Link to post
Share on other sites
Quote:
Original post by Vast
hmm, I see.

I have a couple of questions though.

First, would the initial value of camera.up be 0,1,0 (considering I use Y axis as up)?


Yes

Quote:

Second, what is the difference between the target and camera.direction? Sorry, this should be obvious but I just don't see it, and then as addition how should target be updated in relation to the general camera set up?


Direction = (normalised) vector from position to target = (normalised)
posTarget - posCam

Share this post


Link to post
Share on other sites
EDIT: nevermind, it all works fine!

Thank you very much for all of your help, it was a pleasure having to recieve help from you guys.

Here's the working code:

//==========================
// Get all the prerequisites
//==========================
vector3 direction = new vector3(view.x - position.x,
view.y - position.y,
view.z - position.z);
direction.Normalize();

right = direction.CrossProduct(up).GetNormalized();
up = right.CrossProduct(direction);

//=====================
// Do all the rotations
//=====================
rotation.SetRotation(-x, right);
rotation = rotation.Mul(new quaternion(y, up));
direction = rotation.Rotate(direction);

view.x = position.x + direction.x;
view.y = position.y + direction.y;
view.z = position.z + direction.z;



Thank you very very much :)
- Tima

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!