00001 #include <ros/console.h>
00002 #include <blort/Tracker/ModelLoader.h>
00003 #include <stdexcept>
00004
00005 using namespace Tracking;
00006 using namespace TomGine;
00007 using namespace std;
00008
00009
00010
00011
00012 bool ModelLoader::propertyIsInList(PlyProperty* prop, PlyProperty* list, int n, int* index){
00013
00014 for(int i=0; i<n; i++){
00015 if(equal_strings(prop->name, list[i].name)){
00016 *index = i;
00017 return true;
00018 }
00019 }
00020 return false;
00021 }
00022
00023
00024
00025 ModelLoader::ModelLoader(){
00026 }
00027
00028 ModelLoader::~ModelLoader(){
00029
00030 }
00031
00032
00033 bool ModelLoader::LoadPly(TomGine::tgModel &model, const char* filename){
00034 PlyFile* plyfile;
00035 int i,j;
00036 int nelems;
00037 char **elist;
00038 int file_type;
00039 float version;
00040 char *elem_name;
00041
00042 PlyProperty **plist;
00043
00044 int num_elems;
00045 int nprops;
00046 int index;
00047 char** obj_info;
00048 int num_obj_info;
00049
00050 int num_vertices = 0;
00051 int num_faces = 0;
00052
00053 PlyVertex* plyvertexlist = 0;
00054 PlyFace* plyfacelist = 0;
00055 PlyEdge* plyedgelist = 0;
00056 vector<string> texFilenames;
00057 string strFilename(filename);
00058
00059
00060
00061
00062
00063
00064 plyfile = ply_open_for_reading((char*)filename, &nelems, &elist, &file_type, &version);
00065 if(plyfile==0){
00066 char errmsg[128];
00067 sprintf(errmsg, "[ModelLoader::LoadPly] Error loading ply file %s\n", filename);
00068 throw std::runtime_error(errmsg);
00069 }
00070
00071
00072
00073 obj_info = ply_get_obj_info(plyfile, &num_obj_info);
00074 if(num_obj_info < 1){
00075
00076 }else if(num_obj_info >= 1){
00077 for(i=0; i<num_obj_info; i++){
00078 texFilenames.push_back("");
00079 texFilenames[i].append(filename, 0, strFilename.find_last_of("/")+1);
00080 texFilenames[i].append(obj_info[i]);
00081
00082 }
00083 }
00084
00085
00086 PlyProperty vert_props[] = {
00087 {(char*)"x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
00088 {(char*)"y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
00089 {(char*)"z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
00090 {(char*)"nx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nx), 0, 0, 0, 0},
00091 {(char*)"ny", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ny), 0, 0, 0, 0},
00092 {(char*)"nz", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nz), 0, 0, 0, 0},
00093 {(char*)"s", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,s), 0, 0, 0, 0},
00094 {(char*)"t", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,t), 0, 0, 0, 0},
00095 {(char*)"red", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,r), 0, 0, 0, 0},
00096 {(char*)"green", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,g), 0, 0, 0, 0},
00097 {(char*)"blue", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,b), 0, 0, 0, 0}
00098 };
00099
00100
00101 PlyProperty face_props[] = {
00102 {(char*)"vertex_indices", PLY_USHORT, PLY_UINT, offsetof(PlyFace,v),
00103 1, PLY_USHORT, PLY_UINT, offsetof(PlyFace,nverts)},
00104 };
00105
00106
00107 PlyProperty edge_props[] = {
00108 {(char*)"start", PLY_USHORT, PLY_USHORT, offsetof(PlyEdge,start), 0, 0, 0, 0},
00109 {(char*)"end", PLY_USHORT, PLY_USHORT, offsetof(PlyEdge,end), 0, 0, 0, 0}
00110 };
00111
00112 for(i=0; i<nelems; i++){
00113
00114 elem_name = elist[i];
00115 plist = ply_get_element_description (plyfile, elem_name, &num_elems, &nprops);
00116
00117
00118 if (equal_strings ((char*)"vertex", elem_name)) {
00119
00120 num_vertices = num_elems;
00121 plyvertexlist = (PlyVertex*)malloc(sizeof(PlyVertex) * num_vertices);
00122
00123
00124 for(j=0; j<nprops; j++){
00125 if(propertyIsInList(plist[j], vert_props, 11, &index))
00126 ply_get_property(plyfile, elem_name, &vert_props[index]);
00127 }
00128
00129
00130 for(j=0; j<num_elems; j++){
00131 ply_get_element(plyfile, &plyvertexlist[j]);
00132 }
00133
00134 }
00135
00136
00137 if (equal_strings ((char*)"face", elem_name)) {
00138
00139 num_faces = num_elems;
00140 plyfacelist = (PlyFace*)malloc(sizeof(PlyFace)*num_faces);
00141
00142
00143 for(j=0; j<nprops && j<1; j++){
00144 ply_get_property(plyfile, elem_name, &face_props[j]);
00145 }
00146
00147
00148 for(j=0; j<num_elems; j++){
00149 ply_get_element(plyfile, &plyfacelist[j]);
00150
00151 }
00152 }
00153
00154
00155 if (equal_strings ((char*)"edge", elem_name)) {
00156
00157 plyedgelist = (PlyEdge*)malloc(sizeof(PlyEdge)*num_elems);
00158
00159
00160
00161 for(j=0; j<nprops && j<2; j++){
00162 ply_get_property(plyfile, elem_name, &edge_props[j]);
00163 }
00164
00165
00166 for(j=0; j<num_elems; j++){
00167 ply_get_element(plyfile, &plyedgelist[j]);
00168
00169 }
00170 }
00171 }
00172 ply_close(plyfile);
00173
00174
00175
00176
00177
00178
00179 for(i=0; i<num_vertices; i++){
00180 tgVertex v;
00181 v.pos.x = plyvertexlist[i].x;
00182 v.pos.y = plyvertexlist[i].y;
00183 v.pos.z = plyvertexlist[i].z;
00184 v.normal.x = plyvertexlist[i].nx;
00185 v.normal.y = plyvertexlist[i].ny;
00186 v.normal.z = plyvertexlist[i].nz;
00187 v.texCoord.x = plyvertexlist[i].s;
00188 v.texCoord.y = plyvertexlist[i].t;
00189 model.add(v);
00190 }
00191
00192
00193 for(i=0; i<num_faces; i++){
00194 tgFace f;
00195 for(j=0; j<plyfacelist[i].nverts; j++){
00196 f.v.push_back(plyfacelist[i].v[j]);
00197 }
00198 model.add(f);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 model.ComputeFaceNormals();
00209
00210
00211
00212 if(plyvertexlist) free(plyvertexlist);
00213 if(plyfacelist) free(plyfacelist);
00214 if(plyedgelist) free(plyedgelist);
00215
00216 return true;
00217 }
00218
00219 bool ModelLoader::LoadPly(TrackerModel &model, const char* filename){
00220 PlyFile* plyfile;
00221 int i,j;
00222 int nelems;
00223 char **elist;
00224 int file_type;
00225 float version;
00226 char *elem_name;
00227
00228 PlyProperty **plist;
00229
00230 int num_elems;
00231 int nprops;
00232 int index;
00233 char** obj_info;
00234 int num_obj_info;
00235
00236 int num_vertices = 0;
00237 int num_faces = 0;
00238
00239 int num_passes = 0;
00240 PlyVertex* plyvertexlist = 0;
00241 PlyFace* plyfacelist = 0;
00242 PlyEdge* plyedgelist = 0;
00243 PlyPass* plypasslist = 0;
00244 vector<string> texFilenames;
00245 string strFilename(filename);
00246
00247
00248
00249
00250 plyfile = ply_open_for_reading((char*)filename, &nelems, &elist, &file_type, &version);
00251 if(plyfile==0){
00252 ROS_DEBUG("[ModelLoader::LoadPly] Failed to load ply file '%s'", filename);
00253 return false;
00254 }
00255
00256
00257
00258
00259 obj_info = ply_get_obj_info(plyfile, &num_obj_info);
00260 if(num_obj_info < 1){
00261
00262 }else if(num_obj_info >= 1){
00263 for(i=0; i<num_obj_info; i++){
00264 texFilenames.push_back("");
00265 texFilenames[i].append(filename, 0, strFilename.find_last_of("/")+1);
00266 texFilenames[i].append(obj_info[i]);
00267
00268 }
00269 }
00270
00271 PlyProperty vert_props[] = {
00272 {(char*)"x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
00273 {(char*)"y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
00274 {(char*)"z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
00275 {(char*)"nx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nx), 0, 0, 0, 0},
00276 {(char*)"ny", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ny), 0, 0, 0, 0},
00277 {(char*)"nz", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nz), 0, 0, 0, 0},
00278 {(char*)"s", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,s), 0, 0, 0, 0},
00279 {(char*)"t", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,t), 0, 0, 0, 0},
00280 {(char*)"red", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,r), 0, 0, 0, 0},
00281 {(char*)"green", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,g), 0, 0, 0, 0},
00282 {(char*)"blue", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,b), 0, 0, 0, 0}
00283 };
00284
00285
00286 PlyProperty face_props[] = {
00287 {(char*)"vertex_indices", PLY_USHORT, PLY_UINT, offsetof(PlyFace,v),
00288 1, PLY_USHORT, PLY_UINT, offsetof(PlyFace,nverts)},
00289 };
00290
00291
00292 PlyProperty edge_props[] = {
00293 {(char*)"start", PLY_USHORT, PLY_USHORT, offsetof(PlyEdge,start), 0, 0, 0, 0},
00294 {(char*)"end", PLY_USHORT, PLY_USHORT, offsetof(PlyEdge,end), 0, 0, 0, 0}
00295 };
00296
00297 PlyProperty pass_props[] = {
00298 {(char*)"face_indices", PLY_USHORT, PLY_UINT, offsetof(PlyPass,f),
00299 1, PLY_USHORT, PLY_UINT, offsetof(PlyPass,nfaces)},
00300 {(char*)"m0", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m0), 0, 0, 0, 0},
00301 {(char*)"m1", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m1), 0, 0, 0, 0},
00302 {(char*)"m2", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m2), 0, 0, 0, 0},
00303 {(char*)"m3", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m3), 0, 0, 0, 0},
00304 {(char*)"m4", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m4), 0, 0, 0, 0},
00305 {(char*)"m5", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m5), 0, 0, 0, 0},
00306 {(char*)"m6", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m6), 0, 0, 0, 0},
00307 {(char*)"m7", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m7), 0, 0, 0, 0},
00308 {(char*)"m8", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m8), 0, 0, 0, 0},
00309 {(char*)"m9", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m9), 0, 0, 0, 0},
00310 {(char*)"m10", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m10), 0, 0, 0, 0},
00311 {(char*)"m11", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m11), 0, 0, 0, 0},
00312 {(char*)"m12", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m12), 0, 0, 0, 0},
00313 {(char*)"m13", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m13), 0, 0, 0, 0},
00314 {(char*)"m14", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m14), 0, 0, 0, 0},
00315 {(char*)"m15", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,m15), 0, 0, 0, 0},
00316 {(char*)"x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,x), 0, 0, 0, 0},
00317 {(char*)"y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,y), 0, 0, 0, 0},
00318 {(char*)"w", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,w), 0, 0, 0, 0},
00319 {(char*)"h", PLY_FLOAT, PLY_FLOAT, offsetof(PlyPass,h), 0, 0, 0, 0},
00320 {(char*)"tex_index", PLY_UCHAR, PLY_UCHAR, offsetof(PlyPass,tex), 0, 0, 0, 0}
00321 };
00322
00323 for(i=0; i<nelems; i++){
00324
00325 elem_name = elist[i];
00326 plist = ply_get_element_description (plyfile, elem_name, &num_elems, &nprops);
00327
00328
00329 if (equal_strings ((char*)"vertex", elem_name)) {
00330
00331 num_vertices = num_elems;
00332 plyvertexlist = (PlyVertex*)malloc(sizeof(PlyVertex) * num_vertices);
00333
00334
00335 for(j=0; j<nprops; j++){
00336 if(propertyIsInList(plist[j], vert_props, 11, &index))
00337 ply_get_property(plyfile, elem_name, &vert_props[index]);
00338 }
00339
00340
00341 for(j=0; j<num_elems; j++){
00342 ply_get_element(plyfile, &plyvertexlist[j]);
00343 }
00344
00345 }
00346
00347
00348 if (equal_strings ((char*)"face", elem_name)) {
00349
00350 num_faces = num_elems;
00351 plyfacelist = (PlyFace*)malloc(sizeof(PlyFace)*num_faces);
00352
00353
00354 for(j=0; j<nprops && j<1; j++){
00355 ply_get_property(plyfile, elem_name, &face_props[j]);
00356 }
00357
00358
00359 for(j=0; j<num_elems; j++){
00360 ply_get_element(plyfile, &plyfacelist[j]);
00361
00362 }
00363 }
00364
00365
00366 if (equal_strings ((char*)"edge", elem_name)) {
00367
00368 plyedgelist = (PlyEdge*)malloc(sizeof(PlyEdge)*num_elems);
00369
00370
00371
00372 for(j=0; j<nprops && j<2; j++){
00373 ply_get_property(plyfile, elem_name, &edge_props[j]);
00374 }
00375
00376
00377 for(j=0; j<num_elems; j++){
00378 ply_get_element(plyfile, &plyedgelist[j]);
00379
00380 }
00381 }
00382
00383
00384 if (equal_strings ((char*)"pass", elem_name)) {
00385 num_passes = num_elems;
00386 plypasslist = (PlyPass*)malloc(sizeof(PlyPass)*num_passes);
00387
00388 for(j=0; j<nprops; j++){
00389 ply_get_property(plyfile, elem_name, &pass_props[j]);
00390 }
00391
00392
00393 for(j=0; j<num_passes; j++){
00394 ply_get_element(plyfile, &plypasslist[j]);
00395
00396 }
00397 }
00398
00399 }
00400 ply_close(plyfile);
00401
00402
00403
00404
00405
00406 for(i=0; i<num_vertices; i++){
00407 tgVertex v;
00408 v.pos.x = plyvertexlist[i].x;
00409 v.pos.y = plyvertexlist[i].y;
00410 v.pos.z = plyvertexlist[i].z;
00411 v.normal.x = plyvertexlist[i].nx;
00412 v.normal.y = plyvertexlist[i].ny;
00413 v.normal.z = plyvertexlist[i].nz;
00414 v.texCoord.x = plyvertexlist[i].s;
00415 v.texCoord.y = plyvertexlist[i].t;
00416 model.add(v);
00417 }
00418
00419
00420 for(i=0; i<num_faces; i++){
00421 tgFace f;
00422 for(j=0; j<plyfacelist[i].nverts; j++){
00423 f.v.push_back(plyfacelist[i].v[j]);
00424 }
00425 model.add(f);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435 for(i=0; i<num_passes; i++){
00436 TrackerModel::Pass* p = new TrackerModel::Pass;
00437
00438 for(j=0; j<plypasslist[i].nfaces; j++){
00439 p->f.push_back(plypasslist[i].f[j]);
00440 }
00441
00442 p->modelviewprojection.mat[0] = plypasslist[i].m0;
00443 p->modelviewprojection.mat[1] = plypasslist[i].m1;
00444 p->modelviewprojection.mat[2] = plypasslist[i].m2;
00445 p->modelviewprojection.mat[3] = plypasslist[i].m3;
00446 p->modelviewprojection.mat[4] = plypasslist[i].m4;
00447 p->modelviewprojection.mat[5] = plypasslist[i].m5;
00448 p->modelviewprojection.mat[6] = plypasslist[i].m6;
00449 p->modelviewprojection.mat[7] = plypasslist[i].m7;
00450 p->modelviewprojection.mat[8] = plypasslist[i].m8;
00451 p->modelviewprojection.mat[9] = plypasslist[i].m9;
00452 p->modelviewprojection.mat[10] = plypasslist[i].m10;
00453 p->modelviewprojection.mat[11] = plypasslist[i].m11;
00454 p->modelviewprojection.mat[12] = plypasslist[i].m12;
00455 p->modelviewprojection.mat[13] = plypasslist[i].m13;
00456 p->modelviewprojection.mat[14] = plypasslist[i].m14;
00457 p->modelviewprojection.mat[15] = plypasslist[i].m15;
00458
00459 p->x = plypasslist[i].x;
00460 p->y = plypasslist[i].y;
00461 p->w = plypasslist[i].w;
00462 p->h = plypasslist[i].h;
00463
00464 p->texture->load(texFilenames[i].c_str());
00465
00466 model.m_passlist.push_back(p);
00467 }
00468
00469 if(!model.m_passlist.empty())
00470 model.m_textured = true;
00471
00472 model.ComputeFaceNormals();
00473 model.computeEdges();
00474 model.Update();
00475
00476
00477
00478 if(plyvertexlist) free(plyvertexlist);
00479 if(plyfacelist) free(plyfacelist);
00480 if(plyedgelist) free(plyedgelist);
00481 if(plypasslist) free(plypasslist);
00482 return true;
00483 }
00484
00485 bool ModelLoader::SavePly(TomGine::tgModel &model, const char* filename){
00486 FILE* pFile;
00487 pFile = fopen(filename, "w");
00488
00489 ROS_DEBUG("[ModelLoader::SavePly(Model)] Warning not implemented, use ModelLoader::SavePly(TrackerModel)");
00490
00491 fclose(pFile);
00492 return true;
00493 }
00494
00495 bool ModelLoader::SavePly(TrackerModel &model, const char* name){
00496 ROS_INFO("Saving model to %s", name);
00497 FILE* pFile = 0;
00498 unsigned i,j;
00499 string filename(name);
00500 string texname;
00501 string texfilename;
00502 char number[512];
00503
00504 filename.append(".ply");
00505 pFile = fopen(filename.c_str(), "w");
00506
00507 if(!pFile){
00508 ROS_ERROR("[ModelLoader::SavePly] Can not create file '%s'! Path existing?", name);
00509 throw std::runtime_error("[ModelLoader::SavePly] Can not create file! Path existing?");
00510 }
00511
00512
00513
00514 fputs("ply\n", pFile);
00515 fputs("format ascii 1.0\n", pFile);
00516
00517
00518 for(i=0; i<model.m_passlist.size(); i++){
00519 texname = string("");
00520 texfilename = string("");
00521 size_t start = filename.find_last_of("/");
00522 if(start!=filename.npos){
00523 string modelname(name);
00524 texname.append(modelname.begin()+start+1, modelname.end());
00525 texfilename.append(modelname.begin(), modelname.begin()+start+1);
00526 }else{
00527 texname = string(name);
00528 }
00529
00530 texname.append("-");
00531 sprintf(number, "%.5u", i);
00532 texname.append(number);
00533 texname.append(".jpg");
00534 texfilename.append(texname);
00535 fputs("obj_info ", pFile);
00536 fputs(texname.c_str(), pFile);
00537 fputs("\n", pFile);
00538 model.m_passlist[i]->texture->save(texfilename.c_str());
00539 }
00540
00541
00542 sprintf(number, "%d", model.getVertexSize());
00543 fputs("element vertex ", pFile);
00544 fputs(number, pFile);
00545 fputs("\n", pFile);
00546 fputs("property float x\n", pFile);
00547 fputs("property float y\n", pFile);
00548 fputs("property float z\n", pFile);
00549 fputs("property float nx\n", pFile);
00550 fputs("property float ny\n", pFile);
00551 fputs("property float nz\n", pFile);
00552
00553
00554 sprintf(number, "%d", model.getFaceSize());
00555 fputs("element face ", pFile);
00556 fputs(number, pFile);
00557 fputs("\n", pFile);
00558 fputs("property list uchar uint vertex_indices\n", pFile);
00559
00560
00561
00562 if(!model.m_passlist.empty()){
00563 sprintf(number, "%d", (int)model.m_passlist.size());
00564 fputs("element pass ", pFile);
00565 fputs(number, pFile);
00566 fputs("\n", pFile);
00567 fputs("property list uchar uint face_indices\n", pFile);
00568 fputs("property float m0\n", pFile);
00569 fputs("property float m1\n", pFile);
00570 fputs("property float m2\n", pFile);
00571 fputs("property float m3\n", pFile);
00572 fputs("property float m4\n", pFile);
00573 fputs("property float m5\n", pFile);
00574 fputs("property float m6\n", pFile);
00575 fputs("property float m7\n", pFile);
00576 fputs("property float m8\n", pFile);
00577 fputs("property float m9\n", pFile);
00578 fputs("property float m10\n", pFile);
00579 fputs("property float m11\n", pFile);
00580 fputs("property float m12\n", pFile);
00581 fputs("property float m13\n", pFile);
00582 fputs("property float m14\n", pFile);
00583 fputs("property float m15\n", pFile);
00584 fputs("property float x\n", pFile);
00585 fputs("property float y\n", pFile);
00586 fputs("property float w\n", pFile);
00587 fputs("property float h\n", pFile);
00588 fputs("property uchar tex_index\n", pFile);
00589 }
00590
00591 fputs("end_header\n",pFile);
00592
00593
00594 for(i=0; i<model.getVertexSize(); i++){
00595 tgVertex v = model.getVertex(i);
00596 sprintf( number, "%f %f %f %f %f %f\n",
00597 v.pos.x, v.pos.y, v.pos.z,
00598 v.normal.x, v.normal.y, v.normal.z);
00599 fputs(number, pFile);
00600 }
00601
00602
00603 for(i=0; i<model.getFaceSize(); i++){
00604 tgFace f = model.getFace(i);
00605 sprintf(number, "%d", (int)f.v.size());
00606 fputs(number, pFile);
00607 for(j=0; j<f.v.size(); j++){
00608 sprintf( number, " %d", f.v[j]);
00609 fputs(number, pFile);
00610 }
00611 fputs("\n", pFile);
00612 }
00613
00614
00615 for(i=0; i<model.m_passlist.size(); i++){
00616 TrackerModel::Pass* p = model.m_passlist[i];
00617 sprintf(number, "%d", (int)p->f.size());
00618 fputs(number, pFile);
00619 for(j=0; j<p->f.size(); j++){
00620 sprintf(number, " %d", p->f[j]);
00621 fputs(number, pFile);
00622 }
00623 for(j=0; j<16; j++){
00624 sprintf(number, " %f", p->modelviewprojection.mat[j]);
00625 fputs(number, pFile);
00626 }
00627 sprintf(number, " %f %f %f %f", p->x, p->y, p->w, p->h);
00628 fputs(number, pFile);
00629 sprintf(number, " %u", i);
00630 fputs(number, pFile);
00631 fputs("\n", pFile);
00632 }
00633
00634 fclose(pFile);
00635
00636 printf("saved: %s\n", filename.c_str());
00637
00638 return true;
00639 }
00640