00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "ioOBJ.hpp"
00033 #include <vlCore/TextStream.hpp>
00034 #include <vlCore/VirtualFile.hpp>
00035 #include <vlCore/VirtualDirectory.hpp>
00036 #include <vlCore/VisualizationLibrary.hpp>
00037 #include <vlCore/FileSystem.hpp>
00038 #include <vlGraphics/DoubleVertexRemover.hpp>
00039 #include <vlCore/LoadWriterManager.hpp>
00040 #include <vlGraphics/Effect.hpp>
00041 #include <vlGraphics/Actor.hpp>
00042 #include <string>
00043 #include <vector>
00044 #include <stdio.h>
00045
00046 using namespace vl;
00047
00048 namespace
00049 {
00050
00051
00052
00053 template <class T>
00054 void append(std::vector<T>& vec, const T& data, const int& alloc_step = 1024*10)
00055 {
00056 if (vec.size() == vec.capacity())
00057 vec.reserve( vec.size() + alloc_step );
00058 vec.push_back(data);
00059 }
00060 }
00061
00062
00063
00064 ObjTexture::ObjTexture()
00065 {
00066 mBlendU = false;
00067 mBlendV = false;
00068 mCC = false;
00069 mClamp = false;
00070 mMM_Base = 0.0f;
00071 mMM_Gain = 0.0f;
00072 mO_UVW[0] = 0.0f; mO_UVW[1] = 0.0f; mO_UVW[2] = 0.0f;
00073 mS_UVW[0] = 0.0f; mS_UVW[1] = 0.0f; mS_UVW[2] = 0.0f;
00074 mT_UVW[0] = 0.0f; mT_UVW[1] = 0.0f; mT_UVW[2] = 0.0f;
00075 mTexres_Value = 0.0f;
00076 mImfchan = 0;
00077 mBM = 0.0f;
00078 }
00079
00080 const ObjTexture& ObjTexture::parseLine(const String& line, const String& file)
00081 {
00082 std::vector<String> tokens;
00083 line.split(" \t",tokens,true);
00084
00085 if (!tokens.empty())
00086 {
00087 tokens.erase(tokens.begin());
00088 mFileName = tokens.back();
00089 }
00090 for(int i=0; i<(int)tokens.size(); ++i)
00091 {
00092 if (tokens[i] == "-blendu")
00093 {
00094 mBlendU = tokens[i+1] == "on";
00095 ++i;
00096 }
00097 else
00098 if (tokens[i] == "-blendv")
00099 {
00100 mBlendV = tokens[i+1] == "on";
00101 ++i;
00102 }
00103 else
00104 if (tokens[i] == "-cc")
00105 {
00106 mCC = tokens[i+1] == "on";
00107 ++i;
00108 }
00109 else
00110 if (tokens[i] == "-clamp")
00111 {
00112 mClamp = tokens[i+1] == "on";
00113 ++i;
00114 }
00115 else
00116 if (tokens[i] == "-mm")
00117 {
00118 mMM_Base = (float)tokens[i+1].toDouble();
00119 mMM_Gain = (float)tokens[i+2].toDouble();
00120 i+=2;
00121 }
00122 else
00123 if (tokens[i] == "-o")
00124 {
00125 mO_UVW[0] = (float)tokens[i+1].toDouble();
00126 mO_UVW[1] = (float)tokens[i+2].toDouble();
00127 mO_UVW[2] = (float)tokens[i+3].toDouble();
00128 i+=3;
00129 }
00130 else
00131 if (tokens[i] == "-s")
00132 {
00133 mS_UVW[0] = (float)tokens[i+1].toDouble();
00134 mS_UVW[1] = (float)tokens[i+2].toDouble();
00135 mS_UVW[2] = (float)tokens[i+3].toDouble();
00136 i+=3;
00137 }
00138 else
00139 if (tokens[i] == "-t")
00140 {
00141 mT_UVW[0] = (float)tokens[i+1].toDouble();
00142 mT_UVW[1] = (float)tokens[i+2].toDouble();
00143 mT_UVW[2] = (float)tokens[i+3].toDouble();
00144 i+=3;
00145 }
00146 else
00147 if (tokens[i] == "-texres")
00148 {
00149 mTexres_Value = (float)tokens[i+1].toDouble();
00150 ++i;
00151 }
00152 else
00153 if (tokens[i] == "-imfchan")
00154 {
00155 mImfchan = (unsigned char)tokens[i+1][0];
00156 ++i;
00157 }
00158 else
00159 if (tokens[i] == "-bm")
00160 {
00161 mBM = (float)tokens[i+1].toDouble();
00162 ++i;
00163 }
00164 else
00165 {
00166 if ( i != (int)tokens.size()-1 )
00167 Log::error( Say("Unknown map option '%s' in file '%s'.\n") << tokens[i] << file );
00168 }
00169 }
00170 return *this;
00171 }
00172
00173 void ObjTexture::print()
00174 {
00175 Log::print(
00176 Say("-blendu %s -blendv %s -cc %s -clamp %s -mm %n %n -o %n %n %n -s %n %n %n -t %n %n %n -texres %n -imfchan '%c' -bm %n %s\n")
00177 << (mBlendU ? "on" : "off")
00178 << (mBlendV ? "on" : "off")
00179 << (mCC ? "on" : "off")
00180 << (mClamp ? "on" : "off")
00181 << mMM_Base << mMM_Gain
00182 << mO_UVW[0] << mO_UVW[1] << mO_UVW[2]
00183 << mS_UVW[0] << mS_UVW[1] << mS_UVW[2]
00184 << mT_UVW[0] << mT_UVW[1] << mT_UVW[2]
00185 << mTexres_Value
00186 << mImfchan
00187 << mBM
00188 << mFileName.toStdString().c_str()
00189 );
00190 }
00191
00192
00193
00194 void ObjLoader::loadObjMaterials(VirtualFile* input, std::vector<ObjMaterial>& materials )
00195 {
00196 ref<TextStream> line_reader = new TextStream(input);
00197
00198 String line;
00199 String file = input->path();
00200 while(line_reader->readLine(line))
00201 {
00202 line = line.trim();
00203 if (line.empty() || line[0] == '#')
00204 continue;
00205 else
00206 {
00207 if (line.startsWith("newmtl"))
00208 {
00209 materials.push_back(ObjMaterial());
00210 materials.back().setObjectName( line.field(' ', 1).toStdString().c_str() );
00211 }
00212 else
00213 if (line.startsWith("Ns"))
00214 {
00215 materials.back().setNs (line.field(' ', 1).toFloat());
00216 }
00217 else
00218 if (line.startsWith("Ka"))
00219 {
00220 fvec3 col;
00221 col.r() = (float)line.field(' ', 1).toDouble();
00222 col.g() = (float)line.field(' ', 2).toDouble();
00223 col.b() = (float)line.field(' ', 3).toDouble();
00224 materials.back().setKa(col);
00225 }
00226 else
00227 if (line.startsWith("Kd"))
00228 {
00229 fvec3 col;
00230 col.r() = (float)line.field(' ', 1).toDouble();
00231 col.g() = (float)line.field(' ', 2).toDouble();
00232 col.b() = (float)line.field(' ', 3).toDouble();
00233 materials.back().setKd(col);
00234 }
00235 else
00236 if (line.startsWith("Ks"))
00237 {
00238 fvec3 col;
00239 col.r() = (float)line.field(' ', 1).toDouble();
00240 col.g() = (float)line.field(' ', 2).toDouble();
00241 col.b() = (float)line.field(' ', 3).toDouble();
00242 materials.back().setKs(col);
00243 }
00244 else
00245 if (line.startsWith("Ke"))
00246 {
00247 fvec3 col;
00248 col.r() = (float)line.field(' ', 1).toDouble();
00249 col.g() = (float)line.field(' ', 2).toDouble();
00250 col.b() = (float)line.field(' ', 3).toDouble();
00251 materials.back().setKe(col);
00252 }
00253 else
00254 if (line.startsWith("Tf"))
00255 {
00256
00257 }
00258 else
00259 if (line.startsWith("Ni"))
00260 {
00261 materials.back().setNi(line.field(' ', 1).toFloat());
00262 }
00263 else
00264 if (line.startsWith("d") || line.startsWith("Tr"))
00265 {
00266 materials.back().setTr(line.field(' ', 1).toFloat());
00267 }
00268 else
00269 if (line.startsWith("illum"))
00270 {
00271 materials.back().setIllum(line.field(' ', 1).toInt());
00272 }
00273 else
00274 if (line.startsWith("map_Kd"))
00275 materials.back().setMap_Kd(ObjTexture().parseLine(line,file));
00276 else
00277 if (line.startsWith("map_Ks"))
00278 materials.back().setMap_Ks(ObjTexture().parseLine(line,file));
00279 else
00280 if (line.startsWith("map_Ka"))
00281 materials.back().setMap_Ka(ObjTexture().parseLine(line,file));
00282 else
00283 if (line.startsWith("map_Ns"))
00284 materials.back().setMap_Ns(ObjTexture().parseLine(line,file));
00285 else
00286 if (line.startsWith("map_d"))
00287 materials.back().setMap_d(ObjTexture().parseLine(line,file));
00288 else
00289 if (line.startsWith("decal"))
00290 materials.back().setMap_Decal(ObjTexture().parseLine(line,file));
00291 else
00292 if (line.startsWith("disp"))
00293 materials.back().setMap_Disp(ObjTexture().parseLine(line,file));
00294 else
00295 if (line.startsWith("bump") || line.startsWith("map_bump"))
00296 materials.back().setMap_Bump(ObjTexture().parseLine(line,file));
00297 else
00298 Log::error( Say("Unknown field '%s' in file %s'.\n") << line << file );
00299 }
00300 }
00301 }
00302
00303 ref<ResourceDatabase> ObjLoader::loadOBJ( VirtualFile* file )
00304 {
00305 if (!file)
00306 {
00307 Log::error("loadOBJ() called with NULL argument.\n");
00308 return NULL;
00309 }
00310 ref<TextStream> stream = new TextStream(file);
00311 if ( !stream->inputFile()->open(OM_ReadOnly) )
00312 {
00313 Log::error( Say("loadOBJ(): could not open source file.\n") );
00314 return NULL;
00315 }
00316
00317 mCoords.clear();
00318
00319
00320 std::map< std::string, ref<ObjMaterial> > mMaterials;
00321 std::vector< ref<ObjMesh> > mMeshes;
00322
00323 ref<ObjMaterial> cur_material;
00324 ref<ObjMesh> cur_mesh;
00325
00326 const int BUF_SIZE = 1024;
00327 char cmd[BUF_SIZE];
00328
00329 int line_count = 0;
00330 int f_format_type = 0;
00331 std::string object_name;
00332 bool starts_new_geom = true;
00333 #if 0
00334 bool smoothing_group = false;
00335 #endif
00336
00337 std::string stdstr_line;
00338 while( stream->readLine(stdstr_line) )
00339 {
00340 ++line_count;
00341 std::string line = String::trimStdString(stdstr_line);
00342 if (line.empty() || line[0] == '#')
00343 continue;
00344
00345
00346 while( line[line.length()-1] == '\\' && stream->readLine(stdstr_line) )
00347 {
00348 ++line_count;
00349
00350 line[line.length()-1] = ' ';
00351
00352 line = String::trimStdString(line) + ' ';
00353
00354 line += String::trimStdString(stdstr_line);
00355 }
00356
00357 cmd[0] = 0;
00358 sscanf(line.c_str(), "%s ", cmd);
00359 if ( !cmd[0] )
00360 continue;
00361
00362
00363 if (strcmp(cmd,"v") == 0)
00364 {
00365 float x=0,y=0,z=0,w=1.0f;
00366 sscanf(line.c_str()+2,"%f %f %f", &x, &y, &z);
00367 append(mCoords,fvec4(x,y,z,w));
00368
00369
00370
00371
00372 }
00373 else
00374 if (strcmp(cmd,"vt") == 0)
00375 {
00376
00377 float x=0,y=0,z=0;
00378 sscanf(line.c_str()+3,"%f %f %f", &x, &y, &z);
00379 append(mTexCoords,fvec3(x,y,z));
00380
00381
00382
00383 }
00384 else
00385 if (strcmp(cmd,"vn") == 0)
00386 {
00387 float x=0,y=0,z=0;
00388 sscanf(line.c_str()+3,"%f %f %f", &x, &y, &z);
00389 append(mNormals,fvec3(x,y,z));
00390
00391
00392
00393 }
00394 else
00395
00396
00397
00398
00399
00400
00401 if (strcmp(cmd,"f") == 0)
00402 {
00403
00404 if (starts_new_geom)
00405 {
00406 cur_mesh = new ObjMesh;
00407 cur_mesh->setObjectName(object_name.c_str());
00408 mMeshes.push_back( cur_mesh );
00409 starts_new_geom = false;
00410 cur_mesh->setMaterial(cur_material.get());
00411
00412
00413
00414 int i=1;
00415 while( line[i] == ' ' || line[i] == '\t' ) ++i;
00416 int slash1 = 0;
00417 int slash2 = 0;
00418 while( i < (int)line.size() && line[i] != ' ' && line[i] != '\t' )
00419 {
00420 if (line[i] == '/')
00421 {
00422 if (!slash1)
00423 slash1 = i;
00424 else
00425 if (!slash2)
00426 {
00427 slash2 = i;
00428 break;
00429 }
00430 }
00431 ++i;
00432 }
00433 if (!slash1 && !slash2)
00434 f_format_type = 0;
00435 else
00436 if (slash1 && !slash2)
00437 f_format_type = 1;
00438 else
00439 {
00440 VL_CHECK(slash1)
00441 VL_CHECK(slash2)
00442 if (slash2 == slash1+1)
00443 f_format_type = 2;
00444 else
00445 f_format_type = 3;
00446 }
00447 }
00448
00449 int face_type = 0;
00450
00451 for(size_t i=0; i < line.size(); ++i)
00452 {
00453 if (line[i] == ' ')
00454 {
00455 ++face_type;
00456
00457
00458 while( line[i] == ' ' )
00459 ++i;
00460
00461 if (line[i] == 0)
00462 break;
00463
00464 int iv=-1,ivt=-1,ivn=-1;
00465
00466
00467
00468
00469 switch(f_format_type)
00470 {
00471 case 0:
00472 sscanf(line.c_str()+i, "%d", &iv);
00473 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00474 append(cur_mesh->facePositionIndex(), iv);
00475 break;
00476 case 1:
00477 sscanf(line.c_str()+i, "%d/%d", &iv,&ivt);
00478 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00479 if (ivt>0) --ivt; else ivt = (int)mTexCoords.size() - ivt;
00480 append(cur_mesh->facePositionIndex(), iv);
00481 append(cur_mesh->faceTexCoordIndex(), ivt);
00482 break;
00483 case 2:
00484 sscanf(line.c_str()+i, "%d//%d", &iv,&ivn);
00485 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00486 if (ivn>0) --ivn; else ivn = (int)mNormals.size() - ivn;
00487 append(cur_mesh->facePositionIndex(), iv);
00488 append(cur_mesh->faceNormalIndex(), ivn);
00489 break;
00490 case 3:
00491 sscanf(line.c_str()+i, "%d/%d/%d", &iv,&ivt,&ivn);
00492 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00493 if (ivt>0) --ivt; else ivt = (int)mTexCoords.size() - ivt;
00494 if (ivn>0) --ivn; else ivn = (int)mNormals.size() - ivn;
00495 append(cur_mesh->facePositionIndex(), iv);
00496 append(cur_mesh->faceTexCoordIndex(), ivt);
00497 append(cur_mesh->faceNormalIndex(), ivn);
00498 break;
00499 default:
00500 break;
00501 }
00502 }
00503 }
00504 VL_CHECK(face_type > 2)
00505
00506 append(cur_mesh->face_type(), face_type);
00507 }
00508 else
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 if (strcmp(cmd,"s") == 0)
00585 {
00586
00587 #if 0
00588 if(String::trim(line+1) == "off" || String::trim(line+1) == "0")
00589 smoothing_group = false;
00590 else
00591 smoothing_group = true;
00592 #endif
00593 }
00594 else
00595
00596
00597
00598
00599 if (strcmp(cmd,"o") == 0)
00600 {
00601 starts_new_geom = true;
00602 object_name = String::trimStdString(line.c_str()+1);
00603 }
00604 else
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (strcmp(cmd,"usemtl") == 0)
00624 {
00625 starts_new_geom = true;
00626 std::string mat_name = String(line.c_str()+6).trim().toStdString();
00627
00628 cur_material = mMaterials[mat_name];
00629 }
00630 else
00631 if (strcmp(cmd,"mtllib") == 0)
00632 {
00633
00634 String path = file->path().extractPath() + String(line.c_str()+7).trim();
00635 ref<VirtualFile> vfile = defFileSystem()->locateFile(path, file->path().extractPath());
00636 std::string str_file = file->path().toStdString();
00637 std::string str_path = path.toStdString();
00638 if (vfile)
00639 {
00640
00641 std::vector<ObjMaterial> mats;
00642 loadObjMaterials(vfile.get(), mats);
00643
00644 for(size_t i=0; i < mats.size(); ++i)
00645 mMaterials[mats[i].objectName()] = new ObjMaterial(mats[i]);
00646 }
00647 else
00648 {
00649 Log::error( Say("Could not find OBJ material file '%s'.\n") << path );
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 }
00669
00670 ref<ResourceDatabase> res_db = new ResourceDatabase;
00671
00672
00673
00674 std::map< ObjMaterial*, ref<Effect> > material_map;
00675 for (std::map< std::string, ref<ObjMaterial> >::iterator it = mMaterials.begin();
00676 it != mMaterials.end();
00677 ++it)
00678 {
00679 ref<Effect> effect = new Effect;
00680 res_db->resources().push_back(effect.get());
00681
00682 ref<ObjMaterial> obj_mat = it->second;
00683 material_map[it->second.get()] = effect;
00684 res_db->resources().push_back(effect);
00685
00686 effect->shader()->enable(EN_DEPTH_TEST);
00687 effect->shader()->disable(EN_CULL_FACE);
00688 effect->shader()->enable(EN_LIGHTING);
00689 effect->shader()->gocLightModel()->setTwoSide(true);
00690
00691 if (obj_mat)
00692 {
00693
00694 effect->shader()->gocMaterial()->setObjectName(obj_mat->objectName().c_str());
00695
00696 res_db->resources().push_back(effect->shader()->gocMaterial());
00697
00698 fvec4 diffuse = fvec4( obj_mat->kd(), 1.0f - obj_mat->tr() );
00699 fvec4 ambient = fvec4( obj_mat->ka(), 1.0f - obj_mat->tr() );
00700 fvec4 specular = fvec4( obj_mat->ks(), 1.0f - obj_mat->tr() );
00701 fvec4 emission = fvec4( obj_mat->ke(), 1.0f - obj_mat->tr() );
00702 effect->shader()->gocMaterial()->setDiffuse( diffuse );
00703 effect->shader()->gocMaterial()->setAmbient( ambient );
00704 effect->shader()->gocMaterial()->setSpecular( specular );
00705 effect->shader()->gocMaterial()->setEmission( emission );
00706 effect->shader()->gocMaterial()->setShininess( obj_mat->ns());
00707
00708
00709 if (obj_mat->tr() > 0 || obj_mat->map_d().valid())
00710 {
00711 effect->shader()->enable(EN_BLEND);
00712
00713
00714 if ( obj_mat->map_d().valid() )
00715 {
00716 effect->shader()->gocAlphaFunc()->set(FU_GEQUAL, 0.5);
00717 effect->shader()->enable(EN_ALPHA_TEST);
00718
00719
00720 }
00721 else
00722 {
00723 effect->shader()->enable(EN_CULL_FACE);
00724 effect->shader()->gocLightModel()->setTwoSide(false);
00725 }
00726 }
00727
00728
00729 if (obj_mat->map_Kd().valid())
00730 {
00731
00732 ref<VirtualFile> diff_file = defFileSystem()->locateFile(obj_mat->map_Kd().path(), file->path().extractPath());
00733 ref<Image> diff_img;
00734 if (diff_file)
00735 diff_img = loadImage( diff_file.get() );
00736
00737
00738 if (obj_mat->map_d().valid())
00739 {
00740 ref<VirtualFile> mask_file = defFileSystem()->locateFile(obj_mat->map_d().path(), file->path().extractPath());
00741 ref<Image> mask_img;
00742 if (mask_file)
00743 mask_img = loadImage( mask_file.get() );
00744 if (mask_img)
00745 {
00746 if (mask_img->width() == diff_img->width() && mask_img->height() == diff_img->height())
00747 {
00748 diff_img = diff_img->convertFormat(IF_RGBA); VL_CHECK(diff_img)
00749 diff_img = diff_img->convertType(IT_UNSIGNED_BYTE); VL_CHECK(diff_img)
00750 mask_img = mask_img->convertType(IT_UNSIGNED_BYTE);
00751 int bpp = mask_img->bitsPerPixel() / 8;
00752 unsigned char* mask_px = mask_img->pixels();
00753 unsigned char* mask_end = mask_img->pixels() + mask_img->requiredMemory();
00754 unsigned char* diff_px = diff_img->pixels() + 3;
00755 while( mask_px != mask_end )
00756 {
00757 diff_px[0] = mask_px[0];
00758 mask_px += bpp;
00759 diff_px += 4;
00760 }
00761 }
00762 }
00763 }
00764
00765 if ( diff_img )
00766 {
00767 ref<Texture> texture = new Texture;
00768 texture->getTexParameter()->setMinFilter(TPF_LINEAR_MIPMAP_LINEAR);
00769 texture->getTexParameter()->setMagFilter(TPF_LINEAR);
00770 texture->prepareTexture2D( diff_img.get(), TF_RGBA, true );
00771 effect->shader()->gocTextureSampler(0)->setTexture( texture.get() );
00772 }
00773 }
00774 }
00775 }
00776
00777 for(int imesh=0; imesh<(int)mMeshes.size(); ++imesh)
00778 {
00779 if ( mMeshes[imesh]->facePositionIndex().empty() )
00780 {
00781 Log::warning("OBJ mesh empty.\n");
00782 VL_TRAP()
00783 continue;
00784 }
00785
00786 #ifndef NDEBUG
00787 int sum = 0;
00788 for(int k=0; k<(int)mMeshes[imesh]->face_type().size(); ++k)
00789 sum += mMeshes[imesh]->face_type()[k];
00790 VL_CHECK( sum == (int)mMeshes[imesh]->facePositionIndex().size() )
00791 #endif
00792
00793 ref< ArrayFloat3 > v_coords = new ArrayFloat3;
00794 ref< ArrayFloat3 > n_coords = new ArrayFloat3;
00795
00796 ref< ArrayFloat2 > t_coords2 = new ArrayFloat2;
00797
00798 if ( !mMeshes[imesh]->faceNormalIndex().empty() && mMeshes[imesh]->faceNormalIndex().size() != mMeshes[imesh]->facePositionIndex().size() )
00799 {
00800 Log::print("OBJ mesh corrupted.\n");
00801 continue;
00802 }
00803
00804 if ( !mMeshes[imesh]->faceTexCoordIndex().empty() && mMeshes[imesh]->faceTexCoordIndex().size() != mMeshes[imesh]->facePositionIndex().size() )
00805 {
00806 Log::print("OBJ mesh corrupted.\n");
00807 continue;
00808 }
00809
00810
00811
00812 int tri_verts_count = 0;
00813 for(int k=0; k<(int)mMeshes[imesh]->face_type().size(); ++k)
00814 tri_verts_count += (mMeshes[imesh]->face_type()[k] - 2) * 3;
00815
00816 v_coords->resize( tri_verts_count );
00817 if ( !mMeshes[imesh]->faceNormalIndex().empty() )
00818 n_coords->resize( tri_verts_count );
00819 if ( !mMeshes[imesh]->faceTexCoordIndex().empty() )
00820 t_coords2->resize( tri_verts_count );
00821
00822
00823
00824 int src_base_idx = 0;
00825 int dst_base_idx = 0;
00826 for(int iface=0; iface<(int)mMeshes[imesh]->face_type().size(); ++iface)
00827 {
00828 int type = mMeshes[imesh]->face_type()[iface];
00829 for( int ivert=2; ivert < type; ++ivert )
00830 {
00831 int a = mMeshes[imesh]->facePositionIndex()[src_base_idx+0];
00832 int b = mMeshes[imesh]->facePositionIndex()[src_base_idx+ivert-1];
00833 int c = mMeshes[imesh]->facePositionIndex()[src_base_idx+ivert];
00834
00835 VL_CHECK( a>= 0)
00836 VL_CHECK( b>= 0)
00837 VL_CHECK( c>= 0)
00838 VL_CHECK( a<(int)mCoords.size() )
00839 VL_CHECK( b<(int)mCoords.size() )
00840 VL_CHECK( c<(int)mCoords.size() )
00841
00842 v_coords->at(dst_base_idx+0) = mCoords[a].xyz();
00843 v_coords->at(dst_base_idx+1) = mCoords[b].xyz();
00844 v_coords->at(dst_base_idx+2) = mCoords[c].xyz();
00845
00846 if (!mMeshes[imesh]->faceNormalIndex().empty())
00847 {
00848 int na = mMeshes[imesh]->faceNormalIndex()[src_base_idx+0];
00849 int nb = mMeshes[imesh]->faceNormalIndex()[src_base_idx+ivert-1];
00850 int nc = mMeshes[imesh]->faceNormalIndex()[src_base_idx+ivert];
00851
00852 VL_CHECK( na>= 0)
00853 VL_CHECK( nb>= 0)
00854 VL_CHECK( nc>= 0)
00855 VL_CHECK( na<(int)mNormals.size() )
00856 VL_CHECK( nb<(int)mNormals.size() )
00857 VL_CHECK( nc<(int)mNormals.size() )
00858
00859 n_coords->at(dst_base_idx+0) = mNormals[na];
00860 n_coords->at(dst_base_idx+1) = mNormals[nb];
00861 n_coords->at(dst_base_idx+2) = mNormals[nc];
00862 }
00863
00864
00865 if (!mMeshes[imesh]->faceTexCoordIndex().empty())
00866 {
00867 int na = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+0];
00868 int nb = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+ivert-1];
00869 int nc = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+ivert];
00870
00871 VL_CHECK( na>= 0)
00872 VL_CHECK( nb>= 0)
00873 VL_CHECK( nc>= 0)
00874 VL_CHECK( na<(int)mTexCoords.size() )
00875 VL_CHECK( nb<(int)mTexCoords.size() )
00876 VL_CHECK( nc<(int)mTexCoords.size() )
00877
00878 t_coords2->at(dst_base_idx+0) = mTexCoords[na].st();
00879 t_coords2->at(dst_base_idx+1) = mTexCoords[nb].st();
00880 t_coords2->at(dst_base_idx+2) = mTexCoords[nc].st();
00881 }
00882
00883 dst_base_idx+=3;
00884 }
00885 src_base_idx += type;
00886 }
00887
00888
00889
00890 ref<Geometry> geom = new Geometry;
00891 geom->setObjectName(mMeshes[imesh]->objectName().c_str());
00892 geom->setVertexArray( v_coords.get() );
00893 if ( mMeshes[imesh]->faceNormalIndex().size() )
00894 geom->setNormalArray( n_coords.get() );
00895 if ( mMeshes[imesh]->faceTexCoordIndex().size() )
00896 geom->setTexCoordArray(0, t_coords2.get() );
00897 geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, 0, tri_verts_count) );
00898
00899
00900
00901 ref<Effect> effect = material_map[ mMeshes[imesh]->material() ];
00902 if (!effect)
00903 {
00904 effect = material_map[ mMeshes[imesh]->material() ] = new Effect;
00905 res_db->resources().push_back(effect.get());
00906
00907 effect->shader()->enable(EN_DEPTH_TEST);
00908 effect->shader()->disable(EN_CULL_FACE);
00909 effect->shader()->enable(EN_LIGHTING);
00910 effect->shader()->gocLightModel()->setTwoSide(true);
00911 }
00912 VL_CHECK(effect)
00913
00914
00915 ref<Actor> actor = new Actor(geom.get(), NULL);
00916 res_db->resources().push_back(actor);
00917 actor->setObjectName(mMeshes[imesh]->objectName().c_str());
00918 actor->setEffect(effect.get());
00919 }
00920
00921 stream->inputFile()->close();
00922
00923 return res_db;
00924 }
00925
00926 ref<ResourceDatabase> vl::loadOBJ( const String& path )
00927 {
00928 ref<VirtualFile> file = defFileSystem()->locateFile( path );
00929 if (file)
00930 return loadOBJ( file.get() );
00931 else
00932 {
00933 Log::error( Say("Could not locate '%s'.\n") << path );
00934 return NULL;
00935 }
00936 }
00937
00938 ref<ResourceDatabase> vl::loadOBJ( VirtualFile* file )
00939 {
00940 return ObjLoader().loadOBJ(file);
00941 }
00942