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

Revision 1314, 5.2 KB checked in by mattausch, 18 years ago (diff)

started osp mesh construction for obj files. Introduced new primitive faceintersectable

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