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

Revision 1328, 5.6 KB checked in by mattausch, 18 years ago (diff)
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 1
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
38struct ltstr
39{
40        bool operator()(const string s1, const string s2) const
41        {
42                return s1 < s2;
43        }
44};
45
46//const static int nMaxFaces = 6;
47
48
49static Face *LoadFace(char *str,
50                                          const VertexContainer &vertices,
51                                          map<int, Vector3> &hashTable)
52{
53        char *pch = strtok(str + 1, " ");
54       
55        VertexIndexContainer indices;
56        while (pch != NULL)
57        {
58                const int index = (int)strtol(pch, NULL, 10) - 1;
59                //Debug << index << " x ";
60               
61                // store vertex in hash table
62                hashTable[index] = vertices[index];
63                indices.push_back(index);
64               
65                pch = strtok(NULL, " ");
66        }
67        //if (indices.size() > 4) return NULL;
68
69        return new Face(indices);
70}
71
72
73static Triangle3 *LoadTriangle(char *str,
74                                                           const VertexContainer &vertices,
75                                                           map<int, Vector3> &hashTable)
76{
77        char *pch = strtok(str + 1, " ");
78       
79        VertexIndexContainer indices;
80       
81        while (pch != NULL)
82        {
83                const int index = (int)strtol(pch, NULL, 10) - 1;
84                //Debug << index << " x ";
85               
86                // store vertex in hash table
87                hashTable[index] = vertices[index];
88                indices.push_back(index);
89               
90                pch = strtok(NULL, " ");
91        }
92        //if (indices.size() > 4) return NULL;
93
94        return new Triangle3(indices[0], indices[1], indices[2]);
95}
96
97
98static Mesh *CreateMesh(FaceContainer &faces,
99                                                const map<int, Vector3> &hashTable)
100{
101        Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
102       
103        FaceContainer::const_iterator fit, fit_end = faces.end();
104
105        for (fit = faces.begin(); fit != fit_end; ++ fit)
106        {
107                Face *face = *fit;
108                VertexIndexContainer::iterator vit, vit_end = face->mVertexIndices.end();
109               
110                for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit)
111                {
112                        // go through indices
113                        const int index = *vit;           
114                        //Debug << "old idx: " << (*vit) << endl;
115                        map<int, Vector3>::const_iterator hit = hashTable.find(index);
116
117                        // correct face index (nust be relative to start of verices)
118                        (*vit) = (int)distance(hashTable.begin(), hit);
119                        //Debug << "new idx: " << (*vit) << endl;
120                }
121        }
122
123        VertexContainer vertices;
124
125        map<int, Vector3>::const_iterator hit, hit_end = hashTable.end();
126
127        // store vertices in given order
128        for (hit = hashTable.begin(); hit != hit_end; ++ hit)
129        {
130                mesh->mVertices.push_back((*hit).second);
131        }
132
133        mesh->mFaces = faces;
134        // can't do cleanup because coupling with kdf file for intel ray tracer
135        mesh->Preprocess(false);
136
137        return mesh;
138}
139
140
141// HACK: associate mesh instances with triangles
142static void AssociateFacesWithInstance(MeshInstance *mi,
143                                                                           vector<FaceParentInfo> &parents)
144{
145  Mesh *mesh = mi->GetMesh();
146 
147  FaceContainer::const_iterator fit, fit_end = mesh->mFaces.end();
148  int i = 0;
149  for (fit = mesh->mFaces.begin(); fit != fit_end; ++ fit, i++)
150        {
151          parents.push_back(FaceParentInfo(mi, i));
152        }
153}
154
155
156static void ProcessMesh(FaceContainer &faces,
157                                                map<int, Vector3> &hashTable,
158                                                SceneGraphNode *root,
159                                                vector<FaceParentInfo> *parents)
160{
161        Mesh *mesh = CreateMesh(faces, hashTable);
162
163        // make an instance of this mesh
164        MeshInstance *mi = new MeshInstance(mesh);
165               
166        if (parents)
167        {
168                AssociateFacesWithInstance(mi, *parents);
169        }
170
171        root->mGeometry.push_back(mi); 
172
173        // reset tables
174        hashTable.clear();
175        faces.clear();
176}
177
178
179bool ObjParser::ParseFile(const string filename,
180                                                  SceneGraphNode **proot,
181                                                  const bool loadPolygonsAsMeshes,
182                                                  vector<FaceParentInfo> *parents)
183{
184        FILE *file;
185        if ((file = fopen(filename.c_str(), "rt")) == NULL)
186                return false;
187        cout << "here2" << endl;
188        map<int, Vector3> hashTable; // table associating indices with vectors
189       
190        VertexContainer vertices; // table for vertices
191        FaceContainer faces;
192
193        SceneGraphNode *root = new SceneGraphNode;
194
195        char str[100];
196        int meshGrouping;
197        Environment::GetSingleton()->GetIntValue("ObjParser.meshGrouping", meshGrouping);
198
199        int nMaxFaces = meshGrouping;
200
201        while (fgets(str, 80, file) != NULL)
202        {
203                switch (str[0])
204                {
205                case 'v':
206                        {
207                                float x,y,z; //cout << "v";
208                               
209                                // vertex
210                                sscanf(str + 1, "%f %f %f", &x, &y, &z);
211                                vertices.push_back(Vector3(x,y,z));
212                                //Debug << "vertex: " << vertices.back() << endl;
213                                break;
214                        }
215                case 'f':
216                        {
217                                cout << "f";
218#if CONNECT_SEQUENTIAL_FACES
219                                Face *face = LoadFace(str, vertices, hashTable);
220                                if (!face) break;
221
222                                faces.push_back(face);
223
224                                if (faces.size() >= nMaxFaces)
225                                {
226                                        ProcessMesh(faces, hashTable, root, parents);
227                                }
228#else
229                               
230                                Triangle3 *triangle = LoadTriangle(str, vertices, hashTable);
231                                root->mGeometry.push_back(new TriangleIntersectable(triangle));
232#endif
233                                break;
234                        }   // end face
235                default:
236                        break;
237                }
238        }
239
240#if CONNECT_SEQUENTIAL_FACES
241        // there could be faces remaining
242        if (!faces.empty())
243        {       
244                ProcessMesh(faces, hashTable, root, parents);
245        }
246#endif
247
248        fclose(file);
249        *proot = root;
250
251        return true;
252}
253
254}
Note: See TracBrowser for help on using the repository browser.