Hello Guest

Isometric Camera

  • 3 Replies
  • 6441 Views
Isometric Camera
« on: November 26, 2014, 04:30:59 »
EDIT: I could just do "glTranslatef((-yaw / 2) - zoom, -zoom, (yaw / 2) - zoom)". So I guess the new question is, is that the best way to do it?

Hey everyone, so I'm working on an isometric top down game. So far it's working out pretty well. My problem is...

I'm trying to make the mouse move the camera in this isometric view. So I can easily get the Y axis of the mouse to control up/down with glTranslatef(pitch, 0, pitch), but I also want to move the camera left/right. Since I'm drawing a true isometric view, left/right is not a visual axis. Left/right is an imaginary line intersecting the X axis and Z axis. I want to move the camera along this line. For the following image, pretend this imaginary axis is "Q".



So how can I move the camera along imaginary "Q"?

I have an isometric perspective set up using gluLookAt. This works fine. My code for that:
Code: [Select]
glPopAttrib();
glPushAttrib(GL_ENABLE_BIT);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glViewport(0, 0, Display.getWidth(), Display.getHeight());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45, (float)Display.getWidth() / (float)Display.getHeight(), 0.1f, 100);

final float distance = (float)Math.sqrt(1.0d / 3.0d);

gluLookAt(distance, distance, distance,
0, 0, 0,
0, 1, 0);
glTranslatef(-5, -5, -5);
//glRotatef(0, 0, 0, 0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

So in the main loop I do this:
Code: [Select]
dx = Mouse.getDX();
dy = Mouse.getDY();

pitch += dy * 0.05;
yaw += dx * 0.05;

if(Keyboard.isKeyDown(Settings.VIEW_UP)) pitch += Settings.VIEW_MOVE_SPEED;
if(Keyboard.isKeyDown(Settings.VIEW_DOWN)) pitch -= Settings.VIEW_MOVE_SPEED;
if(Keyboard.isKeyDown(Settings.VIEW_LEFT)) /* TODO */;
if(Keyboard.isKeyDown(Settings.VIEW_RIGHT)) /* TODO */;

glLoadIdentity();

glTranslatef(pitch - zoom, -zoom, pitch - zoom);

Just a note: I removed some code just for simplicity when posting this.
Just another note: Sorry if some of this is confusing. I'm not a very good at explaining things. If you have any clarifying questions, feel free to ask.

Thanks!
« Last Edit: November 26, 2014, 05:41:19 by oyasunadev »

Re: Isometric Camera
« Reply #1 on: November 26, 2014, 06:43:21 »
You could also do this:

Code: [Select]
float x = 0f;
float z = 0f;

float ry = 45f;

(check input method) {
       z += Math.cos(Math.toRadians(ry-90)) * speed;
       x -= Math.sin(Math.toRadians(ry-90)) * speed;
}

(render method) {
      glMatrixMode(GL_PROJECTION);
      glTranslatef(x,0,z);
      glRotatef(ry, 0, 1, 0);
      glMatrixMode(GL_MODELVIEW);
      render();
}

This moves the camera sideways on  45-degree axis.
To move in the opposite direction, put negative speed instead of just speed
« Last Edit: November 26, 2014, 09:47:11 by Andrew_3ds »

*

Kai

Re: Isometric Camera
« Reply #2 on: November 26, 2014, 20:21:23 »
To move the camera along its own local coordinate system's x-axis, you would simply need to compute the camera's "right" vector as the cross product of the camera's "direction" vector (which itself is subtraction of "look at" point and camera position, like you specify for gluLookAt) and the camera's "up" vector.

So: right = direction x up

Then, you would simply need to offset the camera's position and the "look at" position, that you give to gluLookAt, by any scaled "right" vector.
Note: Be sure to normalize the vectors first, or else your computed "right" vector would also not be normalized.

To move along the y-axis, you would offset the camera's position and "look at" position by a scaled "up" vector, which is NOT the "up" vector you specify via "gluLookAt" but is itself the cross product of your previously computed "right" vector and the "direction" vector of the camera.

So: up = right x direction

Computing the "up" vector like this ensures that, as you tilt your camera up and down (apply "pitch" that is), your "up" direction follows along and does not always point to world (0,1,0). So, moving up and down works then as expected.

One noteworthy thing is, that this computation gives you also an orthonormal basis (right, up, direction) for rotating any vector from local camera coordinate system to world coordinates. So this transformation is essentially what gluLookAt computes internally, only that gluLookAt also adds the translation components (camera position) to it and that it then computes the inverse of this transformation, since OpenGL wants to transform from world-to-camera.

Hope, that helps!
« Last Edit: November 27, 2014, 00:17:11 by Kai »

Re: Isometric Camera
« Reply #3 on: November 27, 2014, 03:06:54 »
Thanks to both.