Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Don't forget to read Tuesday's email newsletter for your chance to win a free copy of Construct 2!


Problem with Arcball/Trackball implementation using SDL + Opengl


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 mako1131   Members   -  Reputation: 115

Like
0Likes
Like

Posted 05 April 2013 - 05:06 AM

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



Sponsor:

#2 HypnotiC   Members   -  Reputation: 112

Like
1Likes
Like

Posted 05 April 2013 - 06:28 PM

I haven't known much about quaternions yet, but it seems that something is wrong with your rotation matrix multiplication:

Should    

      ball_new = ball_old * ball;

     ball_old = ball;

be 

     ball_new = ball * ball_old;

     ball_old = ball_new; ?

 

Since we are concatenating the newly constructed rotation to the accumulated rotation so far. 

(Seems ball_new is the accumulative rotation matrix)

 

 

 


Edited by HypnotiC, 05 April 2013 - 06:32 PM.


#3 mako1131   Members   -  Reputation: 115

Like
0Likes
Like

Posted 06 April 2013 - 04:07 AM

Yeah you are right it should probably be  ball_old = ball_new; ... But may I ask why should I multiply ball * ball_old  instead of ball_old * ball;?  I know that order of matrix multiplication is important and it's not the same multiplying matrices A*B and B*A, but somewhere I read that arcball matrix rotation should be placed after all other matrices...so I basically put the new rotation matrix at the end of everything.



#4 mako1131   Members   -  Reputation: 115

Like
0Likes
Like

Posted 07 April 2013 - 06:48 AM

I finally figured it out...it's working now.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS