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

Revision 1344, 5.8 KB checked in by mattausch, 18 years ago (diff)

worked on triangle processing. logical units will be created by grouping objects
using their visibility definitions.

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