Urgent Help: quaternion based view transform like in ogre
Posted: Sun Jul 17, 2005 8:27 pm
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
m_up.Normalize();
//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
m_look.Normalize();
//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:
camPos
====
(-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
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
m_up.Normalize();
//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
m_look.Normalize();
//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:
camPos
====
(-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