src/OBJObject.cpp

Go to the documentation of this file.
00001 
00002 #include <stdexcept>
00003 #include <fstream>
00004 #include <sstream>
00005 
00006 #include "OBJObject.h"
00007 #include "Triangle.h"
00008 //#include "SimpleKDTree.h"
00009 #include "SAHKDTree.h"
00010 #include "defines.h"
00011 
00012 
00015 struct FaceIdcs
00016 {
00017     int v[4];
00018     int vn[4];
00019     int vt[4];
00020 
00021     FaceIdcs()
00022     {
00023         for (int i=0; i<4; i++)
00024             v[i] = vn[i] = vt[i] = 0;
00025     }
00026 
00027     FaceIdcs(std::istream & aStream)
00028     {
00029         for (int i=0; i<4; i++)
00030             v[i] = vn[i] = vt[i] = 0;
00031 
00032         char c;
00033         for(int i = 0; i < 3; i++)
00034         {
00035             aStream >> std::ws >> v[i] >> std::ws;
00036             if (aStream.peek() != '/')
00037                 continue;
00038             aStream >> c >> std::ws;
00039             if (aStream.peek() == '/')
00040             {
00041                 aStream >> c >> std::ws >> vn[i];
00042                 continue;
00043             }
00044             else
00045                 aStream >> vt[i];
00046             if (aStream.peek() != '/')
00047                 continue;
00048             aStream >> c >> vn[i];
00049         }
00050     }
00051 };
00052 
00053 
00056 static Vec3f vec3fFromStream(std::istream & aStream)
00057 {
00058     float x, y, z;
00059     aStream >> x >> std::ws >> y >> std::ws >> z;
00060     return Vec3f(x, y, z);
00061 }
00062 
00063 
00066 static TexCoordinate texCoordinateFromStream(std::istream & aStream)
00067 {
00068     float x, y;
00069     aStream >> x >> std::ws >> y;
00070     return TexCoordinate(x, y);
00071 }
00072 
00073 
00074 /* ************************************************************************** */
00075 
00076 
00081 OBJObject::OBJObject(const std::string & fileName)
00082     : Object(false),
00083         mPrimitives(NULL),
00084         mKdTree(NULL)
00085 {
00086     LOG("Creating OBJ Object");
00087     mPrimitives = new std::vector<Primitive *>;
00088     read(fileName);
00089 }
00090 
00091 
00097 OBJObject::OBJObject(const OBJObject & other)
00098     : Object(other),
00099         mPrimitives(other.mPrimitives),
00100         mKdTree(other.mKdTree)
00101 {
00102 }
00103 
00104 
00107 OBJObject::~OBJObject()
00108 {
00109     if (*mRefCounter <= 1)
00110     {
00111         // cleanup primitives
00112         std::vector<Primitive *>::iterator it = mPrimitives->begin();
00113         for (; it != mPrimitives->end(); ++it)
00114             delete *it;
00115         delete mPrimitives;
00116 
00117         // delete tree
00118         delete mKdTree;
00119     }
00120 }
00121 
00122 
00125 void OBJObject::setShader(Shader * sh)
00126 {
00127     std::vector<Primitive *>::iterator it = mPrimitives->begin();
00128     for (; it != mPrimitives->end(); ++it)
00129         (*it)->setShader(sh);
00130 }
00131 
00132 
00135 void OBJObject::setCastShadows(bool b)
00136 {
00137     Object::setCastShadows(b);
00138 
00139     // set to each primitive
00140     std::vector<Primitive *>::iterator it = mPrimitives->begin();
00141     for (; it != mPrimitives->end(); ++it)
00142         (*it)->setCastShadows(b);
00143 }
00144 
00145 
00151 void OBJObject::read(const std::string & fileName, const PrimitiveFactory & factory)
00152 {
00153     LOG("Parsing OBJFile : " << fileName);
00154 
00155     std::ifstream               ifile(fileName.c_str());
00156     std::vector<FaceIdcs>       faces;
00157     std::vector<Vec3f>          vert;
00158     std::vector<Vec3f>          norm;
00159     std::vector<TexCoordinate>  text;
00160 
00161     if (!ifile)
00162     {
00163         LOG("Could not open file");
00164         throw ObjectFileOpenException(fileName);
00165     }
00166     
00167     // while not end of file
00168     while (!ifile.eof())
00169     {
00170         // get line
00171         std::string curLine;
00172         std::getline(ifile, curLine);
00173 
00174         // read type of the line
00175         std::istringstream issLine(curLine);
00176         std::string lineType;
00177         issLine >> std::ws >> lineType;
00178 
00179         // based on the type parse data
00180         if (lineType == "v")
00181             vert.push_back(vec3fFromStream(issLine));
00182         else if (lineType == "vn")
00183             norm.push_back(vec3fFromStream(issLine).normal());
00184         else if (lineType == "vt")
00185             text.push_back(texCoordinateFromStream(issLine));
00186         else if (lineType == "f")
00187             faces.push_back(issLine);
00188         else if (lineType == "#" || lineType == "")
00189         {
00190             // comment / empty line
00191         }
00192         else if (lineType == "o")
00193         {
00194             std::string data;
00195             issLine >> std::ws >> data;
00196             LOG("Reading object \"" << data << "\"");
00197         }
00198         else if (lineType == "g")
00199         {
00200             std::string data;
00201             issLine >> std::ws >> data;
00202             LOG("Found type \"" << lineType << "\" : sub-object group \"" << data << "\" : NOT USED YET");
00203         }
00204         else if (lineType == "usemtl")
00205         {
00206             std::string data;
00207             issLine >> std::ws >> data;
00208             LOG("Found type \"" << lineType << "\" : use material \"" << data << "\" : NOT USED YET");
00209         }
00210         else if (lineType == "mtllib")
00211         {
00212             std::string data;
00213             issLine >> std::ws >> data;
00214             LOG("Found type \"" << lineType << "\" : material file \"" << data << "\" : NOT USED YET");
00215         }
00216         else
00217         {
00218             LOG("Found unknown line Type \"" << lineType << "\"");
00219         }
00220     }
00221 
00222     // iterate through all stored faces and create triangles
00223     for (std::vector<FaceIdcs>::iterator it = faces.begin(); it != faces.end(); ++it)
00224     {
00225         Vec3f           v[3];
00226         Vec3f           vn[3];
00227         TexCoordinate   vt[3];
00228         for (int i = 0; i < 3; i++)
00229         {
00230             v[i] = vert[it->v[i] - 1];
00231             if (it->vn[i] >= 1 && it->vn[i] <= static_cast<int>(norm.size()))
00232                 vn[i] = norm[it->vn[i] - 1];
00233             else if (it->vn[i] == 0)
00234                 vn[i] = Vec3f();
00235             else
00236             {
00237                 LOG("FUCK normal: it->vn[" << i << "] = " << it->vn[i] << " , norm.size() = " << norm.size());
00238             }
00239             if (it->vt[i] >= 1 && it->vt[i] <= static_cast<int>(text.size()))
00240                 vt[i] = text[it->vt[i] - 1];
00241             else if (it->vt[i] == 0)
00242                 vt[i] = TexCoordinate();
00243             else
00244             {
00245                 LOG("FUCK texture: it->vt[" << i << "] = " << it->vt[i] << " , text.size() = " << text.size());
00246             }
00247         }
00248 
00249         // create primitive by the factory
00250         mPrimitives->push_back(factory.create(  Triangle(v[0], v[1], v[2]),
00251                                                 vn[0], vn[1], vn[2],
00252                                                 vt[0], vt[1], vt[2] ));
00253     }
00254 
00255     buildAccelStructure();
00256 
00257     LOG("Number of Vertices:       " << (vert.size()) );
00258     LOG("Number of Triangles:      " << mPrimitives->size() );
00259     LOG("Number of Faces:          " << faces.size() );
00260     LOG("Number of Normals:        " << norm.size() );
00261     LOG("Number of TexCoordinates: " << text.size() );
00262     LOG("Finished Parsing");
00263 }
00264 
00265 
00268 void OBJObject::calcBounds()
00269 {
00270     mBoundingBox.clear();
00271 
00272     std::vector<Primitive *>::const_iterator it = mPrimitives->begin();
00273     for (; it != mPrimitives->end(); ++it)
00274         mBoundingBox.extend((*it)->bounds());
00275 
00276     LOG("bb.min: " << mBoundingBox.minVertex() << " , bb.max: " << mBoundingBox.maxVertex());
00277 }
00278 
00279 
00282 void OBJObject::buildAccelStructure()
00283 {
00284     // compute the bounding box
00285     calcBounds();
00286 
00287     // recreate the tree
00288     delete mKdTree;
00289 //    mKdTree = new SimpleKDTree();
00290     mKdTree = new SAHKDTree();
00291 
00292     // build acceleration data structure
00293     mKdTree->buildTree(*mPrimitives, mBoundingBox);
00294 }
00295 
00296 

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1