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 "vlOBJ.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() );
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"))
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
00318 mCoords.clear();
00319
00320
00321 std::map< std::string, ref<ObjMaterial> > mMaterials;
00322 std::vector< ref<ObjMesh> > mMeshes;
00323
00324 ref<ObjMaterial> cur_material;
00325 ref<ObjMesh> cur_mesh;
00326
00327 const int BUF_SIZE = 1024;
00328 char cmd[BUF_SIZE];
00329
00330 int line_count = 0;
00331 int f_format_type = 0;
00332 std::string object_name;
00333 bool starts_new_geom = true;
00334 #if 0
00335 bool smoothing_group = false;
00336 #endif
00337
00338 std::string stdstr_line;
00339 while( stream->readLine(stdstr_line) )
00340 {
00341 ++line_count;
00342 std::string line = String::trimStdString(stdstr_line);
00343 if (line.empty() || line[0] == '#')
00344 continue;
00345
00346
00347 while( line[line.length()-1] == '\\' && stream->readLine(stdstr_line) )
00348 {
00349 ++line_count;
00350
00351 line[line.length()-1] = ' ';
00352
00353 line = String::trimStdString(line) + ' ';
00354
00355 line += String::trimStdString(stdstr_line);
00356 }
00357
00358 cmd[0] = 0;
00359 sscanf(line.c_str(), "%s ", cmd);
00360 if ( !cmd[0] )
00361 continue;
00362
00363
00364 if (strcmp(cmd,"v") == 0)
00365 {
00366 float x=0,y=0,z=0,w=1.0f;
00367 sscanf(line.c_str()+2,"%f %f %f", &x, &y, &z);
00368 append(mCoords,fvec4(x,y,z,w));
00369
00370
00371
00372
00373 }
00374 else
00375 if (strcmp(cmd,"vt") == 0)
00376 {
00377
00378 float x=0,y=0,z=0;
00379 sscanf(line.c_str()+3,"%f %f %f", &x, &y, &z);
00380 append(mTexCoords,fvec3(x,y,z));
00381
00382
00383
00384 }
00385 else
00386 if (strcmp(cmd,"vn") == 0)
00387 {
00388 float x=0,y=0,z=0;
00389 sscanf(line.c_str()+3,"%f %f %f", &x, &y, &z);
00390 append(mNormals,fvec3(x,y,z));
00391
00392
00393
00394 }
00395 else
00396
00397
00398
00399
00400
00401
00402 if (strcmp(cmd,"f") == 0)
00403 {
00404
00405 if (starts_new_geom)
00406 {
00407 cur_mesh = new ObjMesh;
00408 cur_mesh->setObjectName(object_name);
00409 mMeshes.push_back( cur_mesh );
00410 starts_new_geom = false;
00411 cur_mesh->setMaterial(cur_material.get());
00412
00413
00414
00415 int i=1;
00416 while( line[i] == ' ' || line[i] == '\t' ) ++i;
00417 int slash1 = 0;
00418 int slash2 = 0;
00419 while( i < (int)line.size() && line[i] != ' ' && line[i] != '\t' )
00420 {
00421 if (line[i] == '/')
00422 {
00423 if (!slash1)
00424 slash1 = i;
00425 else
00426 if (!slash2)
00427 {
00428 slash2 = i;
00429 break;
00430 }
00431 }
00432 ++i;
00433 }
00434 if (!slash1 && !slash2)
00435 f_format_type = 0;
00436 else
00437 if (slash1 && !slash2)
00438 f_format_type = 1;
00439 else
00440 {
00441 VL_CHECK(slash1)
00442 VL_CHECK(slash2)
00443 if (slash2 == slash1+1)
00444 f_format_type = 2;
00445 else
00446 f_format_type = 3;
00447 }
00448 }
00449
00450 int face_type = 0;
00451
00452 for(size_t i=0; i < line.size(); ++i)
00453 {
00454 if (line[i] == ' ')
00455 {
00456 ++face_type;
00457
00458
00459 while( line[i] == ' ' )
00460 ++i;
00461
00462 if (line[i] == 0)
00463 break;
00464
00465 int iv=-1,ivt=-1,ivn=-1;
00466
00467
00468
00469
00470 switch(f_format_type)
00471 {
00472 case 0:
00473 sscanf(line.c_str()+i, "%d", &iv);
00474 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00475 append(cur_mesh->facePositionIndex(), iv);
00476 break;
00477 case 1:
00478 sscanf(line.c_str()+i, "%d/%d", &iv,&ivt);
00479 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00480 if (ivt>0) --ivt; else ivt = (int)mTexCoords.size() - ivt;
00481 append(cur_mesh->facePositionIndex(), iv);
00482 append(cur_mesh->faceTexCoordIndex(), ivt);
00483 break;
00484 case 2:
00485 sscanf(line.c_str()+i, "%d//%d", &iv,&ivn);
00486 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00487 if (ivn>0) --ivn; else ivn = (int)mNormals.size() - ivn;
00488 append(cur_mesh->facePositionIndex(), iv);
00489 append(cur_mesh->faceNormalIndex(), ivn);
00490 break;
00491 case 3:
00492 sscanf(line.c_str()+i, "%d/%d/%d", &iv,&ivt,&ivn);
00493 if (iv>0) --iv; else iv = (int)mCoords.size() - iv;
00494 if (ivt>0) --ivt; else ivt = (int)mTexCoords.size() - ivt;
00495 if (ivn>0) --ivn; else ivn = (int)mNormals.size() - ivn;
00496 append(cur_mesh->facePositionIndex(), iv);
00497 append(cur_mesh->faceTexCoordIndex(), ivt);
00498 append(cur_mesh->faceNormalIndex(), ivn);
00499 break;
00500 default:
00501 break;
00502 }
00503 }
00504 }
00505 VL_CHECK(face_type > 2)
00506
00507 append(cur_mesh->face_type(), face_type);
00508 }
00509 else
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
00585 if (strcmp(cmd,"s") == 0)
00586 {
00587
00588 #if 0
00589 if(String::trim(line+1) == "off" || String::trim(line+1) == "0")
00590 smoothing_group = false;
00591 else
00592 smoothing_group = true;
00593 #endif
00594 }
00595 else
00596
00597
00598
00599
00600 if (strcmp(cmd,"o") == 0)
00601 {
00602 starts_new_geom = true;
00603 object_name = String::trimStdString(line.c_str()+1);
00604 }
00605 else
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 if (strcmp(cmd,"usemtl") == 0)
00625 {
00626 starts_new_geom = true;
00627 std::string mat_name = String(line.c_str()+6).trim().toStdString();
00628
00629 cur_material = mMaterials[mat_name];
00630 }
00631 else
00632 if (strcmp(cmd,"mtllib") == 0)
00633 {
00634
00635 String path = file->path().extractPath() + String(line.c_str()+7).trim();
00636 ref<VirtualFile> vfile = defFileSystem()->locateFile(path, file->path().extractPath());
00637 std::string str_file = file->path().toStdString();
00638 std::string str_path = path.toStdString();
00639 if (vfile)
00640 {
00641
00642 std::vector<ObjMaterial> mats;
00643 loadObjMaterials(vfile.get(), mats);
00644
00645 for(size_t i=0; i < mats.size(); ++i)
00646 mMaterials[mats[i].objectName()] = new ObjMaterial(mats[i]);
00647 }
00648 else
00649 {
00650 Log::error( Say("Could not find OBJ material file '%s'.\n") << path );
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 }
00670
00671 ref<ResourceDatabase> res_db = new ResourceDatabase;
00672
00673
00674
00675 std::map< ObjMaterial*, ref<Effect> > material_map;
00676 for (std::map< std::string, ref<ObjMaterial> >::iterator it = mMaterials.begin();
00677 it != mMaterials.end();
00678 ++it)
00679 {
00680 ref<Effect> effect = new Effect;
00681 res_db->resources().push_back(effect.get());
00682
00683 ref<ObjMaterial> obj_mat = it->second;
00684 material_map[it->second.get()] = effect;
00685 res_db->resources().push_back(effect);
00686
00687 effect->shader()->enable(EN_DEPTH_TEST);
00688 effect->shader()->disable(EN_CULL_FACE);
00689 effect->shader()->gocLightModel()->setTwoSide(true);
00690
00691 if (obj_mat)
00692 {
00693
00694 effect->shader()->gocMaterial()->setObjectName(obj_mat->objectName());
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 if (obj_mat->tr() < 1.0f)
00709 {
00710 effect->shader()->enable(EN_BLEND);
00711 effect->shader()->enable(EN_CULL_FACE);
00712 effect->shader()->gocLightModel()->setTwoSide(false);
00713 }
00714
00715 if (obj_mat->map_Kd().valid())
00716 {
00717 ref<Texture> texture = new Texture;
00718
00719 String tex_path = obj_mat->map_Kd().path();
00720 ref<VirtualFile> tex_file = defFileSystem()->locateFile(obj_mat->map_Kd().path(),file->path().extractPath());
00721 if (tex_file)
00722 tex_path = tex_file->path();
00723 texture->prepareTexture2D( tex_path, TF_RGBA );
00724 effect->shader()->gocTexEnv(0)->setMode(TEM_DECAL);
00725 effect->shader()->gocTextureUnit(0)->setTexture( texture.get() );
00726 }
00727 }
00728 }
00729
00730 for(int imesh=0; imesh<(int)mMeshes.size(); ++imesh)
00731 {
00732 if ( mMeshes[imesh]->facePositionIndex().empty() )
00733 {
00734 Log::warning("OBJ mesh empty.\n");
00735 VL_TRAP()
00736 continue;
00737 }
00738
00739 #ifndef NDEBUG
00740 int sum = 0;
00741 for(int k=0; k<(int)mMeshes[imesh]->face_type().size(); ++k)
00742 sum += mMeshes[imesh]->face_type()[k];
00743 VL_CHECK( sum == (int)mMeshes[imesh]->facePositionIndex().size() )
00744 #endif
00745
00746 ref< ArrayFloat3 > v_coords = new ArrayFloat3;
00747 ref< ArrayFloat3 > n_coords = new ArrayFloat3;
00748
00749 ref< ArrayFloat2 > t_coords2 = new ArrayFloat2;
00750
00751 if ( !mMeshes[imesh]->faceNormalIndex().empty() && mMeshes[imesh]->faceNormalIndex().size() != mMeshes[imesh]->facePositionIndex().size() )
00752 {
00753 Log::print("OBJ mesh corrupted.\n");
00754 continue;
00755 }
00756
00757 if ( !mMeshes[imesh]->faceTexCoordIndex().empty() && mMeshes[imesh]->faceTexCoordIndex().size() != mMeshes[imesh]->facePositionIndex().size() )
00758 {
00759 Log::print("OBJ mesh corrupted.\n");
00760 continue;
00761 }
00762
00763
00764
00765 int tri_verts_count = 0;
00766 for(int k=0; k<(int)mMeshes[imesh]->face_type().size(); ++k)
00767 tri_verts_count += (mMeshes[imesh]->face_type()[k] - 2) * 3;
00768
00769 v_coords->resize( tri_verts_count );
00770 if ( !mMeshes[imesh]->faceNormalIndex().empty() )
00771 n_coords->resize( tri_verts_count );
00772 if ( !mMeshes[imesh]->faceTexCoordIndex().empty() )
00773 t_coords2->resize( tri_verts_count );
00774
00775
00776
00777 int src_base_idx = 0;
00778 int dst_base_idx = 0;
00779 for(int iface=0; iface<(int)mMeshes[imesh]->face_type().size(); ++iface)
00780 {
00781 int type = mMeshes[imesh]->face_type()[iface];
00782 for( int ivert=2; ivert < type; ++ivert )
00783 {
00784 int a = mMeshes[imesh]->facePositionIndex()[src_base_idx+0];
00785 int b = mMeshes[imesh]->facePositionIndex()[src_base_idx+ivert-1];
00786 int c = mMeshes[imesh]->facePositionIndex()[src_base_idx+ivert];
00787
00788 VL_CHECK( a>= 0)
00789 VL_CHECK( b>= 0)
00790 VL_CHECK( c>= 0)
00791 VL_CHECK( a<(int)mCoords.size() )
00792 VL_CHECK( b<(int)mCoords.size() )
00793 VL_CHECK( c<(int)mCoords.size() )
00794
00795 v_coords->at(dst_base_idx+0) = mCoords[a].xyz();
00796 v_coords->at(dst_base_idx+1) = mCoords[b].xyz();
00797 v_coords->at(dst_base_idx+2) = mCoords[c].xyz();
00798
00799 if (!mMeshes[imesh]->faceNormalIndex().empty())
00800 {
00801 int na = mMeshes[imesh]->faceNormalIndex()[src_base_idx+0];
00802 int nb = mMeshes[imesh]->faceNormalIndex()[src_base_idx+ivert-1];
00803 int nc = mMeshes[imesh]->faceNormalIndex()[src_base_idx+ivert];
00804
00805 VL_CHECK( na>= 0)
00806 VL_CHECK( nb>= 0)
00807 VL_CHECK( nc>= 0)
00808 VL_CHECK( na<(int)mNormals.size() )
00809 VL_CHECK( nb<(int)mNormals.size() )
00810 VL_CHECK( nc<(int)mNormals.size() )
00811
00812 n_coords->at(dst_base_idx+0) = mNormals[na];
00813 n_coords->at(dst_base_idx+1) = mNormals[nb];
00814 n_coords->at(dst_base_idx+2) = mNormals[nc];
00815 }
00816
00817
00818 if (!mMeshes[imesh]->faceTexCoordIndex().empty())
00819 {
00820 int na = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+0];
00821 int nb = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+ivert-1];
00822 int nc = mMeshes[imesh]->faceTexCoordIndex()[src_base_idx+ivert];
00823
00824 VL_CHECK( na>= 0)
00825 VL_CHECK( nb>= 0)
00826 VL_CHECK( nc>= 0)
00827 VL_CHECK( na<(int)mTexCoords.size() )
00828 VL_CHECK( nb<(int)mTexCoords.size() )
00829 VL_CHECK( nc<(int)mTexCoords.size() )
00830
00831 t_coords2->at(dst_base_idx+0) = mTexCoords[na].st();
00832 t_coords2->at(dst_base_idx+1) = mTexCoords[nb].st();
00833 t_coords2->at(dst_base_idx+2) = mTexCoords[nc].st();
00834 }
00835
00836 dst_base_idx+=3;
00837 }
00838 src_base_idx += type;
00839 }
00840
00841
00842
00843 ref<Geometry> geom = new Geometry;
00844 res_db->resources().push_back(geom);
00845
00846 geom->setObjectName(mMeshes[imesh]->objectName());
00847 geom->setVertexArray( v_coords.get() );
00848 if ( mMeshes[imesh]->faceNormalIndex().size() )
00849 geom->setNormalArray( n_coords.get() );
00850 if ( mMeshes[imesh]->faceTexCoordIndex().size() )
00851 geom->setTexCoordArray(0, t_coords2.get() );
00852 geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, 0, tri_verts_count) );
00853
00854
00855
00856 ref<Effect> effect = material_map[ mMeshes[imesh]->material() ];
00857 if (!effect)
00858 {
00859 effect = material_map[ mMeshes[imesh]->material() ] = new Effect;
00860 res_db->resources().push_back(effect.get());
00861
00862 effect->shader()->enable(EN_DEPTH_TEST);
00863 effect->shader()->disable(EN_CULL_FACE);
00864 effect->shader()->gocLightModel()->setTwoSide(true);
00865 }
00866 VL_CHECK(effect)
00867
00868
00869
00870 ref<Actor> actor = new Actor(geom.get(),NULL);
00871 res_db->resources().push_back(actor);
00872 actor->setObjectName(mMeshes[imesh]->objectName());
00873 actor->setEffect(effect.get());
00874 }
00875
00876 stream->inputFile()->close();
00877
00878
00879
00880
00881
00882
00883 return res_db;
00884 }
00885
00886 ref<ResourceDatabase> vl::loadOBJ( const String& path )
00887 {
00888 ref<VirtualFile> file = defFileSystem()->locateFile( path );
00889 if (file)
00890 return loadOBJ( file.get() );
00891 else
00892 {
00893 Log::error( Say("Could not locate '%s'.\n") << path );
00894 return NULL;
00895 }
00896 }
00897
00898 ref<ResourceDatabase> vl::loadOBJ( VirtualFile* file )
00899 {
00900 return ObjLoader().loadOBJ(file);
00901 }
00902