#include #include #include #include using namespace std; #include "Vector3.h" #include "Mesh.h" #include "SceneGraph.h" #include "ObjParser.h" //#include "Material.h" #include "Environment.h" #include "ResourceManager.h" namespace GtpVisibilityPreprocessor { #define ROTATE_SCENE 0 // HACK static void RotateMesh(Mesh *mesh) { VertexContainer::iterator it, it_end = mesh->mVertices.end(); const float angle = 30.0f * PI / 180.0f; const Matrix4x4 rot = RotationYMatrix(angle); for (it = mesh->mVertices.begin(); it != it_end; ++ it) { (*it) = rot * (*it); } } struct ltstr { bool operator()(const string s1, const string s2) const { return s1 < s2; } }; const static int nMaxFaces = 6; Face *LoadFace(char *str, const VertexContainer &vertices, map &hashTable) { // cout << "f"; char *pch; pch = strtok(str + 1, " "); VertexIndexContainer indices; while (pch != NULL) { const int index = (int)strtol(pch, NULL, 10) - 1; //Debug << index << " x "; // store vertex in hash table hashTable[index] = vertices[index]; indices.push_back(index); pch = strtok(NULL, " "); } //if (indices.size() > 4) return NULL; return new Face(indices); } Mesh *CreateMesh(FaceContainer &faces, const map &hashTable) { Mesh *mesh = MeshManager::GetSingleton()->CreateResource(); FaceContainer::const_iterator fit, fit_end = faces.end(); for (fit = faces.begin(); fit != fit_end; ++ fit) { Face *face = *fit; VertexIndexContainer::iterator vit, vit_end = face->mVertexIndices.end(); for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit) { // go through indices const int index = *vit; //Debug << "old idx: " << (*vit) << endl; map::const_iterator hit = hashTable.find(index); // correct face index (nust be relative to start of verices) (*vit) = distance(hashTable.begin(), hit); //Debug << "new idx: " << (*vit) << endl; } } VertexContainer vertices; map::const_iterator hit, hit_end = hashTable.end(); // store vertices in given order for (hit = hashTable.begin(); hit != hit_end; ++ hit) { mesh->mVertices.push_back((*hit).second); } mesh->mFaces = faces; mesh->Preprocess(); /*for (int i = 0; i < faces.size(); ++ i) { Debug << "face: "; for (int j = 0; j < faces[i]->mVertexIndices.size(); ++ j) { Debug << "i " << faces[i]->mVertexIndices[j] << " " << endl; Debug << "v " << mesh->mVertices[faces[i]->mVertexIndices[j]] << " "; } Debug << endl; }*/ return mesh; } // HACK: associate mesh instances with triangles void AssociateFacesWithInstance(MeshInstance *mi, vector &parents) { Mesh *mesh = mi->GetMesh(); FaceContainer::const_iterator fit, fit_end = mesh->mFaces.end(); for (fit = mesh->mFaces.begin(); fit != fit_end; ++ fit) { parents.push_back(mi); } } bool ObjParser::ParseFile(const string filename, SceneGraphNode **proot, const bool loadPolygonsAsMeshes, vector *parents) { FILE *file; if ((file = fopen(filename.c_str(), "rt")) == NULL) return false; VertexContainer vertices; // table for vertices map hashTable; // table associating indices with vectors FaceContainer faces; char str[100]; SceneGraphNode *root = new SceneGraphNode; cout<<"HERE2!\n"; int meshGrouping; Environment::GetSingleton()->GetIntValue("ObjParser.meshGrouping", meshGrouping); while (fgets(str, 80, file) != NULL) { switch (str[0]) { case 'v': { float x,y,z; //cout << "v"; // vertex sscanf(str + 1, "%f %f %f", &x, &y, &z); vertices.push_back(Vector3(x,y,z)); //Debug << "vertex: " << vertices.back() << endl; break; } case 'f': { Face *face = LoadFace(str, vertices, hashTable); if (!face) break; faces.push_back(face); if (faces.size() >= nMaxFaces) { Mesh *mesh = CreateMesh(faces, hashTable); // make an instance of this mesh MeshInstance *mi = new MeshInstance(mesh); root->mGeometry.push_back(mi); if (parents) { AssociateFacesWithInstance(mi, *parents); } // reset tables hashTable.clear(); faces.clear(); } break; } // end face default: break; } } // there could be faces remaining if (1 && !faces.empty()) { Mesh *mesh = CreateMesh(faces, hashTable); // make an instance of this mesh MeshInstance *mi = new MeshInstance(mesh); if (parents) { AssociateFacesWithInstance(mi, *parents); } root->mGeometry.push_back(mi); } // reset tables hashTable.clear(); faces.clear(); fclose(file); *proot = root; return true; } }