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

  1. /*!
  2. \file l3dsloader.cpp
  3. \author Karsten Schwenk
  4. \version 1.0
  5.  
  6. See header for describtion (l3dsloader.h).
  7.  
  8. Important is the #load3DS() function - all the other functions are just dirty-coded helpers.
  9. */
  10.  
  11. #include "L3dsLoader.h"
  12.  
  13.  
  14. #include <stdlib.h>
  15. #include <string.h>
  16. //#include <config.h>
  17. #ifdef WITH_DMALLOC
  18. #include <dmalloc.h>
  19. #endif
  20. #include <math.h>
  21.  
  22. #include "Model.h"
  23. #include "matrixmath.h"
  24. #include "vectormath.h"
  25. //#include "light.h"
  26. //#include "File.h"
  27. #include "log.h"
  28. #include "TextureHandler.h"
  29. #include "ShaderHandler.h"
  30.  
  31.  
  32.  
  33. static mat4x4_t stdMatrix={ 1,0,0,0,
  34.                             0,1,0,0,
  35.                             0,0,1,0,
  36.                             0,0,0,1 };
  37.  
  38. static mat4x4_t flipMatrix={1,0,0,0,
  39.                             0,0,-1,0,
  40.                             0,1,0,0,
  41.                             0,0,0,1 };
  42.  
  43. static mat4x4_t invFlipMatrix={ 1,0,0,0,
  44.                                 0,0,1,0,
  45.                                 0,-1,0,0,
  46.                                 0,0,0,1 };
  47.  
  48.  
  49. char* L3dsLoader::path=NULL;
  50.  
  51. /*
  52. static void rib_concat_transform(FILE *o, Lib3dsMatrix m){
  53.   int i,j;
  54.  
  55.   fprintf(o, "ConcatTransform [");
  56.   for (i=0; i<4; ++i) {
  57.     for (j=0; j<4; ++j) {
  58.       fprintf(o, "%f ", m[i][j]);
  59.     }
  60.   }
  61.   fprintf(o, "]\n");
  62. }
  63.  
  64.  
  65. static void rib_camera(FILE *o, Lib3dsFile *f, Lib3dsMatrix M){
  66.   Lib3dsNode *c;
  67.   Lib3dsNode *t;
  68.   const char *name=camera;
  69.  
  70.   ASSERT(f);
  71.   if (!name) {
  72.     if (f->cameras) {
  73.       name=f->cameras->name;
  74.     }
  75.   }
  76.   if (!name) {
  77.     fprintf(stderr, "***ERROR*** No camera found!\n");
  78.     exit(1);
  79.   }
  80.   c=lib3ds_file_node_by_name(f, name, LIB3DS_CAMERA_NODE);
  81.   t=lib3ds_file_node_by_name(f, name, LIB3DS_TARGET_NODE);
  82.   if (!c || !t) {
  83.     fprintf(stderr, "***ERROR*** Invalid camera/target!\n");
  84.     exit(1);
  85.   }
  86.  
  87.   lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll);
  88.   rib_concat_transform(o, M);
  89.   fprintf(o, "Projection \"perspective\" \"fov\" [%f]\n", c->data.camera.fov);
  90. }
  91.  
  92. */
  93. void L3dsLoader::setupLights(Lib3dsFile *f){
  94. /*
  95.     Lib3dsLight *light;
  96.     Lib3dsNode *l;
  97.     Lib3dsNode *s;
  98.     int lightId=LIGHT1;
  99.  
  100.     for(int i=lightId;i<NUM_LIGHTS;i++){
  101.         lights[i]->switchOff();
  102.     }
  103.  
  104.     for (light=f->lights; light; light=light->next) {
  105.         if(lightId>=NUM_LIGHTS){
  106.             warn("in l3dsloader::setupLights()): Too many lights in scene. Aborting.\n\n");
  107.             break;
  108.         }
  109.  
  110.         l=lib3ds_file_node_by_name(f, light->name, LIB3DS_LIGHT_NODE);
  111.         s=lib3ds_file_node_by_name(f, light->name, LIB3DS_SPOT_NODE);
  112.         if(!l){
  113.             warn("(in l3dsloader::setupLights()): Invalid light.\n\n");
  114.         }else{
  115.             vec4_t pos;
  116.             vectorInit4d(l->data.light.pos[0], l->data.light.pos[2], -l->data.light.pos[1], 1.0f, pos);
  117.             lights[lightId]->setPosition(pos);
  118.             vec4_t col;
  119.             vectorInit4d(l->data.light.col[0], l->data.light.col[1], l->data.light.col[2], 1.0f, col);
  120.             lights[lightId]->setColor(col);
  121.             lights[lightId]->setAttenuation(1.0f, 0.1f, 0.0f);
  122.             if(s){    // spotlight
  123.                 vec3_t dir;
  124.                 vec3_t spotPos;
  125.                 vectorInit3d(s->data.spot.pos[0], s->data.spot.pos[2], -s->data.spot.pos[1], spotPos);
  126.                 vectorSub3d(spotPos, pos, dir);
  127.                 vectorNormalize3d(dir, dir);
  128.                 lights[lightId]->setupSpotLight(30.0f, 5.0f, dir);    // FIXME: richtige werte einsetzen!
  129.                 log("processed spotlight %i; col: %.1f %.1f %.1f; pos: %.1f %.1f %.1f; dir: %.1f %.1f %.1f.\n", lightId, col[0], col[1], col[2], pos[0], pos[1], pos[2], dir[0], dir[1], dir[2]);
  130.             }else{
  131.                 vec3_t dir;
  132.                 vectorInit3d(0.0f, 0.0f, 0.0f, dir);
  133.                 lights[lightId]->setupSpotLight(180.0f, 1.0f, dir);
  134.                 log("processed pointlight %i; col: %.1f %.1f %.1f; pos: %.1f %.1f %.1f.\n", lightId, col[0], col[1], col[2], pos[0], pos[1], pos[2]);
  135.             }
  136.  
  137.             lights[lightId]->switchOn();
  138.             lightId++;
  139.         }
  140.     }
  141. */
  142. }
  143.  
  144. Mesh* L3dsLoader::nodeToMesh(Lib3dsFile *f, Lib3dsNode *node/*, Model* m*/){
  145.     //log("processing node %s\n", node->name);
  146.  
  147.     int i;
  148.  
  149.     Lib3dsMesh *mesh;
  150.     Mesh* newMesh=new Mesh();
  151.  
  152.     if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)) {
  153.         //log("converting node: %s\n", node->name);
  154.         mesh=lib3ds_file_mesh_by_name(f, node->name);
  155.         ASSERT(mesh);
  156.         if (mesh) {
  157.             Lib3dsMaterial* materialLookUp[128];
  158.             Material* newMaterials[128];
  159.             for(i=0;i<128;i++){
  160.                 materialLookUp[i]=NULL;
  161.                 newMaterials[i]=NULL;
  162.             }
  163.             Material* stdMat=new Material();
  164. //            vectorInit4d(0.2f, 0.2f, 0.2f, 1.0f, stdMat->ambient);
  165. //            vectorInit4d(0.8f, 0.8f, 0.8f, 1.0f, stdMat->diffuse);
  166. //            vectorInit4d(1.0f, 1.0f, 1.0f, 1.0f, stdMat->specular);
  167. //            stdMat->shininess=1.0;
  168.             vectorInit4d(1.0f, 1.0f, 1.0f, 1.0f, stdMat->color);
  169.             stdMat->setAttribs();
  170.  
  171.             
  172.             Lib3dsObjectData *d=&node->data.object;
  173.             
  174.             Lib3dsMatrix N,M,X;
  175.             lib3ds_matrix_copy(N, node->matrix);
  176.             lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
  177.             //lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[2], d->pivot[1]);
  178.             lib3ds_matrix_copy(M, mesh->matrix);
  179.             lib3ds_matrix_inv(M);
  180.             lib3ds_matrix_mul(X,N,M);
  181.  
  182.             mat4x4_t m;
  183.             matrixMultMatrix(flipMatrix, (float*)X, 4, m);
  184.             matrixMultMatrix(m, invFlipMatrix, 4, m);
  185.             matrixCopy(m, newMesh->transformationMatrix, 4);
  186. //            printf("processing matrix: \n");
  187. //            matrixPrint(newMesh->transformationMatrix, 4);
  188.  
  189.             unsigned p;
  190.             Lib3dsVector *normalL=(Lib3dsVector*)malloc(3*sizeof(Lib3dsVector)*mesh->faces);
  191.             lib3ds_mesh_calculate_normals(mesh, normalL);
  192.  
  193.             for (p=0; p<mesh->faces; ++p) {
  194.                 Lib3dsFace *face=&mesh->faceL[p];
  195.                 Lib3dsMaterial *mat=lib3ds_file_material_by_name(f, face->material);
  196.                 
  197.                 Face* newFace=new Face();
  198.                 if (mat) {
  199. //                    printf("processing material\n");
  200.                     for(i=0;i<128;i++){
  201.                         if(materialLookUp[i]==mat){
  202.                             newFace->material=newMaterials[i];
  203. //                            printf("found mat in lut: %i\n", i);
  204.                             break;
  205.                         }
  206.                     }
  207.  
  208.                     if(i==128){    // material not yet in array -> add new one
  209.                         Material* newMat=new Material();
  210.                         //printf("ASDF trans: %f (%f %f)\n",mat->transparency,  mat->ambient[3], mat->diffuse[3]);
  211. //                        vectorInit4d(mat->ambient[0], mat->ambient[1], mat->ambient[2], 1.0f-mat->transparency/*mat->ambient[3]*/, newMat->ambient);
  212. //                        vectorInit4d(mat->diffuse[0], mat->diffuse[1], mat->diffuse[2], 1.0f-mat->transparency/*mat->diffuse[3]*/, newMat->diffuse);
  213. //                        vectorInit4d(mat->specular[0], mat->specular[1], mat->specular[2], 1.0f-mat->transparency/*mat->specular[3]*/, newMat->specular);
  214. //                        vectorInit4d(0.0f, 0.0f, 0.0f, 1.0f, newMat->emissive);
  215. //                        newMat->shininess=(float)(mat->shininess*100.0);
  216.  
  217.                         vectorInit4d(mat->diffuse[0], mat->diffuse[1], mat->diffuse[2], 1.0f-mat->transparency/*mat->diffuse[3]*/, newMat->color);
  218.  
  219.                         if(*mat->texture1_map.name!='\0'){
  220.                             char buff[256];
  221.                             strcpy(buff, path);
  222.                             strcat(buff, mat->texture1_map.name);
  223.                             //strlwr(buff);    // convert everything to lower case
  224.                             if(ShaderHandler::hasShaderForImageFile(buff))
  225.                                 newMat->addShader(ShaderHandler::getShader(buff));
  226.                             else
  227.                                 newMat->addTexture(TextureHandler::getTexture(buff));
  228.                         }
  229.  
  230.                         if(*mat->self_illum_map.name!='\0'){    // this serves as lightmap
  231.                             char buff[256];
  232.                             strcpy(buff, path);
  233.                             strcat(buff, mat->self_illum_map.name);
  234.                             //strlwr(buff);    // convert everything to lower case
  235.                             newMat->addLightmap(TextureHandler::getTexture(buff));
  236.                         }
  237.                         //log("mat.name: %s, %s, %s, %s\n", mat->name, mat->texture1_map.name, mat->texture2_map.name, mat->self_illum_map.name );
  238.  
  239.                         newMat->setAttribs();
  240.     
  241.                         for(i=0;i<128;i++){
  242.                             if(materialLookUp[i]==NULL){
  243.                                 materialLookUp[i]=mat;
  244.                                 newMaterials[i]=newMat;
  245. //                                newMesh->addMaterial(newMat);
  246.                                 newFace->material=newMat;
  247. //                                printf("generated new material: %i\n", i);
  248.                                 break;
  249.                             }
  250.                         }
  251.                     }
  252.                 }else{ // no mat
  253.                     newFace->material=stdMat;
  254. //                    newMesh->addMaterial(stdMat);
  255. //                    printf("added stdMat\n");
  256.                 }
  257.             
  258.                 newFace->vertices=new GLfloat[9];
  259.                 newFace->colors=new GLfloat[9];
  260.                 newFace->normals=new GLfloat[9];
  261.                 newFace->texCoords1=new GLfloat[6];
  262.                 newFace->texCoords2=new GLfloat[6];
  263.                 newFace->numVertices=3;
  264.                 newFace->numNormals=3;
  265.                 newFace->numTexCoords=3;
  266.                 newFace->numIndices=3;                // THINKABOUTME: Punkte wirklich vertauschen (F▄R NORMALE!)??
  267. /*
  268.                 vectorInit3d(mesh->pointL[face->points[0]].pos[0], mesh->pointL[face->points[0]].pos[1], mesh->pointL[face->points[0]].pos[2], &newFace->vertices[0]);
  269.                 vectorInit3d(mesh->pointL[face->points[1]].pos[0], mesh->pointL[face->points[1]].pos[1], mesh->pointL[face->points[1]].pos[2], &newFace->vertices[3]);
  270.                 vectorInit3d(mesh->pointL[face->points[2]].pos[0], mesh->pointL[face->points[2]].pos[1], mesh->pointL[face->points[2]].pos[2], &newFace->vertices[6]);
  271.  
  272.                 vectorInit3d(normalL[3*p+0][0], normalL[3*p+0][1], normalL[3*p+0][2], &newFace->normals[0]);
  273.                 vectorInit3d(normalL[3*p+1][0], normalL[3*p+1][1], normalL[3*p+1][2], &newFace->normals[3]);
  274.                 vectorInit3d(normalL[3*p+2][0], normalL[3*p+2][1], normalL[3*p+2][2], &newFace->normals[6]);
  275.  
  276.                 //newFace->calcNormal();
  277.                 vectorCopy3d(face->normal, newFace->normal);    // FIXME: warum geht calcnormal nicht?!
  278. */
  279.                 vectorInit3d(mesh->pointL[face->points[0]].pos[0], mesh->pointL[face->points[0]].pos[2], -mesh->pointL[face->points[0]].pos[1], &newFace->vertices[0]);
  280.                 vectorInit3d(mesh->pointL[face->points[1]].pos[0], mesh->pointL[face->points[1]].pos[2], -mesh->pointL[face->points[1]].pos[1], &newFace->vertices[3]);
  281.                 vectorInit3d(mesh->pointL[face->points[2]].pos[0], mesh->pointL[face->points[2]].pos[2], -mesh->pointL[face->points[2]].pos[1], &newFace->vertices[6]);
  282.  
  283.                 vectorInit3d(normalL[3*p+0][0], normalL[3*p+0][2], -normalL[3*p+0][1], &newFace->normals[0]);
  284.                 vectorInit3d(normalL[3*p+1][0], normalL[3*p+1][2], -normalL[3*p+1][1], &newFace->normals[3]);
  285.                 vectorInit3d(normalL[3*p+2][0], normalL[3*p+2][2], -normalL[3*p+2][1], &newFace->normals[6]);
  286.  
  287.                 vectorCopy3d(newFace->material->color, &newFace->colors[0]);
  288.                 vectorCopy3d(newFace->material->color, &newFace->colors[3]);
  289.                 vectorCopy3d(newFace->material->color, &newFace->colors[6]);
  290.  
  291.                 //newFace->calcNormal();
  292.                 vectorInit3d(face->normal[0], face->normal[2], -face->normal[1], newFace->normal);
  293.  
  294.                 if(mesh->texels>0){
  295.                     vec2_t t0, t1, t2;
  296.  
  297.                     vectorCopy2d(mesh->texelL[face->points[0]], t0);
  298.                     vectorCopy2d(mesh->texelL[face->points[1]], t1);
  299.                     vectorCopy2d(mesh->texelL[face->points[2]], t2);
  300.  
  301. /*                    if(mat){
  302.                         t0[0]=mat->texture1_map.offset[0]+ mat->texture1_map.scale[0]*mesh->texelL[0][0];
  303.                         t0[1]=mat->texture1_map.offset[1]+ mat->texture1_map.scale[1]*mesh->texelL[0][1];
  304.                     }else{
  305.                         vectorCopy2d(mesh->texelL[face->points[0]], t0);
  306.                     }
  307. *///                    printf("have texels\n");
  308.                     vectorCopy2d(t0, &newFace->texCoords1[0]);
  309.                     vectorCopy2d(t1, &newFace->texCoords1[2]);
  310.                     vectorCopy2d(t2, &newFace->texCoords1[4]);
  311.  
  312.                     vectorCopy2d(t0, &newFace->texCoords2[0]);
  313.                     vectorCopy2d(t1, &newFace->texCoords2[2]);
  314.                     vectorCopy2d(t2, &newFace->texCoords2[4]);
  315.                 }else{
  316. //                    printf("have NO texels\n");
  317.                     vectorInit2d(0.0, 0.0, &newFace->texCoords1[0]);
  318.                     vectorInit2d(0.0, 0.0, &newFace->texCoords1[2]);
  319.                     vectorInit2d(0.0, 0.0, &newFace->texCoords1[4]);
  320.  
  321.                     vectorInit2d(0.0, 0.0, &newFace->texCoords2[0]);
  322.                     vectorInit2d(0.0, 0.0, &newFace->texCoords2[2]);
  323.                     vectorInit2d(0.0, 0.0, &newFace->texCoords2[4]);
  324.                 }
  325.  
  326. //                if(mat->two_sided){
  327. //                    newFace->flags |= FACE_FLAG_TWO_SIDED;
  328. //                }    // FIXME: oben machen!!
  329.  
  330.                 newMesh->addFace(newFace);
  331. //                printf("processing face xy\n");
  332.     
  333.             }    //for
  334.  
  335.             free(normalL);
  336.  
  337.             newMesh->name=strcpy(new char[strlen(mesh->name)+1], mesh->name);
  338.         }    //mesh
  339.  
  340.     }else{    //dummy
  341.         newMesh->name="DUMMY";
  342.     
  343. //        Lib3dsObjectData *d=&node->data.object;
  344.             
  345.             //Lib3dsMatrix N;            // FIXME: was is'n das fⁿr ein matrix-scheiss???!!!! ich nehm' einfach die identitΣt
  346.             //lib3ds_matrix_copy(N, node->matrix);
  347.             //lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
  348.             //lib3ds_matrix_copy(M, mesh->matrix);
  349.             //lib3ds_matrix_inv(M);
  350.             //lib3ds_matrix_mul(X,N,M);
  351.             matrixCopy(stdMatrix, newMesh->transformationMatrix, 4);
  352. //            printf("processing matrix: \n");
  353. //            matrixPrint(newMesh->transformationMatrix, 4);
  354.     }
  355.  
  356.     node->user.d=(unsigned long)newMesh;    // damit wir's bei genMatrix wiederfinden
  357.  
  358.     Lib3dsNode *n;
  359.     newMesh->numChilds=0;
  360.     for (n=node->childs; n; n=n->next) {
  361.         newMesh->addChild(nodeToMesh(f,n/*,m*/));
  362.     }
  363.  
  364.     newMesh->setRenderMode();
  365.  
  366.     return newMesh;
  367. }
  368.  
  369.  
  370. void L3dsLoader::lib3dsFileToModel(Lib3dsFile *f, Model* m/*, int current*/){
  371.  
  372.  
  373.     Lib3dsNode *n;
  374.     Mesh* mesh;
  375.     for (n=f->nodes; n; n=n->next) {
  376.         //printf("node %s of file %s\n", n->name, f->name);
  377.         mesh=nodeToMesh(f,n/*,m*/);
  378.         matrixMultMatrix(stdMatrix, mesh->transformationMatrix, 4, mesh->transformationMatrix);
  379.         m->addMesh(mesh);
  380.     }
  381.     m->numFrames=1;
  382.  
  383. }
  384.  
  385. void L3dsLoader::generateNodeMatrix(Lib3dsFile* f, Model* m, Lib3dsNode* node, int frame, mat4x4_t matParent){
  386.     mat4x4_t mat;
  387.  
  388.     matrixCopy(stdMatrix, mat, 4);
  389.  
  390.  
  391.     if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)){
  392.         Lib3dsMesh* mesh=lib3ds_file_mesh_by_name(f, node->name);
  393.         ASSERT(mesh);
  394.         Lib3dsObjectData *d=&node->data.object;
  395.  
  396.         Lib3dsMatrix N,M,X;
  397.         lib3ds_matrix_copy(N, node->matrix);
  398.         lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
  399.         lib3ds_matrix_copy(M, mesh->matrix);
  400.         lib3ds_matrix_inv(M);
  401.         lib3ds_matrix_mul(X,N,M);
  402.  
  403.         matrixMultMatrix(matParent, &X[0][0], 4, mat);
  404.     }else{
  405. //        Lib3dsMesh* mesh=lib3ds_file_mesh_by_name(f, node->name);
  406. //        ASSERT(mesh);
  407.         Lib3dsObjectData *d=&node->data.object;
  408.  
  409.         Lib3dsMatrix N;
  410.         lib3ds_matrix_copy(N, node->matrix);
  411.         lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
  412. //        lib3ds_matrix_copy(M, mesh->matrix);
  413. //        lib3ds_matrix_inv(M);
  414. //        lib3ds_matrix_mul(X,N,M);
  415.  
  416.         matrixMultMatrix(matParent, &N[0][0], 4, mat);
  417.     }
  418. //        printf("processing matrix: \n");
  419. //        matrixPrint(newMesh->transformationMatrix, 4);
  420.  
  421.         //printf("MAT user.d: %d\n", mesh->user.d);
  422.     int id=m->getMeshId((Mesh*)node->user.d);
  423.     if(id==-1){
  424.         //printf("NEW MESH??\n");    // THINKABOUTME: 
  425.         warn("(in 3dsLoader::generateNodeMatrix()): Unknown mesh id. Aborting tree.\n\n");
  426.         return;
  427.     }
  428.         //printf("adding matrix: id: %i, frame: %i\n", id, frame);
  429.     m->addMatrix(frame, id, mat);
  430.     
  431.     Lib3dsNode *n;
  432.     for (n=node->childs; n; n=n->next) {
  433. //        printf("node %s od file %s\n", n->name, f->name);
  434.         generateNodeMatrix(f, m, n, frame, mat);
  435.     }
  436.  
  437. }
  438.  
  439. /*!
  440. This function loads a 3ds file into a #Model object. You can also specify whether or not you like the keyframe and light information to be extracted.
  441. \param filename the name of the 3ds file
  442. \param model pointer to the #Model object
  443. \param generateMatrices should matrices for the keyframes be generated? (for animated player models)
  444. \param setupLights should the OpenGL lights be setup according to the lights in the scene? (for arenas)
  445. \return \c true on success \c false on errors
  446. */
  447. bool L3dsLoader::load3DS(const char* filename, Model* model, bool generateMatrices, bool setupLights){
  448.     Lib3dsFile *f=0;
  449. //    printf("loading file... ");
  450.     f=lib3ds_file_load(filename);
  451. //    printf("done.\n");
  452.     if (!f) {
  453. //        warn("(in load3DS()): Couldn't load file '%s'.\n", filename);
  454.         return false;
  455.     }
  456.  
  457.     path=File::extractPath(filename);
  458.  
  459.     int i=f->segment_from;
  460.     lib3ds_file_eval(f,1.0f*i);
  461.     lib3dsFileToModel(f,model);
  462.  
  463.     delete[] path;
  464.  
  465.     if(setupLights){
  466.         log("extracting lights.\n");
  467.         L3dsLoader::setupLights(f);
  468.     }
  469.  
  470.     if(generateMatrices){
  471.         model->numFrames=f->frames+1;//f->segment_to - f->segment_from +1;
  472.         log("generating matrices for %i frames.\n", f->frames);    
  473.         for (i=f->segment_from+1; i<=f->segment_to; ++i) {
  474.             //printf("frame %i", i);
  475.             lib3ds_file_eval(f,1.0f*i);
  476.  
  477.             Lib3dsNode *n;
  478.             for (n=f->nodes; n; n=n->next) {
  479.                 generateNodeMatrix(f, model, n, i, stdMatrix);
  480.             }
  481.         }
  482.     }
  483. //    model->dump();
  484.     lib3ds_file_free(f);
  485.     return true;
  486. }
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.