C++读入obj格式模型文件

来源:互联网 发布:淘宝开店注意事项 编辑:程序博客网 时间:2024/05/17 07:35

http://blog.csdn.net/wangjiannuaa/article/details/6758173


[cpp] view plaincopyprint?
  1. #ifndef  _LOADOBJ_H_  
  2. #define  _LOADOBJ_H_  
  3.   
  4. #include <math.h>  
  5. #include <iostream>  
  6. #include <fstream>  
  7. #include <string>  
  8. #include <vector>  
  9.   
  10. using namespace std;  
  11.   
  12. #define dot(u,v)   ((u).x * (v).x + (u).y * (v).y + (u).z*(v).z)    
  13. #define norm2(v)   dot(v,v)        // norm2 = squared length of vector    
  14. #define norm(v)    sqrt(norm2(v))  // norm = length of vector    
  15. #define d(u,v)     norm(u-v)       // distance = norm of difference    
  16.   
  17. // Obj loader  
  18. struct TriangleFace   
  19. {  
  20.     int v[3]; // vertex indices  
  21. };  
  22.   
  23. class float3  
  24. {  
  25. public:   
  26.     float x;  
  27.     float y;  
  28.     float z;  
  29. public:   
  30.     float3(){x=0;y=0;z=0;}  
  31.     float3(float mx,float my,float mz){x=mx;y=my;z=mz;}  
  32.     ~float3(){}  
  33.   
  34.     float3 operator+(float3);  
  35.     float3 operator-(float3);  
  36.     float3 operator/(float);  
  37.   
  38.     friend float3 operator*(float m,float3 f3)  
  39.     {  
  40.         return float3(f3.x*m,f3.y*m,f3.z*m);  
  41.     }  
  42.     friend float3 operator*(float3 f3,float m)  
  43.     {  
  44.         return float3(f3.x*m,f3.y*m,f3.z*m);  
  45.     }  
  46.   
  47.     float3 operator=(float3);  
  48.   
  49.     float3& operator += (float3);  
  50.       
  51. };  
  52.   
  53. float3 float3::operator +(float3 m)  
  54. {  
  55.     float3 result;  
  56.     result.x = x+m.x;  
  57.     result.y = y+m.y;  
  58.     result.z = z+m.z;  
  59.     return result;  
  60. }  
  61.   
  62. float3 float3::operator - (float3 m)  
  63. {  
  64.     float3 result;  
  65.     result.x = x-m.x;  
  66.     result.y = y-m.y;  
  67.     result.z = z-m.z;  
  68.     return result;  
  69. }  
  70.   
  71. float3 float3::operator /(float m)  
  72. {  
  73.     if(m==0){  
  74.         printf("error /");  
  75.         return float3(x,y,z);  
  76.     }  
  77.     else  
  78.         return float3(x/m,y/m,z/m);  
  79. }  
  80.   
  81. float3 float3::operator =(float3 f3)  
  82. {  
  83.     x = f3.x;  
  84.     y = f3.y;  
  85.     z = f3.z;  
  86.     return float3(x,y,z);  
  87. }  
  88.   
  89. struct TriangleMesh  
  90. {  
  91.     vector<float3> verts;  
  92.     vector<TriangleFace> faces;  
  93.     //模型的包围盒  
  94.     float3 bounding_box[2];  
  95.     //模型的包围球参数  
  96.     float3 bounding_sphere_c;  
  97.     float bounding_sphere_r;  
  98. };  
  99.   
  100. TriangleMesh mesh;  
  101.   
  102. int total_number_of_triangles = 0;  
  103.   
  104. // Scene bounding box   
  105. float3 scene_aabbox_min;  
  106. float3 scene_aabbox_max;  
  107.   
  108. void loadObj(const std::string filename, TriangleMesh &mesh);  
  109.   
  110. void loadObj( const std::string filename, TriangleMesh &mesh )  
  111. {  
  112.     std::ifstream in(filename.c_str());  
  113.   
  114.     if(!in.good())  
  115.     {  
  116.         cout  << "ERROR: loading obj:(" << filename << ") file is not good" << "\n";  
  117.         exit(0);  
  118.     }  
  119.   
  120.     char buffer[256], str[255];  
  121.     float f1,f2,f3;  
  122.       
  123.     while(!in.getline(buffer,255).eof())  
  124.     {  
  125.         buffer[255]='\0';  
  126.   
  127.         sscanf_s(buffer,"%s",str,255);  
  128.   
  129.         // reading a vertex  
  130.         if (buffer[0]=='v' && (buffer[1]==' '  || buffer[1]==32) )  
  131.         {  
  132.             if ( sscanf(buffer,"v %f %f %f",&f1,&f2,&f3)==3)  
  133.             {  
  134.                 mesh.verts.push_back(float3(f1,f2,f3));  
  135.             }  
  136.             else  
  137.             {  
  138.                 cout << "ERROR: vertex not in wanted format in OBJLoader" << "\n";  
  139.                 exit(-1);  
  140.             }  
  141.         }  
  142.         // reading FaceMtls   
  143.         else if (buffer[0]=='f' && (buffer[1]==' ' || buffer[1]==32) )  
  144.         {  
  145.             TriangleFace f;  
  146.             int nt = sscanf(buffer,"f %d %d %d",&f.v[0],&f.v[1],&f.v[2]);  
  147.             if( nt!=3 )  
  148.             {  
  149.                 cout << "ERROR: I don't know the format of that FaceMtl" << "\n";  
  150.                 exit(-1);  
  151.             }  
  152.   
  153.             mesh.faces.push_back(f);  
  154.         }  
  155.     }  
  156.       
  157.     float xmin,ymin,zmin,xmax,ymax,zmax;  
  158.     int Pxmin,Pxmax,Pymin,Pymax,Pzmin,Pzmax;  
  159.       
  160.     //calculate the bounding sphere  
  161.     xmin = xmax = mesh.verts[0].x;  
  162.     ymin = ymax = mesh.verts[0].y;  
  163.     zmin = zmax = mesh.verts[0].z;  
  164.     Pxmin = Pxmax = Pymin = Pymax = Pzmin = Pzmax = 0;  
  165.   
  166.     //calculate the bounding box  
  167.     mesh.bounding_box[0] = float3(mesh.verts[0].x,mesh.verts[0].y,mesh.verts[0].z);  
  168.     mesh.bounding_box[1] = float3(mesh.verts[0].x,mesh.verts[0].y,mesh.verts[0].z);  
  169.   
  170.     for(unsigned int i = 1; i < mesh.verts.size(); i++)  
  171.     {  
  172.         //update min value  
  173.         mesh.bounding_box[0].x = min(mesh.verts[i].x,mesh.bounding_box[0].x);  
  174.         mesh.bounding_box[0].y = min(mesh.verts[i].y,mesh.bounding_box[0].y);  
  175.         mesh.bounding_box[0].z = min(mesh.verts[i].z,mesh.bounding_box[0].z);  
  176.   
  177.         //update max value  
  178.         mesh.bounding_box[1].x = max(mesh.verts[i].x,mesh.bounding_box[1].x);  
  179.         mesh.bounding_box[1].y = max(mesh.verts[i].y,mesh.bounding_box[1].y);  
  180.         mesh.bounding_box[1].z = max(mesh.verts[i].z,mesh.bounding_box[1].z);  
  181.   
  182.         //update the  x min and max  
  183.         if (mesh.verts[i].x < xmin){  
  184.             xmin = mesh.verts[i].x;  
  185.             Pxmin = i;  
  186.         }  
  187.         else if(mesh.verts[i].x > xmax){  
  188.             xmax = mesh.verts[i].x;  
  189.             Pxmax = i;  
  190.         }  
  191.         //update the y min and max  
  192.         if (mesh.verts[i].y < ymin){  
  193.             ymin = mesh.verts[i].y;  
  194.             Pymin = i;  
  195.         }  
  196.         else if(mesh.verts[i].y > ymax){  
  197.             ymax = mesh.verts[i].y;  
  198.             Pymax = i;  
  199.         }  
  200.         //update the z min and max  
  201.         if(mesh.verts[i].z < zmin){  
  202.             zmin = mesh.verts[i].z;  
  203.             Pzmin = i;  
  204.         }  
  205.         else if(mesh.verts[i].z > zmax){  
  206.             zmax = mesh.verts[i].z;  
  207.             Pzmax = i;  
  208.         }  
  209.     }  
  210.       
  211.     //calculate the bounding sphere  
  212.     float3 dVx = mesh.verts[Pxmax] - mesh.verts[Pxmin];  
  213.     float3 dVy = mesh.verts[Pymax] - mesh.verts[Pymin];  
  214.     float3 dVz = mesh.verts[Pzmax] - mesh.verts[Pzmin];  
  215.     float dx2 = norm2(dVx);  
  216.     float dy2 = norm2(dVy);  
  217.     float dz2 = norm2(dVz);  
  218.   
  219.     float3 center;  
  220.     float  radius2;  
  221.     float  radius;  
  222.   
  223.     if (dx2 >= dy2 && dx2>=dz2) {                 // x direction is largest extent    
  224.         center = mesh.verts[Pxmin] + (dVx / 2.0);   // Center = midpoint of extremes    
  225.         radius2 = norm2(mesh.verts[Pxmax] - center);// radius squared    
  226.     }    
  227.     else if (dy2 >= dx2  && dy2>=dz2){                // y direction is largest extent    
  228.         center = mesh.verts[Pymin] + (dVy / 2.0);   // Center = midpoint of extremes    
  229.         radius2 = norm2(mesh.verts[Pymax] - center);// radius squared    
  230.     }   
  231.     else{  
  232.         center = mesh.verts[Pzmin] + (dVz / 2.0);   // Center = midpoint of extremes    
  233.         radius2 = norm2(mesh.verts[Pzmax] - center);// radius squared     
  234.     }  
  235.   
  236.     radius = sqrt(radius2);    
  237.   
  238.     // now check that all points V[i] are in the ball    
  239.     // and if not, expand the ball just enough to include them    
  240.     float3 dV;  
  241.     float dist2,dist;  
  242.     for (unsigned int i=0;i<mesh.verts.size();i++)  
  243.     {  
  244.         dV = mesh.verts[i] - center;  
  245.         dist2 = norm2(dV);  
  246.         if (dist2 <= radius2) // V[i] is inside the ball already    
  247.             continue;  
  248.   
  249.         // V[i] not in ball, so expand ball to include it    
  250.         dist = sqrt(dist2);    
  251.         radius = (radius + dist) / 2.0;         // enlarge radius just enough    
  252.         radius2 = radius * radius;    
  253.         center = center + ((dist-radius)/dist) * dV;   // shift Center toward V[i]    
  254.           
  255.     }  
  256.       
  257.     mesh.bounding_sphere_c = center;  
  258.     mesh.bounding_sphere_r = radius;  
  259.       
  260.     cout<< "----------obj file loaded-------------"<<endl;  
  261.     cout<<"number of faces:" << mesh.faces.size() << " number of vertices:" << mesh.verts.size() << endl;  
  262.     cout<< "obj bounding box: min:("   
  263.         << mesh.bounding_box[0].x << "," << mesh.bounding_box[0].y << "," << mesh.bounding_box[0].z <<") max:("   
  264.         << mesh.bounding_box[1].x << "," << mesh.bounding_box[1].y << "," << mesh.bounding_box[1].z <<")" << endl  
  265.         <<"obj bounding sphere center:"<<mesh.bounding_sphere_c.x<<","<<mesh.bounding_sphere_c.y<<","<<mesh.bounding_sphere_c.z<<endl  
  266.         <<"obj bounding sphere radius:"<<mesh.bounding_sphere_r<<endl;  
  267.   
  268. }  
  269.   
  270.   
  271. #endif  

用法:


[cpp] view plaincopyprint?
  1. #include "LoadObj.h"  
  2.   
  3. void main()  
  4. {  
  5.     std::string filename = "E:\\codeLab\\cube.obj";  
  6.       
  7.     TriangleMesh mesh;  
  8.   
  9.     loadObj(filename, mesh);  
  10. }  


注意:请使用英文目录。
0 0
原创粉丝点击