# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/plugins/vlOBJ.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    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    * Utility function
    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 // ObjTexture
    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 // loadObjMaterials
    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         // skip transmission filter
    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   /*Log::info( Say("Loading '%s'.\n") << file->path() );*/
    00317
    00318   mCoords.clear();
    00319   // std::vector<float> mNormals;
    00320   // std::vector<float> mTexCoords;
    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     // note: comments cannot be multiline
    00347     while( line[line.length()-1] == '\\' && stream->readLine(stdstr_line) )
    00348     {
    00349       ++line_count;
    00350       // remove "\"
    00351       line[line.length()-1] = ' ';
    00352       // remove spaces before \ and insert a single ' ' space
    00353       line = String::trimStdString(line) + ' ';
    00354       // appends new line
    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     // Vertex data:
    00364     if (strcmp(cmd,"v") == 0) // Geometric vertices
    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       /*append(mCoords,x);
    00370       append(mCoords,y);
    00371       append(mCoords,z);
    00372       append(mCoords,w);*/
    00373     }
    00374     else
    00375     if (strcmp(cmd,"vt") == 0) // Texture vertices
    00376     {
    00377       // note, this might have less than 3 mCoords
    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       /*append(mTexCoords,x);
    00382       append(mTexCoords,y);
    00383       append(mTexCoords,z);*/
    00384     }
    00385     else
    00386     if (strcmp(cmd,"vn") == 0) // Vertex mNormals
    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       /*append(mNormals,x);
    00392       append(mNormals,y);
    00393       append(mNormals,z);*/
    00394     }
    00395     else
    00396     /*if (strcmp(cmd,"vp") == 0) // Parameter space vertices
    00397     {
    00398     }
    00399     else*/
    00400 // ----------------------------------------------------------------------------
    00401     // Elements:
    00402     if (strcmp(cmd,"f") == 0) // Face
    00403     {
    00404       // starts new geometry if necessary
    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         // detect vertex format
    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       // divide into tokens
    00452       for(size_t i=0; i < line.size(); ++i)
    00453       {
    00454         if (line[i] == ' ')
    00455         {
    00456           ++face_type;
    00457
    00458           // eat all the spaces
    00459           while( line[i] == ' ' )
    00460             ++i;
    00461
    00462           if (line[i] == 0)
    00463             break;
    00464
    00465           int iv=-1,ivt=-1,ivn=-1;
    00466           // 0 = f v       v       v
    00467           // 1 = f v/vt    v/vt    v/vt
    00468           // 2 = f v//vn   v//vn   v//vn
    00469           // 3 = f v/vt/vn v/vt/vn v/vt/vn
    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       // track the face type in order to triangulate it later
    00507       append(cur_mesh->face_type(), face_type);
    00508     }
    00509     else
    00510     /*if (strcmp(cmd,"p") == 0) // Point
    00511     {
    00512     }
    00513     else
    00514     if (strcmp(cmd,"l") == 0) // Line
    00515     {
    00516     }
    00517     else
    00518     if (strcmp(cmd,"curv") == 0) // Curve
    00519     {
    00520     }
    00521     else
    00522     if (strcmp(cmd,"curv2") == 0) // 2D Curve
    00523     {
    00524     }
    00525     else
    00526     if (strcmp(cmd,"surf") == 0) // Surface
    00527     {
    00528     }
    00529     else
    00530 // ----------------------------------------------------------------------------
    00531     // Free-form curve/surface attributes:
    00532     if (strcmp(cmd,"deg") == 0) // Degree
    00533     {
    00534     }
    00535     else
    00536     if (strcmp(cmd,"bmat") == 0) // Basis matrix
    00537     {
    00538     }
    00539     else
    00540     if (strcmp(cmd,"step") == 0) // Step size
    00541     {
    00542     }
    00543     else
    00544     if (strcmp(cmd,"cstype") == 0) // Curve or surface type
    00545     {
    00546     }
    00547     else
    00548 // ----------------------------------------------------------------------------
    00549     // Free-form curve/surface body statements:
    00550     if (strcmp(cmd,"parm") == 0) // Parameter values
    00551     {
    00552     }
    00553     else
    00554     if (strcmp(cmd,"trim") == 0) // Outer trimming loop
    00555     {
    00556     }
    00557     else
    00558     if (strcmp(cmd,"hole") == 0) // Inner trimming loop
    00559     {
    00560     }
    00561     else
    00562     if (strcmp(cmd,"scrv") == 0) // Special curve
    00563     {
    00564     }
    00565     else
    00566     if (strcmp(cmd,"sp") == 0) // Special point
    00567     {
    00568     }
    00569     else
    00570     if (strcmp(cmd,"end") == 0) // End statement
    00571     {
    00572     }
    00573     else
    00574 // ----------------------------------------------------------------------------
    00575     // Connectivity between free-form surfaces:
    00576     if (strcmp(cmd,"con") == 0) // Connect
    00577     {
    00578     }
    00579     else
    00580     // Grouping:
    00581     if (strcmp(cmd,"g") == 0) // Group name
    00582     {
    00583     }
    00584     else*/
    00585     if (strcmp(cmd,"s") == 0) // Smoothing group
    00586     {
    00587       // not used
    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     /*if (strcmp(cmd,"mg") == 0) // Merging group
    00597     {
    00598     }
    00599     else*/
    00600     if (strcmp(cmd,"o") == 0) // Object name
    00601     {
    00602       starts_new_geom = true;
    00603       object_name = String::trimStdString(line.c_str()+1);
    00604     }
    00605     else
    00606 // ----------------------------------------------------------------------------
    00607     // Display/render attributes:
    00608     /*if (strcmp(cmd,"bevel") == 0) // Bevel interpolation
    00609     {
    00610     }
    00611     else
    00612     if (strcmp(cmd,"c_interp") == 0) // Color interpolation
    00613     {
    00614     }
    00615     else
    00616     if (strcmp(cmd,"d_interp") == 0) // Dissolve interpolation
    00617     {
    00618     }
    00619     else
    00620     if (strcmp(cmd,"lod") == 0) // Level of detail
    00621     {
    00622     }
    00623     else*/
    00624     if (strcmp(cmd,"usemtl") == 0) // Material name
    00625     {
    00626       starts_new_geom = true;
    00627       std::string mat_name = String(line.c_str()+6).trim().toStdString();
    00628       // can also become NULL
    00629       cur_material = mMaterials[mat_name];
    00630     }
    00631     else
    00632     if (strcmp(cmd,"mtllib") == 0) // Material library
    00633     {
    00634       // creates the path for the mtl
    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         // reads the material
    00642         std::vector<ObjMaterial> mats;
    00643         loadObjMaterials(vfile.get(), mats);
    00644         // updates the material library
    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     /*else
    00654     if (strcmp(cmd,"shadow_obj") == 0) // Shadow casting
    00655     {
    00656     }
    00657     else
    00658     if (strcmp(cmd,"trace_obj") == 0) // Ray tracing
    00659     {
    00660     }
    00661     else
    00662     if (strcmp(cmd,"ctech") == 0) // Curve approximation technique
    00663     {
    00664     }
    00665     else
    00666     if (strcmp(cmd,"stech") == 0) // Surface approximation technique
    00667     {
    00668     }*/
    00669   }
    00670
    00671   ref<ResourceDatabase> res_db = new ResourceDatabase;
    00672
    00673   // compile the material/effect library
    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       // sets the name
    00694       effect->shader()->gocMaterial()->setObjectName(obj_mat->objectName());
    00695       // add the Material to the ResourceDatabase
    00696       res_db->resources().push_back(effect->shader()->gocMaterial());
    00697       // setup the material
    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       // setup transparency
    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       // setup texture
    00715       if (obj_mat->map_Kd().valid())
    00716       {
    00717         ref<Texture> texture = new Texture;
    00718         // locate texture
    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     // we support only 2d textures
    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     // allocate vertex buffer
    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     // fill geometry
    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         // we consider all the texture coords as 2d
    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     // Geometry
    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     // Material/Effect
    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     // Actor
    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   /* now managed by GeometryLoadCallback */
    00879   /*for(unsigned i=0; i<res_db->count<Geometry>(); ++i)
    00880     if (res_db->get<Geometry>(i)->normalArray() == NULL)
    00881       res_db->get<Geometry>(i)->computeNormals();*/
    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 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:24.
Permission is granted to use this page to write and publish articles regarding Visualization Library.