Hello,

I am trying to implement arcball / trackball camera rotation to my program but It doesn't work. I read some articles about matrices, quaternions etc. and I tought I finally understood the idea, but apparently I am doing something wrong. Basically I register two mouse positions, create axis of rotation, calculate angle, converted this information to quaternion and then quaternion to rotation matrix. It looks like it's rotating, but not in the way I want. So i would appreciate some help because I am desperate.

Most of the code on the internet use glu, but I don't want to because I have already started to learn SDL and I like it. Here's part of the most important code:

void Vector3D::SetZ(float r) //set z coord. - projection to sphere, r - sphere radius { float delta = sqrt(x*x + y*y); if (delta <= r*0.70710678118) z = sqrt(r*r - delta*delta); else z = (r*r*0.5)/delta; } //from main.cpp: . . . SDL_GetMouseState(&currMX, &currMY); relx = event.motion.xrel; rely = event.motion.yrel; cMX = 2.*currMX/screen_width-1.; //normalizing screen coordinates cMY = screen_height - currMY; cMY = 2.*cMY/screen_height-1.; rely = -rely; if(relx<0)relx = -relx; if(rely<0)rely = -rely; if(rot) { d.Set(relx,rely,0); //distance vector from point 1 to point 2 if(d.Length() - eps >0) { z.Set(cMX, cMY, 0); //projection on sphere k.Set(z[0]+d[0],z[1]+d[1],z[2]+d[2]); // z - start position, k - end position k.SetZ(1); z.SetZ(1); rotaxis.CrossProduct(z, k); //rotation axis k.Normalize(); //normalizing vectors z.Normalize(); rotaxis.Normalize(); float pom = z[0]*k[0]+z[1]*k[1]+z[2]*k[2]; //dot product if(pom<-1) //setting angle (had problems that acos returned NAN) angle = -M_PI; else if (pom>1) angle = 0; else angle = acos(pom); float qw = cos(angle*0.5); //setting up quaternion float qx = rotaxis[0]*sin(angle*0.5); float qy = rotaxis[1]*sin(angle*0.5); float qz = rotaxis[2]*sin(angle*0.5); //quaternion transformed to rotation matrix ball.set( qw*qw + qx*qx - qy*qy - qz*qz, 2*qx*qy + 2*qw*qz, 2*qx*qz - 2*qw*qy, 0, 2*qx*qy - 2*qw*qz, qw*qw - qx*qx + qy*qy - qz*qz, 2*qy*qz + 2*qw*qx, 0, 2*qx*qz + 2*qw*qy, 2*qy*qz - 2*qw*qx, qw*qw - qx*qx - qy*qy + qz*qz, 0, 0, 0, 0, qw*qw + qx*qx + qy*qy + qz*qz ); } else ball.identity(); ball_new = ball_old * ball; ball_old = ball; } //RENDERING glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // camera transformation: matrixView.identity(); matrixView.rotate(-cameraAngleX, 1,0,0); // 1: rotate on x-axis matrixView.rotate(-cameraAngleY, 0,1,0); // 2: rotate on y-axis matrixView.rotate(-cameraAngleZ, 0,0,1); // 3: rotate on z-axis matrixView.translate(0, 0, -cameraDistance); // model transform: //matrixModel.identity(); //matrixModel.rotate(45, 0,1,0); // 1st transform //matrixModel.translate(0, 2, 0); // 2nd transform //matrixModel.translate(0, 0, -2); // build modeview matrix: Mmv = Mv * Mm matrixModelView.identity(); matrixModelView = matrixView * matrixModel * ball_new; glLoadMatrixf(matrixModelView.getTranspose()); //drawing

Thanks for any help suggestions!

Mako