Freelook camera problems

Started by
1 comment, last by CrashStar 18 years ago
I think the problem is somewhere in this 2 functions:

void camera::RotateCamera(double Angle, double x, double y, double z)
{
  quaternion temp, quat_view, result;

  temp.x = x * sin(Angle/2);
  temp.y = y * sin(Angle/2);
  temp.z = z * sin(Angle/2);
  temp.w = cos(Angle/2);

  quat_view.x = look.x;
  quat_view.y = look.y;
  quat_view.z = look.z;
  quat_view.w = 0;

  result = mult(mult(temp, quat_view), conjugate(temp));

  look.x = result.x;
  look.y = result.y;
  look.z = result.z;
}

void camera::control()
{    
     vect MouseDirection;
     //middle
     int midx = screensize.x/2;
     int midy = screensize.y/2;
     
     static double xrot = 0.0;
     double maxAngle = 1;
     
     quaternion dlp;
     dlp.x = look.x - pos.x;
     dlp.y = look.y - pos.y;
     dlp.z = look.z - pos.z;
     
     
     if((pt.x == midx) && (pt.y == midy))
    return;
    

      
    MouseDirection.x = (midx - pt.x)/MouseSensitivity; 
    MouseDirection.y = (midy - pt.y)/MouseSensitivity;
    SetCursorPos(midx, midy);
      if(xrot > 1)
  {
    xrot = 1;
    return;
  }
  
     if(xrot < -1)
  {
    xrot = -1;
    return;
  }
  else
  {
    // get the axis to rotate around the x-axis. 
    quaternion Axis = CrossProduct(dlp, up);
    // To be able to use the quaternion conjugate, the axis to
    // rotate around must be normalized.
    Axis = normalize(Axis);

    // Rotate around the y axis
    RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
    // Rotate around the x axis
    RotateCamera(MouseDirection.x, 0, 1, 0);
  }
  
  
  gluLookAt(pos.x, pos.y, pos.z, look.x, look.y, look.z, up.x, up.y, up.z);
}

this is my code for freelook camera. screen reacts with some flickering only on the objects that camera affects. can anyone tell me whats wrong? It seems like everything rotates and comes back at the same time. This is the rest of camera code:

//quaternions

typedef struct{
        double x;
        double y;
        double z;
        double w;
        } quaternion;

typedef struct{
        double x;
        double y;
        double z;
        } vect;
        
        
quaternion CrossProduct(quaternion v1, quaternion v2)
 {
     quaternion v3;
     
     v3.x = v1.y * v2.z - v1.z * v2.y;
     v3.y = v1.x * v2.z - v1.z * v2.x;
     v3.z = v1.x * v2.y - v1.y * v2.x;
     
          
    return v3; 
 }            

        
double lenght(quaternion quat)
{
  return sqrt(quat.x * quat.x + quat.y * quat.y +
              quat.z * quat.z + quat.w * quat.w);                 
}

quaternion normalize(quaternion quat)
{
  double L = lenght(quat);

  quat.x /= L;
  quat.y /= L;
  quat.z /= L;
  quat.w /= L;

  return quat;
}


quaternion conjugate(quaternion quat)
{
  quat.x = -quat.x;
  quat.y = -quat.y;
  quat.z = -quat.z;
  return quat;
}


quaternion mult(quaternion A, quaternion B)
{
  quaternion C;

  C.x = A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  C.y = A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  C.z = A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  C.w = A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
  return C;
}


// camera class declaration

class camera
{
    public:
        camera();

        
        
        inline void place();
        inline void control();
        inline void RotateCamera(double Angle, double x, double y, double z);
        
        quaternion pos, look, up;
        quaternion q_look;
};



// camera class functions and constructors

camera::camera()
{
 pos.x=0;
 pos.y=0;
 pos.z=0; 
 look.x = 0;
 look.y = 0;
 look.z = -1;

}

void camera::RotateCamera(double Angle, double x, double y, double z)
{
  quaternion temp, quat_view, result;

  temp.x = x * sin(Angle/2);
  temp.y = y * sin(Angle/2);
  temp.z = z * sin(Angle/2);
  temp.w = cos(Angle/2);

  quat_view.x = look.x;
  quat_view.y = look.y;
  quat_view.z = look.z;
  quat_view.w = 0;

  result = mult(mult(temp, quat_view), conjugate(temp));

  look.x = result.x;
  look.y = result.y;
  look.z = result.z;
}

