home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Ac3dLoader.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-08-04  |  15.1 KB  |  660 lines

  1. /*!
  2. \file ac3dloader.cpp
  3. \author Karsten Schwenk
  4. \version 1.0
  5.  
  6. See header for describtion (ac3dloader.h).
  7. */
  8.  
  9. #include "Ac3dLoader.h"
  10. #include "Tokenizer.h"
  11. #include "TextureHandler.h"
  12.  
  13. #include <math.h>
  14.  
  15. #include "vectormath.h"
  16. #include "matrixmath.h"
  17.  
  18. #include "log.h"
  19.  
  20. static int getTokens(char *s, int *argc, char *argv[]){
  21.     char *p = s;
  22.     char *st;
  23.     char c;
  24.     //int n;
  25.     int tc;
  26.  
  27.     tc = 0;
  28.     while ((c=*p) != 0){
  29.         if ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13)){
  30.             if (c == '"'){
  31.                 c = *p++;
  32.                 st = p;
  33.                 while ((c = *p) && ((c != '"')&&(c != '\n')&& ( c != 13)) ){
  34.                     if (c == '\\')
  35.                         strcpy(p, p+1);
  36.                     p++;
  37.                 }
  38.                 *p=0;
  39.                 argv[tc++] = st;
  40.             }else{
  41.                 st = p;
  42.                 while ((c = *p) && ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13)) )
  43.                     p++;
  44.                 *p=0;
  45.                 argv[tc++] = st;
  46.             }
  47.         }
  48.         p++;
  49.     }
  50.  
  51.     *argc = tc;
  52.     return(tc);
  53. }
  54.  
  55. /*
  56.  
  57.   Ac3dSurface
  58.  
  59.   */
  60.  
  61. Ac3dSurface::Ac3dSurface(Ac3dObject *object){
  62.     ob=object;
  63. }
  64.  
  65. void Ac3dSurface::calcNormal(){
  66.     float len;
  67.  
  68.     normal[0] = (ob->v[indices[1]*3+1] - ob->v[indices[0]*3+1]/*v2->y-v1->y*/)*
  69.                 (ob->v[indices[2]*3+2] - ob->v[indices[0]*3+2]/*v3->z-v1->z*/)-
  70.                 (ob->v[indices[2]*3+1] - ob->v[indices[0]*3+1]/*v3->y-v1->y*/)*
  71.                 (ob->v[indices[1]*3+2] - ob->v[indices[0]*3+2]/*v2->z-v1->z*/);
  72.     normal[1] = (ob->v[indices[1]*3+2] - ob->v[indices[0]*3+2]/*v2->z-v1->z*/)*
  73.                 (ob->v[indices[2]*3+0] - ob->v[indices[0]*3+0]/*v3->x-v1->x*/)-
  74.  
  75.                 (ob->v[indices[2]*3+2] - ob->v[indices[0]*3+2]/*v3->z-v1->z*/)*
  76.                 (ob->v[indices[1]*3+0] - ob->v[indices[0]*3+0]/*v2->x-v1->x*/);
  77.     normal[2] = (ob->v[indices[1]*3+0] - ob->v[indices[0]*3+0]/*v2->x-v1->x*/)*
  78.                 (ob->v[indices[2]*3+1] - ob->v[indices[0]*3+1]/*v3->y-v1->y*/)-
  79.                 (ob->v[indices[2]*3+0] - ob->v[indices[0]*3+0]/*v3->x-v1->x*/)*
  80.                 (ob->v[indices[1]*3+1] - ob->v[indices[0]*3+1]/*v2->y-v1->y*/);
  81.  
  82.     len = (float)sqrt(normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]);
  83.  
  84.     if (len > 0){
  85.         normal[0] /= len;
  86.         normal[1] /= len;
  87.         normal[2] /= len;
  88.     }
  89. }
  90.  
  91.  
  92. /*
  93.  
  94.   Ac3dMaterial
  95.  
  96.   */
  97.  
  98. Ac3dMaterial::Ac3dMaterial(char *buff){
  99.     if (getTokens(buff, &tokc, tokv) != 22){
  100.         warn("(in A3dMaterial::Ac3dMaterial()): Expected 21 params after \"MATERIAL\". Ignoring values.\n\n");
  101.     }else{
  102.         shininess = (GLfloat)atof(tokv[19]);
  103.         transparency = (GLfloat)atof(tokv[21]);
  104.  
  105.         name = newString(tokv[1]);
  106.  
  107.         diffuse[0] = (GLfloat)atof(tokv[3]);
  108.         diffuse[1] = (GLfloat)atof(tokv[4]);
  109.         diffuse[2] = (GLfloat)atof(tokv[5]);
  110.         diffuse[3] = 1.0f - transparency;
  111.  
  112.         ambient[0] = (GLfloat)atof(tokv[7]);
  113.         ambient[1] = (GLfloat)atof(tokv[8]);
  114.         ambient[2] = (GLfloat)atof(tokv[9]);
  115.         ambient[3] = 1.0f - transparency;
  116.  
  117.         emissive[0] = (GLfloat)atof(tokv[11]);
  118.         emissive[1] = (GLfloat)atof(tokv[12]);
  119.         emissive[2] = (GLfloat)atof(tokv[13]);
  120.         emissive[3] = 1.0f;
  121.  
  122.         specular[0] = (GLfloat)atof(tokv[15]);
  123.         specular[1] = (GLfloat)atof(tokv[16]);
  124.         specular[2] = (GLfloat)atof(tokv[17]);
  125.         specular[3] = 1.0f;
  126.  
  127. /*    ????
  128.                 shi = (float)atof(tokv[6]);
  129.                 tran = (float)atof(tokv[7]);
  130. */
  131.     }
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  
  138.   Ac3dObject
  139.  
  140.   */
  141.  
  142. void Ac3dObject::clearObject(){
  143.     name="unnamed";
  144.  
  145.     mat=NULL;
  146.     surf=NULL;
  147.     kids=NULL;
  148.     v=NULL;
  149.     n=NULL;
  150.     texCoords=NULL;
  151.  
  152.     nMat=0;
  153.     nV=0;
  154.     nN=0;
  155.     nSurf=0;
  156.     nIndices=0;
  157.     nKids=0;
  158.     type=-1;
  159.  
  160.     v=NULL;
  161.     n=NULL;
  162.     indices=NULL;
  163.     texCoords=NULL;
  164.  
  165.     loc[0]=0;
  166.     loc[1]=0;
  167.     loc[2]=0;
  168.  
  169.     matrixCopy(id3x3, rotMatrix, 3);
  170.  
  171.     line=0;
  172.  
  173. //    isTriangulation=false;
  174.     hasTextures=false;
  175.  
  176.     if(texture!=NULL){
  177.         //delete texture;
  178.     }
  179.     texture=NULL;
  180.     texOffsX=texOffsY=0.0;
  181.     texRepeatX=texRepeatY=1.0;
  182. }
  183.  
  184.  
  185. Ac3dObject::Ac3dObject(const char *filename){
  186.  
  187.     clearObject();
  188.     FILE *f = fopen(filename, "r");
  189.  
  190.     if (f == NULL){
  191.         warn("(in Ac3dObject::Ac3dObject()): Couldn't open %s - Object unchanged\n\n", filename);
  192.     }else{
  193.         readLine(f);
  194.  
  195.         if (strncmp(buff, "AC3D", 4)){
  196.             warn("(in Ac3dObject::Ac3dObject()): '%s' seems not to be a valid AC3D file - Object unchanged.\n\n", filename);
  197.             fclose(f);
  198.             return;
  199.         }
  200.  
  201.         line=0;
  202.         readFromFile(f);
  203.         calcNormals();
  204.         fclose(f);
  205. //        printf("%s loaded: %i Vertices, %i Surfaces, %i kids, isTriangulation: %b\n", filename, nV, nSurf, nKids, isTriangulation);
  206.     }
  207. }
  208.  
  209. Ac3dObject::Ac3dObject(FILE *f, int *l, Ac3dObject *parent){
  210.     clearObject();
  211.  
  212.     line=*l;
  213.     
  214.     mat = parent->mat;
  215.     nMat = parent->nMat;
  216.     readFromFile(f);
  217.     calcNormals();
  218. //    fclose(f);
  219. }
  220.  
  221.  
  222.  
  223. Ac3dSurface *Ac3dObject::readSurface(FILE *f){
  224.  
  225.     char t[20];
  226.  
  227.     Ac3dSurface *ret = new Ac3dSurface(this);
  228.  
  229.     while(!feof(f)){
  230.         readLine(f);
  231.         sscanf(buff, "%s", t);
  232.  
  233.         if (streq(t, "SURF")){
  234.             int flgs;
  235.  
  236.             if (getTokens(buff, &tokc, tokv) != 2){
  237.                 warn("(in Ac3dObject::readSurface()): SURF should be followed by one flags argument. Ignoring flag.\n\n");
  238.             }else{
  239.                 flgs = strtol(tokv[1], NULL, 0);
  240.                 ret->flags = flgs;
  241.             }
  242.         }else if (streq(t, "mat")){
  243.             int mindx;
  244.  
  245.             sscanf(buff, "%s %d", t, &mindx);
  246.             ret->mat = mindx;//+startmatindex;
  247.         }
  248.         else if (streq(t, "refs")){
  249.             int num, n;
  250.             int ind;
  251.             float tx, ty;
  252.  
  253.             sscanf(buff, "%s %d", t, &num);
  254.  
  255.  
  256.             ret->nIndices = num;
  257.             ret->indices = new unsigned int[num];
  258.             ret->texCoords = new float[num*2];
  259. //            ret->tOffs[1] = new float[num];
  260.  
  261.             for (n = 0; n < num; n++){
  262.                 fscanf(f, "%d %f %f\n", &ind, &tx, &ty); line++;
  263.                 ret->indices[n] = ind;
  264.  
  265.                 tx = texOffsX + tx * texRepeatX;    // texOffs/Repeat vom object einrechnen
  266.                 ty = texOffsY + ty * texRepeatY;
  267.  
  268.                 ret->texCoords[n*2+0] = tx;
  269.                 ret->texCoords[n*2+1] = ty;
  270.             }
  271.  
  272.             if (ret->nIndices >= 3)
  273.                 ret->calcNormal();
  274.  
  275.             return(ret);
  276.         }else
  277.             warn("(in Ac3dObejct::readSurface()): Unexpected token '%s'. Ignoring.\n", t);
  278.  
  279.     }
  280.     return NULL;
  281. }
  282.  
  283.  
  284. void Ac3dObject::readLine(FILE *f){
  285.     fgets(buff, 255, f);
  286.     line++;
  287. }
  288.  
  289. void Ac3dObject::addMaterial(Ac3dMaterial *m){
  290.     nMat++;
  291.     Ac3dMaterial **newMat = new Ac3dMaterial*[nMat];
  292.     for(int i=0; i<nMat-1; i++)
  293.         newMat[i]=mat[i];
  294.  
  295.     delete[] mat;
  296.     newMat[nMat-1]=m;
  297.     mat=newMat;
  298. //    printf("addMaterial: nMat: %i\n", nMat);
  299. }
  300.  
  301. void Ac3dObject::calcNormals(){
  302.     int i, j, k;
  303.  
  304.     nN=nV;
  305.     n = new float[nN*3];
  306.  
  307.     for (i = 0; i < nV; i++){
  308.         n[i*3+0]=0.0;
  309.         n[i*3+1]=0.0;
  310.         n[i*3+2]=0.0;
  311.         int found = 0;
  312.  
  313.         for (j = 0; j < nSurf; j++){
  314.             for (k = 0; k < surf[j]->nIndices; k++)
  315.                 if (surf[j]->indices[k] == (unsigned int)i){
  316.                     n[i*3+0]+=surf[j]->normal[0];
  317.                     n[i*3+1]+=surf[j]->normal[1];
  318.                     n[i*3+2]+=surf[j]->normal[2];
  319.                     found++;
  320.                 }
  321.         }
  322.         if (found > 0){
  323.             n[i*3+0] /= found;
  324.             n[i*3+1] /= found;
  325.             n[i*3+2] /= found;
  326.         }
  327.     }
  328.  
  329. }
  330.  
  331.  
  332.  
  333.  
  334. bool Ac3dObject::readFromFile(FILE *f){
  335.  
  336.  
  337.     // Hier geht's ab
  338.     char t[20];    //token
  339.     while(!feof(f)){
  340.         readLine(f);
  341.         sscanf(buff, "%s", t);
  342.  
  343.         if (streq(t, "MATERIAL")){
  344. //            float shi, tran;
  345. //            printf("adding Material %i\n", nMat);
  346.             addMaterial(new Ac3dMaterial(buff));
  347.  
  348.         }else if (streq(t, "OBJECT")){
  349.             char tpe[20];
  350.             char str[20];
  351. //            ob = new_object();
  352.  
  353.             sscanf(buff, "%s %s", str, tpe);
  354.  
  355.             if (streq("world", tpe))
  356.                 type=OBJECT_WORLD;
  357.             else if (streq("group", tpe))
  358.                 type=OBJECT_GROUP;
  359.             else if (streq("light", tpe))
  360.                 type=OBJECT_LIGHT;
  361.             else if (streq("poly", tpe))
  362.                 type=OBJECT_NORMAL;
  363.             else
  364.                 type=OBJECT_NORMAL;
  365. //            printf("reading Object type: %s\n",tpe);
  366.  
  367. //            type = string_to_objecttype(type);
  368. /*        }else if (streq(t, "data")){    // ??????????
  369.             if (getTokens(buff, &tokc, tokv) != 2){
  370.                 printToLogFile("expected 'data <number>' at line %d\n", line);
  371.             }else{
  372.                 char *str;
  373.                 int len;
  374.  
  375.                 len = atoi(tokv[1]);
  376.                 if (len > 0){
  377.                     str = (char *)myalloc(len+1);
  378.                     fread(str, len, 1, f);
  379.                     str[len] = 0;
  380.                     fscanf(f, "\n"); line++;
  381.                     ob->data = STRING(str);
  382.                     myfree(str);
  383.                 }
  384.             }
  385.  
  386. */        }else if(streq(t, "name")){
  387.             int numtok = getTokens(buff, &tokc, tokv);
  388.             if (numtok != 2){
  389.                 warn("(in Ac3dObject::readFromFile()): Expected quoted name at line %d (got %d tokens). Ignoring name statement\n\n", line, numtok);
  390.                 return false;
  391.             }else{
  392.                 name = newString(tokv[1]);
  393.             }
  394. //            printf("reading name: %s \n",name);
  395.  
  396.  
  397.         }else if(streq(t, "texture")){
  398.             if (getTokens(buff, &tokc, tokv) != 2){
  399.                 warn("(in Ac3dObject::readFronFile()): Expected quoted texture name at line %d. Ignoring texture statement.\n\n", line);
  400.                 return false;
  401.             }else{
  402.                 texture = TextureHandler::getTexture(tokv[1]);
  403.                 hasTextures=true;
  404.             }
  405.  
  406.         }else if(streq(t, "texrep")){
  407.             if (getTokens(buff, &tokc, tokv) != 3)
  408.                 warn("(in Ac3dObject::readFronFile()): Expected 'texrep <float> <float>' at line %d.\n\n", line);
  409.             else{
  410.                 texRepeatX = (float)atof(tokv[1]);
  411.                 texRepeatY = (float)atof(tokv[2]);
  412.             }
  413.  
  414.         }else if(streq(t, "texoff")){
  415.             if (getTokens(buff, &tokc, tokv) != 3)
  416.                 warn("(Ac3dObject::readFromFile()): Expected 'texoff <float> <float>' at line %d.\n\n", line);
  417.             else{
  418.                 texOffsX = (float)atof(tokv[1]);
  419.                 texOffsY = (float)atof(tokv[2]);
  420.             }
  421.  
  422.         }else if(streq(t, "rot")){
  423. //            printf("reading rot\n");
  424.             float r[9];
  425.             char str2[5];
  426.             int n;
  427.  
  428.             sscanf(buff, "%s %f %f %f %f %f %f %f %f %f", str2, &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] );
  429.  
  430.             for (n = 0; n < 9; n++)
  431.                 rotMatrix[n] = r[n];
  432.  
  433.         }else if(streq(t, "loc")){
  434. //            printf("reading loc\n");
  435.             char str[5];
  436.             float tmp[3];
  437.             sscanf(buff, "%s %f %f %f", str,
  438.  
  439.                            &tmp[0], &tmp[1], &tmp[2]);
  440.             loc[0]=tmp[0];
  441.             loc[1]=tmp[1];
  442.             loc[2]=tmp[2];
  443. /*        }else if (streq(t, "url")){    // scheiss drauf
  444. */        }else if(streq(t, "numvert")){
  445.  
  446.             int num, n;
  447.             char str[10];
  448.  
  449.             sscanf(buff, "%s %d", str, &num);
  450.  
  451. //            printf("reading vertex array: %i vertices\n",num);
  452.             if (num > 0){
  453.                 nV = num;
  454.                 v = new float[3*num];//(ACVertex *)myalloc(sizeof(ACVertex)*num);
  455.                 float tmp[3];
  456.  
  457.                 for (n = 0; n < num; n++){
  458.                     fscanf(f, "%f %f %f\n", &tmp[0], &tmp[1], &tmp[2]);
  459.                     v[n*3+0]=tmp[0];
  460.                     v[n*3+1]=tmp[1];
  461.                     v[n*3+2]=tmp[2];
  462.                     line++;
  463. //                    vertices[n] = p;
  464.                 }
  465.             }
  466.         }else if (streq(t, "numsurf")){
  467.             int num, n;
  468.             char str[10];
  469.  
  470.             sscanf(buff, "%s %d", str, &num);
  471. //            printf("reading surfaces: %i surfaces\n",num);
  472.  
  473.             if (num > 0){
  474.                 nSurf = num;
  475.                 surf = new Ac3dSurface *[num];
  476.  
  477.                 for (n = 0; n < num; n++){
  478.                     surf[n] = readSurface(f);
  479.                 }
  480.             }
  481.         }else if(streq(t, "kids")){
  482.  
  483.             int num, n;
  484.  
  485.             sscanf(buff, "%s %d", t, &num);
  486.  
  487. //            printf("reading kids: %i kids\n", num);
  488.             if (num != 0){
  489.                 nKids = num;
  490.                 kids = new Ac3dObject *[num];
  491.  
  492.                 for (n = 0; n < num; n++){
  493.                     kids[n] = new Ac3dObject(f, &line, this);
  494.                 }
  495.  
  496.             }
  497.             break; // THINKABOUTME: h÷rt's von aleine auf?    return(ob);
  498.         }
  499.     }
  500.     return true;
  501. }
  502.  
  503.  
  504. void Ac3dObject::dumpObject(){
  505.     int i;
  506.  
  507.     if(name!=NULL)
  508.         printf("OBJECT %s: nV: %i, nN:%i, nSurf:%i\n", name, nV, nN, nSurf);
  509.  
  510.     printf("loc: %f %f %f     rot: ", loc[0],loc[1],loc[2]);
  511.     matrixPrint(rotMatrix, 3);
  512. /*
  513.     for(i=0; i<nMat; i++){
  514.         printf("Material %i: amb: %f %f %f  diff: %f %f %f  spec: %f %f %f  emi: %f %f %f  shi: %f  trans: %f\n",
  515.             i,
  516.             mat[i]->ambient[0], mat[i]->ambient[1], mat[i]->ambient[2],
  517.             mat[i]->diffuse[0], mat[i]->diffuse[1], mat[i]->diffuse[2],
  518.             mat[i]->specular[0], mat[i]->specular[1], mat[i]->specular[2],
  519.             mat[i]->emissive[0], mat[i]->emissive[1], mat[i]->emissive[2],
  520.             mat[i]->shininess, mat[i]->transparency
  521.             );
  522.     }
  523.  
  524.     printf("loc: %f %f %f\n", loc[0], loc[1], loc[2]);
  525.  
  526.     for(i=0; i<nV; i++){
  527.         printf("vertex array[%i]: %f %f %f \n", i, (float)v[i*3+0], (float)v[i*3+1], (float)v[i*3+2]);
  528.     }
  529.  
  530.     for(i=0; i<nN; i++){
  531.         printf("normal array[%i]: %f %f %f \n", i, (float)n[i*3+0], (float)n[i*3+1], (float)n[i*3+2]);
  532.     }
  533.  
  534.     for(i=0; i<nSurf; i++){
  535.         printf("surface[%i]: nIndices: %i  mat: %i \n", i, surf[i]->nIndices, surf[i]->mat);
  536.     }
  537. */
  538.     for(i=0; i<nKids; i++){
  539.         printf("\n\n-- kid %i\n\n", i);
  540.         kids[i]->dumpObject();
  541.     }
  542.  
  543. }
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551. Mesh* Ac3dLoader::Ac3dObjectToMesh(Ac3dObject* o){
  552.     int i, j;
  553.     Mesh* ret=new Mesh();
  554.     int *materialLookUp=new int[o->nMat];
  555.  
  556.     if(o->name!=NULL)
  557.         ret->name=newString(o->name);
  558.  
  559.     //printf("\n\nadding mats for %s\n", ret->name);
  560.     for(i=0;i<o->nMat;i++){
  561.         for(j=0;j<o->nSurf;j++){
  562.             if(o->surf[j]->mat==i){
  563.                 Material* mat=new Material();
  564. /*
  565.                 vectorCopy4d(o->mat[i]->ambient, mat->ambient);
  566.                 vectorCopy4d(o->mat[i]->diffuse, mat->diffuse);
  567.                 vectorCopy4d(o->mat[i]->specular, mat->specular);
  568.                 vectorCopy4d(o->mat[i]->emissive, mat->emissive);
  569.                 mat->shininess=o->mat[i]->shininess;
  570. */
  571.                 vectorCopy4d(o->mat[i]->diffuse, mat->color);
  572.  
  573.                 if(o->hasTextures){
  574.                     mat->addTexture(o->texture);
  575.                 }
  576.                 mat->setAttribs();
  577.                 materialLookUp[i]=ret->addMaterial(mat);
  578.                 //printf("mat %i added -> %i.\n",i,materialLookUp[i]);
  579.                 break;
  580.             }
  581.         }
  582.         //printf("asd");
  583.     }
  584.  
  585.  
  586.     for(i=0;i<o->nSurf;i++){
  587.         Face* face=new Face();
  588.  
  589.         face->material=ret->materials[materialLookUp[o->surf[i]->mat]];
  590.         //printf("face->mat: %i\n",materialLookUp[o->surf[i]->mat]);
  591.  
  592.         face->vertices=new GLfloat[o->surf[i]->nIndices*3];
  593.         face->colors=new GLfloat[o->surf[i]->nIndices*3];
  594.         face->normals=new GLfloat[o->surf[i]->nIndices*3];
  595.         face->texCoords1=new GLfloat[o->surf[i]->nIndices*2];
  596.         face->texCoords2=new GLfloat[o->surf[i]->nIndices*2];
  597.         face->numIndices=face->numNormals=face->numColors=face->numVertices=face->numTexCoords= o->surf[i]->nIndices;
  598.  
  599.         for(j=0;j<o->surf[i]->nIndices;j++){
  600.             vectorCopy3d(&o->v[o->surf[i]->indices[j]*3], &face->vertices[j*3]);
  601.             vectorCopy3d(face->material->color, &face->colors[j*3]);
  602.             if(o->surf[i]->flags & SURFACE_SHADED)
  603.                 vectorCopy3d(&o->n[o->surf[i]->indices[j]*3], &face->normals[j*3]);
  604.             else
  605.                 vectorCopy3d(o->surf[i]->normal, &face->normals[j*3]);
  606.  
  607.             vectorCopy2d(&o->surf[i]->texCoords[j*2], &face->texCoords1[j*2]);
  608.             vectorCopy2d(&o->surf[i]->texCoords[j*2], &face->texCoords2[j*2]);
  609.         }
  610.  
  611.         face->calcNormal();
  612.         ret->addFace(face);
  613.     }
  614.  
  615.  
  616.     GLfloat mat[16]={
  617.         o->rotMatrix[0], o->rotMatrix[1], o->rotMatrix[2], 0,
  618.         o->rotMatrix[3], o->rotMatrix[4], o->rotMatrix[5], 0,
  619.         o->rotMatrix[6], o->rotMatrix[7], o->rotMatrix[8], 0,
  620.         o->loc[0],        o->loc[1],            o->loc[2],        1
  621.     };
  622.  
  623.     matrixCopy(mat, ret->transformationMatrix, 4);
  624.  
  625.     ret->numChilds=o->nKids;
  626.     ret->childs=new Mesh*[ret->numChilds];
  627.     for(i=0;i<o->nKids;i++){
  628.         ret->childs[i]=Ac3dObjectToMesh(o->kids[i]);
  629.         ret->childs[i]->parent=ret;
  630.     }
  631.  
  632.     ret->setRenderMode();
  633.  
  634.     delete[] materialLookUp;
  635.     return ret;
  636. }
  637.  
  638. /*!
  639. This function loads an ac3d file into a #Model object (that can be rendered instantly with #renderModel()).
  640. This is usually called from within the #Model constructor.
  641. \return \c true on success \c false on errors
  642. */
  643. bool Ac3dLoader::loadAC3D(const char* filename, Model* model){
  644.  
  645.     Ac3dObject* o=new Ac3dObject(filename);
  646.  
  647.  
  648. //    o->dumpObject();
  649.  
  650.     model->addMesh(Ac3dObjectToMesh(o));
  651.     model->numKeyframes=1;
  652. //    model->dump();
  653.  
  654.     delete o;
  655.     return true;
  656. }
  657.  
  658.  
  659.  
  660.