|
Scientific Animation
An Introduction |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
/**
* The timer callback
*
* @param value The animation time (in milliseconds)
*/
void onTimer(int value)
{
if (rotation == ROTATING)
{
// Update the rotation angle (for the current axis
// of rotation)
angle += 2.0;
if(angle > 360.0) angle -= 360.0;
svaSetRotation(0.0, angle, 0.0);
}
else if (rotation == RESETTING)
{
angle = 0.0;
svaSetRotation(0.0, angle, 0.0);
rotation = STOPPED;
}
}
/**
* The display callback
*/
void onDisplay()
{
double alpha;
feature *f;
GLenum type;
GLfloat v[3];
for (int i=0; i<numberOfFeatures; i++)
{
// Get the Feature
f = &features[i];
// Determine the Feature's type
if (strcmp(f->type, "POLYGON") == 0) type = GL_POLYGON;
else if (strcmp(f->type, "LINE_STRIP") == 0) type = GL_LINE_STRIP;
else type = GL_POINTS;
// Begin the graphics primitive
glBegin(type);
{
glColor3fv(colors[f->id]);
for (int j=0; j<f->size; j++)
{
// Use the Cartesian coordinates
v[0] = f->x[j];
v[1] = f->y[j];
v[2] = f->z[j];
glVertex3fv(v);
}
}
glEnd();
}
}
/**
* The mouse callback (i.e., the function that is called
* each time a mouse button is pressed or released).
*
* @param button The button (e.g., SVA_LEFT_BUTTON)
* @param state The state (e.g., SVA_UP or SVA_DOWN)
* @param x The x-position of the mouse
* @param y The y-position of the mouse
*/
void onMouseClick(int button, int state, GLfloat x, GLfloat y)
{
if (state == SVA_DOWN)
{
if(button == SVA_LEFT_BUTTON)
{
if (rotation == STOPPED) rotation = ROTATING;
else if (rotation == ROTATING) rotation = STOPPED;
}
else if(button == SVA_RIGHT_BUTTON)
{
rotation = RESETTING;
}
}
}
/**
* The display callback
*/
void onDisplay()
{
feature *f;
float alpha;
GLenum type;
GLfloat v[3];
for (int i=0; i<numberOfFeatures; i++)
{
// Get the Feature
f = &features[i];
// Determine the Feature's type
if (strcmp(f->type, "POLYGON") == 0) type = GL_POLYGON;
else if (strcmp(f->type, "LINE_STRIP") == 0) type = GL_LINE_STRIP;
else type = GL_POINTS;
// Begin the graphics primitive
glBegin(type);
{
glColor3fv(colors[f->id]);
for (int j=0; j<f->size; j++)
{
if (status == STOPPED)
{
// Use the Cartesian coordinates
v[0] = f->x[j];
v[1] = f->y[j];
v[2] = f->z[j];
}
else if (status == UNFOLDING)
{
// Interpolate between Cartesian and projected coordinates
alpha = (float)step / NUMSTEPS;
v[0] = (1.-alpha)*f->x[j] + alpha*f->xProj[j];
v[1] = (1.-alpha)*f->y[j] + alpha*f->yProj[j];
v[2] = (1.-alpha)*f->z[j] + alpha*1.0;
}
glVertex3fv(v);
}
}
glEnd();
}
}
/**
* The display callback
*/
void onDisplay()
{
GLfloat v[3];
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// Set the color
glColor3f(1.0, 0.0, 0.0);
// Create the mapping
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &data[0][0]);
// Draw the curve, piece by piece
glBegin(GL_LINE_STRIP);
{
for (int i=0; i<100; i++)
{
glEvalCoord1f(((float)i)/100.0);
}
}
glEnd();
// Instead of the above, one could use:
//
// glMapGrid1f(100, 0.0, 1.0 );
// glEvalMesh1(GL_LINE, 0, 100);
}
/**
* The timer callback
*/
void onTimer(int time)
{
if (status != STOPPED) frame++;
if (status == BACK_MOVING)
{
// Move p1
data[0][0] += 0.05;
// Move c2
data[2][0] += 0.05;
data[2][1] += 0.05;
if (frame == 10)
{
frame = 0;
status = FRONT_MOVING;
}
}
else if (status == FRONT_MOVING)
{
// Move p2
data[3][0] += 0.05;
// Move c1
data[1][0] += 0.05;
// Move c2
data[2][1] -= 0.05;
if (frame == 10)
{
frame = 0;
status = BACK_MOVING;
}
}
}