// Mesh.cpp // NKU CSC 480/580 - Kirby // --------------------------------------------------------- // An simple immutable class for representing a mesh, // using a file format simplified from the .X format. // Revised 3/29/06 to add a getBoundingRadius() member. // // Normals are associated with faces, not vertices. // Faces are vectors of indices into the vector of vertices. // --------------------------------------------------------- #include "Mesh.h" #include Mesh::Mesh( ifstream& meshfile ) // Construct a mesh by reading vertices and faces from a file in // the simple-x file format. Calculate and store normals with faces. { // Read vertices, keeping track of largest distance from origin (radius of bounding ball). int numVertices ; meshfile >> numVertices ; _vertices.resize( numVertices ) ; _radius= 0 ; for ( int i=0 ; i < numVertices ; ++i ) { Point3 point ; meshfile >> point ; _vertices[i]= point ; double r= point.asVector().norm() ; if ( r > _radius ) _radius= r ; } // Read faces. int numFaces ; meshfile >> numFaces ; _faces.resize( numFaces ) ; vector face ; for ( int j=0 ; j < numFaces ; ++j ) { int numVertsThisFace ; meshfile >> numVertsThisFace ; assert( numVertsThisFace > 2 ) ; // Read indices into face. face.resize( numVertsThisFace ) ; for ( int jj=0 ; jj < numVertsThisFace ; ++ jj ) { meshfile >> i ; face[jj]= i ; } // Add this face into the vector of faces. _faces[j]= face ; } // Calculate and store normals (cross product of first 2 face edge vectors). for ( int j=0 ; j < numFaces ; ++j ) { const vector& face= _faces[j] ; Vector3 edgeA= _vertices[face[1]] - _vertices[face[0]] ; Vector3 edgeB= _vertices[face[2]] - _vertices[face[1]] ; Vector3 n= edgeA ^ edgeB ; _normals.push_back( normalize( n ) ) ; } } void Mesh::dump( ostream& out ) const // Print the contents of this mesh in an easily inspectable form. { // Print out all the vertices out << "Vertices" << endl ; int numVertices= getNumVertices() ; for ( int i=0 ; i < numVertices ; ++i ) out << i << "\t" << _vertices[i] << endl ; // Print out all the faces out << "Faces" << endl ; int numFaces= getNumFaces() ; for ( int j=0 ; j < numFaces ; ++j ) { out << j << "\t" ; const vector& face= _faces[j] ; // Print out the edge indices for face j for ( int jj=0 ; jj < (int) face.size() ; ++jj ) out << face[jj] << " " ; // Print out the normal vector for face j out << "normal: " << _normals[j] << endl ; } } int Mesh::makeDisplayList() const // Create an OpenGL display list from this mesh. { int id= glGenLists(1) ; glNewList( id, GL_COMPILE ) ; { int numFaces= getNumFaces() ; for ( int j=0 ; j < numFaces ; ++j ) { const vector& face= getFace(j) ; // refer to face j int numVertsThisFace= (int) face.size() ; glBegin( GL_POLYGON ) ; glNormal3dv( getNormal( j ).asArray() ) ; for ( int jj=0 ; jj < numVertsThisFace ; ++jj ) { glVertex3dv( getVertex( face[jj] ).asArray() ) ; } glEnd() ; } } glEndList() ; return id ; }