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

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