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 ....

RevLine 
[2961]1#include "ObjConverter.h"
[3012]2#include "SimpleTri.h"
3#include "SimpleVec.h"
[2961]4#include "gzstream.h"
5#include <iostream>
6
7
8using namespace std;
9
[3146]10//#define USE_TEXTURE
[2961]11
[3146]12
[2961]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{
[3146]22        vector<string> triples;
[2961]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
[3146]29        while (pch)
[2961]30        {
[3146]31                string s(pch);
32                //s += "\n",
33                triples.push_back(s);
34               
[2961]35                pch = strtok_s(NULL, " ", &next_token);   
36        }
37
38        vector<int> indices;
39        vector<int> nIndices;
40        vector<int> tIndices;
41
[3146]42        char seps[] = " /\t\n";
43
44        for (size_t i = 0; i < triples.size(); ++ i)
[2961]45        {
[3146]46                static int dummy = 0;
47
48                size_t found;
49                found = triples[i].find_first_of(seps);
50                size_t prevfound = 0;
[3012]51                // vertex, normal, texture indices
[3146]52                string str = triples[i].substr(prevfound, found);
[2961]53
[3146]54                int index = (int)strtol(str.c_str(), NULL, 10) - 1;
55
[2963]56                int tIndex = index;
[3146]57                int nIndex = index;     
58               
59                prevfound = found;
60                found = triples[i].find_first_of(seps, found + 1); 
[2963]61
[3146]62                if (found != string::npos)
63                {
64                        str = triples[i].substr(prevfound, found);
[2961]65
[3146]66                        int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
67                        if (idx > 0) tIndex = idx;
[3012]68                }
69
[3146]70                if ((found + 1) < triples[i].size())
[3012]71                {
[3146]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;
[3012]76                }
77
[2961]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                {
[3076]89                        // change orientation of faces?
[3059]90#if 1
[2961]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]]);
[2963]102
[3146]103
[3012]104                        if (!normals.empty())
105                        {
[3146]106                                //if (dummy < 3) cout << nIndices[idx1] << " " << nIndices[idx2] << " " << nIndices[idx3] << endl;
[3012]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                        {
[3146]113                                // no face normals? => create normals
114                                const SimpleTri tri(vertices[indices[idx1]],
115                                                        vertices[indices[idx2]],
116                                                                        vertices[indices[idx3]]);
[3012]117                                const SimpleVec n = tri.GetNormal();
[2963]118
[3012]119                                faceNormals.push_back(n);
120                                faceNormals.push_back(n);
121                                faceNormals.push_back(n);
122                        }
[2961]123
[3146]124                        ++ dummy;
[3012]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                        }
[2961]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
[3012]163        geom->mVertices = new SimpleVec[numElements];
164        geom->mNormals = new SimpleVec[numElements];
[2961]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        {
[3161]174#if 0
[3076]175                // convert to our camera system: change y and z
[2961]176                geom->mVertices[i].x = faceVertices[i].x;
177                geom->mVertices[i].y = -faceVertices[i].z;
178                geom->mVertices[i].z = faceVertices[i].y;
[3012]179       
[2961]180                geom->mNormals[i].x = faceNormals[i].x;
181                geom->mNormals[i].y = -faceNormals[i].z;
182                geom->mNormals[i].z = faceNormals[i].y;
[3146]183
[3012]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;
[2961]192
[3012]193#endif
[3089]194
[2965]195                if (i < geom->mTexcoordCount)
[2963]196                {
197                        geom->mTexcoords[i].first = faceTexcoords[i].first;
198                        geom->mTexcoords[i].second = faceTexcoords[i].second;
199                }
[2961]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        {
[3146]263                switch (str[0])
[2961]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);
[3012]273                                        normals.push_back(SimpleVec(x, y, z));
[2961]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);
[3161]281                                        //const float scale = 5e-3f;
282                                        const float scale = 1.0f;
[3146]283                                        vertices.push_back(SimpleVec(x * scale, y * scale, z* scale));
[2961]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
[3012]297                                if (0 &&
298                                        (((line % 1000) == 999) && !faceVertices.empty()))
[2963]299                                {
300                                        ++ mNumShapes;
301
302                                        LoadShape(faceVertices, faceNormals, faceTexcoords);
303
304                                        faceVertices.clear();
305                                        faceNormals.clear();
306                                        faceTexcoords.clear();
307                                }
308
[2961]309                                break;
310                        }   // end face
[3076]311                case 'g': // load a new shape
[2961]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:
[3146]326                        // throw away line
[2961]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 
[3012]355        str.write(reinterpret_cast<char *>(geom->mVertices), sizeof(SimpleVec) * vertexCount);
356        str.write(reinterpret_cast<char *>(geom->mNormals), sizeof(SimpleVec) * vertexCount);
[2961]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
[3146]368#ifdef USE_TEXTURE
[3089]369        int texId = 0;
[3146]370#else
371        int texId = -1;
372#endif
373
[2961]374        str.write(reinterpret_cast<char *>(&texId), sizeof(int));
375
376        bool alphaTestEnabled = false;
[3146]377        //bool cullFaceEnabled = false;
378        bool cullFaceEnabled = true;
[2961]379
380        str.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
381        str.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
382
383        // material
[3076]384        bool hasMaterial = true;
385        //bool hasMaterial = false;
[2961]386        str.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
387       
388        if (hasMaterial)
389        {
[3128]390                SimpleVec ambient, diffuse, spec, emm;
[2961]391
392                ambient.x = ambient.y = ambient.z = 0.2f;
[3161]393                //diffuse.x = diffuse.y = diffuse.z = 1.0f;
394                diffuse.x = 0.7f; diffuse.y = 0.5f; diffuse.z = 0.2f;
[3146]395                spec.x    = spec.y    = spec.z    =  .0f;
[3128]396                emm = spec;
[2961]397
398                // only write rgb part of the material
[3012]399                str.write(reinterpret_cast<char *>(&ambient), sizeof(SimpleVec));
400                str.write(reinterpret_cast<char *>(&diffuse), sizeof(SimpleVec));
[3128]401                str.write(reinterpret_cast<char *>(&spec), sizeof(SimpleVec));
402                str.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
[2961]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
[3146]418#ifdef USE_TEXTURE
[3089]419        int textureCount = 1;
[3146]420#else
421        int textureCount = 0;
422#endif
[2961]423        ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
424
425        if (textureCount > 0)
426        {
[3076]427                // hack
[2961]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
[3089]435                int boundS = 1, boundT = 1;
[2961]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.