Jump to content
  • Advertisement
Sign in to follow this  
Vern777

Help, I have some Quaternion problems...

This topic is 4804 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, thanks for reading my post :) I'm trying to implement a third person camera system featuring azimuth,elevate, and dolly using quaternions. I use gluLookAt() so I have eye, view, and up vectors. I use a parametric vector line to represent my camera system (would this be a good idea?), such that: eye = view + t*u Where view is the view position, t the dolly variable, u is a unit directional vector. At t=1.0 the camera is 1.0 unit away from the object I'm looking at. u is a unit vector generated using quaternion. To generate U I do this: For azimuth I use: Qnew = q*p*conjugate(q) This transforms the quaternion p (representing a point). Where q is defined as q(0,(0,1,0)) So you see I rotate p about the Y axis. For elevate I do the same thing except I rotate p about the viewRight vector. However there is a problem with my elevation code. My camera will not rotate correctly about the viewRight vector unless the camera is directly facing the z axis. I.E instead of elevating straight up it veers to the left or right, it keeps on circling about... So if I azimuth 90 degree, and then elevate by 45 degrees, the rotation is off. Anyone know why? Also do you have to concatnate both the azimuth and elevate quaternions in order to use them? Can you azimuth, then extract the point p, then use elevate again on that point p. Do you have to create an azimuth quat, then an elevate quat, and concat these two and extract the point p? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Before trying to answer and just messing you up, let me ask a couple of questions. 'y' is up; what is considered to be forward, x or z? Also, what is viewRight? Is it a world axis such as x or z, or a local axis computed from your y rotation?

Share this post


Link to post
Share on other sites
I'm sorry I was not clear on these things :)

Forward vector is actually the vector I'm rotating. So it is viewForward.

I'm trying to azimuth about the world Y axis (up), elevating about the local viewRight vector.

In the end I use the parametric vector line equation to get the final view and eye to pass to gluLookAt()

I vaguely remeber reading some where using different basis is bad for quaternions.

Share this post


Link to post
Share on other sites
Perhaps the viewRight is incorrect.

THe behavior I have seems like that it is not elevating correctly about the right vector.

It is like I'm rotating about a constant right vector, thus the right vector does not reflect the right vector that is normal to both forward and up.

Share this post


Link to post
Share on other sites
I have a couple of thoughts but I don't want to jump to conclusions without understanding fully what you're trying to do. Perhaps you could post the relevant code? That is, just the portions pertaining to the problem - the camera rotation code, calculating the viewRight vector, calling gluLookAt(), etc.

Share this post


Link to post
Share on other sites
Yes I found the problem!

I was generating the up right vectors using this:

WARNING sloppy code ahead...

[source lan ="cpp"]
/**
*This method will recalculate our up and right vectors
*We pick and arbitray vector v.
*We cross v with _rotPosition to get a vector that is orthgonal to _rotPosition. X axis is a good canadiate.
*If v is close to (0,0,0) this means we picked v that is nearly parallel to _foward, we choose another arbitrary vector, y axis is good.
*By definition y axis is orthogonal to x axis so we are guaranteed to generate orthogonal vector with _forward.
*To get the _right vector we cross v and _forward.
*To get up vector we cross _right and _forward
*/

void PerspectiveCamera::recalUpRightVectors()
{
MVector3d v(1,0,0);
v = v.crossProduct(_rotPosition);
if(v.dotProduct(v) < M_EPSILON) //bad arbitray vector
{
v.setXYZ(0,1,0);
v = v.crossProduct(_rotPosition);
}
v.normalize();
_right = v.crossProduct(_rotPosition);
_right.normalize();
_up = _right.crossProduct(_rotPosition);
_up.normalize();


}



Which I think generates the orthogonal vectors but the right vector is not what I need.

So to fix it I also rotate my view right vector with the same quaternion that I use for the azimuth() method.

[source lan ="cpp"]
/**
* This method azimuth the camera by degrees around the focus point.
*
* @param double degrees the degree of rotation
* @return void
**/

void PerspectiveCamera::azimuth(double degrees)
{

//formula to transform a vector quaternion

using quaternion
//about unit axis W is
//q^ = q*p*~q (where ~q is conjugate of q)
degrees *= PIOVER180; //convert to radian
MVector3d focusUp(0,1,0);
double costhetaover2 = cos(degrees/2);
double sinthetaover2 = sin(degrees/2);
MQuaternion q(costhetaover2,focusUp*sinthetaover2);
//_rotPosition.normalize();
MQuaternion p(0,_rotPosition);
MQuaternion q1;
q1.conjugate(q);
MQuaternion ans;
ans.setEqualTo(q*p*q1);
ans.getImaginary(_rotPosition);
//rotate right vector
p.setEqualTo(0,_right);
ans.setEqualTo(q*p*q1);
ans.getImaginary(_right);
}




And then I use gluLookAt()

[source lan ="cpp"]
/**
* Applies gluLookAt()
*/

void PerspectiveCamera::look()
{
//recalUpRightVectors();
//_position.setEqualTo(_position + _dollyVector);



_position.setEqualTo(_focus + _rotPosition*_dollyT);
gluLookAt(_position.v[0], _position.v[1], _position.v[2],
_focus.v[0], _focus.v[1], _focus.v[2],
0,1,0);
//_up.v[0], _up.v[1], _up.v[2]);
//_dollyVector.setXYZ(0,0,0);
}



I think this fixed the problem. Hope my logic didn't fail me again somewhere lol...

I love this site.

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!