home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / ModelLoader.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-06  |  10.2 KB  |  356 lines

  1. #include "ModelLoader.h"
  2.  
  3. #include "File.h"
  4. #include "ShaderHandler.h"
  5. #include "TextureHandler.h"
  6. #include "log.h"
  7. #include "collision.h"
  8.  
  9. Material** ModelLoader::materialList;
  10. int ModelLoader::numMaterials;
  11. char* ModelLoader::path;
  12.  
  13. Material* ModelLoader::readMaterial(File* f){
  14.     char buff[256];
  15.     Tokenizer t(" =\t\n\r\"|", "\"");
  16.  
  17.     Material* mat=new Material();
  18.  
  19.     while(f->readLine(256, buff, true) != -1){
  20.         
  21.         //printf("Model: line: %s\n", buff);
  22.         t.tokenize(buff);
  23.  
  24.         if(t.tokc==0)
  25.             continue;
  26.  
  27.         if(streq(t.tokv[0], "NAME")){
  28.             // ignore name
  29.         }else if(streq(t.tokv[0], "SURFACE_TYPE")){
  30.             if( streq(t.tokv[1], "METAL") ){
  31.                 mat->surfaceType = MATERIAL_SURFACE_TYPE_METAL;
  32.             }else if( streq(t.tokv[1], "STONE") ){
  33.                 mat->surfaceType = MATERIAL_SURFACE_TYPE_STONE;
  34.             }else if( streq(t.tokv[1], "WOOD") ){
  35.                 mat->surfaceType = MATERIAL_SURFACE_TYPE_WOOD;
  36.             }else if( streq(t.tokv[1], "DIRT") ){
  37.                 mat->surfaceType = MATERIAL_SURFACE_TYPE_DIRT;
  38.             }else{
  39.                 warn("(in ModelLoader::readMaterial() (%s, line %i)): Unknown surface type '%s'.\n\n", f->filename, f->line, t.tokv[1]);
  40.             }
  41.         }else if(streq(t.tokv[0], "COLLISION_FLAGS")){
  42.             for(int i=1;i<t.tokc;i++){
  43.                 if(streq(t.tokv[i], "WALK_THROUGH")){
  44.                     mat->collisionFlags |= COLLISION_FLAG_WALK_THROUGH;
  45.                 }else if(streq(t.tokv[i], "SHOOT_THROUGH")){
  46.                     mat->collisionFlags |= COLLISION_FLAG_SHOOT_THROUGH;
  47.                 }else if(streq(t.tokv[i], "NONE")){
  48.                     mat->collisionFlags = COLLISION_FLAG_NONE;
  49.                 }else{
  50.                     warn("(in ModelLoader::readMaterial() (%s, line %i)): Unknown collisionFlag '%s'.\n\n", f->filename, f->line, t.tokv[i]);
  51.                 }
  52.             }
  53.  
  54.         }else if(streq(t.tokv[0], "COLOR")){
  55.             sscanf(t.tokv[1], "%f %f %f %f", &mat->color[0], &mat->color[1], &mat->color[2], &mat->color[3]);
  56.         }else if(streq(t.tokv[0], "TEXTURE")){
  57.             char p[256];
  58.             strcpy(p, path);
  59.             strcat(p, t.tokv[1]);
  60.             if(ShaderHandler::hasShaderForImageFile(p))
  61.                 mat->addShader(ShaderHandler::getShader(p));
  62.             else
  63.                 mat->addTexture(TextureHandler::getTexture(p));
  64.         }else if(streq(t.tokv[0], "LIGHTMAP")){
  65.             char p[256];
  66.             strcpy(p, path);
  67.             strcat(p, t.tokv[1]);
  68.             mat->addLightmap(TextureHandler::getTexture(p));
  69.             
  70.  
  71.         }else if(streq(t.tokv[0], "{")){
  72.             continue;
  73.         }else if(streq(t.tokv[0], "}")){
  74.             break;//return true;
  75.         }else{
  76.             warn("(in ModelLoader::readMaterial() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  77.         }
  78.     }
  79.  
  80.     mat->setAttribs();
  81.  
  82.     return mat;
  83. }
  84.  
  85. bool ModelLoader::readMaterialList(File* f){
  86.     char buff[256];
  87.     Tokenizer t(" =\t\n\r\"", "\"");
  88.  
  89.     int matCount=0;
  90.  
  91.     while(f->readLine(256, buff, true) != -1){
  92.         
  93.         //printf("Model: line: %s\n", buff);
  94.         t.tokenize(buff);
  95.  
  96.         if(t.tokc==0)
  97.             continue;
  98.  
  99.         if(streq(t.tokv[0], "NUM_MATERIALS")){
  100.             numMaterials=atoi(t.tokv[1]);
  101.             materialList=new Material*[numMaterials];
  102.         }else if(streq(t.tokv[0], "MATERIAL")){
  103.             materialList[matCount]=readMaterial(f);
  104.             matCount++;
  105.  
  106.         }else if(streq(t.tokv[0], "{")){
  107.             continue;
  108.         }else if(streq(t.tokv[0], "}")){
  109.             break;//return true;
  110.         }else{
  111.             warn("(in ModelLoader::readMaterialList() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  112.         }
  113.     }
  114.  
  115.     return true;
  116. }
  117. /*
  118. bool ModelLoader::readKeyframeList(File* f){
  119.     char buff[256];
  120.     Tokenizer t(" =\t\n\r\"", "\"");
  121.  
  122.  
  123.     while(f->readLine(256, buff, true) != -1){
  124.         
  125.         //printf("Model: line: %s\n", buff);
  126.         t.tokenize(buff);
  127.  
  128.         if(t.tokc==0)
  129.             continue;
  130.  
  131.         if(streq(t.tokv[0], "NUM_KEYFRAMES")){
  132.             numKeyframes = atoi(t.tokv[1]);
  133.             materialList = new Material*[numMaterials];
  134.         }else if(streq(t.tokv[0], "KEYFRAME")){
  135.             int kfNumber = atoi(t.tokv[1]);
  136.             readKeyframe(f, kfNumber);
  137.  
  138.         }else if(streq(t.tokv[0], "{")){
  139.             continue;
  140.         }else if(streq(t.tokv[0], "}")){
  141.             break;//return true;
  142.         }else{
  143.             warn("(in ModelLoader::readMaterialList() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  144.         }
  145.     }
  146.  
  147.     return true;
  148. }
  149. */
  150. Mesh* ModelLoader::readMesh(File* f){
  151.     Mesh* m=new Mesh();
  152.  
  153.     char buff[256];
  154.     Tokenizer t(" =\t\n\r\"", "\"");
  155.  
  156. //    int matCount=0;
  157.  
  158.     while(f->readLine(256, buff, true) != -1){
  159.         
  160.         //printf("Model: line: %s\n", buff);
  161.         t.tokenize(buff);
  162.  
  163.         if(t.tokc==0)
  164.             continue;
  165.  
  166.         if(streq(t.tokv[0], "TRANSFORMATION_MATRIX")){
  167. //            sscanf(t.tokv[1], "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f"
  168. //                , &m->transformationMatrix[0], &m->transformationMatrix[1], &m->transformationMatrix[2], &m->transformationMatrix[3]
  169. //                , &m->transformationMatrix[4], &m->transformationMatrix[5], &m->transformationMatrix[6], &m->transformationMatrix[7]
  170. //                , &m->transformationMatrix[8], &m->transformationMatrix[9], &m->transformationMatrix[10], &m->transformationMatrix[11]
  171. //                , &m->transformationMatrix[12], &m->transformationMatrix[13], &m->transformationMatrix[14], &m->transformationMatrix[15]
  172. //                );
  173.             //printf("N: %i\n", n);
  174.         }else if(streq(t.tokv[0], "MATERIAL")){
  175.             m->numMaterials=1;
  176.             m->materials=new Material*[1];
  177.             m->materials[0]=materialList[atoi(t.tokv[1])];
  178.  
  179. //            printf("MAT: %i, hasTex %i, hasLM %i\n", atoi(t.tokv[1]), m->materials[0]->hasTexture, m->materials[0]->hasLightmap);
  180.         }else if(streq(t.tokv[0], "NUM_VERTICES")){
  181.             m->numVertices=m->numColors=m->numNormals=m->numTexCoords=atoi(t.tokv[1]);
  182.             m->vertices=new float[m->numVertices*3];
  183.             m->colors=new float[m->numColors*3];
  184.             m->normals=new float[m->numNormals*3];
  185.             m->texCoords1=new float[m->numTexCoords*2];
  186.             m->texCoords2=new float[m->numTexCoords*2];
  187.         }else if(streq(t.tokv[0], "VERTEX_LIST")){
  188.             f->readLine(256, buff, true);
  189.  
  190.             //int n;
  191.             for(int i=0;i<m->numVertices;i++){
  192.                 f->readLine(256, buff, true);
  193. /*
  194.                 sscanf(buff, "VERTEX %i: %f %f %f  %f %f %f  %f %f  %f %f"
  195.                     , &n
  196.                     , &m->vertices[i*3+0], &m->vertices[i*3+1], &m->vertices[i*3+2]
  197.                     , &m->colors[i*3+0], &m->colors[i*3+1], &m->colors[i*3+2]
  198.                     , &m->texCoords1[i*2+0], &m->texCoords1[i*2+1]
  199.                     , &m->texCoords2[i*2+0], &m->texCoords2[i*2+1]);
  200. */
  201.                 Tokenizer t2(buff, " ", "");
  202.                 vectorInit3d((float)atof(t2.tokv[2]), (float)atof(t2.tokv[3]), (float)atof(t2.tokv[4]), &m->vertices[i*3]);
  203.                 vectorInit3d((float)atof(t2.tokv[5]), (float)atof(t2.tokv[6]), (float)atof(t2.tokv[7]), &m->colors[i*3]);
  204.                 vectorInit2d((float)atof(t2.tokv[8]), (float)atof(t2.tokv[9]), &m->texCoords1[i*2]);
  205.                 vectorInit2d((float)atof(t2.tokv[10]), (float)atof(t2.tokv[11]), &m->texCoords2[i*2]);
  206.  
  207.                 vectorInit3d(0.0f, 0.0f, 0.0f, &m->normals[i*3]);
  208.             }
  209.  
  210.             f->readLine(256, buff, true);
  211.  
  212.         }else if(streq(t.tokv[0], "NUM_FACES")){
  213.             m->numFaces=atoi(t.tokv[1]);
  214.             m->faces=new Face*[m->numFaces];
  215.         }else if(streq(t.tokv[0], "FACE_LIST")){
  216.             f->readLine(256, buff, true);
  217.  
  218.             int ind1, ind2, ind3;
  219.             for(int i=0;i<m->numFaces;i++){
  220.                 Face* fa=new Face();
  221.  
  222.                 f->readLine(256, buff, true);
  223. /*
  224.                 sscanf(buff, "FACE %i: %i %i %i  %f %f %f"
  225.                     , &n
  226.                     , &ind1, &ind2, &ind3
  227.                     , &fa->normal[0], &fa->normal[1], &fa->normal[2]);
  228. */
  229.                 Tokenizer t2(buff, " ", "");
  230.                 ind1=atoi(t2.tokv[2]);
  231.                 ind2=atoi(t2.tokv[3]);
  232.                 ind3=atoi(t2.tokv[4]);
  233.                 //vectorInit3d((float)atof(t2.tokv[5]), (float)atof(t2.tokv[6]), (float)atof(t2.tokv[7]), fa->normal);
  234.  
  235.                 fa->numIndices=3;
  236.                 fa->indices=new unsigned int[3];
  237.                 fa->indices[0]=ind1;
  238.                 fa->indices[1]=ind2;
  239.                 fa->indices[2]=ind3;
  240.  
  241.                 fa->numVertices=3;
  242.                 fa->vertices=new float[9];
  243.                 vectorCopy3d(&m->vertices[ind1*3], &fa->vertices[0]);
  244.                 vectorCopy3d(&m->vertices[ind2*3], &fa->vertices[3]);
  245.                 vectorCopy3d(&m->vertices[ind3*3], &fa->vertices[6]);
  246.                 
  247.                 fa->numColors=3;
  248.                 fa->colors=new float[9];
  249.                 vectorCopy3d(&m->colors[ind1*3], &fa->colors[0]);
  250.                 vectorCopy3d(&m->colors[ind2*3], &fa->colors[3]);
  251.                 vectorCopy3d(&m->colors[ind3*3], &fa->colors[6]);
  252. /*
  253.                 fa->numNormals=3;
  254.                 fa->normals=new float[9];
  255.                 vectorCopy3d(&m->normals[ind1*3], &fa->normals[0]);
  256.                 vectorCopy3d(&m->normals[ind2*3], &fa->normals[3]);
  257.                 vectorCopy3d(&m->normals[ind3*3], &fa->normals[6]);
  258. */
  259.                 fa->numTexCoords=3;
  260.                 fa->texCoords1=new float[6];
  261.                 vectorCopy2d(&m->texCoords1[ind1*2], &fa->texCoords1[0]);
  262.                 vectorCopy2d(&m->texCoords1[ind2*2], &fa->texCoords1[2]);
  263.                 vectorCopy2d(&m->texCoords1[ind3*2], &fa->texCoords1[4]);
  264.                 fa->texCoords2=new float[6];
  265.                 vectorCopy2d(&m->texCoords2[ind1*2], &fa->texCoords2[0]);
  266.                 vectorCopy2d(&m->texCoords2[ind2*2], &fa->texCoords2[2]);
  267.                 vectorCopy2d(&m->texCoords2[ind3*2], &fa->texCoords2[4]);
  268.  
  269.                 fa->material=m->materials[0];
  270.  
  271.                 fa->calcNormal();
  272.  
  273.                 // correct vertex normals!
  274.                 fa->numNormals=3;
  275.                 fa->normals=new float[9];
  276.                 vectorCopy3d(fa->normal, &fa->normals[0]);
  277.                 vectorCopy3d(fa->normal, &fa->normals[3]);
  278.                 vectorCopy3d(fa->normal, &fa->normals[6]);
  279.                 vectorCopy3d(fa->normal, &m->normals[ind1*3]);
  280.                 vectorCopy3d(fa->normal, &m->normals[ind2*3]);
  281.                 vectorCopy3d(fa->normal, &m->normals[ind3*3]);
  282.  
  283.  
  284.                 m->faces[i]=fa;
  285.  
  286.             }
  287.  
  288.             f->readLine(256, buff, true);
  289.  
  290.         }else if(streq(t.tokv[0], "{")){
  291.             continue;
  292.         }else if(streq(t.tokv[0], "}")){
  293.             break;//return true;
  294.         }else{
  295.             warn("(in ModelLoader::readMesh() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  296.         }
  297.     }
  298.  
  299.     m->setRenderMode();
  300.  
  301.     return m;
  302. }
  303.  
  304.  
  305. bool ModelLoader::loadModel(const char* filename, Model* model){
  306.     path=File::extractPath(filename);
  307.  
  308.     File* f=new File(filename, "rt");
  309.     if(!f->isOpen()){
  310.  
  311.         return false;
  312.     }
  313.  
  314.  
  315.  
  316.  
  317.     char buff[256];
  318.     Tokenizer t(" =\t\n\r\"", "\"");
  319.  
  320.     while(f->readLine(256, buff, true) != -1){
  321.         
  322.         //printf("Model: line: %s\n", buff);
  323.         t.tokenize(buff);
  324.  
  325.         if(t.tokc==0)
  326.             continue;
  327.  
  328.         if(streq(t.tokv[0], "MATERIAL_LIST")){
  329.             readMaterialList(f);
  330. //        }else if(streq(t.tokv[0], "KEYFRAME_LIST")){
  331. //            readKeyframeList(f);
  332.         }else if(streq(t.tokv[0], "MESH")){
  333.             Mesh* m=readMesh(f);
  334.             model->addMesh(m);
  335.  
  336.         }else if(streq(t.tokv[0], "{")){
  337.             continue;
  338.         }else if(streq(t.tokv[0], "}")){
  339.             break;//return true;
  340.         }else{
  341.             warn("(in ModelLoader::loadModel() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  342.         }
  343.     }
  344.  
  345.  
  346.  
  347.     f->close();
  348.  
  349.     delete[] materialList;
  350.     delete[] path;
  351.  
  352. //    model->dump();
  353.     
  354.     return true;
  355. }
  356.