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

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