PDA

View Full Version : Turntable camera



Agarwean
12-13-2011, 12:06 PM
Hello

I would like to implement a functionality similar to turntable camera in Blender. I need to move (strafe) 3D object and rotate it. After move it I would like to rotate scene always around of center of the screen. Actually after move object in any direction of the screen it rotates around its local coordinate system, not around center of the screen. It looks like the rotation center point is moving together with object. I've tried to use glTranslate function in several ways in the main render method, but I didn't get expected results.
In the Mouse button down event I read the cursor position:


...
previousX = Mouse.X;
previousY = Mouse.Y;
previousZ = Mouse.Y;

prev_eyeX = (float)Mouse.X;
prev_eyeY = (float)Mouse.Y;
prev_eyeZ = (float)Mouse.Y;
...

In the mouse move event I modify the values of variables depending of the pressed mouse button


...
if (Mouse[MouseButton.Middle])
{
rot_x += (Mouse.Y - previousY);
rot_y += (Mouse.X - previousX);
}

if (Mouse[MouseButton.Right])
{
eyeZ += (Mouse.Y - prev_eyeZ) * 0.05f; // zoom in/out scene
}

if (Mouse[MouseButton.Left])
{
centerX -= (Mouse.X - previousX) * 0.005f; // centerX, centerY, centerZ determine the target point of camera view
centerY += (Mouse.Y - previousY) * 0.005f;
centerZ -= (Mouse.Y - previousZ) * 0.005f;

eyeX -= (Mouse.X - prev_eyeX) * 0.005f; // eyeX, eyeY, eyeZ determine the position of camera
eyeY += (Mouse.Y - prev_eyeY) * 0.005f;

translate_x -= (Mouse.X - previousX) * 0.005f; // translate_x, translate_y determines the object displacement
translate_y += (Mouse.Y - previousY) * 0.005f;
}

previousX = (float)Mouse.X;
previousY = (float)Mouse.Y;
previousZ = (float)Mouse.Y;

prev_eyeX = (float)Mouse.X;
prev_eyeY = (float)Mouse.Y;
prev_eyeZ = (float)Mouse.Y;
...

Main render method:


...
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

double aspect = Width / (float)Height;
GL.MatrixMode(MatrixMode.Projection);
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.Pi Over4, (float)aspect, 0.1f, 100.0f);
GL.LoadMatrix(ref perspective);

GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();

Matrix4 lookat = Matrix4.LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);

GL.Rotate(rot_x, 1.0f, 0.0f, 0.0f);
GL.Rotate(rot_y, 0.0f, 1.0f, 0.0f);
GL.Rotate(rot_z, 0.0f, 0.0f, 1.0f);

GL.Translate(-translate_x, -translate_y, -translate_z);

RenderCube();

this.SwapBuffers();
...


Could you please suggest me how should I modify algorithm to get the expected results?

Thanks in advance for your any suggestions.

--
Regards,
Agarwean

ZbuffeR
12-13-2011, 02:50 PM
Beware of copypaste :
previousZ = Mouse.Y; // Z !!
prev_eyeZ = (float)Mouse.Y; // Z !!

Read notes from "1:01:10" :
http://www.shamusyoung.com/twentysidedtale/?p=12574

Agarwean
12-14-2011, 10:46 AM
Beware of copypaste :
previousZ = Mouse.Y; // Z !!
prev_eyeZ = (float)Mouse.Y; // Z !!

Read notes from "1:01:10" :
http://www.shamusyoung.com/twentysidedtale/?p=12574
I know exactly what kind of issue you mean, but in my case I move object using mouse on the application window and I've got access only to X and Y position of the mouse cursor. Therefore I've applied such solution (currently in test purposes).

ZbuffeR
12-14-2011, 01:26 PM
In that case, put 0. Why let something that will be confusing later ?

For your original problem, try translate then rotate :


GL.Translate(-translate_x, -translate_y, -translate_z);

GL.Rotate(rot_x, 1.0f, 0.0f, 0.0f);
GL.Rotate(rot_y, 0.0f, 1.0f, 0.0f);
GL.Rotate(rot_z, 0.0f, 0.0f, 1.0f);

Agarwean
12-17-2011, 09:42 AM
I tried to change X and Y values only and translate before rotate, it didn't help.

mobeen
12-18-2011, 11:25 AM
Wouldn't it be better to just rotate the camera,
On rotation simply increment/decrement theta and phi based on drag amount on x and y axis. Then calculate the new eye position and pass it to lookAt function to get the new modelview matrix


//0 < theta < PI
//0 < phi < 2*PI
//radius is the distance of the camera
//to the target
eyeX = radius * cos(phi) * sin(theta);
eyeY = radius * cos(theta);
eyeZ = radius * sin(phi) * sin(theta);

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

double aspect = Width / (float)Height;
GL.MatrixMode(MatrixMode.Projection);
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.Pi Over4, (float)aspect, 0.1f, 100.0f);
GL.LoadMatrix(ref perspective);

GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();

Matrix4 lookat = Matrix4.LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
GL.LoadMatrix(ref lookat);

RenderCube();

this.SwapBuffers();
}

Agarwean
02-29-2012, 01:48 PM
//0 < theta < PI
//0 < phi < 2*PI
//radius is the distance of the camera
//to the target
eyeX = radius * cos(phi) * sin(theta);
eyeY = radius * cos(theta);
eyeZ = radius * sin(phi) * sin(theta);


Does it give me a circle-based camera rotation around the object?