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

  1. #include "Model.h"
  2.  
  3. #include "Q3bspLoader.h"
  4. #include "ModelLoader.h"
  5. #include "vectormath.h"
  6. #include "matrixmath.h"
  7. #include "Tokenizer.h"
  8.  
  9. #include "log.h"
  10.  
  11. Model::Model(const char* filename){
  12.     name="uninitialized";
  13.  
  14.     meshes = NULL;
  15.     numMeshes = 0;
  16.  
  17.     materials = NULL;
  18.     numMaterials = 0;
  19.  
  20.     matrices = NULL;
  21.     numKeyframes = 0;
  22.  
  23. //    loadModel(filename);
  24.     File f(filename, "rt");
  25.     if(f.isOpen()){
  26.         if( !readFromFile(&f) )
  27.             error("(in Model::Model()): readFromFile() returned false.\n\n");
  28.     }else{
  29.         error("(in Model::Model()): Couldn't open file '%s'.\n\n", filename);
  30.     }
  31.  
  32.     calcBSphere();
  33.     calcAABB();
  34.  
  35. }
  36.  
  37. Model::~Model(){
  38.     clearModel();
  39. }
  40.  
  41. void Model::clearModel(){    // THINKABOUTME: meshes l÷schen??
  42. }
  43. /*
  44. void Model::loadModel(const char* filename){
  45.     Tokenizer t(filename, ".", "");
  46.     char* ext=t.tokv[t.tokc-1];
  47.  
  48.     if(!strcasecmp(ext, "3ds")){
  49.         if(load3DS(filename, this))
  50.             log("Model loaded: '%s' (3ds import).\n", filename);
  51.         else
  52.             error("(in Model::Model()): Couldn't load 3ds-file '%s'.\n\n", filename);
  53.     }else if(!strcasecmp(ext, "ac")){
  54.         if(loadAC3D(filename, this))
  55.  
  56.             log("Model loaded: '%s' (ac3d import).\n", filename);
  57.         else
  58.             error("(in Model::Model()): Couldn't load ac3d-file '%s'.\n\n", filename);
  59.     }else{
  60.         error("(in Model::loadModel()): unkown extension: '%s'. Model not loaded.\n", ext);
  61.     }
  62. }
  63.  
  64. void Model::loadModel(const char* filename, bool generateMatrices=true, bool setupLights=false){
  65.     Tokenizer t(filename, ".", "");
  66.     char* ext=t.tokv[t.tokc-1];
  67.  
  68.     if(!strcasecmp(ext, "3ds")){
  69.         if(L3dsLoader::load3DS(filename, this, generateMatrices, setupLights))
  70.             log("Model loaded: '%s' (3ds import).\n", filename);
  71.         else
  72.             error("(in Model::Model()): Couldn't load 3ds-file '%s'.\n\n", filename);
  73.     }else if(!strcasecmp(ext, "ac")){
  74.         if(Ac3dLoader::loadAC3D(filename, this))
  75.             log("Model loaded: '%s' (ac3d import).\n", filename);
  76.         else
  77.             error("(in Model::Model()): Couldn't load ac3d-file '%s'.\n\n", filename);
  78.     }else if(!strcasecmp(ext, "bsp")){
  79.         if(Q3bspLoader::loadBSP(filename, this))
  80.             log("Model loaded: '%s' (q3bsp import).\n", filename);
  81.         else
  82.             error("(in Model::Model()): Couldn't load ac3d-file '%s'.\n\n", filename);
  83.     }else if(!strcasecmp(ext, "model")){
  84.         if(ModelLoader::loadModel(filename, this))
  85.             log("Model loaded: '%s' (model import).\n", filename);
  86.         else
  87.             error("(in Model::Model()): Couldn't load model-file '%s'.\n\n", filename);
  88.     }else{
  89.         error("(in Model::loadModel()): unkown extension: '%s'. Model not loaded.\n", ext);
  90.     }
  91. }
  92. */
  93. int Model::addMesh(Mesh* mesh){
  94.     int i;
  95.     int id, parentId;
  96.     mat4x4_t mat;
  97.  
  98.     numMeshes++;
  99.     Mesh** newM=new Mesh*[numMeshes];
  100.     for(i=0;i<numMeshes-1;i++){
  101.         newM[i]=meshes[i];
  102.     }
  103.     newM[numMeshes-1]=mesh;
  104.     delete[] meshes;
  105.     meshes=newM;
  106.  
  107.     id=numMeshes-1;
  108.     parentId=getMeshId(mesh->parent);
  109.     if(parentId==-1){
  110.         matrixCopy(mesh->transformationMatrix, mat, 4);
  111.     }else{
  112.         matrixMultMatrix(matrices[0][parentId], mesh->transformationMatrix, 4, mat);
  113.     }
  114.     addMatrix(0, id, mat);
  115.  
  116.  
  117.     for(i=0;i<mesh->numChilds;i++){
  118.         addMesh(mesh->childs[i]);
  119.     }
  120.  
  121.     return id;
  122. }
  123.  
  124. int Model::addMatrix(int frame, int id, mat4x4_t mat){
  125.     if(frame<0 || frame>=numKeyframes){
  126.         error("(in Model::addMatrix()): frame invalid.\n");
  127.         return -1;
  128.     }
  129.     if(id<0 || id>=numMeshes){
  130.         error("(in Model::addMatrix()): Mesh id invalid.\n");
  131.         return -1;
  132.     }
  133.     matrixCopy(mat, matrices[frame][id], 4);
  134.     return id;
  135. }
  136.  
  137. int Model::getMeshId(Mesh* mesh){
  138.     int i;
  139.  
  140.     for(i=0;i<numMeshes;i++){
  141.         if(meshes[i]==mesh){
  142.             return i;
  143.         }
  144.     }
  145.  
  146.     return -1;
  147. }
  148.  
  149.  
  150. void Model::calcBSphere(){
  151.  
  152. }
  153.  
  154. void Model::calcAABB(){
  155.     
  156.     vectorInit3d(FLT_MAX, FLT_MAX, FLT_MAX, min);
  157.     vectorInit3d(-FLT_MAX, -FLT_MAX, -FLT_MAX, max);
  158.  
  159.     int i,j,k;
  160.     int numFaces=0;
  161.     int numVertices=0;
  162.  
  163.     for(i=0;i<numMeshes;i++){
  164.         for(j=0;j<meshes[i]->numFaces;j++){
  165.             numFaces++;
  166.             for(k=0;k<meshes[i]->faces[j]->numVertices;k++){
  167.                 numVertices++;
  168.                 vec4_t p;
  169.                 vectorInit4d(meshes[i]->faces[j]->vertices[k*3+0], meshes[i]->faces[j]->vertices[k*3+1], meshes[i]->faces[j]->vertices[k*3+2], 1.0f, p);
  170.                 matrixMultVector(matrices[0][i], p, 4, p);
  171.                 vectorScale3d(1/p[3], p, p);
  172.                 
  173.                 min[0]=p[0]<min[0] ? p[0] : min[0];
  174.                 min[1]=p[1]<min[1] ? p[1] : min[1];
  175.                 min[2]=p[2]<min[2] ? p[2] : min[2];
  176.                 
  177.                 max[0]=p[0]>max[0] ? p[0] : max[0];
  178.                 max[1]=p[1]>max[1] ? p[1] : max[1];
  179.                 max[2]=p[2]>max[2] ? p[2] : max[2];
  180.             }
  181.         }
  182.     }
  183.     
  184.     if(numFaces==0){
  185.         vectorInit3d(-0.1f,-0.1f,-0.1f,min);
  186.         vectorInit3d( 0.1f, 0.1f, 0.1f,max);
  187.     }
  188.     log("Model has %i vertices forming %i faces in %i meshes (%i keyframes).\n", numVertices, numFaces, numMeshes, numKeyframes);
  189. //    printf("model: %f %f %f;  %f %f %f\n", min[0], min[1], min[2], max[0],max[1],max[2]);
  190. }
  191.  
  192.  
  193.  
  194. bool Model::readFromFile(File* f){
  195.     char buff[256];
  196.     Tokenizer t(" =\t\n\r\"", "\"");
  197.  
  198.     while(f->readLine(256, buff, true) != -1){
  199.         
  200.         //printf("Model: line: %s\n", buff);
  201.         t.tokenize(buff);
  202.  
  203.         if(t.tokc==0)
  204.             continue;
  205.  
  206.         if(streq(t.tokv[0], "MATERIAL_LIST")){
  207.             readMaterialList(f);
  208.         }else if(streq(t.tokv[0], "KEYFRAME_LIST")){
  209.             readKeyframeList(f);
  210.         }else if(streq(t.tokv[0], "MESH_LIST")){
  211.             readMeshList(f);
  212. //        }else if(streq(t.tokv[0], "MESH")){
  213. //            this->addMesh(new Mesh(f, this));
  214.  
  215.         }else if(streq(t.tokv[0], "{")){
  216.             continue;
  217.         }else if(streq(t.tokv[0], "}")){
  218.             break;//return true;
  219.         }else{
  220.             warn("(in Model::readFromFile() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  221.         }
  222.     }
  223.  
  224.     return true;
  225.  
  226. }
  227.  
  228. bool Model::readMaterialList(File* f){
  229.     char buff[256];
  230.     Tokenizer t(" =\t\n\r\"", "\"");
  231.  
  232.     while(f->readLine(256, buff, true) != -1){
  233.         
  234.         //printf("Model: line: %s\n", buff);
  235.         t.tokenize(buff);
  236.  
  237.         if(t.tokc==0)
  238.             continue;
  239.  
  240.         if(streq(t.tokv[0], "NUM_MATERIALS")){
  241.             numMaterials = atoi(t.tokv[1]);
  242.             materials = new Material*[numMaterials];
  243.         }else if( streq(t.tokv[0], "MATERIAL") ){
  244.             int matId = atoi(t.tokv[1]);
  245.             materials[matId] = new Material(f);
  246.  
  247.         }else if(streq(t.tokv[0], "{")){
  248.             continue;
  249.         }else if(streq(t.tokv[0], "}")){
  250.             break;//return true;
  251.         }else{
  252.             warn("(in Model::readMaterialList() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  253.         }
  254.     }
  255.  
  256.     return true;
  257. }
  258.  
  259. bool Model::readMeshList(File* f){
  260.     char buff[256];
  261.     Tokenizer t(" =\t\n\r\"", "\"");
  262.  
  263.     while(f->readLine(256, buff, true) != -1){
  264.         
  265.         //printf("Model: line: %s\n", buff);
  266.         t.tokenize(buff);
  267.  
  268.         if(t.tokc==0)
  269.             continue;
  270.  
  271.         if( streq(t.tokv[0], "NUM_MESHES") ){
  272.             numMeshes = atoi(t.tokv[1]);
  273.             meshes = new Mesh*[numMeshes];
  274.         }else if( streq(t.tokv[0], "MESH") ){
  275.             int meshId = atoi(t.tokv[1]);
  276.             meshes[meshId] = new Mesh(f, this);
  277.  
  278.         }else if(streq(t.tokv[0], "{")){
  279.             continue;
  280.         }else if(streq(t.tokv[0], "}")){
  281.             break;//return true;
  282.         }else{
  283.             warn("(in Model::readMeshList() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  284.         }
  285.     }
  286.  
  287.     return true;
  288. }
  289.  
  290. bool Model::readKeyframeList(File* f){
  291.     char buff[256];
  292.     Tokenizer t(" =\t\n\r\"", "\"");
  293.  
  294.     while(f->readLine(256, buff, true) != -1){
  295.         
  296.         //printf("Model: line: %s\n", buff);
  297.         t.tokenize(buff);
  298.  
  299.         if(t.tokc==0)
  300.             continue;
  301.  
  302.         if( streq(t.tokv[0], "NUM_KEYFRAMES") ){
  303.             numKeyframes = atoi(t.tokv[1]);
  304.             matrices = new GLfloat**[numKeyframes];
  305.         }else if( streq(t.tokv[0], "KEYFRAME") ){
  306.             int keyframeId = atoi(t.tokv[1]);
  307.             matrices[keyframeId] = readKeyframe(f);
  308.  
  309.         }else if(streq(t.tokv[0], "{")){
  310.             continue;
  311.         }else if(streq(t.tokv[0], "}")){
  312.             break;//return true;
  313.         }else{
  314.             warn("(in Model::readMeshList() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  315.         }
  316.     }
  317.  
  318.     return true;
  319. }
  320.  
  321. GLfloat** Model::readKeyframe(File* f){
  322.     char buff[256];
  323.     Tokenizer t(" =\t\n\r\"", "\"");
  324.  
  325.     GLfloat** matrices = new GLfloat*[numMeshes];
  326.  
  327.     while(f->readLine(256, buff, true) != -1){
  328.         
  329.         //printf("Model: line: %s\n", buff);
  330.         t.tokenize(buff);
  331.  
  332.         if(t.tokc==0)
  333.             continue;
  334.  
  335.         if( streq(t.tokv[0], "MATRIX") ){
  336.             int matrixId = atoi(t.tokv[1]);
  337.             matrices[matrixId] = new GLfloat[16];
  338.  
  339. //            if(t.tokc != 18){
  340. //                warn();
  341. //            }
  342.             for(int i=0;i<16;i++){
  343.                 matrices[matrixId][i] = (float)atof(t.tokv[2+i]);
  344.             }
  345.         }else if(streq(t.tokv[0], "{")){
  346.             continue;
  347.         }else if(streq(t.tokv[0], "}")){
  348.             break;//return true;
  349.         }else{
  350.             warn("(in Model::readKeyframes() (%s, line %i)): Unknown token '%s'.\n\n", f->filename, f->line, t.tokv[0]);
  351.         }
  352.     }
  353.  
  354.     return matrices;
  355.  
  356. }
  357.  
  358. void Model::dump(){
  359.     int i;
  360.  
  361.     printf("--> Model '%s': numMeshes: %i, numKeyframes: %i\n", name, numMeshes, numKeyframes);
  362.  
  363.     for(i=0;i<numMeshes;i++){
  364.         printf(" * Mesh %i:\n", i);
  365.         meshes[i]->dump();
  366.     }
  367.     printf("<-- Model '%s' end.\n\n", name);
  368. }
  369.  
  370.