Monday, May 09, 2005

Rotation in OpengGl

Fixed the rotation for the rendered colon mesh in opengl.

Basic problem was the disabling of the reshape(width,height) function in the main.

got a better idea about the mouse rotation concept in OpenGl.

Here is a link


The source code is given as under

static GLuint tb_lasttime;
static GLfloat tb_lastposition[3];

static GLfloat tb_angle=0.0;
static GLfloat tb_axis[3];
static GLfloat tb_transform[4][4];
static GLuint tb_width;
static GLuint tb_height;

static GLint tb_button=-1;
static GLboolean tb_tracking=GL_FALSE;
static GLboolean tb_animate=GL_TRUE;

float dx,dy,dz;
int rotate_id,zoom_id,pan_id;

static void _tbPointToVector(int x,int y,int width,int height,float v[3])
{
float d,a;

v[0] = (2.0 * x - width) / width;
v[1] = (height - 2.0 * y) / height;
d = sqrt(v[0] * v[0] + v[1] * v[1]);
v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] *= a;
v[1] *= a;
v[2] *= a;
}

static void
_tbAnimate(void)
{
glutPostRedisplay();
}

void
_tbStartMotion(int x, int y, int button, int time)
{
assert(tb_button != -1);

tb_tracking = GL_TRUE;
tb_lasttime = time;
_tbPointToVector(x, y, tb_width, tb_height, tb_lastposition);
}

void
_tbStopMotion(int button, unsigned time)
{
assert(tb_button != -1);

tb_tracking = GL_FALSE;

if (time == tb_lasttime &&amp; tb_animate) {
glutIdleFunc(_tbAnimate);
} else {
tb_angle = 0.0;
if (tb_animate)
glutIdleFunc(0);
}
}

void
tbAnimate(GLboolean animate)
{
tb_animate = animate;
}

void
tbInit(GLuint button)
{
tb_button = button;
tb_angle = 0.0;

/* put the identity in the trackball transform */
glPushMatrix();
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
glPopMatrix();
}

void
tbMatrix()
{
assert(tb_button != -1);

glPushMatrix();
glLoadIdentity();
/*ROTATION*/
if (rotate_id)
glRotatef(tb_angle, tb_axis[0], tb_axis[1], tb_axis[2]);
/*ZOOMING*/
else if (zoom_id)
glTranslatef(0.0,0.0,50*dy);
/*PANNING*/
else if (pan_id)
glTranslatef(150*dx,150*dy,0.0);
glMultMatrixf((GLfloat *)tb_transform);
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
glPopMatrix();

glMultMatrixf((GLfloat *)tb_transform);
}

void
tbReshape(int width, int height)
{
assert(tb_button != -1);

tb_width = width;
tb_height = height;
}

void
tbMouse(int button, int state, int x, int y)
{
assert(tb_button != -1);

if (state == GLUT_DOWN && button == tb_button)
_tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
else if (state == GLUT_UP && button == tb_button)
_tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME));
}

void
tbMotion(int x, int y)
{
GLfloat current_position[3];

assert(tb_button != -1);

if (tb_tracking == GL_FALSE)
return;

_tbPointToVector(x, y, tb_width, tb_height, current_position);

/* calculate the angle to rotate by (directly proportional to the
length of the mouse movement */
dx = current_position[0] - tb_lastposition[0];
dy = current_position[1] - tb_lastposition[1];
dz = current_position[2] - tb_lastposition[2];
tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);

/* calculate the axis of rotation (cross product) */
tb_axis[0] = tb_lastposition[1] * current_position[2] -
tb_lastposition[2] * current_position[1];
tb_axis[1] = tb_lastposition[2] * current_position[0] -
tb_lastposition[0] * current_position[2];
tb_axis[2] = tb_lastposition[0] * current_position[1] -
tb_lastposition[1] * current_position[0];

/* reset for next time */
tb_lasttime = glutGet(GLUT_ELAPSED_TIME);
tb_lastposition[0] = current_position[0];
tb_lastposition[1] = current_position[1];
tb_lastposition[2] = current_position[2];

/* remember to draw new position */
glutPostRedisplay();
}

void reshape(int w,int h)
{
width=w;
height=h;
tbReshape(width,height);

}

void mouse(int button,int button_state,int x,int y)
{
tbMouse(button,button_state,x,y);
}

void motion(int x,int y)
{
tbMotion(x,y);
}

void rotate(int=0)
{
rotate_id=1;
zoom_id=0;
pan_id=0;

}

void init(void)
{

glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOOTH);
tbInit(GLUT_LEFT_BUTTON);
tbAnimate(GL_TRUE);

}

void idle()
{
glutSetWindow(mainWindow);
glutPostRedisplay();
}

void refresh(int=0)
{
init();
reshape(width,height);
}


void instance(int=0)
{
reshape(width,height);
}

void dispmode(int=0)
{
reshape(width,height);
}

void display()
{

tbMatrix();

/* RENDER mesh here */

}

void main(int argc, char* argv)
{

/* initialize */

init();

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc(reshape);

/* other formalities */

}

Not the best code to enable totally flexible, trackball-type movement of the image, but the code does serve it's purpose of providing basic rotation in order to view the colon from a different angle.

0 Comments:

Post a Comment

<< Home