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

Revision 1972, 6.3 KB checked in by mattausch, 17 years ago (diff)

implemented improved ray casting

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