Create quaternion with inverse rotation(s)

Started by
4 comments, last by Vexator 12 years, 8 months ago
Ignore this, see last post instead. Thank you!

Let's say I have a quaternion which represents a camera's orientation about the x and y axis. Can I create a quaternion from that which represents the inverse rotations around those axes?

I need this for the following reason: So far I've had entities which computed their view matrix like this:

// m_rotation is a quaternion, m_translation a vector
mat4 rotationMatrix = glm::mat4_cast( m_rotation );
mat4 translationMatrix = glm::translate( mat4(), m_translation );

m_viewMatrix = translationMatrix*rotationMatrix


On top of that, I had a separate camera class which computed its view matrix like this:

mat4 rotationMatrix = glm::mat4_cast( m_rotation );
mat4 translationMatrix = glm::translate( mat4(), m_translation );

// rotation first, to rotate around camera's center instead of the scene's origin
m_viewMatrix = rotationMatrix*translationMatrix


Now I'd like to combine the two. A camera would have to be attached to an entity to be translated and rotated. So I could e.g. have an entity which has both a camera and a first-person weapon model attached to it, and translating the entity would translate both the camera and the weapon in the same way.
Now, if I simply use the rotation-second view matrix of the entity for the camera as well, the weapon is displayed properly but the camera rotates around the scene's origin instead of around its own position. If I instead compute a separate rotation-first view matrix from the entity's translation and rotation matrices and use that for the camera, the camera rotates around its own center (great!) but the weapon is rotated the other way round.

So I guess I'll have to somehow invert the entity's rotation quaternion/matrix before using it to create a rotation-first view matrix for the camera, so that both camera and other entity components like the weapon rotate in the same way. So how would I do that? glm::inverse(rotation) doesn't do the trick.

Thank you!
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
Advertisement
Bumping, elaborated on the problem, still hoping for replies.
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
I don't understand all what you have written, but attaching a camera to an object is commonly done using forward kinematics.

For any object in the scene (also the camera) compose the local transformation matrix, i.e. the transformation that computes the placement of the object w.r.t. its reference co-ordinate frame, as
L := R * T
(when using row vectors what I assume you do; if not, then reverse all the orders of matrix multiplications in this post). Notice that this first rotates the object and hence rotation happens to occur w.r.t. the origin of the object. The rotated object is then translated to its desired position.

If the object is related to the world directly, then the model transformation matrix is identical to the local transformation matrix
M = L
but if the object's local matrix is given w.r.t. to another object's local frame, then the inner object's local matrix can be expressed further in the reference frame of the parental object as
L * L[sub]P[/sub]
with L[sub]P[/sub] being the local transformation matrix of the said parental object. This means that, starting from an inner object and going up a chain of parental objects, the model matrix becomes
M := L * L[sub]P1[/sub] * L[sub]P2[/sub] * ... * L[sub]Pn[/sub]

Now think of the camera as an object attached to an object that itself is given in world space. Hence the camera matrix (i.e. the model matrix of the camera) is
C := L * L[sub]P1[/sub]
The view matrix is the inverse of the camera matrix, so
V := C[sup]-1[/sup] = L[sub]P1[/sub][sup]-1[/sup] * L[sup]-1[/sup]

To render an object's mesh you have to use the chain of local > world > view, where local > world is named a model matrix above, so
M * V
is the way to go.

Example: Assume that you want to render the camera itself (regardless of that a camera does not see itself), then it would be
M * V = C * V = V[sup]-1[/sup] * V = I
and hence the identity transformation; the camera sees itself transformation invariant. That's fine.

Example: Assume that you want to render the camera parental object, then
L[sub]P1[/sub] * V = L[sub]P1[/sub] * L[sub]P1[/sub][sup]-1[/sup] * L[sup]-1[/sup] = L[sup]-1[/sup]
and hence it depends not on the placement of the parental object in the world but only on the relation of the camera to its parental object. That's fine.


Is that what you're looking for?
I'll try to clarify. I've got the following hierachy:

TRANSFORM (translation, rotation, scaling)
- CAMERA (view matrix)
- MESH (model matrix)


The transform object has functions such as translate() and rotate() to modify its position and orientation in the world. To this transform, two objects are attached: a camera and a mesh which represents a first person weapon. When the transform is translated or rotated, i want the camera and the mesh to translate and rotate accordingly.

The camera requires a view matrix and the mesh requires a model matrix. Both of these matrices have to be computed every frame from the transform's translation and rotation. I got it working now, with the following code:

// view matrix
mat4 rotationMatrix = glm::mat4_cast( m_rotation );
mat4 translationMatrix = glm::translate( mat4(), m_translation );

m_viewMatrix = rotationMatrix*translationMatrix;

// model matrix
mat4 rotationMatrixInverse = inverse( rotationMatrix );
mat4 translationMatrixInverse = inverse( translationMatrix );

m_modelMatrix = translationMatrixInverse*rotationMatrixInverse;


As you can see, I have to invert the rotation and the translation matrices before using them to compute the model matrix, so that mesh and camera align. If I use the inverted matrices to compute the view matrix instead (as it should be), the camera's rotation is distorted.

So my question is: what do I have to change to be able to use the actual translation and rotation to compute the model matrix and the inverted values for the view matrix?
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
[font="arial, verdana, tahoma, sans-serif"]The situation you are describing is exactly what I've expressed in my previous post up and inclusive the 1st example.

However, regardless whether you compute[/font]
M[sup]-1[/sup] * C = ( T[sup]-1[/sup] * R[sup]-1[/sup] ) * ( R * T ) = I
or else
M * C[sup]-1[/sup] = ( R * T ) * ( T[sup]-1[/sup] * R[sup]-1[/sup] ) = I
or else
C[sup]-1[/sup] * M = ( T[sup]-1[/sup] * R[sup]-1[/sup] ) * ( R * T ) = I
or else
C * M[sup]-1[/sup] = ( R * T ) * ( T[sup]-1[/sup] * R[sup]-1[/sup] ) = I
you ever get identity in this special arrangement. So if "camera rotation gets distorted" ... how exactly do you concatenate the model and the view matrix? Are you further sure that your inverse() works correctly?


The camera requires a view matrix and the mesh requires a model matrix. ...

Not exactly. Instead, both objects require a placement matrix, which is often named the camera matrix for the camera and the model matrix for the model. In this case it is the same matrix. The view matrix, on the other hand, is required by the rendering process and computed by inverting the camera matrix.
thank you for not giving up on me!

How exactly do you concatenate the model and the view matrix?[/quote]

after computing the two matrices from the transform's position and orientation, i upload them to the shader and compute the final vertex position like this (in GLSL):

uniform Transform
{
mat4 view; // Transform::m_viewMatrix
mat4 model; // Transform::m_modelMatrix
} transform;

mat4 modelView = transform.view*transform.model;
mat4 modelViewProjection = projection.perspective*modelView;

gl_Position = modelViewProjection*in_vertexPos;


Are you further sure that your inverse() works correctly?[/quote]

i'm using glm::inverse(), see line 505 and the following here: http://www.assembla....rix.inl?rev=108

I made two short videos to illustrate what's wrong. In the first video, rotation looks ok, in the second one its "distorted":

http://www.youtube.c...h?v=7xgRv9JYfKc
http://www.youtube.c...h?v=6quv9-PaV9w
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com

This topic is closed to new replies.

Advertisement