Ignore:
Timestamp:
06/22/06 19:19:09 (19 years ago)
Author:
gumbau
Message:

Added OBJ files loader

Location:
GTP/trunk/Lib/Geom/shared/GeoTool
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshLoader.h

    r989 r1050  
    188188                        void    normalizeModel(Mesh     *geoMesh); 
    189189 
     190                        // Imports an OBJ object 
     191                        void importOBJ(FILE *f, Mesh *geoMesh); 
     192 
    190193                public: 
    191194 
  • GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h

    r1024 r1050  
    279279 
    280280        //      Open a mesh file. 
    281         void    openMeshFile(); 
     281        void    openMeshFile(void); 
    282282 
    283283        //      Check if file exists. 
  • GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp

    r1024 r1050  
    1111 
    1212#include        "GeoMeshLoader.h" 
     13#include        <algorithm> 
     14#include        <cctype> 
     15#include        <map> 
    1316 
    1417using namespace Geometry; 
     
    992995{ 
    993996        unsigned        short   uno; 
    994   unsigned      short   chunkID; 
    995         char                                            version[255]; 
    996         char                                            kk; 
    997         FILE                                            *pFile; 
    998         SubMesh                                 *geosubmesh; 
     997        unsigned        short   chunkID; 
     998        char            version[255]; 
     999        char            kk; 
     1000        FILE            *pFile; 
     1001        SubMesh         *geosubmesh; 
    9991002 
    10001003        //      Debug. 
     
    10061009                                <<      endl; 
    10071010 
     1011        // retrieve the extension of the file 
     1012        std::string fileExt; 
     1013        std::string completeFileName(nameFileMesh); 
     1014        for (std::string::reverse_iterator it = completeFileName.rbegin(); it!=completeFileName.rend(); it++) 
     1015                if (*it=='.') 
     1016                        break; 
     1017                else 
     1018                        fileExt += *it; 
     1019 
     1020        std::transform(fileExt.begin(), fileExt.end(), fileExt.begin(), std::toupper); 
     1021        reverse(fileExt.begin(),fileExt.end()); 
     1022         
    10081023        geoMesh =       NULL; 
    10091024 
     
    10111026        pFile   =       fopen(nameFileMesh, "rb"); 
    10121027 
    1013   if (pFile) 
     1028        if (pFile) 
    10141029        { 
    10151030                //      Initialize the current submesh; 
     
    10191034                geoMesh =       new     Mesh(); 
    10201035 
    1021                 //      Count the submeshes 
    1022                 //      and next build the geomesh. 
    1023                 for (int option = 0; option < 2;option++) 
    1024                 { 
    1025                         //      Initialize Error. 
     1036                if (fileExt==std::string("OBJ")) 
     1037                { 
    10261038                        mError  =       false; 
    1027          
    1028                         fread(&uno,sizeof(unsigned short),1,pFile); 
    1029  
    1030                         if (uno != M_HEADER) 
    1031                         { 
    1032                                 //      Debug. 
    1033                                 cout    <<      "Error: Header not found." 
    1034                                         <<      endl; 
    1035  
    1036                                 //      Error. 
    1037                                 mError  =       true; 
    1038                         } 
    1039  
    1040                         // Read version. 
    1041                         fgets(version,255,pFile); 
    1042  
    1043                         cout    <<      version <<      endl; 
    1044  
    1045                         if (strcmp(version,"[MeshSerializer_v1.30]\n")) 
    1046                         { 
    1047                                 //      Debug. 
    1048                                 cout    <<      "Error: Wrong mesh version." 
    1049                                         <<      endl 
    1050                                         <<      "Only version 1.3 or older allowed." 
    1051                                         <<      endl; 
    1052  
    1053                                 //      Error. 
    1054                                 mError  =       true; 
    1055                         } 
    1056  
    1057                         while(!feof(pFile)) 
    1058                         { 
    1059                                 chunkID = readChunk(pFile); 
    1060  
    1061                                 switch (chunkID) 
     1039                        importOBJ(pFile,geoMesh); 
     1040                } 
     1041                else 
     1042                { 
     1043                        //      Count the submeshes 
     1044                        //      and next build the geomesh. 
     1045                        for (int option = 0; option < 2;option++) 
     1046                        { 
     1047                                //      Initialize Error. 
     1048                                mError  =       false; 
     1049                 
     1050                                fread(&uno,sizeof(unsigned short),1,pFile); 
     1051 
     1052                                if (uno != M_HEADER) 
    10621053                                { 
    1063                                         case M_MESH: 
    1064                                                 readMesh(pFile, geoMesh, option); 
    1065                                                 break; 
     1054                                        //      Debug. 
     1055                                        cout    <<      "Error: Header not found." 
     1056                                                <<      endl; 
     1057 
     1058                                        //      Error. 
     1059                                        mError  =       true; 
    10661060                                } 
    1067                         } 
    1068  
    1069                         //      Create the submesh array. 
    1070                         if (option == SUBMESH_COUNT) 
    1071                         { 
    1072                                 geoMesh->mSubMesh       = new SubMesh[geoMesh->mSubMeshCount]; 
    1073                         } 
    1074  
    1075                         //      Move the curso to the begining of the file. 
    1076                         fseek(pFile,0,SEEK_SET); 
    1077                 } 
    1078  
    1079                 //      Goes to the end of the file. 
    1080                 fseek(pFile,0,SEEK_END); 
    1081  
    1082                 //      Gets the size of the file. 
    1083                 mFileSize       =       ftell(pFile); 
     1061 
     1062                                // Read version. 
     1063                                fgets(version,255,pFile); 
     1064 
     1065                                cout    <<      version <<      endl; 
     1066 
     1067                                if (strcmp(version,"[MeshSerializer_v1.30]\n")) 
     1068                                { 
     1069                                        //      Debug. 
     1070                                        cout    <<      "Error: Wrong mesh version." 
     1071                                                <<      endl 
     1072                                                <<      "Only version 1.3 or older allowed." 
     1073                                                <<      endl; 
     1074 
     1075                                        //      Error. 
     1076                                        mError  =       true; 
     1077                                } 
     1078 
     1079                                while(!feof(pFile)) 
     1080                                { 
     1081                                        chunkID = readChunk(pFile); 
     1082 
     1083                                        switch (chunkID) 
     1084                                        { 
     1085                                                case M_MESH: 
     1086                                                        readMesh(pFile, geoMesh, option); 
     1087                                                        break; 
     1088                                        } 
     1089                                } 
     1090 
     1091                                //      Create the submesh array. 
     1092                                if (option == SUBMESH_COUNT) 
     1093                                { 
     1094                                        geoMesh->mSubMesh       = new SubMesh[geoMesh->mSubMeshCount]; 
     1095                                } 
     1096 
     1097                                //      Move the curso to the begining of the file. 
     1098                                fseek(pFile,0,SEEK_SET); 
     1099                        } 
     1100 
     1101                        //      Goes to the end of the file. 
     1102                        fseek(pFile,0,SEEK_END); 
     1103 
     1104                        //      Gets the size of the file. 
     1105                        mFileSize       =       ftell(pFile); 
     1106                } 
    10841107 
    10851108                // Close the mesh file. 
     
    13511374} 
    13521375 
     1376struct face_t 
     1377{ 
     1378        int v1,v2,v3; 
     1379        int t1,t2,t3; 
     1380        int n1,n2,n3; 
     1381}; 
     1382 
     1383 
     1384class vertex_arranger_node 
     1385{ 
     1386public: 
     1387        int v, n, t; 
     1388 
     1389        vertex_arranger_node(void){ 
     1390                v=n=t=-1; 
     1391        } 
     1392        vertex_arranger_node(int iv, int in=-1, int it=-1){ 
     1393                v=iv; 
     1394                n=in; 
     1395                t=it; 
     1396        } 
     1397 
     1398        bool operator<(const vertex_arranger_node &vu) const { 
     1399                if (v<vu.v) return true; 
     1400                if (v>vu.v) return false; 
     1401                if (n<vu.n) return true; 
     1402                if (n>vu.n) return false; 
     1403                if (t<vu.t) return true; 
     1404                if (t>vu.t) return false; 
     1405                return false; 
     1406        } 
     1407        bool operator==(const vertex_arranger_node &vu) const { 
     1408                return (v==vu.v && v==vu.v && n==vu.n && n==vu.n && t==vu.t && t==vu.t); 
     1409        } 
     1410}; 
     1411 
     1412 
     1413void    GeoMeshLoader::importOBJ(FILE *f, Mesh *mesh) 
     1414{ 
     1415        mesh->hasSkeleton=false; 
     1416        mesh->mSubMeshCount=0; 
     1417 
     1418        std::vector<Geometry::Vector3> vertices; 
     1419        std::vector<Geometry::Vector3> normals; 
     1420        std::vector<Geometry::Vector2> texcoords; 
     1421        std::vector<std::vector<face_t> > faces; 
     1422        std::vector<face_t> current_faces; 
     1423 
     1424        mesh->mMeshBounds.maxX = -99999999.9f; 
     1425        mesh->mMeshBounds.maxY = -99999999.9f; 
     1426        mesh->mMeshBounds.maxZ = -99999999.9f; 
     1427        mesh->mMeshBounds.minX =  99999999.9f; 
     1428        mesh->mMeshBounds.minY =  99999999.9f; 
     1429        mesh->mMeshBounds.minZ =  99999999.9f; 
     1430        mesh->mMeshBounds.radius = 1.0f; 
     1431        mesh->mMeshBounds.scaleFactor = 1.0f; 
     1432 
     1433        char line[256]=""; 
     1434        while(!feof(f)) 
     1435        { 
     1436                fgets(line,256,f); 
     1437                if (line[0]=='v' && line[1]==' ') 
     1438                { 
     1439                        Geometry::Vector3 v3; 
     1440                        sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z); 
     1441                        vertices.push_back(v3); 
     1442                } 
     1443                else if (line[0]=='v' && line[1]=='t') 
     1444                { 
     1445                        Geometry::Vector2 v2; 
     1446                        sscanf(line+2,"%f %f",&v2.x,&v2.y); 
     1447                        texcoords.push_back(v2); 
     1448                } 
     1449                else if (line[0]=='v' && line[1]=='n') 
     1450                { 
     1451                        Geometry::Vector3 v3; 
     1452                        sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z); 
     1453                        normals.push_back(v3); 
     1454                } 
     1455                else if (line[0]=='f') 
     1456                { 
     1457                        face_t auxface; 
     1458                        auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0; 
     1459                        int n = sscanf(line+2,"%d/%d/%d %d/%d/%d %d/%d/%d", &auxface.v1,&auxface.t1,&auxface.n1,  
     1460                                                                                                                            &auxface.v2,&auxface.t2,&auxface.n2,  
     1461                                                                                                                                &auxface.v3,&auxface.t3,&auxface.n3); 
     1462                        if (n<9) 
     1463                        { 
     1464                                auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0; 
     1465                                n = sscanf(line+2,"%d//%d %d//%d %d//%d", &auxface.v1,&auxface.n1,  
     1466                                                                                                                  &auxface.v2,&auxface.n2,  
     1467                                                                                                                  &auxface.v3,&auxface.n3); 
     1468                                if (n<6) 
     1469                                { 
     1470                                        auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0; 
     1471                                        n = sscanf(line+2,"%d/%d %d/%d %d/%d", &auxface.v1,&auxface.t1, 
     1472                                                                                                                   &auxface.v2,&auxface.t2,  
     1473                                                                                                                   &auxface.v3,&auxface.t3); 
     1474                                        if (n<6) 
     1475                                        { 
     1476                                                auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0; 
     1477                                                n = sscanf(line+2,"%d %d %d", &auxface.v1,&auxface.v2,&auxface.v3); 
     1478                                        } 
     1479                                } 
     1480                        } 
     1481 
     1482                        auxface.v1=abs(auxface.v1); auxface.v2=abs(auxface.v2); auxface.v3=abs(auxface.v3); 
     1483                        auxface.t1=abs(auxface.t1); auxface.t2=abs(auxface.t2); auxface.t3=abs(auxface.t3); 
     1484                        auxface.n1=abs(auxface.n1); auxface.n2=abs(auxface.n2); auxface.n3=abs(auxface.n3); 
     1485                        auxface.v1--; auxface.v2--; auxface.v3--; 
     1486                        auxface.t1--; auxface.t2--; auxface.t3--; 
     1487                        auxface.n1--; auxface.n2--; auxface.n3--; 
     1488                        current_faces.push_back(auxface); 
     1489                } 
     1490                else if (line[0]=='g') 
     1491                { 
     1492                        if (current_faces.size()>0) 
     1493                                faces.push_back(current_faces); 
     1494                        current_faces.clear(); 
     1495                } 
     1496        } 
     1497 
     1498        if (current_faces.size()>0) 
     1499                faces.push_back(current_faces); 
     1500        current_faces.clear(); 
     1501 
     1502        mesh->mSubMeshCount = faces.size(); 
     1503        bool found_texcoords=!texcoords.empty(); 
     1504 
     1505        if (normals.empty()) 
     1506        { 
     1507                // calculate face normals 
     1508                for (int i=0, inormal=0; i<mesh->mSubMeshCount; i++) 
     1509                { 
     1510                        Geometry::SubMesh *submesh = mesh->mSubMesh+i; 
     1511                         std::vector<face_t> & vecfaces = faces[i]; 
     1512                        int j=0; 
     1513                        for (std::vector<face_t>::iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++,inormal++) 
     1514                        { 
     1515                                face_t & auxface = *it; 
     1516                                auxface.n1 = inormal; 
     1517                                auxface.n2 = inormal; 
     1518                                auxface.n3 = inormal; 
     1519                                Geometry::Vector3 v1,v2,v3,v31,v21,nor; 
     1520                                v1 = vertices[auxface.v1]; 
     1521                                v2 = vertices[auxface.v2]; 
     1522                                v3 = vertices[auxface.v3]; 
     1523                                v31 = v3 - v1; 
     1524                                v21 = v2 - v1; 
     1525                                nor = v21.crossProduct(v31); 
     1526                                nor.normalise(); 
     1527                                normals.push_back(nor); 
     1528                        }                        
     1529                } 
     1530        } 
     1531 
     1532        // fill up the mesh structure with the loaded information 
     1533 
     1534        std::map<vertex_arranger_node,int> vertex_map; 
     1535                  
     1536        mesh->mSubMesh=new Geometry::SubMesh[mesh->mSubMeshCount]; 
     1537        for (int i=0; i<mesh->mSubMeshCount; i++) 
     1538        { 
     1539                Geometry::SubMesh *submesh = mesh->mSubMesh+i; 
     1540                int j=0; 
     1541                const std::vector<face_t> & vecfaces = faces[i]; 
     1542                std::vector<Geometry::Index> aux_indices; 
     1543                submesh->mSharedVertexBuffer = true; 
     1544                submesh->mIndexCount = vecfaces.size()*3; 
     1545                submesh->mIndex=new Geometry::Index[submesh->mIndexCount]; 
     1546                 
     1547                for (std::vector<face_t>::const_iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++) 
     1548                { 
     1549                        const face_t & auxface = *it; 
     1550 
     1551                        vertex_arranger_node v1(auxface.v1,auxface.n1,auxface.t1); 
     1552                        vertex_arranger_node v2(auxface.v2,auxface.n2,auxface.t2); 
     1553                        vertex_arranger_node v3(auxface.v3,auxface.n3,auxface.t3); 
     1554 
     1555                        std::map<vertex_arranger_node,int>::iterator res; 
     1556                        res=vertex_map.find(v1); 
     1557                        if (res==vertex_map.end()) 
     1558                        { 
     1559                                int val = vertex_map.size(); 
     1560                                vertex_map[v1] = val; 
     1561                                submesh->mIndex[j*3+0] = val; 
     1562                        } 
     1563                        else 
     1564                                submesh->mIndex[j*3+0] = res->second; 
     1565 
     1566                        res=vertex_map.find(v2); 
     1567                        if (res==vertex_map.end()) 
     1568                        { 
     1569                                int val = vertex_map.size(); 
     1570                                vertex_map[v2] = val; 
     1571                                submesh->mIndex[j*3+1] = val; 
     1572                        } 
     1573                        else 
     1574                                submesh->mIndex[j*3+1] = res->second; 
     1575 
     1576                        res=vertex_map.find(v3); 
     1577                        if (res==vertex_map.end()) 
     1578                        { 
     1579                                int val = vertex_map.size(); 
     1580                                vertex_map[v3] = val; 
     1581                                submesh->mIndex[j*3+2] = val; 
     1582                        } 
     1583                        else 
     1584                                submesh->mIndex[j*3+2] = res->second; 
     1585                }                        
     1586        } 
     1587 
     1588        mesh->mVertexBuffer=new Geometry::VertexBuffer; 
     1589        mesh->mVertexBuffer->mVertexCount = vertex_map.size(); 
     1590        mesh->mVertexBuffer->mPosition = new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount]; 
     1591        mesh->mVertexBuffer->mTexCoords = texcoords.empty()?NULL:new Geometry::Vector2[mesh->mVertexBuffer->mVertexCount]; 
     1592        mesh->mVertexBuffer->mNormal = normals.empty()?NULL:new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount]; 
     1593        mesh->mVertexBuffer->mVertexInfo = Geometry::VERTEX_POSITION | (texcoords.empty()?0:Geometry::VERTEX_TEXCOORDS) | (normals.empty()?0:Geometry::VERTEX_NORMAL); 
     1594 
     1595        // sort the calculated vertices 
     1596         
     1597        vertex_arranger_node * vertex_list = new vertex_arranger_node[mesh->mVertexBuffer->mVertexCount]; 
     1598        for (std::map<vertex_arranger_node,int>::iterator it=vertex_map.begin(); it!=vertex_map.end(); it++) 
     1599                vertex_list[it->second] = it->first; 
     1600 
     1601 
     1602        for (int i=0; i<mesh->mSubMeshCount; i++) 
     1603                mesh->mSubMesh[i].mVertexBuffer=mesh->mVertexBuffer; 
     1604         
     1605        for (int j=0; j<mesh->mVertexBuffer->mVertexCount; j++) 
     1606        {                
     1607                int vi = vertex_list[j].v; 
     1608                int ti = vertex_list[j].t; 
     1609                int ni = vertex_list[j].n; 
     1610 
     1611                Geometry::Vector3 auxpos(vertices[vi]); 
     1612                if (auxpos.x < mesh->mMeshBounds.minX) mesh->mMeshBounds.minX = auxpos.x; 
     1613                if (auxpos.y < mesh->mMeshBounds.minY) mesh->mMeshBounds.minY = auxpos.y; 
     1614                if (auxpos.z < mesh->mMeshBounds.minZ) mesh->mMeshBounds.minZ = auxpos.z; 
     1615                if (auxpos.x > mesh->mMeshBounds.maxX) mesh->mMeshBounds.maxX = auxpos.x; 
     1616                if (auxpos.y > mesh->mMeshBounds.maxY) mesh->mMeshBounds.maxY = auxpos.y; 
     1617                if (auxpos.z > mesh->mMeshBounds.maxZ) mesh->mMeshBounds.maxZ = auxpos.z; 
     1618 
     1619                mesh->mVertexBuffer->mPosition[j] = auxpos; 
     1620                mesh->mVertexBuffer->mNormal[j] = normals[ni]; 
     1621                if (found_texcoords) 
     1622                        mesh->mVertexBuffer->mTexCoords[j] = texcoords[ti];              
     1623        } 
     1624 
     1625        delete[] vertex_list; 
     1626} 
     1627 
  • GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp

    r1018 r1050  
    503503 
    504504                //      Allocate memory. 
    505                 mSharedPosArray =       new GLfloat[vertex_buffer->mVertexCount * 3]; 
    506                 mSharedNorArray =       new GLfloat[vertex_buffer->mVertexCount * 3]; 
    507                 mSharedTexCoordArray    =       new GLfloat[vertex_buffer->mVertexCount * 2]; 
     505                mSharedPosArray = new GLfloat[vertex_buffer->mVertexCount * 3]; 
     506                mSharedNorArray = new GLfloat[vertex_buffer->mVertexCount * 3]; 
     507                if (vertex_buffer->mTexCoords) 
     508                        mSharedTexCoordArray = new GLfloat[vertex_buffer->mVertexCount * 2]; 
     509                else 
     510                        mSharedTexCoordArray = NULL; 
    508511 
    509512                for (int vertex = 0; vertex < vertex_buffer->mVertexCount; vertex++) 
     
    517520                        mSharedNorArray[(3 * vertex) + 2]       =       vertex_buffer->mNormal[vertex].z; 
    518521 
    519                         mSharedTexCoordArray[2 * vertex]                =       vertex_buffer->mTexCoords[vertex].x; 
    520                         mSharedTexCoordArray[(2 * vertex) + 1]  =       vertex_buffer->mTexCoords[vertex].y; 
     522                        if (vertex_buffer->mTexCoords) 
     523                        { 
     524                                mSharedTexCoordArray[2 * vertex]                =       vertex_buffer->mTexCoords[vertex].x; 
     525                                mSharedTexCoordArray[(2 * vertex) + 1]  =       vertex_buffer->mTexCoords[vertex].y; 
     526                        } 
    521527                } 
    522528        } 
  • GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp

    r1026 r1050  
    5151                                                                                cb_menuFileLoadTexture_i(o,v); 
    5252} 
     53 
    5354 
    5455inline void GeoMeshViewUI::cb_menuFileLoadTextureSubMesh_i(fltk::Item *item, void *) 
     
    24442445//      Open a mesh file. 
    24452446//--------------------------------------------------------------------------- 
    2446 void    GeoMeshViewUI::openMeshFile() 
     2447void    GeoMeshViewUI::openMeshFile(void) 
    24472448{ 
    24482449        Mesh                                                    *mesh_loaded; 
     
    24512452        static  char                    title[256]; 
    24522453         
    2453         fcho    =       new fltk::FileChooser("", 
    2454                                                                                                                                 "*.mesh", 
    2455                                                                                                                                 fltk::FileChooser::CREATE, 
    2456                                                                                                                                 "Open mesh file"); 
     2454        fcho    =       new fltk::FileChooser("", "*.{mesh,obj}", fltk::FileChooser::CREATE, "Open a mesh"); 
    24572455 
    24582456        fcho->exec(); 
Note: See TracChangeset for help on using the changeset viewer.