Advertisement

md2 parsing

Started by December 22, 2001 10:25 AM
-1 comments, last by Validus 23 years, 2 months ago
Hello, awile back someone asked for code to pars a md2 models so I looked back thrue all my old stuff and found this. I am waening you that I made it back when I was in grade 10 so it is not perfesanal qualty in any way but it is farly simple so you can get the idea really well from it. It will read only the firse frame and put that in to a desplay list. If any one wants to ues this in anything you have my permistion just give me some cerdit. Hedder stuff
                
typedef FILE* FILE_PTR;
typedef vertex3D float[3];
typedef vertex2D float[2];

typedef struct
{
   int magic_num;  // this makes sure we have a md2 file

   int vertion;  // the vertion number 

   int tex_with; // the with of the texture

   int tex_hight; // the hight of the texture

   int frame_size; // we donot ues this yeat

   int num_tex; // the number of texture we have 

   int num_vertex; // the number of vertexs we have 

   int num_texcoords; // the number of texture coodinits should be same as above 

   int num_faces; // number of trinagles

   int num_glcommands; // extra rending stuff not uesed yeat

   int num_frams; // anamation stuff not uesed

   int offset_textures; // mem offsets 

   int offset_texcoords;
   int offset_faces;
   int offset_frames;
   int offset_glcommands;
   int offset_end;
} md2_hedder;       

typedef char md2_texture_name[64];
typedef struct
{
   byte v[3];
   byte lightnormIndex;
}md2_frame_point;
typedef struct
{
   float trans[3];
   float scale[3];
   char name[16];
}md2_frame;   
   
typedef struct
{
   short tex[2];
} md2_texcoord;

typedef struct
{
   short vertex[3];
   short texind[3];
} md2_face;

typedef struct
{
   md2_hedder hedder;
   md2_texture_name *textures;
   md2_texcoord *texture_coords;
   md2_face *faces;
   md2_frame frame_hedder;
   vertex3D *vertex_points;
   vertex2D *texture_points;

}md2_model; 
#define MAX_MD2_VERTEX  2048 
#define MAX_FRAME_SIZE  (MAX_MD2_VERTEX * 4 + 128)
int ReadTopLevel(FILE_PTR*);
  
ok here is the function the int is for the deasply list id and the file name of the md2
              
void Load_md2_mesh (int *list, char *File_Name)
{
   FILE * Data_File;
   md2_model *model;
   md2_frame_point temp_point;
   int i;
   float norm[3];

   if ((model = (md2_model*) malloc(sizeof(md2_model))) == NULL)
   {
      printf("\n DAM Error #0001\n");
      exit(1);
   }
         
   if ((Data_File = fopen(File_Name, "rb")) == NULL)
   {
      printf("\n File Acces Error #0001 \n");
      exit(1);
   }
   // now that we have the file open and the the var made it is time to read the hedder data 

   memset (model, 0, sizeof(md2_model)); //fill model with 0 needed????

   fread(&model->hedder, sizeof(md2_hedder),1,Data_File); //readthe hedder

   // check Magic number to be sure this is a MD2 file 

   if (model->hedder.magic_num != (int) (('2' << 24) + ('P' << 16)+ ('D' << 8)+'I'))
   {
      printf("\nThis is Not a MD2 (quake II model) file\n");
      fclose(Data_File);
      exit(1);          
   }
   ////////JUST PRINTING SOME INFO

   printf("\n Vertion: %d\n", model->hedder.vertion);
   printf("Number of vertexs: %d\n", model->hedder.num_vertex);
   printf("Number of triangles: %d\n", model->hedder.num_faces);
   printf("Number of Texture coords: %d\n", model->hedder.num_texcoords);
   
   // lets get the face(triangle) info now 

   fseek(Data_File, model->hedder.offset_faces, SEEK_SET);
   if ((model->faces = (md2_face*) malloc(sizeof(md2_face)*model->hedder.num_faces)) == NULL)
   {
      printf("\n DAM Error #0001 \n");
      exit(1);
   }
   for (i = 0; i < model->hedder.num_faces; i++)
      fread(&model->faces[i], sizeof(md2_face), 1, Data_File);            
   
   // We now want to get the texture coord frome the file 

   fseek(Data_File, model->hedder.offset_texcoords, SEEK_SET);
   if (((model->texture_coords = (md2_texcoord*) malloc(sizeof(md2_texcoord)*model->hedder.num_texcoords)) == NULL) ||
      ((model->texture_points = (vetex2D*) malloc(sizeof(vertex2D)*model->hedder.num_texcoords)) == NULL))
   {
      printf("\n DAM Error #0001\n");
      exit(1);
   }
   for (i=0; i < model->hedder.num_texcoords; i++)
   {
      fread(&model->texture_coords[i], sizeof(md2_texcoord), 1, Data_File);               
      model->texture_points[i][0] = (float)model->texture_coords[i].tex[0] / (float)model->hedder.tex_with; 
      model->texture_points[i][1] = (float)model->texture_coords[i].tex[1] / (float)model->hedder.tex_with;
   }      
   //ok now we need the points from the first frame 

   fseek(Data_File, model->hedder.offset_frames, SEEK_SET);
   fread(&model->frame_hedder, sizeof(md2_frame), 1, Data_File); //get the hedder

   if ((model->vertex_points = (vertex3D*) malloc(sizeof(vertex3D)*model->hedder.num_vertex)) == NULL)
   {
      printf("\n DAM Error #0001\n");
      exit(1);
   }
   for(i=0; i < model->hedder.num_vertex; i++)
   {
      fread(&temp_point, sizeof(md2_frame_point),1, Data_File);
      /* not unpack the vertex points */ 
      model->vertex_points[i][0] = model->frame_hedder.scale[0]*temp_point.v[0]+model->frame_hedder.trans[0];
      model->vertex_points[i][1] = model->frame_hedder.scale[1]*temp_point.v[1]+model->frame_hedder.trans[1];
      model->vertex_points[i][2] = model->frame_hedder.scale[2]*temp_point.v[2]+model->frame_hedder.trans[2];
   }
   
   // we should be done with the file now so I will close it 

   fclose(Data_File);
   
   // now it is time to put this stuff in to a display list                                

   *list = glGenLists(1);
   glNewList(*list, GL_COMPILE);
      for(i=0; i < model->hedder.num_faces; i++)
      {
      Normal(model->vertex_points[model->faces[i].vertex[0]], 
             model->vertex_points[model->faces[i].vertex[1]],
	     model->vertex_points[model->faces[i].vertex[2]], norm)
	     ;
      glBegin(GL_TRIANGLES);
         glNormal3fv(norm);
         glTexCoord2fv(model->texture_points[model->faces[i].texind[0]]);
	 glVertex3fv(model->vertex_points[model->faces[i].vertex[0]]);
	 
	 glTexCoord2fv(model->texture_points[model->faces[i].texind[1]]);
	 glVertex3fv(model->vertex_points[model->faces[i].vertex[1]]);
	 
	 glTexCoord2fv(model->texture_points[model->faces[i].texind[2]]);
	 glVertex3fv(model->vertex_points[model->faces[i].vertex[2]]);
      glEnd();	           
      }
   glEndList();                                
   // our little model has server us well and now it is time to free it 

   free(model->textures);
   free(model->texture_coords);
   free(model->faces);
   free(model->vertex_points);
   free(model->texture_points);
   free(model); 

} 
              
Hope this can be of use to someone Edited by - Validus on December 22, 2001 3:57:37 PM Edited by - Validus on December 22, 2001 3:58:46 PM

This topic is closed to new replies.

Advertisement