How to move camera in Perspective with the mouse ?

Hi,

I would like to move my camera with my mouse, a simple X,Y translation. In fact, I have a solution that work. To translate an object in space by using the mouse we use the glUnproject method to project the 2 screen coordinates to the space, then, we use the difference (delta) to translate the CAMERA.

This method is perfect with the “glOrtho” mode, but this one doesn’t work with the “glPerspective” !!!

Does someone has an idea of the problem ?

Here is the code :

private void MoveCamera(Point lastMouse, Point newMouse)
{
OnUpdateViewport();
ApplySceneMode();

lastMouse.Y = oglImage.ActualHeight - 1 - lastMouse.Y;
newMouse.Y = oglImage.ActualHeight - 1 - newMouse.Y;

#region Get the projection/screen information

Matrix4 projectionMatrix = Matrix4.Identity.Clone();
Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projectionMatrix.Values);

Matrix4 modelMatrix = Matrix4.Identity.Clone();
Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, modelMatrix.Values);

int[] viewport = new int[4];
Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);

#endregion

#region Unproject

double distance = (_lookAt.Eye - _lookAt.EyeAt).Length;

Vector3 last3 = new Vector3();
Vector3 new3 = new Vector3();
Glu.gluUnProject(lastMouse.X, lastMouse.Y, distance, modelMatrix.Values, projectionMatrix.Values, viewport, out last3.x, out last3.y, out last3.z);
Glu.gluUnProject(newMouse.X, newMouse.Y, distance, modelMatrix.Values, projectionMatrix.Values, viewport, out new3.x, out new3.y, out new3.z);

#endregion

Vector3 delta3 = new3 - last3;

// Move the camera
_lookAt.Eye -= delta3;
_lookAt.EyeAt -= delta3;
}

private void ApplySceneMode()
{
//---- Set up the view
Gl.glMatrixMode(Gl.GL_PROJECTION); // Set up the projection
Gl.glLoadIdentity();

if (LayoutType == LayoutType.ViewPort_Perspective)
{
// Calculate The Aspect Ratio Of The Window
Glu.gluPerspective(45, _aspectRatio, 1, 10000); // 0.1 cause a strange effect !
}
else
{
// Set the orthogonal view
Gl.glOrtho(-_aspectRatio * VIEWPORT_SPACE_SIZE / 2, _aspectRatio * VIEWPORT_SPACE_SIZE / 2, VIEWPORT_SPACE_SIZE / 2, -VIEWPORT_SPACE_SIZE / 2, 0, 10000);

// Set the zoom factor
Gl.glScaled(_orthoScale, _orthoScale, _orthoScale);
}

Glu.gluLookAt(
_lookAt.Eye.x, _lookAt.Eye.y, _lookAt.Eye.z,
_lookAt.EyeAt.x, _lookAt.EyeAt.y, _lookAt.EyeAt.z,
_lookAt.EyeUp.x, _lookAt.EyeUp.y, _lookAt.EyeUp.z);

//---- Set up the model
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
}

private double OnUpdateViewport()
{
int width = (int)oglImage.ActualWidth;
int height = (int)oglImage.ActualHeight;
if (height == 0)
height = 1;

//---- Reset The Current Viewport
Gl.glViewport(0, 0, width, height);

// Returns the aspect ratio
return ((double)width) / height;
}