void camera::control()
{    
     vect MouseDirection;
     //middle
     int midx = screensize.x/2;
     int midy = screensize.y/2;
     
     static double xrot = 0.0;
     double maxAngle = 1;
     
     quaternion dlp;
     dlp.x = look.x - pos.x;
     dlp.y = look.y - pos.y;
     dlp.z = look.z - pos.z;
     
     
  if((pt.x == midx) && (pt.y == midy))
   return;
    

      
    MouseDirection.x = (midx - pt.x)/MouseSensitivity; 
    MouseDirection.y = (midy - pt.y)/MouseSensitivity;
   SetCursorPos(midx, midy);
   
   
      if(xrot > 1)
  {
    xrot = 1;
    return;
  }
  
     if(xrot < -1)
  {
    xrot = -1;
    return;
  }
  else
  {
    // get the axis to rotate around the x-axis. 
    quaternion Axis = CrossProduct(dlp, up);
    // To be able to use the quaternion conjugate, the axis to
    // rotate around must be normalized.
    Axis = normalize(Axis);

    // Rotate around the y axis
    RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
    // Rotate around the x axis
    RotateCamera(MouseDirection.x, 0, 1, 0);
  }
  
  
  gluLookAt(pos.x, pos.y, pos.z, look.x, look.y, look.z, up.x, up.y, up.z);
}


camera cam1;



