source: GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp @ 1979

Revision 1979, 6.8 KB checked in by mattausch, 17 years ago (diff)

removed errors in loader

RevLine 
[1233]1#include <stdlib.h>
[1221]2#include <iostream>
3#include <list>
4#include <map>
[1976]5#include <math.h>
6
[1221]7using namespace std;
8
9#include "Vector3.h"
10#include "Mesh.h"
11#include "SceneGraph.h"
12
13#include "ObjParser.h"
14//#include "Material.h"
[1328]15#include "Triangle3.h"
[1221]16#include "Environment.h"
17#include "ResourceManager.h"
[1315]18#include "IntersectableWrapper.h"
[1221]19
20
21namespace GtpVisibilityPreprocessor {
22
[1344]23#define CONNECT_SEQUENTIAL_FACES 0
[1221]24#define ROTATE_SCENE 0
[1328]25
[1976]26// hack: define this as in the intel ray tracer
27#define FLT_EPSILON 1.192092896e-07f
28
[1221]29// HACK
[1328]30static void RotateMesh(Mesh *mesh)
31{
32        VertexContainer::iterator it, it_end = mesh->mVertices.end();
[1221]33
[1328]34        const float angle = 30.0f * PI / 180.0f;
35        const Matrix4x4 rot = RotationYMatrix(angle);
[1221]36
[1328]37        for (it = mesh->mVertices.begin(); it != it_end; ++ it)
38        {
39                (*it) = rot * (*it);       
[1221]40        }
[1328]41}
[1221]42
[1344]43
[1328]44struct ltstr
45{
46        bool operator()(const string s1, const string s2) const
[1221]47        {
[1328]48                return s1 < s2;
49        }
50};
[1221]51
52
[1328]53static Face *LoadFace(char *str,
54                                          const VertexContainer &vertices,
55                                          map<int, Vector3> &hashTable)
[1221]56{
[1328]57        char *pch = strtok(str + 1, " ");
[1221]58       
59        VertexIndexContainer indices;
60        while (pch != NULL)
61        {
62                const int index = (int)strtol(pch, NULL, 10) - 1;
63                //Debug << index << " x ";
64               
65                // store vertex in hash table
66                hashTable[index] = vertices[index];
67                indices.push_back(index);
68               
69                pch = strtok(NULL, " ");
70        }
71
72        return new Face(indices);
73}
74
75
[1972]76static void LoadTriangles(char *str,
77                                                  const VertexContainer &vertices,
[1979]78                                                  vector<Triangle3> &triangles,
79                                                  const int line)
[1221]80{
[1328]81        char *pch = strtok(str + 1, " ");
82       
83        VertexIndexContainer indices;
84       
85        while (pch != NULL)
86        {
87                const int index = (int)strtol(pch, NULL, 10) - 1;
[1979]88                                               
[1328]89                // store vertex in hash table
[1972]90                //hashTable[index] = vertices[index];
[1328]91                indices.push_back(index);
92               
[1979]93                //if (line == 451703)
94                //      cout << index + 1 << " ";
95
[1328]96                pch = strtok(NULL, " ");
[1972]97
98                // problem: don't know how intel ray tracer tesselates
99                if ((int)indices.size() > 2)
100                {
[1978]101                        const int index_2 = (int)indices.size() - 2;
102                        const int index_3 = (int)indices.size() - 1;
[1972]103
104                        triangles.push_back(Triangle3(vertices[indices[0]],
[1979]105                                                                                  vertices[indices[index_2]],           
106                                                                                  vertices[indices[index_3]]));
[1972]107                }
[1328]108        }
[1979]109        //if (line == 451703)
110        //      cout << "t: " << triangles.size() << endl;
[1328]111}
112
113
114static Mesh *CreateMesh(FaceContainer &faces,
115                                                const map<int, Vector3> &hashTable)
116{
[1221]117        Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
118       
119        FaceContainer::const_iterator fit, fit_end = faces.end();
120
121        for (fit = faces.begin(); fit != fit_end; ++ fit)
122        {
123                Face *face = *fit;
124                VertexIndexContainer::iterator vit, vit_end = face->mVertexIndices.end();
125               
126                for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit)
127                {
128                        // go through indices
129                        const int index = *vit;           
130                        //Debug << "old idx: " << (*vit) << endl;
131                        map<int, Vector3>::const_iterator hit = hashTable.find(index);
132
133                        // correct face index (nust be relative to start of verices)
[1314]134                        (*vit) = (int)distance(hashTable.begin(), hit);
[1221]135                        //Debug << "new idx: " << (*vit) << endl;
136                }
137        }
138
139        VertexContainer vertices;
140
141        map<int, Vector3>::const_iterator hit, hit_end = hashTable.end();
142
143        // store vertices in given order
144        for (hit = hashTable.begin(); hit != hit_end; ++ hit)
145        {
146                mesh->mVertices.push_back((*hit).second);
147        }
148
149        mesh->mFaces = faces;
[1292]150        // can't do cleanup because coupling with kdf file for intel ray tracer
151        mesh->Preprocess(false);
152
[1221]153        return mesh;
154}
155
156
157// HACK: associate mesh instances with triangles
[1328]158static void AssociateFacesWithInstance(MeshInstance *mi,
159                                                                           vector<FaceParentInfo> &parents)
[1221]160{
[1344]161        Mesh *mesh = mi->GetMesh();
162
163        int i = 0;
[1655]164        FaceContainer::const_iterator fit, fit_end = mesh->mFaces.end();
165
[1344]166        for (fit = mesh->mFaces.begin(); fit != fit_end; ++ fit, i++)
[1221]167        {
[1344]168                parents.push_back(FaceParentInfo(mi, i));
[1221]169        }
170}
171
172
[1328]173static void ProcessMesh(FaceContainer &faces,
174                                                map<int, Vector3> &hashTable,
175                                                SceneGraphNode *root,
176                                                vector<FaceParentInfo> *parents)
177{
178        Mesh *mesh = CreateMesh(faces, hashTable);
179        // make an instance of this mesh
180        MeshInstance *mi = new MeshInstance(mesh);
181               
182        if (parents)
183        {
184                AssociateFacesWithInstance(mi, *parents);
185        }
186
187        root->mGeometry.push_back(mi); 
188
189        // reset tables
190        hashTable.clear();
191        faces.clear();
192}
193
194
[1973]195bool TriangleValid(const Triangle3 &triangle)
196{
[1976]197        const Vector3 a = triangle.mVertices[0] - triangle.mVertices[1];
198        const Vector3 b = triangle.mVertices[0] - triangle.mVertices[2];
199        const Vector3 cross_a_b = CrossProd(a, b);
[1973]200
[1976]201        if (SqrMagnitude(cross_a_b) <= 0.000001 * FLT_EPSILON * FLT_EPSILON)
202        {
[1978]203                cout << "x";
204                // v0, v1 & v2 lies on a line (area == 0)
[1976]205                return false;
206        }
[1973]207
[1976]208        return true;
[1973]209}
210
[1976]211
[1221]212bool ObjParser::ParseFile(const string filename,
[1344]213                                                  SceneGraphNode *root,
[1379]214                                                  const bool loadMeshes,
[1281]215                                                  vector<FaceParentInfo> *parents)
[1221]216{
217        FILE *file;
218        if ((file = fopen(filename.c_str(), "rt")) == NULL)
[1344]219        {       
[1221]220                return false;
[1344]221        }
222
[1221]223        map<int, Vector3> hashTable; // table associating indices with vectors
[1327]224        VertexContainer vertices; // table for vertices
[1221]225        FaceContainer faces;
226
[1979]227        int line = 0;
228
229        char str[1000];
[1221]230        int meshGrouping;
231        Environment::GetSingleton()->GetIntValue("ObjParser.meshGrouping", meshGrouping);
232
[1292]233        int nMaxFaces = meshGrouping;
234
[1979]235        while (fgets(str, 1000, file) != NULL)
236        {++ line;
[1876]237          switch (str[0])
[1221]238                {
[1876]239                case 'v': // vertex  or normal
240                  {
241                        switch (str[1]) {
242                        case 'n' :
243                          // normal do nothing
244                          break;
245                        default:
246                          float x, y, z; //cout << "v";
247                          sscanf(str + 1, "%f %f %f", &x, &y, &z);
248                          vertices.push_back(Vector3(x,y,z));
249                          //cout << "vertex: " << vertices.back() << endl;
[1233]250                        }
[1876]251                        break;
252                  }
[1221]253                case 'f':
254                        {
[1655]255                                //      cout << "f";
[1421]256                                if (loadMeshes)
257                                {
258                                        Face *face = LoadFace(str, vertices, hashTable);
259                                        if (!face) break;
[1344]260       
[1421]261                                        faces.push_back(face);
[1328]262
[1421]263                                        if (faces.size() >= nMaxFaces)
264                                        {
265                                                ProcessMesh(faces, hashTable, root, parents);
266                                        }
267                                }
268                                else
[1221]269                                {
[1972]270                                        vector<Triangle3> triangles;
271                                       
[1979]272                                        LoadTriangles(str, vertices, triangles, line);
[1978]273
[1972]274                                        vector<Triangle3>::const_iterator tit, tit_end = triangles.end();
[1344]275
[1972]276                                        for (tit = triangles.begin(); tit != tit_end; ++ tit)
[1421]277                                        {
[1979]278                                                if (0 && !TriangleValid(*tit)) continue;
279
[1972]280                                                TriangleIntersectable *obj = new TriangleIntersectable(*tit);   
[1979]281                        root->mGeometry.push_back(obj);
[1421]282                                        }
[1344]283                                }
[1221]284                                break;
[1314]285                        }   // end face
[1221]286                default:
287                        break;
288                }
289        }
[1979]290        //cout << "\n** " << root->mGeometry.size() << " " << " lines: " << line << endl;
[1421]291        if (loadMeshes)
292        {
293                // there could be faces remaining
294                if (!faces.empty())
295                {       
296                        ProcessMesh(faces, hashTable, root, parents);
297                }
[1221]298        }
[1421]299
[1344]300        // reset tables
301        hashTable.clear();
302        faces.clear();
[1221]303        fclose(file);
[1344]304       
[1221]305        return true;
306}
307
[1272]308}
Note: See TracBrowser for help on using the repository browser.