1
votes

In my app I have a set of object lying around the scene. They are all grouped inside box. When user zoom out to see whole box and starts rotate it then the pivot point is in the middle of box,. When you zoom in to see specific object inside then rotating camera so that the object that you are looking at (or space in front of you) then they are still rotating around this previous pivot point.

What I would like to achieve is to have pivot point always in front of camera. In other words, when you zoom out and see box it rotates as it is doing now. When you zoom in to specific object/space then camera rotate around it.

I've created simple images to show what I mean - triangle is camera, red box is some object/space and orange circle is a path on which element is going on while rotating. The first one is what I have now, the second what I'd like to have.

now

future

I know that in OpenGL there isn't something like camera, so in fact it is whole world moving and not one point. So far I've created something like that:

glPushMatrix();
glTranslatef(translate[0], translate[1], translate[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
DrawObject();
glPopMatrix();

translate is an array of values simulating camera movement.

EDIT:

After Ike answer I modified a little my code so now it looks like this:

glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();

So if I'm getting Iko's solution correctly now my biggest concern is calculating correctly pivot point according to place that I'm looking at. Is it correct thinking?

1

1 Answers

1
votes

One way to get this kind of representation is to kind of translate the pivot to the origin, then rotate, and then step backwards, away from the pivot.

Effectively you translate in the opposite direction of the pivot (negative pivot, effectively moving it to the origin). Then rotate to the desired viewing angle. And then "step back" (translate along -Z in a right-handed coordinate system).

Something like this:

mat4 modelview_matrix(float distance, const vec3& pivot, const vec3& rotation_xyz)
{
    mat4 distance_mat = tmat(0.0, 0.0, -distance);
    mat4 rot_mat = rmat(rotation_xyz[0], rotation_xyz[1], rotation_xyz[2]);
    mat4 pivot_mat = tmat(-pivot[0], -pivot[1], -pivot[2]);
    return distance_mat * rot_mat * pivot_mat;
}

tmat and rmat above are basically just constructing translation and rotation matrices.

That allows you to orbit the camera around a pivot of your choice. Panning can be achieved by actually moving the pivot around, giving you those CAD-style viewport navigation controls.

So if I'm getting Iko's solution correctly now my biggest concern is calculating correctly pivot point according to place that I'm looking at. Is it correct thinking?

Pretty much -- maybe with a slight tweak. That pivot point will always be what you look at -- it's going to be your center of interest. You can, for example, put it at the center of the bounding box of your scene, e.g. (some 3D software does this to fit/frame the view around the scene). After that, it's up to you to place the pivot point where you like based on the kind of software design you're after. The camera will always be looking at it.

Edit

glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();

For this kind of thing, you probably want something more like this:

glTranslatef(-pivot[0], -pivot[1], -pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(0, 0, -distance);

... and outside of pushing to the transformation stack and rendering individual objects (do this at the top of the call stack). That's what gives you something akin to "camera control".

Then when you render each object, push the current transformation and do the necessary local transformations for each object and child. That gives you something akin to objects moving around and being oriented in the world independently of the camera, and a motion hierarchy with parent-child relationships.