Urgent Help: quaternion based view transform like in ogre

Get answers to all your basic programming questions. No Ogre questions, please!
Post Reply
Posts: 5
Joined: Sun Jul 17, 2005 7:56 pm

Urgent Help: quaternion based view transform like in ogre

Post by silvia_steven_2000 »

Hi All

I have spent allot of time trying to resolve my problem but I could not
find a solution. I posted my question on gamedev but no body helped.
may be they are scared from quaternions. then I remembered that OGRE
uses quaternions extensively since I took a look at it the very first
time it was released. I am using directx so the coordinate system is left handed
where the positive z axis goes into the screen. I am trying to build a simple
camera. I am given the up vector, the position of the camera and the target to
look at. with this information in hand, it is very easy to build a left handed
look at matrix, I already did that but this is not what I want. my scene nodes
including cameras have their orientaions stored as quaternions. wheneve I need
to animate a node I manipulate the orientaion quaternion then finally it gets
converted into a world transform. this is working fine with me but I could not
make it work in case of camera. the same way I need to manipulate the camera
orientation quaternion and finally convert it to a view transform. sorry for
the long explanation but I think it might help. here is what I did :

the view transfom is the inverse of the transform needed to move the
camera position to the origin and realign the camera look, up and right with
the z, u and x axes

//Set camera position
m_relPos = camPos

//up vector

//Calculate look at vector
//m_relPos below should be the absolute pos but here
//I am assuming the camera has no parent
m_look = m_target - m_relPos

//Normalize the look vector

//Quaternion to rotate the look to z
core::Quaternion look2z;

//Quaternion to rotate the up to y
core::Quaternion up2y;

//calculate look2z
look2z = look2z.getRotationTo(m_look, core::Vector3::UNITZ);

//calculate up2y
up2y = up2y.getRotationTo(m_up, core::Vector3::UNITY);

//Update camera orientation
m_relOrient = look2z * up2y;

so far the camera m_relPos and m_relOrient are there
convert the m_relOrient to rotation matrix and set the translation
to m_relPos and store it in m_relTransform

//Calculate view transform as:
m_view = m_relTransform.getInverse();

what is really confusing me is that I guess there is something
tricky here. for example:

if we look at the origin from the positions:


(-10, 0, 0); ok
(-10, 10, 0); ok
(-10, 0, -10); ok
(-10, 10, -10); view is shifted or rotated
(0, 0, -10); ok
(0, 10, -10); view is shifted or rotated
(10, 0, -10); ok
(10, 10, -10); view is shifted or rotated
(10, 0, 0); ok
(10, 10, 0); ok

it does not work only in the cases where the y and z of the look vector
are both non zero. I can not find an explanation for this. I am suspicious
about the fact that direct x is a left handed system while the quaternion
math assumes right handed system.

sorry for the long message, I entended to do that to make things clear.
any help is appreciated, I think if Steve 'sinbad' Streeting
take a look at this might figure it out since he used quats
allot in the engine design.

thanks again
User avatar
OGRE Community Helper
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am

Post by discipline »

Hi there. First some disciplining:
- Be sure to read the forum rules before posting.
- Next, don't put "Urgent help" in your subject line.
- Enclose your code within blocks that look like this:

Code: Select all

 [ /code].  The forum will format your code nicely.  Please edit your post and do this.
- And there are more people who can help you besides just sinbad.  He's a busy man.

Now that that is taken care of, you may find [url=http://www.ogre3d.org/wiki/index.php/Quaternion_and_Rotation_Primer]our quaternion primer[/url] useful.

I'm not sure what you are trying to accomplish, so I'm going to guess.  I think you want an fps style camera where up and the top of the screen are always parallel.  If you look up, to the right and down at right angles, up is still at the top of your screen.  However in a descent style game, up-right-down will induce a roll and up will actually be pointing to the right side of your monitor.

The quaternion primer above shows how to take care of this.  Basically, remove the y components of your vectors before you normalize or use getRotationTo.  If that's not what you are after, please elaborate on what specifically it is you want and what is wrong.  (ie what exactly does "shifted or rotated" mean?)
Posts: 5
Joined: Sun Jul 17, 2005 7:56 pm

Post by silvia_steven_2000 »

I am so sorry, honestly I did not read the rules, sorry again.

actually not, I am not doing an fps.

I need to implement a simple a look at camera, position it somewhere and set a target to look at. the input information is the position, up vector and target point. using such info I could build a left handed look at matrix. however what I need is to convert the position, up and look to an orientaion quaternion and a position. then convert that into a view transform. why I need that, because I used to animate nodes using their orientation quaternions. whenever the orientation is manipulated, the view is changed. looking to the origin from the positions I provided is working fine except in the positions I marked not ok. I mean by shifted or rotated, is that I can see my object located at the origin but it is not in the middle of the screen , it is at the top left corner of the screen.
I do not know how one can post images , I could submit some snapshots where it is working and not working.
User avatar
OGRE Community Helper
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am

Post by discipline »

For snapshots, you need web space. then you'd put them in like this: [img]http://image_url [ /img].

Hmm, Does your engine allow for working exclusively in quaternions? Why not just rotate the camera by m_relOrient once you've calculated it? Maybe there's something wrong in your matrix conversions.

Does it also not work when Y and Z are both positive 10? What about if your lookat point is not the origin. I bet that if your origin point is all non-zero numbers, that your camera will almost always be off.

Here's how I think about it, and what I'd try first working in Ogre:

Code: Select all

Vector3 target(a,b,c);
// Get vector from camera to target
Vector3 direction = target - mCamera->getPosition();
// Get vector the camera is pointing towards
Vector3 camDir = mCamera->getOrientation * Vector3::NEGATIVE_UNIT_Z; // Direction camera was initially facing

// Flatten vectors
Vector3 work1(camDir.x, 0, camDir.z);            
Vecotr3 work2(directin.x, 0, direction.z);

// Get rotatation on XZ plane only
Quaternion quat = work1.getRotationTo(work2);
// New direction vector
camDir = camDir * quat;       
// Add in pitch rotation
quat = quat * camDir.getRotationTo(direction);

// Rotate
That should do it. After the first quat calculation, the only difference between the camera's direction and target is a local pitch. The axis of rotation is the cross product between the two vectors camDir and direction. The angle of rotation is an ArcCos of the dot product between the two. This does assume your camera starts out with up at the top of your screen.
Posts: 5
Joined: Sun Jul 17, 2005 7:56 pm

Post by silvia_steven_2000 »

thanks allot for the input, I printed out the quaternion primer and skimmed through it. it opened my eyes on some hints that might solve the problem. I will try the hints and see what happens. I might get back to the forum. thanks for replies and sorry for not following the rules.
Posts: 5
Joined: Sun Jul 17, 2005 7:56 pm

Post by silvia_steven_2000 »

Thanks allot guys, I fixed the problem, I just added an extra checking to my own way of calculating the view transform and it is working fine. the quaternion primer gave a hint that I would have never solved it without. my problem basically was in finding the quaternion to rotate a vector v to -v. in such cases there are infinite number of ways to do it so one should pick one axis and 180 degrees. thanks again and sorry for not following the rules. I might get back to the forum since u guys are helpful.
Post Reply