phoenix's picture

arcball - rotating object problem

I use arcball method to rotate a teapot by mouse in the scene. I already did it and the rotation was pretty smooth when i set the camera as following : position (0,0,10), target = (0,0,0) and upvector =(0,1,0) in gluLookAt method. But when i changed positon or target or upvector or both of them, the rotation goes so wrong with the mouse. what i want is to rotate objects in the scene freely by the mouse whatever the way the camera is set. Sorry for my English. Any ideas for this?
Thanks for any help.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
objarni's picture

phoenix - I think you must give us more information to be able to help you --

- are you using GL-matrix to setup projection or LookAt?
- how are your matrices computed? in what order are they multiplied?
- are you looking for orbitting behaviour or camera movement/rotation?
- etc.

phoenix's picture

The code is a little bit long. I use the project in SelectionExample.zip that JTalton posted : http://www.opentk.com/node/213
It's about picking, but you can rotate object by the mouse. The project used the arcball method. The rotation is totally right but only when you set the view matrix ( for camera) like i said: position (0,0,10), target = (0,0,0) and upvector =(0,1,0), or in default , as red book says : position (0,0,1), target = (0,0,0) and upvector =(0,1,0) in gluLookAt method. When I change this setting for camera, i can't rotate objects in the scene with the mouse in the right way. So, it means when changing the eye's position or rotation, i have to change something (I don't know, some matrix ...??? ) to get the right rotation. I hope you understand me. Any suggestions?

objarni's picture

Are you trying to rotate the object around itself, or are you trying to orbit the camera around the object?
(yes I know this is very similar visually, but I want you to think about what you are conceptually trying to achieve)

phoenix's picture

I'm trying to rotate the object around itself by the mouse using an arcball. I think the sample project that JTalton posted in http://www.opentk.com/node/213
already helped me to orbit the camera around the object by the mouse(using an arcball). Now i also want to use the "arcball method" to rotate the object around itself with the mouse control. But i see a problem as i said when i set the camera different from default ((0,0,1) for eye position (or camera position) and look at point (0,0,0) and upvector (0,1,0)), the rotation with mouse control (using arcball) to rotate the object around itself is not right any more. The object rotates chaotically. For instance, I set eye :(1,2,3) , look at point : (0,0,0) , upvector: (4,5,6 ).

I hope you get my point.

flopoloco's picture

Check this code for any hints... There is a 3rd person camera system, along with lots of spinning cubes.
http://www.opentk.com/node/571

P.S. Though, we would be more helpful if you could post a "minimal" application describing your problem (parts for camera rotation and cube rotation only needed). :)

I guess that would be something like that:

using System;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
 
namespace OpenTKTrackballTest
{
	class Program : GameWindow
	{
		private int rotation;
 
		public override void OnLoad(EventArgs e)
		{
		}
 
		public override void OnRenderFrame(RenderFrameEventArgs e)
		{
			GL.Clear(ClearBufferMask.ColorBufferBit);
 
			GL.LoadIdentity();
			GL.Rotate(Convert.ToDouble(rotation), 0.0, 0.0, 1.0);
			GL.Begin(BeginMode.Lines);
			GL.Vertex2(-3, 0);
			GL.Vertex2(3, 0);
			GL.Vertex2(0, -3);
			GL.Vertex2(0, 3);
			GL.End();
 
			SwapBuffers();
		}
 
		protected override void OnResize(OpenTK.Platform.ResizeEventArgs e)
		{
 
		}
 
		public override void OnUpdateFrame(UpdateFrameEventArgs e)
		{
			rotation += Mouse.XDelta;
		}
 
		public static void Main(string[] args)
		{
			using (Program program = new Program())
			{
	       		program.Run();
			}
		}
	}
}
nythrix's picture

For instance, I set eye :(1,2,3) , look at point : (0,0,0) , upvector: (4,5,6 ).
You cannot set the three of these deliberately. Given
eye = (ex,ey,ez)
target = (tx,ty,tz)
then any non-zero up vector (upx, upy, upz) satisfying the following equation
(tx-ex)upx + (ty-ey)upy + (tz-ez)upz = 0 //or in vector notation (target-eye) dot up = 0
is a valid up vector for the given eye and target.

Edit: In other words the up vector and the (target-eye) vector HAVE to be orthogonal (ie. the angle between them is 90 degrees).
http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation

In your case:
eye=(1,2,3)
target=(0,0,0)
which gives
((0,0,0) - (1,2,3)) dot (4,5,6) =/= 0 !!!
therefore (4,5,6) is not a valid up vector.

For example (1,1,-1) is one of the many valid up vectors. Try
eye=(1,2,3)
target=(0,0,0)
up=(1,1,-1)
and see if it works.

Edit2: Just checked gluLookAt and apparently it takes care about proper orthogonality so you don't have to do it yourself. Go figure...

phoenix's picture

Sorry for my mistake, I know the upvector perpendicular to the vector created by target and eye point, but i didn't mean to set the camera like that. I mean when i use an arcball the rotate object arround itself with the mouse control in this setting : eye point (0,0,1) , target (0,0,0), upvector (0,1,0) for the lookAt method, i got the right rotation with mouse control. Everything is fine until i want to set a different position for the camera. for example as you say:
eye=(1,2,3)
target=(0,0,0)
up=(1,1,-1)

JTalton's picture

I have not played with arcball rotation of objects. So take what I post here with a grain of salt.

Rotating an object about itself. The projection matrix should not change. The modelmatrix should be used to rotate the model.
Smooth rotation needs quaternions which represent a rotation (yaw, pitch, and roll).

The Object should store a TransformMatrix that represents the rotation of the object (start with IdentityMatrix).
On MouseDown, find the vector from the object to the location on the arcball. Convert that to a MouseDownQuaternion.
On MouseMove, find the vector from the object to the location on the arcball. Convert that to a MouseMoveQuaternion.
Determine the RotationChangeQuaternion from the MouseDownQuaternion to the MouseMoveQuaternion (need to look up how to do this).
Convert the RotationChangeQuaternion to a RotationChangeMatrix and multiply that time the objects TransformMatrix to get the matrix that should be used to transform the object.
On MouseUp, apply the RotationChangeMatrix to the objects TransformMatrix so it stays in that position.

All of this rotation should be only on the object and should not be affected by the camera. The only thing the camera affects is the calculation of where on the arcball the mouse click intersects.

Reference: http://rainwarrior.thenoos.net/dragon/arcball.html