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]