root/OpenSceneGraph/trunk/src/osgPlugins/obj/obj.cpp @ 3324

Revision 3324, 16.9 kB (checked in by robert, 10 years ago)

Removed debugging output.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <fstream>
15
16#include "obj.h"
17
18#include <osg/Notify>
19
20using namespace obj;
21
22bool Model::readline(std::istream& fin, char* line, const int LINE_SIZE)
23{
24    if (LINE_SIZE<1) return false;
25
26    bool eatWhiteSpaceAtStart = true;
27
28    char* ptr = line;
29    char* end = line+LINE_SIZE-1;
30    bool skipNewline = false;
31    while (fin && ptr<end)
32    {
33
34        int c=fin.get();
35        int p=fin.peek();
36        if (c=='\r')
37        {
38            if (p=='\n')
39            {
40                // we have a windows line endings.
41                fin.get();
42                // osg::notify(osg::NOTICE)<<"We have dos line ending"<<std::endl;
43                if (skipNewline)
44                {
45                    skipNewline = false;
46                    continue;
47                }
48                else break;
49            }
50            // we have Mac line ending
51            // osg::notify(osg::NOTICE)<<"We have mac line ending"<<std::endl;
52            if (skipNewline)
53            {
54                skipNewline = false;
55                continue;
56            }
57            else break;
58        }
59        else if (c=='\n')
60        {
61            // we have unix line ending.
62            // osg::notify(osg::NOTICE)<<"We have unix line ending"<<std::endl;
63            if (skipNewline)
64            {
65                skipNewline = false;
66                continue;
67            }
68            else break;
69        }
70        else if (c=='\\' && (p=='\r' || p=='\n'))
71        {
72            // need to keep return;
73            skipNewline = true;   
74        }
75        else if (c!=std::ifstream::traits_type::eof()) // don't copy eof.
76        {
77            skipNewline = false;
78
79            if (!eatWhiteSpaceAtStart || (c!=' ' && c!='\t'))
80            {
81                eatWhiteSpaceAtStart = false;
82                *ptr++ = c;
83            }
84        }
85       
86       
87    }
88    *ptr = 0;
89   
90    return true;
91}
92
93
94bool Model::readMTL(std::istream& fin)
95{
96    osg::notify(osg::INFO)<<"Reading MTL file"<<std::endl;
97
98    const int LINE_SIZE = 4096;
99    char line[LINE_SIZE];
100    float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
101
102    Material* material = &(materialMap[""]);
103
104    while (fin)
105    {
106        readline(fin,line,LINE_SIZE);
107        if (line[0]=='#')
108        {
109            // comment line
110            // osg::notify(osg::NOTICE) <<"Comment: "<<line<<std::endl;
111        }
112        else if (strlen(line)>0)
113        {
114            if (strncmp(line,"Ka ",3)==0)
115            {
116                unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
117
118                if (fieldsRead==1)      material->ambient.set(r,0.0f,0.0f,1.0f);
119                else if (fieldsRead==2) material->ambient.set(r,g,0.0f,1.0f);
120                else if (fieldsRead==3) material->ambient.set(r,g,b,1.0f);
121                else if (fieldsRead==4) material->ambient.set(r,g,b,a);
122            }
123            else if (strncmp(line,"Kd ",3)==0)
124            {
125                unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
126
127                if (fieldsRead==1)      material->diffuse.set(r,0.0f,0.0f,1.0f);
128                else if (fieldsRead==2) material->diffuse.set(r,g,0.0f,1.0f);
129                else if (fieldsRead==3) material->diffuse.set(r,g,b,1.0f);
130                else if (fieldsRead==4) material->diffuse.set(r,g,b,a);
131            }
132            else if (strncmp(line,"Ks ",3)==0)
133            {
134                unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
135
136                if (fieldsRead==1)      material->specular.set(r,0.0f,0.0f,1.0f);
137                else if (fieldsRead==2) material->specular.set(r,g,0.0f,1.0f);
138                else if (fieldsRead==3) material->specular.set(r,g,b,1.0f);
139                else if (fieldsRead==4) material->specular.set(r,g,b,a);
140            }
141            else if (strncmp(line,"Ke ",3)==0)
142            {
143                unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
144
145                if (fieldsRead==1)      material->emissive.set(r,0.0f,0.0f,1.0f);
146                else if (fieldsRead==2) material->emissive.set(r,g,0.0f,1.0f);
147                else if (fieldsRead==3) material->emissive.set(r,g,b,1.0f);
148                else if (fieldsRead==4) material->emissive.set(r,g,b,a);
149            }
150            else if (strncmp(line,"Tf ",3)==0)
151            {
152                unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
153
154                if (fieldsRead==1)      material->Tf.set(r,0.0f,0.0f,1.0f);
155                else if (fieldsRead==2) material->Tf.set(r,g,0.0f,1.0f);
156                else if (fieldsRead==3) material->Tf.set(r,g,b,1.0f);
157                else if (fieldsRead==4) material->Tf.set(r,g,b,a);
158            }
159            else if (strncmp(line,"newmtl ",7)==0)
160            {
161                std::string materialName(line+7);
162                if (material->name != materialName)
163                {
164                    material = & materialMap[materialName];
165                    material->name = materialName;
166                }
167            }
168            else if (strncmp(line,"sharpness ",10)==0)
169            {
170                float sharpness = 0.0f;
171                unsigned int fieldsRead = sscanf(line+10,"%f", &sharpness);
172
173                if (fieldsRead==1) material->sharpness = sharpness;
174            }
175            else if (strncmp(line,"illum ",6)==0)
176            {
177                int illum = 0;
178                unsigned int fieldsRead = sscanf(line+6,"%d", &illum);
179
180                if (fieldsRead==1) material->illum = illum;
181            }
182            else if (strncmp(line,"Ns ",3)==0)
183            {
184                int Ns = 0;
185                unsigned int fieldsRead = sscanf(line+3,"%d", &Ns);
186
187                if (fieldsRead==1) material->Ns = Ns;
188            }
189            else if (strncmp(line,"Ni ",3)==0)
190            {
191                int Ni = 0;
192                unsigned int fieldsRead = sscanf(line+3,"%d", &Ni);
193
194                if (fieldsRead==1) material->Ni = Ni;
195            }
196            else if (strncmp(line,"illum ",6)==0)
197            {
198                int illum = 0;
199                unsigned int fieldsRead = sscanf(line+6,"%d", &illum);
200
201                if (fieldsRead==1) material->illum = illum;
202            }
203            else if (strncmp(line,"Tr ",3)==0)
204            {
205                float alpha=1.0f;
206                unsigned int fieldsRead = sscanf(line+3,"%f", &alpha);
207
208                if (fieldsRead==1)
209                {
210                    material->ambient[3] = alpha;
211                    material->diffuse[3] = alpha;
212                    material->specular[3] = alpha;
213                    material->emissive[3] = alpha;
214                }
215            }
216            else if (strncmp(line,"d ",2)==0)
217            {
218                float alpha=1.0f;
219                unsigned int fieldsRead = sscanf(line+2,"%f", &alpha);
220
221                if (fieldsRead==1)
222                {
223                    material->ambient[3] = alpha;
224                    material->diffuse[3] = alpha;
225                    material->specular[3] = alpha;
226                    material->emissive[3] = alpha;
227                }
228            }
229            else if (strncmp(line,"map_Ka ",7)==0)
230            {
231                std::string filename(line+7);
232                material->map_Ka = filename;
233            }
234            else if (strncmp(line,"map_Kd ",7)==0)
235            {
236                std::string filename(line+7);
237                material->map_Kd = filename;
238            }
239            else if (strncmp(line,"map_Ks ",7)==0)
240            {
241                std::string filename(line+7);
242                material->map_Ks = filename;
243            }
244            else
245            {
246                osg::notify(osg::NOTICE) <<"*** line not handled *** :"<<line<<std::endl;
247            }
248       
249        }
250
251    }
252
253    return true;
254}
255
256bool Model::readOBJ(std::istream& fin)
257{
258    osg::notify(osg::INFO)<<"Reading OBJ file"<<std::endl;
259
260    const int LINE_SIZE = 4096;
261    char line[LINE_SIZE];
262    float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f;
263
264    while (fin)
265    {
266        readline(fin,line,LINE_SIZE);
267        if (line[0]=='#')
268        {
269            // comment line
270            // osg::notify(osg::NOTICE) <<"Comment: "<<line<<std::endl;
271        }
272        else if (strlen(line)>0)
273        {
274            if (strncmp(line,"v ",2)==0)
275            {
276                unsigned int fieldsRead = sscanf(line+2,"%f %f %f %f", &x, &y, &z, &w);
277
278                if (fieldsRead==1) vertices.push_back(osg::Vec3(x,0.0f,0.0f));
279                else if (fieldsRead==2) vertices.push_back(osg::Vec3(x,y,0.0f));
280                else if (fieldsRead==3) vertices.push_back(osg::Vec3(x,y,z));
281                else if (fieldsRead>=4) vertices.push_back(osg::Vec3(x/w,y/w,z/w));
282            }
283            else if (strncmp(line,"vn ",3)==0)
284            {
285                unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z);
286
287                if (fieldsRead==1) normals.push_back(osg::Vec3(x,0.0f,0.0f));
288                else if (fieldsRead==2) normals.push_back(osg::Vec3(x,y,0.0f));
289                else if (fieldsRead==3) normals.push_back(osg::Vec3(x,y,z));
290            }
291            else if (strncmp(line,"vt ",3)==0)
292            {
293                unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z);
294
295                if (fieldsRead==1) texcoords.push_back(osg::Vec2(x,0.0f));
296                else if (fieldsRead==2) texcoords.push_back(osg::Vec2(x,y));
297                else if (fieldsRead==3) texcoords.push_back(osg::Vec2(x,y));
298            }
299            else if (strncmp(line,"l ",2)==0 ||
300                     strncmp(line,"p ",2)==0 ||
301                     strncmp(line,"f ",2)==0)
302            {
303                char* ptr = line+2;
304               
305                Element* element = new Element( (line[0]=='p') ? Element::POINTS :
306                                                (line[0]=='l') ? Element::POLYLINE :
307                                                Element::POLYGON );
308
309                // osg::notify(osg::NOTICE)<<"face"<<ptr<<std::endl;
310
311                int vi=0, ti=0, ni=0;
312                while(*ptr!=0)
313                {
314                    // skip white space
315                    while(*ptr==' ') ++ptr;
316                   
317                    if (sscanf(ptr, "%d/%d/%d", &vi, &ti, &ni) == 3)
318                    {
319                        // osg::notify(osg::NOTICE)<<"   vi="<<vi<<"/ti="<<ti<<"/ni="<<ni<<std::endl;
320                        element->vertexIndices.push_back(remapVertexIndex(vi));
321                        element->normalIndices.push_back(remapNormalIndex(ni));
322                        element->texCoordIndices.push_back(remapTexCoordIndex(ti));
323                    }
324                    else if (sscanf(ptr, "%d//%d", &vi, &ni) == 2)
325                    {
326                        // osg::notify(osg::NOTICE)<<"   vi="<<vi<<"//ni="<<ni<<std::endl;
327                        element->vertexIndices.push_back(remapVertexIndex(vi));
328                        element->normalIndices.push_back(remapNormalIndex(ni));
329                    }
330                    else if (sscanf(ptr, "%d/%d", &vi, &ti) == 2)
331                    {
332                        // osg::notify(osg::NOTICE)<<"   vi="<<vi<<"/ti="<<ti<<std::endl;
333                        element->vertexIndices.push_back(remapVertexIndex(vi));
334                        element->texCoordIndices.push_back(remapTexCoordIndex(ti));
335                    }
336                    else if (sscanf(ptr, "%d", &vi) == 1)
337                    {
338                        // osg::notify(osg::NOTICE)<<"   vi="<<vi<<std::endl;
339                        element->vertexIndices.push_back(remapVertexIndex(vi));
340                    }
341
342                    // skip to white space or end of line
343                    while(*ptr!=' ' && *ptr!=0) ++ptr;
344               
345                }
346               
347                if (!element->normalIndices.empty() && element->normalIndices.size() != element->vertexIndices.size())
348                {
349                    element->normalIndices.clear();
350                }
351               
352                if (!element->texCoordIndices.empty() && element->texCoordIndices.size() != element->vertexIndices.size())
353                {
354                    element->texCoordIndices.clear();
355                }
356               
357                if (!element->vertexIndices.empty())
358                {
359                    Element::CoordinateCombination coordateCombination = element->getCoordinateCombination();
360                    if (coordateCombination!=currentElementState.coordinateCombination)
361                    {
362                        currentElementState.coordinateCombination = coordateCombination;
363                        currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
364                    }
365                    addElement(element);
366                }
367                else
368                {
369                    // empty element, don't both adding, just unref to delete it.
370                    element->unref();
371                }
372
373            }
374            else if (strncmp(line,"usemtl ",7)==0)
375            {
376                std::string materialName(line+7);
377                if (currentElementState.materialName != materialName)
378                {
379                    currentElementState.materialName = materialName;
380                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
381                }
382            }
383            else if (strncmp(line,"mtllib ",7)==0)
384            {
385                std::ifstream mfin(line+7);
386                if (mfin)
387                {
388                    readMTL(mfin);
389                }
390            }
391            else if (strncmp(line,"o ",2)==0)
392            {
393                std::string objectName(line+2);
394                if (currentElementState.objectName != objectName)
395                {
396                    currentElementState.objectName = objectName;
397                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
398                }
399            }
400            else if (strncmp(line,"g ",2)==0)
401            {
402                std::string groupName(line+2);
403                if (currentElementState.groupName != groupName)
404                {
405                    currentElementState.groupName = groupName;
406                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
407                }
408            }
409            else if (strncmp(line,"s ",2)==0)
410            {
411                int smoothingGroup=0;
412                if (strncmp(line+2,"off",3)==0) smoothingGroup = 0;
413                else sscanf(line+2,"%d",&smoothingGroup);
414               
415                if (currentElementState.smoothingGroup != smoothingGroup)
416                {
417                    currentElementState.smoothingGroup = smoothingGroup;
418                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
419                }
420            }
421            else
422            {
423                osg::notify(osg::NOTICE) <<"*** line not handled *** :"<<line<<std::endl;
424            }
425       
426        }
427
428    }
429#if 0
430    osg::notify(osg::NOTICE) <<"vertices :"<<vertices.size()<<std::endl;
431    osg::notify(osg::NOTICE) <<"normals :"<<normals.size()<<std::endl;
432    osg::notify(osg::NOTICE) <<"texcoords :"<<texcoords.size()<<std::endl;
433    osg::notify(osg::NOTICE) <<"materials :"<<materialMap.size()<<std::endl;
434    osg::notify(osg::NOTICE) <<"elementStates :"<<elementStateMap.size()<<std::endl;
435   
436    unsigned int pos=0;
437    for(ElementStateMap::iterator itr=elementStateMap.begin();
438        itr!=elementStateMap.end();
439        ++itr,++pos)
440    {
441        const ElementState& es = itr->first;
442        ElementList& el = itr->second;
443        osg::notify(osg::NOTICE)<<"ElementState "<<pos<<std::endl;
444        osg::notify(osg::NOTICE)<<"    es.objectName="<<es.objectName<<std::endl;
445        osg::notify(osg::NOTICE)<<"    es.groupName="<<es.groupName<<std::endl;
446        osg::notify(osg::NOTICE)<<"    es.materialName="<<es.materialName<<std::endl;
447        osg::notify(osg::NOTICE)<<"    es.smoothGroup="<<es.smoothingGroup<<std::endl;
448        osg::notify(osg::NOTICE)<<"    ElementList ="<<el.size()<<std::endl;
449       
450    }
451#endif
452    return true;
453}
454
455
456void Model::addElement(Element* element)
457{
458    if (!currentElementList)
459    {
460        currentElementList = & (elementStateMap[currentElementState]);
461    }
462    currentElementList->push_back(element);
463   
464}
Note: See TracBrowser for help on using the browser.