This page was last updated: October 11, 2024
This project is to animate a helicopter and look at it in two different 3D views.
Note: you need to call gluLookAt( ) once and only once.
and so on.
HeliList = glGenLists( 1 );
glNewList( HeliList, GL_COMPILE );
int i;
struct edge *ep;
struct point *p0, *p1;
glPushMatrix( );
glTranslatef( 0., -1., 0. );
glRotatef( 97., 0., 1., 0. );
glRotatef( -15., 0., 0., 1. );
glBegin( GL_LINES );
for( i=0, ep = Heliedges; i < Helinedges; i++, ep++ )
{
p0 = &Helipoints[ ep->p0 ];
p1 = &Helipoints[ ep->p1 ];
glVertex3f( p0->x, p0->y, p0->z );
glVertex3f( p1->x, p1->y, p1->z );
}
glEnd( );
glPopMatrix( );
glEndList( );
HeliList = glGenLists( 1 );
glNewList( HeliList, GL_COMPILE );
int i;
struct point *p0, *p1, *p2;
struct tri *tp;
float p01[3], p02[3], n[3];
glPushMatrix( );
glTranslatef( 0., -1., 0. );
glRotatef( 97., 0., 1., 0. );
glRotatef( -15., 0., 0., 1. );
glBegin( GL_TRIANGLES );
for( i=0, tp = Helitris; i < Helintris; i++, tp++ )
{
p0 = &Helipoints[ tp->p0 ];
p1 = &Helipoints[ tp->p1 ];
p2 = &Helipoints[ tp->p2 ];
// fake "lighting" from above:
p01[0] = p1->x - p0->x;
p01[1] = p1->y - p0->y;
p01[2] = p1->z - p0->z;
p02[0] = p2->x - p0->x;
p02[1] = p2->y - p0->y;
p02[2] = p2->z - p0->z;
Cross( p01, p02, n );
Unit( n, n );
n[1] = fabs( n[1] );
n[1] += .25;
if( n[1] > 1. )
n[1] = 1.;
glColor3f( 0., n[1], 0. );
glVertex3f( p0->x, p0->y, p0->z );
glVertex3f( p1->x, p1->y, p1->z );
glVertex3f( p2->x, p2->y, p2->z );
}
glEnd( );
glPopMatrix( );
glEndList( );
In the glColor3f( ) call, take whatever R, G, B triple you want the helicopter to have and scale them all by n[1]. In the above example, Joe Graphics wanted a green helicopter.
Then in Display( ), say:
glCallList( HeliList );
where you used to call up the BoxList.
// blade parameters:
#define BLADE_RADIUS 1.0
#define BLADE_WIDTH 0.4
// draw the helicopter blade with radius BLADE_RADIUS and
// width BLADE_WIDTH centered at (0.,0.,0.) in the XY plane
BladeList = glGenLists( 1 );
glNewList( BladeList, GL_COMPILE );
glBegin( GL_TRIANGLES );
glVertex2f( BLADE_RADIUS, BLADE_WIDTH/2. );
glVertex2f( 0., 0. );
glVertex2f( BLADE_RADIUS, -BLADE_WIDTH/2. );
glVertex2f( -BLADE_RADIUS, -BLADE_WIDTH/2. );
glVertex2f( 0., 0. );
glVertex2f( -BLADE_RADIUS, BLADE_WIDTH/2. );
glEnd( );
glEndList( );
Then glCallList the BladeList twice in Display( ) along with the appropriate glPushMatrix, glPopMatrix, glScalef, glRotatef, and glTranslatef calls.
Not sure where to start? Read on!
Play with these so that when your program starts up, your are seeing the helicopter and your whole scene from a good angle.
float Time; #define MS_IN_THE_ANIMATION_CYCLE 10000and put this code in Animate( ):
int ms = glutGet( GLUT_ELAPSED_TIME ); // milliseconds ms %= MS_IN_THE_ANIMATION_CYCLE; Time = (float)ms / (float)MS_IN_THE_ANIMATION_CYCLE; // [ 0., 1. )
glRotatef( 360.*Time, . . . );The advantage of this is that you will get the same number of milliseconds in the animation cycle regardless of how fast or slow the CPU you run this on is.
The lighting of the helicopter surfaces use two functions, Cross( ) and Unit( ). They are in your sample code already.
bool Frozen;Set Frozen to false in Reset( ). Then, freezing the animation is just a matter is setting the Idle Function to NULL. To un-freeze it, set the Idle Function back to Animate( ). So, in the Keyboard( ) callback, you could say something like:
case 'f': case 'F': Frozen = ! Frozen; if( Frozen ) glutIdleFunc( NULL ); else glutIdleFunc( Animate ); break;
Use Canvas to turn in:
Feature | Points |
---|---|
Correctly draw the helicopter body | 15 |
Correctly scale the blades | 20 |
Correctly position the blades | 20 |
Correctly rotate the blades | 20 |
Recognizable Inside View | 25 |
Potential Total | 100 |