/*Names: Daniel Sternberg and Justin Jang *Date: 9/13/00 *Description: This program will read information in from a file and display *a picture using this information in OpenGL */ // Include this to compile on Windows machine (carlson@cc) #include #include #include #include #include #include typedef struct { /*The vector structure*/ double x,y,z; } xyz_t; void cross_xyz(xyz_t inV, xyz_t inW, xyz_t *outX); float dot_xyz(xyz_t inV, xyz_t inW); void displacement_xyz(xyz_t inV, xyz_t inW, xyz_t *outX); float magnitude_xyz(xyz_t inV); void triangleNormal_xyz(xyz_t a, xyz_t b, xyz_t c, xyz_t *n); double one_val(FILE*); void end_line(FILE *); xyz_t values(FILE*); void initialize_file(char *); void init(void); int main(int, char **); int i=0; xyz_t points[30000]; /*An array of all unique points in the model.*/ int triangles[30000]; /*An array of triangles specified as indices to their *points. There is a maximum of 10000 triangles*/ xyz_t normals[10000]; /*A vector for the normals in OpenGL*/ int num_triangles; /*The number of triangles*/ xyz_t viewpoint; /*The viewpoint vector*/ xyz_t top_left; /*The top left corner of the screen*/ xyz_t pix_displacement; /*The pixel displacement vector*/ xyz_t scan_displacement; /*The scan-line displacement vector*/ xyz_t z_normal; /*The "z-normal" vector out of the view plane*/ xyz_t target_point; /*The center of the viewport*/ xyz_t zoom_in_displacement; /*Vector used to calculate zoom*/ double x_rot=0; /*Values to rotate about the 3 axes and zoom in/out*/ double y_rot=0; double z_rot=0; double zoom=0; double minx=2E9,maxx=-2E9,miny=2E9,maxy=-2E9,minz=2E9,maxz=-2E9; xyz_t model_center; /* Calculates the CROSS PRODUCT of two vectors */ void cross_xyz(xyz_t inV, xyz_t inW, xyz_t *outX) { outX->x = inV.y * inW.z - inV.z * inW.y; outX->y = inV.z * inW.x - inV.x * inW.z; outX->z = inV.x * inW.y - inV.y * inW.x; } /* Calculates the DOT PRODUCT of two vectors */ float dot_xyz(xyz_t inV, xyz_t inW) { return inV.x*inW.x + inV.y*inW.y + inV.z*inW.z; } /* Calculates a displacement vector (subtracts V from W) */ void displacement_xyz(xyz_t inV, xyz_t inW, xyz_t *outX) { outX->x = inW.x - inV.x; outX->y = inW.y - inV.y; outX->z = inW.z - inV.z; } /* Multiplies a vector and a float */ void multiply_xyz(xyz_t inV, float f, xyz_t *outX) { outX->x = inV.x * f; outX->y = inV.y * f; outX->z = inV.z * f; } /* Calculates the magnitude (length) of a vector */ float magnitude_xyz(xyz_t inV) { return sqrt(inV.x*inV.x + inV.y*inV.y + inV.z*inV.z); } /* Calculates a triangle normal (clockwise side is out) */ void triangleNormal_xyz(xyz_t a, xyz_t b, xyz_t c, xyz_t *n) { xyz_t tempV1, tempV2, tempV3; double f; displacement_xyz(a, c, &tempV1); /* Make vector ac */ displacement_xyz(a, b, &tempV2); /* Make vector ab */ cross_xyz(tempV1, tempV2, &tempV3); /* ac x ab --> normal */ /* Normalize the resultant by dividing by its magnitude */ f = 1 / magnitude_xyz(tempV3); n->x = tempV3.x * f; n->y = tempV3.y * f; n->z = tempV3.z * f; } float fmin(float a, float b) /*Calculate the minimum of two *floating point numbers*/ { return (a maxx) maxx = points[p].x; if (points[p].y > maxy) maxy = points[p].y; if (points[p].z > maxz) maxz = points[p].z; p++; } } end_line(infile); /*Calculate the normal for the triangle*/ triangleNormal_xyz(points[triangles[t*3]],points[triangles[t*3+1]],points[triangles[t*3+2]],&normals[t]); } fclose(infile); /*Close the file, we're done with it*/ /*Calculate the center of the model*/ model_center.x = (minx+maxx)/2.0; model_center.y = (miny+maxy)/2.0; model_center.z = (minz+maxz)/2.0; /* The target is at the center of the 256 pix_disp by 256 scan_disp viewport. */ target_point.x = top_left.x + 128 * (pix_displacement.x + scan_displacement.x); target_point.y = top_left.y + 128 * (pix_displacement.y + scan_displacement.y); target_point.z = top_left.z + 128 * (pix_displacement.z + scan_displacement.z); /* Calculate a vector for zooming in and out along the center of the line-of-site. */ displacement_xyz(viewpoint,target_point,&zoom_in_displacement); displacement_xyz(target_point,model_center,&temp); multiply_xyz(zoom_in_displacement, magnitude_xyz(temp)/magnitude_xyz(zoom_in_displacement), &zoom_in_displacement); } void init(void) /*GL initializations*/ { double pix_d, scan_d, view_d; xyz_t rayV; GLfloat mat_specular[4]={1.0,1.0,1.0,1.0}; GLfloat light_pos[3]={viewpoint.x,viewpoint.y,viewpoint.z-999999999}; glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /*Enabling light*/ glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glFrontFace(GL_CW); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /*Specifying the viewport*/ pix_d = magnitude_xyz(pix_displacement); scan_d = magnitude_xyz(scan_displacement); displacement_xyz(viewpoint, target_point, &rayV); view_d = magnitude_xyz(rayV); gluPerspective(atan(pix_d*128/view_d)*180.0/3.14159 /*M_PI*/ *2.0, pix_d/scan_d,fmin(fabs(top_left.z-minz)/2.0,fabs(top_left.z-maxz))/2.0,fabs(viewpoint.z)+fabs(maxz-minz)+999999999); gluLookAt(viewpoint.x,viewpoint.y,viewpoint.z, target_point.x,target_point.y,target_point.z, -scan_displacement.x,-scan_displacement.y,-scan_displacement.z); } void display(void) /*Display the triangles to the screen*/ { int i,k; xyz_t z_rotate; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*Transformations the user specified with the keyboard*/ glPushMatrix(); glTranslated(zoom*zoom_in_displacement.x,zoom*zoom_in_displacement.y,zoom*zoom_in_displacement.z); glRotated(x_rot,1,0,0); glRotated(y_rot,0,1,0); glRotated(z_rot,0,0,1); /*Draw the triangles*/ glBegin(GL_TRIANGLES); for(i=0;i