source: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp @ 3161

Revision 3161, 10.8 KB checked in by mattausch, 16 years ago (diff)

not working ....

Line 
1#include "ObjConverter.h"
2#include "SimpleTri.h"
3#include "SimpleVec.h"
4#include "gzstream.h"
5#include <iostream>
6
7
8using namespace std;
9
10//#define USE_TEXTURE
11
12
13static void LoadIndices(char *str,
14                                                const VertexArray &vertices,
15                                                const VertexArray &normals,
16                                                const vector<pair<float, float> > &texcoords,
17                                                VertexArray &faceVertices,
18                                                VertexArray &faceNormals,
19                                                vector<Texcoord> &faceTexcoords
20                                                )
21{
22        vector<string> triples;
23
24        char *next_token;
25
26        // extract the triples of the form v/t/n v/t/n ...
27        char *pch = strtok_s(str + 1, " ", &next_token);
28
29        while (pch)
30        {
31                string s(pch);
32                //s += "\n",
33                triples.push_back(s);
34               
35                pch = strtok_s(NULL, " ", &next_token);   
36        }
37
38        vector<int> indices;
39        vector<int> nIndices;
40        vector<int> tIndices;
41
42        char seps[] = " /\t\n";
43
44        for (size_t i = 0; i < triples.size(); ++ i)
45        {
46                static int dummy = 0;
47
48                size_t found;
49                found = triples[i].find_first_of(seps);
50                size_t prevfound = 0;
51                // vertex, normal, texture indices
52                string str = triples[i].substr(prevfound, found);
53
54                int index = (int)strtol(str.c_str(), NULL, 10) - 1;
55
56                int tIndex = index;
57                int nIndex = index;     
58               
59                prevfound = found;
60                found = triples[i].find_first_of(seps, found + 1); 
61
62                if (found != string::npos)
63                {
64                        str = triples[i].substr(prevfound, found);
65
66                        int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
67                        if (idx > 0) tIndex = idx;
68                }
69
70                if ((found + 1) < triples[i].size())
71                {
72                        str = triples[i].substr(found + 1);
73
74                        int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
75                        if (idx > 0) nIndex = idx;
76                }
77
78                // store indices
79                if (index >= 0)
80                {
81                        indices.push_back(index);
82                        nIndices.push_back(nIndex);
83                        tIndices.push_back(tIndex);
84                }
85
86                // new triangle found
87                if (indices.size() > 2)
88                {
89                        // change orientation of faces?
90#if 1
91                        int idx1 = 0;
92                        int idx2 = (int)indices.size() - 2;
93                        int idx3 = (int)indices.size() - 1;
94#else
95                        int idx3 = 0;
96                        int idx2 = (int)indices.size() - 2;
97                        int idx1 = (int)indices.size() - 1;
98#endif
99                        faceVertices.push_back(vertices[indices[idx1]]);
100                        faceVertices.push_back(vertices[indices[idx2]]);
101                        faceVertices.push_back(vertices[indices[idx3]]);
102
103
104                        if (!normals.empty())
105                        {
106                                //if (dummy < 3) cout << nIndices[idx1] << " " << nIndices[idx2] << " " << nIndices[idx3] << endl;
107                                faceNormals.push_back(normals[nIndices[idx1]]);
108                                faceNormals.push_back(normals[nIndices[idx2]]);
109                                faceNormals.push_back(normals[nIndices[idx3]]);
110                        }
111                        else
112                        {
113                                // no face normals? => create normals
114                                const SimpleTri tri(vertices[indices[idx1]],
115                                                        vertices[indices[idx2]],
116                                                                        vertices[indices[idx3]]);
117                                const SimpleVec n = tri.GetNormal();
118
119                                faceNormals.push_back(n);
120                                faceNormals.push_back(n);
121                                faceNormals.push_back(n);
122                        }
123
124                        ++ dummy;
125                        if (!texcoords.empty())
126                        {
127                                faceTexcoords.push_back(texcoords[tIndices[idx1]]);
128                                faceTexcoords.push_back(texcoords[tIndices[idx2]]);
129                                faceTexcoords.push_back(texcoords[tIndices[idx3]]);
130                        }
131                }
132        }
133}
134
135
136ObjConverter::ObjConverter()
137{}
138
139
140ObjConverter::~ObjConverter()
141{
142        for (size_t i = 0; i < mGeometry.size(); ++ i)
143        {
144                delete [] mGeometry[i]->mVertices;
145                delete [] mGeometry[i]->mNormals;
146                delete [] mGeometry[i]->mTexcoords;
147
148                delete mGeometry[i];
149        }
150       
151        mGeometry.clear();
152}
153
154
155void ObjConverter::LoadShape(const VertexArray &faceVertices,
156                                                         const VertexArray &faceNormals,
157                                                         const vector<Texcoord> &faceTexcoords)
158{
159        int numElements = (int)faceVertices.size();
160        Geometry *geom = new Geometry();
161
162        // convert the triangles to geometry
163        geom->mVertices = new SimpleVec[numElements];
164        geom->mNormals = new SimpleVec[numElements];
165        geom->mTexcoords = new Texcoord[numElements];
166
167        geom->mVertexCount = numElements;
168        geom->mTexcoordCount = (int)faceTexcoords.size();
169
170        cout << "number of vertices=" << numElements << endl;
171
172        for (int i = 0; i < numElements; ++ i)
173        {
174#if 0
175                // convert to our camera system: change y and z
176                geom->mVertices[i].x = faceVertices[i].x;
177                geom->mVertices[i].y = -faceVertices[i].z;
178                geom->mVertices[i].z = faceVertices[i].y;
179       
180                geom->mNormals[i].x = faceNormals[i].x;
181                geom->mNormals[i].y = -faceNormals[i].z;
182                geom->mNormals[i].z = faceNormals[i].y;
183
184#else
185                geom->mVertices[i].x = faceVertices[i].x;
186                geom->mVertices[i].y = faceVertices[i].y;
187                geom->mVertices[i].z = faceVertices[i].z;
188       
189                geom->mNormals[i].x = faceNormals[i].x;
190                geom->mNormals[i].y = faceNormals[i].y;
191                geom->mNormals[i].z = faceNormals[i].z;
192
193#endif
194
195                if (i < geom->mTexcoordCount)
196                {
197                        geom->mTexcoords[i].first = faceTexcoords[i].first;
198                        geom->mTexcoords[i].second = faceTexcoords[i].second;
199                }
200        }
201
202        mGeometry.push_back(geom);
203}
204
205
206bool ObjConverter::Convert(const string &filename, const std::string &outputFilename)
207{
208        mNumShapes = 0;
209       
210        for (size_t i = 0; i < mGeometry.size(); ++ i)
211        {
212                delete [] mGeometry[i]->mVertices;
213                delete [] mGeometry[i]->mNormals;
214                delete [] mGeometry[i]->mTexcoords;
215
216                delete mGeometry[i];
217        }
218       
219        mGeometry.clear();
220
221        if (!ReadFile(filename))
222        {
223                cerr << "could not read file" << endl;
224                return false;
225        }
226
227        if (!WriteFile(outputFilename))
228        {
229                cerr << "could not write file" << endl;
230                return false;
231        }
232
233
234        return true;
235}
236
237
238bool ObjConverter::ReadFile(const string &filename)
239{
240        FILE *file;
241
242        if ((file = fopen(filename.c_str(), "r")) == NULL)
243        {       
244                return false;
245        }
246       
247        VertexArray faceVertices;
248        VertexArray faceNormals;
249        vector<Texcoord> faceTexcoords;
250
251        VertexArray vertices;
252        VertexArray normals;
253        vector<Texcoord> texcoords;
254
255        vector<int> indices;
256
257        int line = 0;
258        const int len = 10000;
259        char str[len];
260
261        while (fgets(str, len, file) != NULL)
262        {
263                switch (str[0])
264                {
265                case 'v': // vertex or normal
266                        {
267                                float x, y, z;
268
269                                switch (str[1])
270                                {
271                                case 'n' :
272                                        sscanf(str + 2, "%f %f %f", &x, &y, &z);
273                                        normals.push_back(SimpleVec(x, y, z));
274                                        break;
275                                case 't':
276                                        sscanf(str + 2, "%f %f", &x, &y);
277                                        texcoords.push_back(pair<float, float>(x, y));
278                                        break;
279                                default:
280                                        sscanf(str + 1, "%f %f %f", &x, &y, &z);
281                                        //const float scale = 5e-3f;
282                                        const float scale = 1.0f;
283                                        vertices.push_back(SimpleVec(x * scale, y * scale, z* scale));
284                                        //cout <<"v " << x << " " << y << " "<< z << " ";
285                                }
286                                break;
287                        }
288                case 'f':
289                        {
290                                //////////
291                                //-- indices in the current line
292
293                                LoadIndices(str,
294                                                vertices, normals, texcoords,
295                                                faceVertices, faceNormals, faceTexcoords);
296
297                                if (0 &&
298                                        (((line % 1000) == 999) && !faceVertices.empty()))
299                                {
300                                        ++ mNumShapes;
301
302                                        LoadShape(faceVertices, faceNormals, faceTexcoords);
303
304                                        faceVertices.clear();
305                                        faceNormals.clear();
306                                        faceTexcoords.clear();
307                                }
308
309                                break;
310                        }   // end face
311                case 'g': // load a new shape
312                        {/*
313                                if (!faceVertices.empty())
314                                {
315                                        ++ mNumShapes;
316
317                                        LoadShape(faceVertices, faceNormals, faceTexcoords);
318
319                                        faceVertices.clear();
320                                        faceNormals.clear();
321                                        faceTexcoords.clear();
322                                }*/
323                        }
324                        break;
325                default:
326                        // throw away line
327                        break;
328                }
329
330                ++ line;
331        }
332
333        if (!faceVertices.empty())
334        {
335                ++ mNumShapes;
336
337                LoadShape(faceVertices, faceNormals, faceTexcoords);
338
339                faceVertices.clear();
340                faceNormals.clear();
341                faceTexcoords.clear();
342        }
343
344        fclose(file);
345       
346        return true;
347}
348
349
350void ObjConverter::WriteGeometry(ogzstream &str, Geometry *geom)
351{
352        int vertexCount = geom->mVertexCount;
353        str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
354 
355        str.write(reinterpret_cast<char *>(geom->mVertices), sizeof(SimpleVec) * vertexCount);
356        str.write(reinterpret_cast<char *>(geom->mNormals), sizeof(SimpleVec) * vertexCount);
357
358        int texCoordCount = geom->mTexcoordCount;
359        str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
360
361        if (texCoordCount)
362                str.write(reinterpret_cast<char *>(geom->mTexcoords), sizeof(float) * texCoordCount * 2);
363       
364
365        ///////
366        //-- texture
367
368#ifdef USE_TEXTURE
369        int texId = 0;
370#else
371        int texId = -1;
372#endif
373
374        str.write(reinterpret_cast<char *>(&texId), sizeof(int));
375
376        bool alphaTestEnabled = false;
377        //bool cullFaceEnabled = false;
378        bool cullFaceEnabled = true;
379
380        str.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
381        str.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
382
383        // material
384        bool hasMaterial = true;
385        //bool hasMaterial = false;
386        str.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
387       
388        if (hasMaterial)
389        {
390                SimpleVec ambient, diffuse, spec, emm;
391
392                ambient.x = ambient.y = ambient.z = 0.2f;
393                //diffuse.x = diffuse.y = diffuse.z = 1.0f;
394                diffuse.x = 0.7f; diffuse.y = 0.5f; diffuse.z = 0.2f;
395                spec.x    = spec.y    = spec.z    =  .0f;
396                emm = spec;
397
398                // only write rgb part of the material
399                str.write(reinterpret_cast<char *>(&ambient), sizeof(SimpleVec));
400                str.write(reinterpret_cast<char *>(&diffuse), sizeof(SimpleVec));
401                str.write(reinterpret_cast<char *>(&spec), sizeof(SimpleVec));
402                str.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
403        }
404}
405
406
407bool ObjConverter::WriteFile(const string &filename)
408{
409        ogzstream ofile(filename.c_str());
410
411        if (!ofile.is_open())
412                return false;
413       
414
415        /////////
416        //-- write textures
417
418#ifdef USE_TEXTURE
419        int textureCount = 1;
420#else
421        int textureCount = 0;
422#endif
423        ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
424
425        if (textureCount > 0)
426        {
427                // hack
428                const string texName("wood.jpg");
429
430                int texnameSize = (int)texName.length() + 1;
431                ofile.write(reinterpret_cast<char *>(&texnameSize), sizeof(int));
432
433                ofile.write(texName.c_str(), sizeof(char) * texnameSize);
434
435                int boundS = 1, boundT = 1;
436
437                ofile.write(reinterpret_cast<char *>(&boundS), sizeof(int));
438                ofile.write(reinterpret_cast<char *>(&boundT), sizeof(int));
439        }
440
441
442        ///////////
443        //-- write shapes
444
445        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
446
447        vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
448
449        for (it = mGeometry.begin(); it != it_end; ++ it)
450        {
451                WriteGeometry(ofile, *it);
452        }
453
454
455        int entityCount = 1;
456        ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
457
458
459        //////////
460        //-- write single scene entity
461
462        // no transformation
463        bool hasTrafo = false;
464        ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
465
466        // a dummy lod
467        int numLODs = 1;
468        ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
469
470        float dist = 0;
471        ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
472
473        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
474
475        // all shapes belong to this scene entity
476        for (int i = 0; i < mNumShapes; ++ i)
477        {
478                int shapeId = i;
479                ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
480        }
481
482        return true;
483}
Note: See TracBrowser for help on using the repository browser.