home *** CD-ROM | disk | FTP | other *** search
/ Quark 3 / Quark3.iso / KATALOG / ARCHIV / TOOL / T001.ZIP / SOURCE.ZIP / md3IO.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-23  |  10.1 KB  |  406 lines

  1. /*
  2. Copyright (C) Matthew 'pagan' Baranowski & Sander 'FireStorm' van Rossen
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. */
  18.  
  19. #include "system.h"
  20. #include "ndictionary.h"
  21. #include "md3gl.h"
  22. #include "md3view.h"
  23. #include "DiskIO.h"
  24.  
  25. bool    loadmesh( gl_mesh& newMesh , FILE* F )
  26. {
  27.     char    ID[5];
  28.  
  29.     fread(ID, 4,1,F);ID[4]=0;
  30.     if (strcmp(ID,"IDP3")==0)
  31.     {
  32.         char        name[69];
  33.         UINT32        triangleStart;
  34.         UINT32        headerSize;
  35.         UINT32        texvecStart;
  36.         UINT32        vertexStart;
  37.         UINT32        meshSize;
  38.  
  39.         fread(name,68,1,F);name[65]=0; //65 chars, 32-bit aligned == 68 chars in file
  40.         strcpy(newMesh.name,name);
  41.  
  42.         newMesh.meshFrameNum    = get32(F);
  43.         newMesh.skinNum            = get32(F);
  44.         newMesh.vertexNum        = get32(F);
  45.         newMesh.triangleNum        = get32(F);
  46.         triangleStart            = get32(F);
  47.         headerSize                = get32(F);
  48.         texvecStart                = get32(F);
  49.         vertexStart                = get32(F);
  50.         meshSize                = get32(F);
  51.  
  52.         if ( ( headerSize == 108           ) && //header should be 108 bytes long
  53.              ( meshSize   >  triangleStart ) &&
  54.              ( meshSize   >  texvecStart   ) &&
  55.              ( meshSize   >  vertexStart   ) )
  56.         {
  57.             unsigned int i,j;
  58.             char    texName[68];
  59.  
  60.             newMesh.meshFrames      = new FMeshFrame[newMesh.meshFrameNum];
  61.             newMesh.triangles      = new TriVec      [newMesh.triangleNum ];
  62.             newMesh.textureCoord  = new TexVec    [newMesh.vertexNum   ];
  63.             newMesh.iterMesh      = new Vec3      [newMesh.vertexNum   ];
  64.             newMesh.bindings      = new GLuint    [newMesh.skinNum     ];
  65.  
  66.             for (i=0;i<newMesh.skinNum;i++)
  67.             {
  68.                 fread(texName,68,1,F);texName[65]=0;
  69.                 //65 chars, 32-bit aligned == 68 chars in file
  70.  
  71.                 newMesh.bindings[ i ] =
  72.                     loadTexture(texName);
  73.             }
  74.  
  75.             for (i=0;i<newMesh.triangleNum;i++)
  76.             {
  77.                 newMesh.triangles[ i ][ 0 ] = get32(F);
  78.                 newMesh.triangles[ i ][ 1 ] = get32(F);
  79.                 newMesh.triangles[ i ][ 2 ] = get32(F);
  80.             }
  81.  
  82.             for (i=0;i<newMesh.vertexNum;i++)
  83.             {
  84.                 newMesh.textureCoord[ i ][ 0 ] = getFloat(F);
  85.                 newMesh.textureCoord[ i ][ 1 ] = getFloat(F);
  86.             }
  87.  
  88.             UINT16 unknown;
  89.  
  90.             for (i=0;i<newMesh.meshFrameNum;i++)
  91.             {
  92.  
  93.                 newMesh.meshFrames[ i ] = 
  94.                     new Vec3[newMesh.vertexNum];
  95.  
  96.                 for (j=0;j<newMesh.vertexNum;j++)
  97.                 {
  98.                     // big hack, change later!
  99.                     newMesh.meshFrames[ i ][ j ][0]  = ((float)get16(F)) / 64;
  100.                     newMesh.meshFrames[ i ][ j ][1]  = ((float)get16(F)) / 64;
  101.                     newMesh.meshFrames[ i ][ j ][2]  = ((float)get16(F)) / 64;
  102.                     unknown = get16(F);
  103.                 }
  104.             }
  105.             
  106.             return true;
  107.         } else
  108.             return false;
  109.     } else 
  110.         return false;
  111. }
  112.  
  113. bool    loadmodel( gl_model& newModel , FILE* F )
  114. {
  115.     char    ID[5];
  116.  
  117.     ID[0] = fgetc(F);
  118.     ID[1] = fgetc(F);
  119.     ID[2] = fgetc(F);
  120.     ID[3] = fgetc(F);
  121.     ID[4] = 0;
  122.     if (strcmp(ID,"IDP3")==0)
  123.     {
  124.         char        name[69];
  125.         UINT32        maxskinNum;
  126.         UINT32        headerSize;
  127.         UINT32        tagStart;
  128.         UINT32        tagEnd;
  129.         UINT32        fileSize;
  130.         UINT32        version;
  131.  
  132.         version                    = get32(F);
  133.  
  134.         fread(name,68,1,F);name[65]=0; //65 chars, 32-bit aligned == 68 chars in file
  135.  
  136.         newModel.frameNum        = get32(F);
  137.         newModel.tagNum            = get32(F);
  138.         newModel.meshNum        = get32(F);
  139.         maxskinNum                = get32(F);
  140.         headerSize                = get32(F);
  141.         tagStart                = get32(F);
  142.         tagEnd                    = get32(F);
  143.         fileSize                = get32(F);
  144.  
  145.         if ( ( headerSize == 108           ) && //header should be 108 bytes long
  146.              ( fileSize   >  tagStart      ) &&
  147.              ( fileSize   >  tagEnd        ) &&
  148.              ( version    == 15            ) )
  149.         {
  150.             unsigned int i,j;
  151.  
  152.             //initialize matrix to identity matrix
  153.             for (i=0;i<16;i++) 
  154.                 newModel.CTM_matrix[ i ] = 0;
  155.             newModel.CTM_matrix[  1 ] = 1;
  156.             newModel.CTM_matrix[  6 ] = 1;
  157.             newModel.CTM_matrix[ 11 ] = 1;
  158.             newModel.CTM_matrix[ 16 ] = 1;
  159.  
  160.             newModel.modelListPosition = NULL;
  161.             newModel.parent            = NULL;
  162.             newModel.currentFrame    = 0;
  163.             newModel.isBlended        = false;
  164.             newModel.blendParam1    = GL_ONE;
  165.             newModel.blendParam2    = GL_ONE;
  166.             
  167.             newModel.boneFrames = 
  168.                 new BoneFrame[newModel.frameNum];
  169.  
  170.             for (i=0;i<newModel.frameNum;i++)
  171.             {
  172.                 newModel.boneFrames[ i ].Mins[ 0 ]        = getFloat(F);
  173.                 newModel.boneFrames[ i ].Mins[ 1 ]        = getFloat(F);
  174.                 newModel.boneFrames[ i ].Mins[ 2 ]        = getFloat(F);
  175.                 newModel.boneFrames[ i ].Maxs[ 0 ]        = getFloat(F);
  176.                 newModel.boneFrames[ i ].Maxs[ 1 ]        = getFloat(F);
  177.                 newModel.boneFrames[ i ].Maxs[ 2 ]        = getFloat(F);
  178.                 newModel.boneFrames[ i ].Position[ 0 ]    = getFloat(F);
  179.                 newModel.boneFrames[ i ].Position[ 1 ]    = getFloat(F);
  180.                 newModel.boneFrames[ i ].Position[ 2 ]    = getFloat(F);
  181.                 newModel.boneFrames[ i ].Scale            = getFloat(F);
  182.                 
  183.                 fread(newModel.boneFrames[ i ].Creator,16,1,F);
  184.             }
  185.             if (newModel.tagNum!=0)
  186.             {
  187.                 newModel.linkedModels = new gl_model*[newModel.tagNum];
  188.                 for (i=0;i<newModel.tagNum;i++)
  189.                     newModel.linkedModels[ i ] = NULL;
  190.  
  191.                 newModel.tags = 
  192.                     new TagFrame[newModel.frameNum];
  193.  
  194.                 for (i=0;i<newModel.frameNum;i++)
  195.                 {
  196.                     newModel.tags[ i ] = 
  197.                         new Tag[newModel.tagNum];
  198.  
  199.                     for (j=0;j<newModel.tagNum;j++)
  200.                     {
  201.                         fread(newModel.tags[ i ][ j ].Name   ,12,1,F);
  202.                         fread(newModel.tags[ i ][ j ].unknown,52,1,F);
  203.                         newModel.tags[ i ][ j ].Position[ 0 ]        = getFloat(F);
  204.                         newModel.tags[ i ][ j ].Position[ 1 ]        = getFloat(F);
  205.                         newModel.tags[ i ][ j ].Position[ 2 ]        = getFloat(F);
  206.                         newModel.tags[ i ][ j ].Matrix[ 0 ][ 0 ]    = getFloat(F);
  207.                         newModel.tags[ i ][ j ].Matrix[ 1 ][ 0 ]    = getFloat(F);
  208.                         newModel.tags[ i ][ j ].Matrix[ 2 ][ 0 ]    = getFloat(F);
  209.                         newModel.tags[ i ][ j ].Matrix[ 0 ][ 1 ]    = getFloat(F);
  210.                         newModel.tags[ i ][ j ].Matrix[ 1 ][ 1 ]    = getFloat(F);
  211.                         newModel.tags[ i ][ j ].Matrix[ 2 ][ 1 ]    = getFloat(F);
  212.                         newModel.tags[ i ][ j ].Matrix[ 0 ][ 2 ]    = getFloat(F);
  213.                         newModel.tags[ i ][ j ].Matrix[ 1 ][ 2 ]    = getFloat(F);
  214.                         newModel.tags[ i ][ j ].Matrix[ 2 ][ 2 ]    = getFloat(F);
  215.                     }
  216.                 }
  217.             } else
  218.             {
  219.                 newModel.linkedModels    = NULL;
  220.                 newModel.tags            = NULL;
  221.             }
  222.  
  223.             newModel.meshes =
  224.                 new gl_mesh[newModel.meshNum];
  225.  
  226.             for (i=0;i<newModel.meshNum;i++)
  227.             {
  228.                 if (!loadmesh(newModel.meshes[ i ],F))
  229.                     return false;
  230.             }
  231.  
  232.             return true;
  233.         } else
  234.             return false;
  235.     } else 
  236.         return false;
  237. }
  238.  
  239. /*
  240. cleans up allocated model data
  241. */
  242. void delete_gl_model( gl_model *model )
  243. {
  244.     unsigned int i, j, t;
  245.     gl_mesh *mesh;    
  246.     gl_model *linkModel, *parent;
  247.  
  248.     if (model == NULL) return;
  249.         
  250.     // delete tag and bone frame data
  251.     if (model->tags) {
  252.         delete [] model->tags; 
  253.         model->tags = NULL;
  254.     }
  255.  
  256.     if (model->boneFrames) {
  257.         delete [] model->boneFrames; 
  258.         model->boneFrames = NULL;
  259.     }
  260.  
  261.     // remove all meshes
  262.     for (i=0 ; i<model->meshNum ; i++) {
  263.         mesh = &model->meshes[i];
  264.  
  265.         if (mesh->triangles) {
  266.             delete [] mesh->triangles; 
  267.             mesh->triangles = NULL;
  268.         }
  269.  
  270.         if (mesh->textureCoord) {
  271.             delete [] mesh->textureCoord; mesh->textureCoord = NULL;
  272.         }
  273.  
  274.         if (mesh->iterMesh) { 
  275.             delete [] mesh->iterMesh; mesh->iterMesh = NULL;
  276.         }
  277.  
  278.         // free textures from the mesh
  279.         for (t=0 ; t<mesh->skinNum ; t++) 
  280.             freeTexture( mesh->bindings[t] );
  281.  
  282.         if (mesh->bindings) {
  283.             delete [] mesh->bindings; mesh->bindings = NULL;
  284.         }
  285.         
  286.         for (j=0 ; j<mesh->meshFrameNum ; j++) {
  287.             if (mesh->meshFrames[j]) {
  288.                 delete [] mesh->meshFrames[j]; mesh->meshFrames[j] = NULL;
  289.             }
  290.         }
  291.  
  292.         if (mesh->meshFrames) {
  293.             delete [] mesh->meshFrames;    mesh->meshFrames = NULL;
  294.         }
  295.     }
  296.  
  297.     if (model->meshes) {
  298.         delete [] model->meshes; model->meshes = NULL;
  299.     }
  300.     
  301.  
  302.     // remove references from parent
  303.     parent = model->parent;
  304.     if (parent != NULL) {
  305.         for (i=0 ; i<parent->tagNum ; i++) {
  306.             if (parent->linkedModels[i] == model) {
  307.                 parent->linkedModels[i] = NULL;
  308.             }
  309.         }
  310.         model->parent = NULL;
  311.     }    
  312.     
  313.     
  314.     if (model->linkedModels) {
  315.         // remove references from children
  316.         for (i=0 ; i<model->tagNum ; i++) {
  317.             linkModel = model->linkedModels[i];
  318.             if (linkModel != NULL) {
  319.                   //linkModel->parent = NULL;
  320.                 delete_gl_model( linkModel );
  321.             }
  322.         }
  323.     }
  324.  
  325.     // remove the model from mdview.modelList
  326.     if (model->modelListPosition) {
  327.         mdview.modelList->remove( model->modelListPosition );
  328.         if (model == mdview.baseModel) {
  329.             mdview.baseModel = NULL;
  330.         }
  331.     }
  332.  
  333.     // remove all entries in the tag menu
  334.     for (i=0 ; i<model->tagNum ; i++) {
  335.         tagMenu_remove( (GLMODEL_DBLPTR)&model->linkedModels[i] );
  336.     }
  337.  
  338.     delete model;
  339. }
  340.  
  341. bool    loadmd3(gl_model& newModel, char* filename)
  342. {
  343.     FILE* F;
  344.     if ( ( F = fopen( filename , "rb" ) ) != NULL ) 
  345.     {
  346.         if (loadmodel(newModel,F))
  347.         {
  348.             fclose(F);
  349.             return true;
  350.         } else
  351.             return false;
  352.     } else
  353.         return false;
  354. }
  355.  
  356.  
  357. /*
  358. writes out the mesh to a raw file
  359. */
  360. void write_baseModelToRaw( char *fname )
  361. {
  362.  
  363.     gl_model *model = mdview.baseModel;
  364.     gl_mesh        *mesh;
  365.     int i, mesh_num;
  366.     Vec3 *vecs;
  367.     TriVec    *tris;    
  368.     int tri_num, t, v, n;
  369.  
  370.     
  371.     // open up file for writing
  372.     FILE *rawfile = fopen( fname, "wt" );
  373.     if (!rawfile) { 
  374.         Debug("Could not write to raw file %s", fname);
  375.         return;
  376.     }
  377.  
  378.     // write out header
  379.     fprintf(rawfile, "Object1\n");        
  380.     mesh_num = model->meshNum;        
  381.  
  382.     // for all the meshes in a model
  383.     for (i=0 ; i<mesh_num; i++) 
  384.     {        
  385.         mesh      = &model->meshes[i];                
  386.     
  387.         vecs = mesh->meshFrames[model->currentFrame];    
  388.         tris    = mesh->triangles;        
  389.         tri_num = mesh->triangleNum;                
  390.                 
  391.         // write out all the triangles as 3 vertices
  392.         for (t=0 ; t<tri_num ; t++) {
  393.             for (v=0 ; v<3 ; v++) {
  394.                 for (n=0 ; n<3 ; n++) {
  395.                     fprintf(rawfile, "%f ", vecs[tris[t][v]][n] );
  396.                 }                
  397.             }
  398.             fprintf(rawfile, "\n");
  399.         }
  400.     }
  401.  
  402.     fclose(rawfile);
  403. }
  404.  
  405.  
  406.