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

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