Sign in to follow this  
morasta

Transformations in View Space

Recommended Posts

morasta    100
I'm currently working on a project that implements a variety of transformations in different spaces. At the moment, everything is functioning as expected wrt the global coordinates (world space). Despite how the camera is rotated, it follows the correct axes as confirmed by the lines on my ground plane grid. The place I'm hung up at, is how to transform the objects wrt view space, that is, translating left using the GLUT controls moves it left on the viewport, not necessarily left in global coordinates. It depends on the camera really. Conceptually I haven't quite wrapped my head around how this would work. The best idea I've come up with is to unrotate the camera, not quite sure the best way to do this, then transform the object, and then re-rotate the entire scene. I should add that I'm not using gluLookAt. Any thoughts on the best way to go about attacking this problem?

Share this post


Link to post
Share on other sites
lightbringer    1070
Transforms always trip me up a bit with the conceptual thinking part. If I understood you correctly, you will want to first derive the ModelView matrix yourself, then apply transformations to that matrix, then transform it back into world space. I should note that I'm not familiar with GLUT - with this method you will need your own movement controls.

To derive the ModelView,

1) start with an identity matrix
2) multiply by the inverse of camera orientation matrix
3) translate by (model position minus camera position) vector
4) multiply by the model orientation matrix
5) scale if needed

That should be about right, though it's been a long time since I wrote that code (I have doubles for position values in my scenes and OpenGL can't deal with that). After that you should be in view space so you can translate/rotate the matrix as needed before reversing these operations to get back to world space. You can also load this matrix directly with glLoadMatrix(), if you want.

Share this post


Link to post
Share on other sites
morasta    100
Hi Lightbringer,
Thanks, that helps quite a bit. To simplify things, I'll just mention object translations (camera rotations still apply). Two types of handling are needed:
-Translate object wrt global coords
-Translate object wrt view space (a right translate moves it right in the window if the camera rotated a bit).

I think that describes what you said, please correct me if not. That said, the steps you provided make sense and were along the same lines as what I was thinking...which brings me to my next question: what's the best way to invert the camera "matrix." Right now I have it defined as simply:
float matrix[16]

So far I haven't come up with a very clean solution for this. Any thoughts?

Share this post


Link to post
Share on other sites
lightbringer    1070
The way I do it is I keep the camera position (vector3) separate from the camera orientation (quaternion). This way it becomes straightforward. The problem is, as I see it, that you will get back a matrix at the end if you reverse those operations, but you started with model and camera positions and orientations. Unless it's somehow possible to get that info back out of the matrix (I'm not sure how that works), you would have to store view-space translations and rotations separately. This way, you can do your normal operations in world space, then when it comes time to render just derive the ModelView matrix (since order of transformations in OpenGL is backwards, I think you will want to apply your view-space transformations before you start moving the camera), then glLoadMatrix(), then render.

The following shows how I derive the ModelView matrix. It might not be of much help to you unless you look into the LWJGL API to see what does what. Position is my own class which just abstracts basic operations, it works similarly to the LJWGL API. Transform just stores position and orientation.


public static Matrix4f deriveModelViewMatrix(Transform model, Transform camera) {
Matrix4f result = new Matrix4f();

// apply your view-space transforms to result here?

Vector3f pos = Position.subtract(model.position, camera.position, null);
Quaternion newOrient = new Quaternion();
Quaternion.mulInverse(newOrient, camera.orientation, newOrient);

Matrix4f.mul(result, MathUtils.quatToMatrix(newOrient), result);
result.translate(pos);
Matrix4f.mul(result, MathUtils.quatToMatrix(model.orientation), result);
result.scale(new Vector3f(model.scale, model.scale, model.scale));
return result;
}



Share this post


Link to post
Share on other sites
karwosts    840
For inverting the camera matrix one idea I've used was to always compute and store the inverse of the matrix every time you change the matrix.

This way you don't actually have to do any matrix inverting math, its always just there for you when you need it.

For example if you have two rotations and two transformations that you apply to your matrix (M), say named R1, T1, R2, T2.

If:

M = R1*T1*R2*T2;

than inverse matrix I = M' = T2'*R2'*T1'*R1'

So anytime you apply an transform (T) to matrix M

M = M*T, just also perform I = T'*I;

And if T is a translation, scale, or rotation, the inverse is just the opposite of that transform.

Pretty easy to do, you just bake this all into your matrix class and then you always have inverse available, and you don't have to worry about or remember what order your transforms were applied.





Share this post


Link to post
Share on other sites
morasta    100
Great suggestions so far, I think I'm almost there. Using what you guys suggested I'm now able to translate XY coords wrt the view space. Originally I thought the Z was working as well, but it appears to be simply scaling the object. Beyond that I'm not sure where to do my object rotation to avoid having it factor in the camera as well.

So far, here's the "pseudocode" version of what I'm doing.

-Compute transpose of the camera matrix -> m1
glMultMatrixf(m1)
Translatef(xcoord-xtrans, ycoord-ytrans, zcoord-ztrans) //these are negated for proper orientation
glMultMatrixf(camera matrix)

translatef(object x, object y, object z);
glmultmatrixf (object's rotations)
glScalef (object's x, y, z) //this one works perfectly of course

Do any of you guys see any glaring issues here? Can't seem to pinpoint where the issue lies, everything here makes sense in my head.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this