Draw function : (i just copypasted some geometry drawing code so that i can see how camera works.

int DrawGLScene(GLvoid)									// Here's Where We Do All The Drawing
{
    screensize = ScreenSize(); // getting screen size
    GetCursorPos(&pt); // getting cursor pos
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer
	glLoadIdentity();
	cam1.control(); /////// camera function that should implement camera control


  							
	glTranslatef(-1.5f,0.0f,-6.0f);						// Move Left 1.5 Units And Into The Screen 6.0
	glBegin(GL_TRIANGLES);								// Start Drawing A Triangle
		glColor3f(1.0f,0.0f,0.0f);						// Red
		glVertex3f( 0.0f, 1.0f, 0.0f);					// Top Of Triangle (Front)
		glColor3f(0.0f,1.0f,0.0f);						// Green
		glVertex3f(-1.0f,-1.0f, 1.0f);					// Left Of Triangle (Front)
		glColor3f(0.0f,0.0f,1.0f);						// Blue
		glVertex3f( 1.0f,-1.0f, 1.0f);					// Right Of Triangle (Front)
		glColor3f(1.0f,0.0f,0.0f);						// Red
		glVertex3f( 0.0f, 1.0f, 0.0f);					// Top Of Triangle (Right)
		glColor3f(0.0f,0.0f,1.0f);						// Blue
		glVertex3f( 1.0f,-1.0f, 1.0f);					// Left Of Triangle (Right)
		glColor3f(0.0f,1.0f,0.0f);						// Green
		glVertex3f( 1.0f,-1.0f, -1.0f);					// Right Of Triangle (Right)
		glColor3f(1.0f,0.0f,0.0f);						// Red
		glVertex3f( 0.0f, 1.0f, 0.0f);					// Top Of Triangle (Back)
		glColor3f(0.0f,1.0f,0.0f);						// Green
		glVertex3f( 1.0f,-1.0f, -1.0f);					// Left Of Triangle (Back)
		glColor3f(0.0f,0.0f,1.0f);						// Blue
		glVertex3f(-1.0f,-1.0f, -1.0f);					// Right Of Triangle (Back)
		glColor3f(1.0f,0.0f,0.0f);						// Red
		glVertex3f( 0.0f, 1.0f, 0.0f);					// Top Of Triangle (Left)
		glColor3f(0.0f,0.0f,1.0f);						// Blue
		glVertex3f(-1.0f,-1.0f,-1.0f);					// Left Of Triangle (Left)
		glColor3f(0.0f,1.0f,0.0f);						// Green
		glVertex3f(-1.0f,-1.0f, 1.0f);					// Right Of Triangle (Left)
	glEnd();											// Done Drawing The Pyramid

	glTranslatef(1.5f,0.0f,-7.0f);						// Move Right 1.5 Units And Into The Screen 7.0
	glBegin(GL_QUADS);									// Draw A Quad
		glColor3f(0.0f,1.0f,0.0f);						// Set The Color To Blue
		glVertex3f( 1.0f, 1.0f,-1.0f);					// Top Right Of The Quad (Top)
		glVertex3f(-1.0f, 1.0f,-1.0f);					// Top Left Of The Quad (Top)
		glVertex3f(-1.0f, 1.0f, 1.0f);					// Bottom Left Of The Quad (Top)
		glVertex3f( 1.0f, 1.0f, 1.0f);					// Bottom Right Of The Quad (Top)
		glColor3f(1.0f,0.5f,0.0f);						// Set The Color To Orange
		glVertex3f( 1.0f,-1.0f, 1.0f);					// Top Right Of The Quad (Bottom)
		glVertex3f(-1.0f,-1.0f, 1.0f);					// Top Left Of The Quad (Bottom)
		glVertex3f(-1.0f,-1.0f,-1.0f);					// Bottom Left Of The Quad (Bottom)
		glVertex3f( 1.0f,-1.0f,-1.0f);					// Bottom Right Of The Quad (Bottom)
		glColor3f(1.0f,0.0f,0.0f);						// Set The Color To Red
		glVertex3f( 1.0f, 1.0f, 1.0f);					// Top Right Of The Quad (Front)
		glVertex3f(-1.0f, 1.0f, 1.0f);					// Top Left Of The Quad (Front)
		glVertex3f(-1.0f,-1.0f, 1.0f);					// Bottom Left Of The Quad (Front)
		glVertex3f( 1.0f,-1.0f, 1.0f);					// Bottom Right Of The Quad (Front)
		glColor3f(1.0f,1.0f,0.0f);						// Set The Color To Yellow
		glVertex3f( 1.0f,-1.0f,-1.0f);					// Top Right Of The Quad (Back)
		glVertex3f(-1.0f,-1.0f,-1.0f);					// Top Left Of The Quad (Back)
		glVertex3f(-1.0f, 1.0f,-1.0f);					// Bottom Left Of The Quad (Back)
		glVertex3f( 1.0f, 1.0f,-1.0f);					// Bottom Right Of The Quad (Back)
		glColor3f(0.0f,0.0f,1.0f);						// Set The Color To Blue
		glVertex3f(-1.0f, 1.0f, 1.0f);					// Top Right Of The Quad (Left)
		glVertex3f(-1.0f, 1.0f,-1.0f);					// Top Left Of The Quad (Left)
		glVertex3f(-1.0f,-1.0f,-1.0f);					// Bottom Left Of The Quad (Left)
		glVertex3f(-1.0f,-1.0f, 1.0f);					// Bottom Right Of The Quad (Left)
		glColor3f(1.0f,0.0f,1.0f);						// Set The Color To Violet
		glVertex3f( 1.0f, 1.0f,-1.0f);					// Top Right Of The Quad (Right)
		glVertex3f( 1.0f, 1.0f, 1.0f);					// Top Left Of The Quad (Right)
		glVertex3f( 1.0f,-1.0f, 1.0f);					// Bottom Left Of The Quad (Right)
		glVertex3f( 1.0f,-1.0f,-1.0f);					// Bottom Right Of The Quad (Right)
	glEnd();											// Done Drawing The Quad
	
	
	
glColor3f(1.0, 1.0, 1.0);
	 glTranslatef(0.0f,0.0f,+1.0f);	
    glRasterPos2f(-4,2);
	glDisable(GL_BLEND);
    glPrintf("x:%d y:%d", pt.x, pt.y);
    glRasterPos2f(-3,2);
    glPrintf("x:%d y:%d", screensize.x, screensize.y);
 	glEnable(GL_BLEND);

	rtri+=0.2f;											// Increase The Rotation Variable For The Triangle ( NEW )
	rquad-=0.15f;										// Decrease The Rotation Variable For The Quad ( NEW )										// Done Drawing The Quad
	return TRUE;										// Keep Going
  
  

}


As i said, problem is that screen is just blinkin a little when i move a mouse, nothing rotates, but it seems like it rotates fast and then gets back on position again. I used simple quaternion camera tutorial to code this. [Edited by - CrashStar on March 29, 2006 7:28:17 AM]
Advertisement
It would be very helpful if you stated the nature of the problem and if you put the code in code braces (|source lang="cpp"|
|/source|) to make it more readible...
ok, sry, i didnt know how to use code tags

fixed now, someone pls help :)

This topic is closed to new replies.

Advertisement