/// obj2sdf will load a Wavefront .obj file that may contain many parts/materials /// it will split into separate obj files for each part/material and /// create an sdf file with visuals/collisions pointing to the new obj files /// this will make it easier to load complex obj files into pybullet /// see for example export in data/kitchens/fathirmutfak.sdf #include #include #include #define ASSERT_EQ(a,b) assert((a)==(b)); #include "MinitaurSetup.h" #include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" #include #include "Bullet3Common/b3FileUtils.h" #include "../Utils/b3ResourcePath.h" #define MAX_PATH_LEN 1024 int main(int argc, char* argv[]) { const char* fileName = "kitchens/kitchen.obj"; char fileNameWithPath[MAX_PATH_LEN]; bool fileFound = (b3ResourcePath::findResourcePath(fileName,fileNameWithPath,MAX_PATH_LEN))>0; char materialPrefixPath[MAX_PATH_LEN]; b3FileUtils::extractPath(fileNameWithPath,materialPrefixPath,MAX_PATH_LEN); std::vector shapes; std::string err = tinyobj::LoadObj(shapes, fileNameWithPath, materialPrefixPath); char sdfFileName[MAX_PATH_LEN]; sprintf(sdfFileName,"%s%s.sdf",materialPrefixPath,"newsdf"); FILE* sdfFile = fopen(sdfFileName,"w"); if (sdfFile==0) { printf("Fatal: cannot create sdf file %s\n",sdfFileName); exit(0); } fprintf(sdfFile, "\n\t\n\t0 0 -9.8\n"); for (int s=0;s<(int)shapes.size();s++) { tinyobj::shape_t& shape = shapes[s]; if (shape.name.length()) { printf("object name = %s\n", shape.name.c_str()); } char objFileName[MAX_PATH_LEN]; sprintf(objFileName,"%s/part%d.obj",materialPrefixPath,s); FILE* f = fopen(objFileName,"w"); if (f==0) { printf("Fatal: cannot create part obj file %s\n",objFileName); exit(0); } fprintf(f,"# Exported using automatic converter by Erwin Coumans\n"); fprintf(f,"mtllib bedroom.mtl\n"); int faceCount = shape.mesh.indices.size(); int vertexCount = shape.mesh.positions.size(); tinyobj::material_t mat = shape.material; if (shape.name.length()) { const char* objName = shape.name.c_str(); printf("mat.name = %s\n", objName); fprintf(f,"#object %s\n\n",objName); } for (int v=0;v=int(shape.mesh.indices.size())) { continue; } fprintf(f,"f %d/%d/%d %d/%d/%d %d/%d/%d\n", shape.mesh.indices[face]+1,shape.mesh.indices[face]+1,shape.mesh.indices[face]+1, shape.mesh.indices[face+1]+1,shape.mesh.indices[face+1]+1,shape.mesh.indices[face+1]+1, shape.mesh.indices[face+2]+1,shape.mesh.indices[face+2]+1,shape.mesh.indices[face+2]+1); } fclose(f); float kdRed=mat.diffuse[0]; float kdGreen=mat.diffuse[1]; float kdBlue=mat.diffuse[2]; char objSdfPartFileName[MAX_PATH_LEN]; sprintf(objSdfPartFileName,"part%d.obj",s); fprintf(sdfFile,"\t\t\n" "\t\t\t1\n" "\t\t\t0 0 0 0 0 0\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t0\n" "\t\t\t\n" "\t\t\t0.166667\n" "\t\t\t0\n" "\t\t\t0\n" "\t\t\t0.166667\n" "\t\t\t0\n" "\t\t\t0.166667\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t1 1 1\n" "\t\t\t\t%s\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t \n" "\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\t1 1 1\n" "\t\t\t\t\t%s\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\n" "\t\t\t\t1 0 0 1\n" "\t\t\t\t%f %f %f 1\n" "\t\t\t\t0.1 0.1 0.1 1\n" "\t\t\t\t0 0 0 0\n" "\t\t\t \n" "\t\t\t \n" "\t\t\t \n" "\t\t\t\n",objSdfPartFileName,s,s, objSdfPartFileName,objSdfPartFileName, kdRed, kdGreen, kdBlue); } fprintf(sdfFile,"\t\n\n"); fclose(sdfFile); return 0; }