BambooIsland: C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/Modelsmanager.cpp Source File

BambooIsland Abgabe 2

- Main Page
- Related Pages
- Classes
- Files

- File List

# C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/Modelsmanager.cpp

    00001 #include <GL/glew.h>
    00002
    00003 #include "Modelsmanager.h"
    00004 #include "error.h"
    00005
    00006 Modelsmanager::Modelsmanager(void)
    00007 {
    00008
    00009 }
    00010
    00011 Modelsmanager::~Modelsmanager(void)
    00012 {
    00013
    00014 }
    00015
    00022 bool Modelsmanager::loadModel(string identifier, const string meshpath, const string texpath)
    00023 {
    00024         GLfloat *vertices = 0;
    00025         GLfloat *vertexNormals = 0;
    00026         GLuint *faceIndizes = 0;
    00027         GLfloat *texcoords = 0;
    00028         GLfloat **faces = 0;
    00029         GLfloat *tangents = 0;
    00030         int vertexcount;
    00031         int facecount;
    00032
    00033         // XML parsen mittels TinyXML
    00034         TiXmlDocument doc(meshpath.c_str());
    00035         if(!doc.LoadFile()) throw new FileNotFound(meshpath);
    00036
    00037         Model* model=0;
    00038         GLuint texID=0;
    00039
    00040         try
    00041         {
    00042                 TiXmlElement* root = doc.RootElement();
    00043                 if(!root) throw new MeshParsingError("kein Root Element gefunden");
    00044
    00045                 TiXmlNode* node = doc.FirstChild("mesh");
    00046                 if(!node) throw new MeshParsingError("Knoten <mesh> nicht gefunden");
    00047
    00048                 node = node->FirstChild("submeshes");
    00049                 if(!node) throw new MeshParsingError("Knoten <submeshes> nicht gefunden");
    00050
    00051                 TiXmlNode* submeshNode = node->FirstChild("submesh");
    00052                 if(!submeshNode) throw new MeshParsingError("Knoten <submesh> nicht gefunden");
    00053
    00054                 // Model erzeugen und Submeshes durchlaufen
    00055                 model = new Model();
    00056
    00057                 // <submesh> Knoten durchlaufen
    00058                 while(0!=submeshNode)
    00059                 {
    00060
    00061                         TiXmlElement* element = submeshNode->ToElement();
    00062                         if(!element) throw new MeshParsingError("konnte <submesh> nicht zu TiXmlElement casten");
    00063
    00064                         TiXmlAttribute* attribute = element->FirstAttribute();
    00065                         /*while(0!=attribute && attribute->NameTStr() != "usesharedvertices") {
    00066                                 attribute = attribute->Next();
    00067                         }
    00068                         if(!attribute) throw new MeshParsingError("konnte Attribut 'usesharedvertices' nicht finden");
    00069                         // das Attribut ist jetzt sicher usesharedvertices => Wert abfragen
    00070                         if(attribute->Value() != "false") throw new MeshParsingError("usesharedvertices=\"true\" momentan nicht unterstützt");*/
    00071
    00072                         // <geometry> und <faces> Knoten parsen
    00073                         TiXmlNode* submeshchild = submeshNode->FirstChild();
    00074                         while(0!=submeshchild)
    00075                         {
    00076                                 element = submeshchild->ToElement();
    00077                                 if(!element) throw new MeshParsingError("konnte ChildNode von <submesh> nicht zu TiXmlElement casten");
    00078
    00079                                 // falls <geometry> Knoten
    00080                                 if(element->ValueTStr()=="geometry")
    00081                                 {
    00082                                         attribute = element->FirstAttribute();
    00083                                         if( attribute->NameTStr() != "vertexcount" ||
    00084                                                 attribute->QueryIntValue(&vertexcount)!=TIXML_SUCCESS) throw new MeshParsingError("konnte Attribut 'vertexcount' nicht lesen");
    00085
    00086                                         node = element->FirstChild("vertexbuffer");
    00087                                         if(!node) throw new MeshParsingError("Knoten <vertexbuffer> nicht gefunden");
    00088                                         TiXmlElement* vertexbuffer = node->ToElement();
    00089                                         if(!vertexbuffer) throw new MeshParsingError("konnte <vertexbuffer> nicht zu TiXmlElement casten");
    00090
    00091                                         // Attribute 'positions' und 'normals' (jeweils boolean) auslesen
    00092                                         bool positions=false;
    00093                                         bool normals = false;
    00094                                         bool texture_coords=false;
    00095                                         attribute = element->FirstAttribute();
    00096                                         while(0!=attribute)
    00097                                         {
    00098                                                 if              (attribute->Name() == "positions")              { if(attribute->Value() == "true") positions=true; }
    00099                                                 else if (attribute->Name() == "normals")                { if(attribute->Value() == "true") normals=true; }
    00100                                                 else if (attribute->Name() == "texture_coords") { if(attribute->Value() == "1")    texture_coords=true; }
    00101                                                 attribute = attribute->Next();
    00102                                         }
    00103
    00104                                         GLdouble x,y,z;
    00105
    00106                                         // erstelle die Arrays
    00107                                         vertices = new GLfloat[vertexcount*3];
    00108                                         vertexNormals = new GLfloat[vertexcount*3];
    00109                                         texcoords = new GLfloat[vertexcount*2]; // u,v ... 2 Koordinaten
    00110                                         tangents = new GLfloat[vertexcount*3];
    00111
    00112                                         // beginne, <vertexbuffer> auszulesen
    00113                                         TiXmlNode* vertex = vertexbuffer->FirstChild();
    00114                                         // es werden ausschließlich dreieckige Polygone unterstützt, aber wurscht, hier einfach ins VertexArray schreiben
    00115                                         //
    00116                                         // im Folgenden wird davon ausgegangen, dass das XML passt
    00117                                         // d.h. u.A. dass die ToElement() casts etc. funktionieren
    00118                                         for(int i=0; i<vertexcount; i++) // iteriere alle <vertex> Knoten
    00119                                         {
    00120                                                 // finde den <position> knoten
    00121                                                 element = vertex->FirstChild()->ToElement();
    00122                                                 while(0!=element)
    00123                                                 {
    00124                                                         if(element->ValueTStr()=="position")
    00125                                                         {
    00126                                                                 x=0; y=0; z=0;
    00127                                                                 // fülle das Vertexarray mit den Koordinaten aus dem <position> Knoten
    00128                                                                 attribute = element->FirstAttribute();
    00129                                                                 while(0!=attribute)
    00130                                                                 {
    00131                                                                         if(attribute->NameTStr()=="x")          attribute->QueryDoubleValue(&x);
    00132                                                                         else if(attribute->NameTStr()=="y") attribute->QueryDoubleValue(&y);
    00133                                                                         else if(attribute->NameTStr()=="z") attribute->QueryDoubleValue(&z);
    00134                                                                         attribute = attribute->Next();
    00135                                                                 }
    00136                                                                 // Vertexarray befüllen, x,y,z Werte in dieser Reihenfolge: x0,y0,z0,x1,y1,z1,x2,y2,...
    00137                                                                 vertices[3*i]=static_cast<GLfloat>(x);
    00138                                                                 vertices[3*i+1]=static_cast<GLfloat>(y);
    00139                                                                 vertices[3*i+2]=static_cast<GLfloat>(z);
    00140                                                         }
    00141                                                         else if(element->ValueTStr()=="normal")
    00142                                                         {
    00143                                                                 x=0; y=0; z=0;
    00144                                                                 // fülle das vertexNormals Array mit den Koordinaten aus dem <normal> Knoten
    00145                                                                 attribute = element->FirstAttribute();
    00146                                                                 while(0!=attribute)
    00147                                                                 {
    00148                                                                         if(attribute->NameTStr()=="x")          attribute->QueryDoubleValue(&x);
    00149                                                                         else if(attribute->NameTStr()=="y") attribute->QueryDoubleValue(&y);
    00150                                                                         else if(attribute->NameTStr()=="z") attribute->QueryDoubleValue(&z);
    00151                                                                         attribute = attribute->Next();
    00152                                                                 }
    00153                                                                 // Vertexarray befüllen, x,y,z Werte in dieser Reihenfolge: x0,y0,z0,x1,y1,z1,x2,y2,...
    00154                                                                 vertexNormals[3*i]=static_cast<GLfloat>(x);
    00155                                                                 vertexNormals[3*i+1]=static_cast<GLfloat>(y);
    00156                                                                 vertexNormals[3*i+2]=static_cast<GLfloat>(z);
    00157                                                         }
    00158                                                         else if(element->ValueTStr()=="texcoord")
    00159                                                         {
    00160                                                                 x=0; y=0; // eigentlich u, v
    00161                                                                 attribute = element->FirstAttribute();
    00162                                                                 while(0!=attribute)
    00163                                                                 {
    00164                                                                         if(attribute->NameTStr()=="u")          attribute->QueryDoubleValue(&x);
    00165                                                                         else if(attribute->NameTStr()=="v") attribute->QueryDoubleValue(&y);
    00166                                                                         attribute = attribute->Next();
    00167                                                                 }
    00168                                                                 // Texturarray befüllen, u,v Werte in dieser Reihenfolge: u0,v0,u1,v1,u2,v2,...
    00169                                                                 texcoords[2*i]=static_cast<GLfloat>(x);
    00170                                                                 texcoords[2*i+1]=static_cast<GLfloat>(y);
    00171                                                         }
    00172                                                         else if(element->ValueTStr()=="tangent")
    00173                                                         {
    00174                                                                 x=0;
    00175                                                                 y=0;
    00176                                                                 z=0;
    00177                                                                 attribute = element->FirstAttribute();
    00178                                                                 while(0!=attribute)
    00179                                                                 {
    00180                                                                         if(attribute->NameTStr()=="x")          attribute->QueryDoubleValue(&x);
    00181                                                                         else if(attribute->NameTStr()=="y") attribute->QueryDoubleValue(&y);
    00182                                                                         else if(attribute->NameTStr()=="z") attribute->QueryDoubleValue(&z);
    00183                                                                         attribute = attribute->Next();
    00184                                                                 }
    00185                                                                 // Texturarray befüllen, u,v Werte in dieser Reihenfolge: u0,v0,u1,v1,u2,v2,...
    00186                                                                 tangents[3*i]=static_cast<GLfloat>(x);
    00187                                                                 tangents[3*i+1]=static_cast<GLfloat>(y);
    00188                                                                 tangents[3*i+2]=static_cast<GLfloat>(z);
    00189                                                         }
    00190                                                         // gehe zum nächsten ChildNode eines <vertex>, da kann sein <position> oder <normal>
    00191                                                         element = element->NextSiblingElement();
    00192                                                 }
    00193
    00194                                                 // gehe zum nächsten <vertex>
    00195                                                 vertex = vertex->NextSibling();
    00196                                         }
    00197
    00198
    00199                                 } // endif </geometry>
    00200                                 else if(element->ValueTStr()=="faces") // <faces> Knoten
    00201                                 {
    00202
    00203                                         attribute = element->FirstAttribute();
    00204                                         if( attribute->NameTStr() != "count" ||
    00205                                                 attribute->QueryIntValue(&facecount)!=TIXML_SUCCESS) throw new MeshParsingError("konnte Attribut 'count' nicht lesen");
    00206
    00207                                         GLint v1,v2,v3;
    00208
    00209                                         // erstelle die Arrays
    00210                                         faceIndizes = new GLuint[3*facecount];
    00211
    00212                                         // beginne, <faces> auszulesen
    00213                                         TiXmlElement* face = element->FirstChild()->ToElement();
    00214                                         //
    00215                                         // im Folgenden wird davon ausgegangen, dass das XML passt
    00216                                         // d.h. u.A. dass die ToElement() casts etc. funktionieren
    00217                                         for(int i=0; i<facecount; i++) // iteriere alle <face> Knoten
    00218                                         {
    00219                                                 v1=0; v2=0; v3=0;
    00220                                                 // fülle das faceIndizes Array mit den Indizes aus dem <face> Knoten
    00221                                                 attribute = face->FirstAttribute();
    00222                                                 while(0!=attribute)
    00223                                                 {
    00224                                                         if(attribute->NameTStr()=="v1")         attribute->QueryIntValue(&v1);
    00225                                                         else if(attribute->NameTStr()=="v2") attribute->QueryIntValue(&v2);
    00226                                                         else if(attribute->NameTStr()=="v3") attribute->QueryIntValue(&v3);
    00227                                                         attribute = attribute->Next();
    00228                                                 }
    00229                                                 // Vertexarray befüllen, x,y,z Werte in dieser Reihenfolge: x0,y0,z0,x1,y1,z1,x2,y2,...
    00230                                                 faceIndizes[3*i]=v1;
    00231                                                 faceIndizes[3*i+1]=v2;
    00232                                                 faceIndizes[3*i+2]=v3;
    00233
    00234                                                 face=face->NextSiblingElement();
    00235                                         }
    00236
    00237
    00238                                 } // endif </faces>
    00239
    00240                                 submeshchild = submeshchild->NextSibling();
    00241                         } // while-Ende <geometry> und <faces>
    00242
    00243
    00244                         // jetzt müssen wir gültige Daten haben; sonst throw Error
    00245                         if(0==vertices || 0==vertexNormals || 0==faceIndizes) throw new MeshParsingError("Mesh unvollständig");
    00246
    00247
    00248                         // Daten im Model setzen
    00249                         Submesh* submesh = new Submesh();
    00250                         submesh->nVertexCount = vertexcount;
    00251                         submesh->nFaceCount = facecount;
    00252                         submesh->m_pVertices = vertices;
    00253                         submesh->m_pNormals = vertexNormals;
    00254                         submesh->m_pTexcoords = texcoords;
    00255                         submesh->m_pFaceIndizes = faceIndizes;
    00256                         submesh->m_pTangents = tangents;
    00257
    00258                         // submesh dem Model hinzufügen
    00259                         model->submeshes.push_back(submesh);
    00260
    00261                         // gehe zum nächsten <submesh>
    00262                         submeshNode = submeshNode->NextSibling();
    00263                 } // while(0!=submeshNode) end
    00264
    00265
    00266                 // ... und der map hinzufügen
    00267                 models.insert(pair<string, Model*>(identifier, model));
    00268
    00269         } catch(Error *e) {
    00270                 // cleanup
    00271                 if(0!=vertices) delete[] vertices;
    00272                 if(0!=vertexNormals) delete[] vertexNormals;
    00273                 if(0!=faceIndizes) delete[] faceIndizes;
    00274                 if(0!=texcoords) delete[] texcoords;
    00275
    00276                 if(0!=model) delete model;
    00277
    00278
    00279                 // rethrow Error
    00280                 throw e;
    00281         }
    00282
    00283 } // Modelsmanager::loadModel
    00284
    00285
    00286 Model* Modelsmanager::getModel(const string identifier)
    00287 {
    00288         map<string, Model*>::iterator it = models.find(identifier);
    00289         if(it == models.end()) return 0;
    00290         return it->second; // the second element of the key-value pair
    00291 }
    00292
    00293 void Modelsmanager::deleteModel(const string identifier)
    00294 {
    00295         map<string, Model*>::iterator it = models.find(identifier);
    00296         if(it == models.end()) return;
    00297
    00298         delete it->second;
    00299 }
    00300
    00301 Model::Model(void): modelCenter(glm::vec3(0,0,0))
    00302 {
    00303 }
    00304
    00305 Model::~Model(void)
    00306 {
    00307         for(int i=0; i<submeshes.size(); i++)
    00308             delete submeshes[i];
    00309 }
    00310
    00311 Model* Model::clone()
    00312 {
    00313         Model* model=new Model();
    00314         // clone the data
    00315         model->modelCenter = modelCenter;
    00316
    00317         // clone the submeshes
    00318         for(int i=0; i<submeshes.size(); i++)
    00319                 model->submeshes.push_back(submeshes[i]->clone());
    00320
    00321         return model;
    00322 }
    00323
    00324
    00325 Submesh::Submesh(void) : m_pVertices(0), m_pNormals(0), m_pFaceIndizes(0), m_pTangents(0), m_pTexcoords(0), nVertexCount(0)
    00326 {
    00327
    00328 }
    00329
    00330 Submesh::~Submesh(void)
    00331 {
    00332         if(m_pVertices != 0)
    00333             delete[] m_pVertices;
    00334
    00335         if(m_pNormals != 0)
    00336             delete[] m_pNormals;
    00337
    00338         if(m_pFaceIndizes != 0)
    00339             delete[] m_pFaceIndizes;
    00340
    00341         if (m_pTangents != 0)
    00342             delete[] m_pTangents;
    00343
    00344         if (m_pTexcoords != 0)
    00345             delete[] m_pTexcoords;
    00346 }
    00347
    00348
    00349 GLfloat* Submesh::Vertices()
    00350 {
    00351         return m_pVertices;
    00352 }
    00353
    00354
    00355 GLfloat* Submesh::Normals()
    00356 {
    00357         return m_pNormals;
    00358 }
    00359
    00360
    00361 GLfloat* Submesh::Tangents()
    00362 {
    00363         return m_pTangents;
    00364 }
    00365
    00366 GLfloat* Submesh::TexCoords()
    00367 {
    00368     return m_pTexcoords;
    00369 }
    00370
    00371 GLuint* Submesh::FaceIndizes()
    00372 {
    00373         return m_pFaceIndizes;
    00374 }
    00375
    00376 Submesh* Submesh::clone()
    00377 {
    00378         Submesh* model = new Submesh();
    00379
    00380         model->nVertexCount = nVertexCount;
    00381
    00382         model->m_pVertices = new GLfloat[VertexArrayLength()];
    00383         for(int i=0; i<VertexArrayLength(); i++)
    00384             model->m_pVertices[i]=m_pVertices[i];
    00385
    00386         model->m_pNormals = new GLfloat[VertexNormalsArrayLength()];
    00387         for(int i=0; i<VertexNormalsArrayLength(); i++)
    00388             model->m_pNormals[i]=m_pNormals[i];
    00389
    00390         model->nFaceCount = nFaceCount;
    00391
    00392         model->m_pFaceIndizes = new GLuint[FaceIndizesArrayLength()];
    00393
    00394         for(int i=0; i<FaceIndizesArrayLength(); i++)
    00395             model->m_pFaceIndizes[i]=m_pFaceIndizes[i];
    00396
    00397         model->m_pTangents = m_pTangents; //todo: copy data!
    00398
    00399         // copy tex-data
    00400         model->m_pTexcoords = new GLfloat[TexCoordsArrayLength()];
    00401         for(int i=0; i<TexCoordsArrayLength(); i++)
    00402             model->m_pTexcoords[i] = m_pTexcoords[i];
    00403
    00404         return model;
    00405 }

All Classes Functions Variables Enumerations Enumerator