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

Revision 13041, 27.0 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • 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 <iostream>
15#include <sstream>
16#include <fstream>
17#include <string>
18#include <stdio.h>
19
20#include "obj.h"
21
22#include <osg/Notify>
23
24#include <osgDB/FileUtils>
25#include <osgDB/FileNameUtils>
26
27#include <string.h>
28
29using namespace obj;
30
31static std::string strip( const std::string& ss )
32{
33    std::string result;
34    result.assign( ss.begin() + ss.find_first_not_of( ' ' ), ss.begin() + 1 + ss.find_last_not_of( ' ' ) );
35    return( result );
36}
37
38/*
39 * parse a subset of texture options, following
40 * http://local.wasp.uwa.edu.au/~pbourke/dataformats/mtl/
41 */
42static Material::Map parseTextureMap( const std::string& ss, Material::Map::TextureMapType type)
43{
44    Material::Map map;
45    std::string s(ss);
46    for (;;)
47    {
48        if (s[0] != '-')
49            break;
50
51        int n;
52        if (s[1] == 's' || s[1] == 'o')
53        {
54            float x, y, z;
55            if (sscanf(s.c_str(), "%*s %f %f %f%n", &x, &y, &z, &n) != 3)
56            {
57                break;
58            }
59
60            if (s[1] == 's')
61            {
62                // texture scale
63                map.uScale = x;
64                map.vScale = y;
65            }
66            else if (s[1] == 'o')
67            {
68                // texture offset
69                map.uOffset = x;
70                map.vOffset = y;
71            }
72        }
73        else if (s.compare(1,2,"mm")==0)
74        {
75            // texture color offset and gain
76            float base, gain;
77            if (sscanf(s.c_str(), "%*s %f %f%n", &base, &gain, &n) != 2)
78            {
79                break;
80            }
81            // UNUSED
82        }
83        else if (s.compare(1,2,"bm")==0)
84        {
85            // blend multiplier
86            float mult;
87            if (sscanf(s.c_str(), "%*s %f%n", &mult, &n) != 2)
88            {
89                break;
90            }
91            // UNUSED
92        }
93        else if (s.compare(1,5,"clamp")==0)
94        {
95            OSG_NOTICE<<"Got Clamp\n";
96            char c[4];
97            if (sscanf(s.c_str(), "%*s %3s%n", c, &n) != 1)
98            {
99                break;
100            }
101            if(strncmp(c,"on",2)==0) map.clamp = true;
102            else map.clamp = false;    // default behavioud
103        }
104        else
105            break;
106
107        s = strip(s.substr(n));
108    }
109
110    map.name = s;
111    map.type = type;
112    return map;
113}
114
115bool Model::readline(std::istream& fin, char* line, const int LINE_SIZE)
116{
117    if (LINE_SIZE<1) return false;
118
119    bool eatWhiteSpaceAtStart = true;
120    bool changeTabsToSpaces = true;
121
122    char* ptr = line;
123    char* end = line+LINE_SIZE-1;
124    bool skipNewline = false;
125    while (fin && ptr<end)
126    {
127
128        int c=fin.get();
129        int p=fin.peek();
130        if (c=='\r')
131        {
132            if (p=='\n')
133            {
134                // we have a windows line endings.
135                fin.get();
136                // OSG_NOTICE<<"We have dos line ending"<<std::endl;
137                if (skipNewline)
138                {
139                    skipNewline = false;
140                    *ptr++ = ' ';
141                    continue;
142                }
143                else break;
144            }
145            // we have Mac line ending
146            // OSG_NOTICE<<"We have mac line ending"<<std::endl;
147            if (skipNewline)
148            {
149                skipNewline = false;
150                *ptr++ = ' ';
151                continue;
152            }
153            else break;
154        }
155        else if (c=='\n')
156        {
157            // we have unix line ending.
158            // OSG_NOTICE<<"We have unix line ending"<<std::endl;
159            if (skipNewline)
160            {
161                *ptr++ = ' ';
162                continue;
163            }
164            else break;
165        }
166        else if (c=='\\' && (p=='\r' || p=='\n'))
167        {
168            // need to keep return;
169            skipNewline = true;
170        }
171        else if (c!=std::ifstream::traits_type::eof()) // don't copy eof.
172        {
173            skipNewline = false;
174
175            if (!eatWhiteSpaceAtStart || (c!=' ' && c!='\t'))
176            {
177                eatWhiteSpaceAtStart = false;
178                *ptr++ = c;
179            }
180        }
181
182
183    }
184
185    // strip trailing spaces
186    while (ptr>line && *(ptr-1)==' ')
187    {
188        --ptr;
189    }
190
191    *ptr = 0;
192
193    if (changeTabsToSpaces)
194    {
195
196        for(ptr = line; *ptr != 0; ++ptr)
197        {
198            if (*ptr == '\t') *ptr=' ';
199        }
200    }
201
202    return true;
203}
204
205
206std::string Model::lastComponent(const char* linep)
207{
208    std::string line = std::string(linep);
209    int space = line.find_last_of(" ");
210    if (space >= 0) {
211        line = line.substr(space+1);
212    }
213    return line;
214}
215
216bool Model::readMTL(std::istream& fin)
217{
218    OSG_INFO<<"Reading MTL file"<<std::endl;
219
220    const int LINE_SIZE = 4096;
221    char line[LINE_SIZE];
222    float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
223
224    Material* material = 0;// &(materialMap[""]);
225    std::string filename;
226
227    while (fin)
228    {
229        readline(fin,line,LINE_SIZE);
230        if (line[0]=='#' || line[0]=='$')
231        {
232            // comment line
233            // OSG_NOTICE <<"Comment: "<<line<<std::endl;
234        }
235        else if (strlen(line)>0)
236        {
237            if (strncmp(line,"newmtl ",7)==0)
238            {
239                std::string materialName(line+7);
240                material = & materialMap[materialName];
241                material->name = materialName;
242            }
243            else if (material)
244            {
245                if (strncmp(line,"Ka ",3)==0)
246                {
247                    unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
248
249                    if (fieldsRead==1)
250                    {
251                        material->ambient[ 0 ] = r;
252                    }
253                    else if (fieldsRead==2)
254                    {
255                        material->ambient[ 0 ] = r;
256                        material->ambient[ 1 ] = g;
257                    }
258                    else if (fieldsRead==3)
259                    {
260                        material->ambient[ 0 ] = r;
261                        material->ambient[ 1 ] = g;
262                        material->ambient[ 2 ] = b;
263                    }
264                    else if (fieldsRead==4)
265                    {
266                        material->ambient[ 0 ] = r;
267                        material->ambient[ 1 ] = g;
268                        material->ambient[ 2 ] = b;
269                        material->ambient[ 3 ] = a;
270                    }
271                }
272                else if (strncmp(line,"Kd ",3)==0)
273                {
274                    unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
275
276                    if (fieldsRead==1)
277                    {
278                        material->diffuse[ 0 ] = r;
279                    }
280                    else if (fieldsRead==2)
281                    {
282                        material->diffuse[ 0 ] = r;
283                        material->diffuse[ 1 ] = g;
284                    }
285                    else if (fieldsRead==3)
286                    {
287                        material->diffuse[ 0 ] = r;
288                        material->diffuse[ 1 ] = g;
289                        material->diffuse[ 2 ] = b;
290                    }
291                    else if (fieldsRead==4)
292                    {
293                        material->diffuse[ 0 ] = r;
294                        material->diffuse[ 1 ] = g;
295                        material->diffuse[ 2 ] = b;
296                        material->diffuse[ 3 ] = a;
297                    }
298                }
299                else if (strncmp(line,"Ks ",3)==0)
300                {
301                    unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
302
303                    if (fieldsRead==1)
304                    {
305                        material->specular[ 0 ] = r;
306                    }
307                    else if (fieldsRead==2)
308                    {
309                        material->specular[ 0 ] = r;
310                        material->specular[ 1 ] = g;
311                    }
312                    else if (fieldsRead==3)
313                    {
314                        material->specular[ 0 ] = r;
315                        material->specular[ 1 ] = g;
316                        material->specular[ 2 ] = b;
317                    }
318                    else if (fieldsRead==4)
319                    {
320                        material->specular[ 0 ] = r;
321                        material->specular[ 1 ] = g;
322                        material->specular[ 2 ] = b;
323                        material->specular[ 3 ] = a;
324                    }
325                }
326                else if (strncmp(line,"Ke ",3)==0)
327                {
328                    unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
329
330                    if (fieldsRead==1)
331                    {
332                        material->emissive[ 0 ] = r;
333                    }
334                    else if (fieldsRead==2)
335                    {
336                        material->emissive[ 0 ] = r;
337                        material->emissive[ 1 ] = g;
338                    }
339                    else if (fieldsRead==3)
340                    {
341                        material->emissive[ 0 ] = r;
342                        material->emissive[ 1 ] = g;
343                        material->emissive[ 2 ] = b;
344                    }
345                    else if (fieldsRead==4)
346                    {
347                        material->emissive[ 0 ] = r;
348                        material->emissive[ 1 ] = g;
349                        material->emissive[ 2 ] = b;
350                        material->emissive[ 3 ] = a;
351                    }
352                }
353                else if (strncmp(line,"Tf ",3)==0)
354                {
355                    unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
356
357                    if (fieldsRead==1)
358                    {
359                        material->Tf[ 0 ] = r;
360                    }
361                    else if (fieldsRead==2)
362                    {
363                        material->Tf[ 0 ] = r;
364                        material->Tf[ 1 ] = g;
365                    }
366                    else if (fieldsRead==3)
367                    {
368                        material->Tf[ 0 ] = r;
369                        material->Tf[ 1 ] = g;
370                        material->Tf[ 2 ] = b;
371                    }
372                    else if (fieldsRead==4)
373                    {
374                        material->Tf[ 0 ] = r;
375                        material->Tf[ 1 ] = g;
376                        material->Tf[ 2 ] = b;
377                        material->Tf[ 3 ] = a;
378                    }
379                }
380                else if (strncmp(line,"sharpness ",10)==0)
381                {
382                    float sharpness = 0.0f;
383                    unsigned int fieldsRead = sscanf(line+10,"%f", &sharpness);
384
385                    if (fieldsRead==1) material->sharpness = sharpness;
386                }
387                else if (strncmp(line,"illum ",6)==0)
388                {
389                    int illum = 0;
390                    unsigned int fieldsRead = sscanf(line+6,"%d", &illum);
391
392                    if (fieldsRead==1) material->illum = illum;
393                }
394                else if (strncmp(line,"Ns ",3)==0)
395                {
396                    int Ns = 0;
397                    unsigned int fieldsRead = sscanf(line+3,"%d", &Ns);
398
399                    if (fieldsRead==1) material->Ns = Ns;
400                }
401                else if (strncmp(line,"Ni ",3)==0)
402                {
403                    int Ni = 0;
404                    unsigned int fieldsRead = sscanf(line+3,"%d", &Ni);
405
406                    if (fieldsRead==1) material->Ni = Ni;
407                }
408                else if (strncmp(line,"Tr ",3)==0)
409                {
410                    float alpha=1.0f;
411                    unsigned int fieldsRead = sscanf(line+3,"%f", &alpha);
412
413                    if (fieldsRead==1)
414                    {
415                        material->ambient[3] = alpha;
416                        material->diffuse[3] = alpha;
417                        material->specular[3] = alpha;
418                        material->emissive[3] = alpha;
419                    }
420                }
421                else if (strncmp(line,"d ",2)==0)
422                {
423                    float alpha=1.0f;
424                    unsigned int fieldsRead = sscanf(line+2,"%f", &alpha);
425
426                    if (fieldsRead==1)
427                    {
428                        material->ambient[3] = alpha;
429                        material->diffuse[3] = alpha;
430                        material->specular[3] = alpha;
431                        material->emissive[3] = alpha;
432                    }
433                }
434                else if (strncmp(line,"map_Ka ",7)==0)
435                {
436                    material->maps.push_back(parseTextureMap(strip(line+7),Material::Map::AMBIENT));
437                }
438                // diffuse map
439                else if (strncmp(line,"map_Kd ",7)==0)
440                {
441                    material->maps.push_back(parseTextureMap(strip(line+7),Material::Map::DIFFUSE));
442                }
443                // specular colour/level map
444                else if (strncmp(line,"map_Ks ",7)==0)
445                {
446                     material->maps.push_back(parseTextureMap(strip(line+7),Material::Map::SPECULAR));
447                }
448                // map_opacity doesn't exist in the spec, but was already in the plugin
449                // so leave it or plugin will break for some users
450                else if (strncmp(line,"map_opacity ",12)==0)
451                {
452                    material->maps.push_back(parseTextureMap(strip(line+12),Material::Map::OPACITY));
453                }
454                // proper dissolve/opacity map
455                else if (strncmp(line,"map_d ",6)==0)
456                {
457                    material->maps.push_back(parseTextureMap(strip(line+6),Material::Map::OPACITY));
458                }
459                // specular exponent map
460                else if (strncmp(line,"map_Ns ",7)==0)
461                {
462                    material->maps.push_back(parseTextureMap(strip(line+7),Material::Map::SPECULAR_EXPONENT));
463                }
464                // modelling tools and convertors variously produce bump, map_bump, and map_Bump so parse them all
465                else if (strncmp(line,"bump ",5)==0)
466                {
467                    material->maps.push_back(parseTextureMap(strip(line+5),Material::Map::BUMP));
468                }
469                else if (strncmp(line,"map_bump ",9)==0)
470                {
471                    material->maps.push_back(parseTextureMap(strip(line+9),Material::Map::BUMP));
472                }
473                else if (strncmp(line,"map_Bump ",9)==0)
474                {
475                    material->maps.push_back(parseTextureMap(strip(line+9),Material::Map::BUMP));
476                }
477                // displacement map
478                else if (strncmp(line,"disp ",5)==0)
479                {
480                    material->maps.push_back(parseTextureMap(strip(line+5),Material::Map::DISPLACEMENT));
481                }
482                // reflection map (the original code had the possibility of a blank "refl" line
483                // which isn't correct according to the spec, so this bit might break for some
484                // modelling packages...
485                else if (strncmp(line,"refl ",5)==0)
486                {
487                    material->maps.push_back(parseTextureMap(strip(line+5),Material::Map::REFLECTION));
488                }
489                else
490                {
491                    OSG_NOTICE <<"*** line not handled *** :"<<line<<std::endl;
492                }
493            }
494            else
495            {
496                OSG_NOTICE <<"*** line not handled *** :"<<line<<std::endl;
497            }
498
499        }
500
501    }
502
503    return true;
504}
505
506std::string trim(const std::string& s)
507{
508  if(s.length() == 0)
509    return s;
510  int b = s.find_first_not_of(" \t");
511  int e = s.find_last_not_of(" \t");
512  if(b == -1) // No non-spaces
513    return "";
514  return std::string(s, b, e - b + 1);
515}
516
517bool Model::readOBJ(std::istream& fin, const osgDB::ReaderWriter::Options* options)
518{
519    OSG_INFO<<"Reading OBJ file"<<std::endl;
520
521    const int LINE_SIZE = 4096;
522    char line[LINE_SIZE];
523    float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f;
524
525    while (fin)
526    {
527        readline(fin,line,LINE_SIZE);
528        if (line[0]=='#' || line[0]=='$')
529        {
530            // comment line
531            // OSG_NOTICE <<"Comment: "<<line<<std::endl;
532        }
533        else if (strlen(line)>0)
534        {
535            if (strncmp(line,"v ",2)==0)
536            {
537                unsigned int fieldsRead = sscanf(line+2,"%f %f %f %f", &x, &y, &z, &w);
538
539                if (fieldsRead==1) vertices.push_back(osg::Vec3(x,0.0f,0.0f));
540                else if (fieldsRead==2) vertices.push_back(osg::Vec3(x,y,0.0f));
541                else if (fieldsRead==3) vertices.push_back(osg::Vec3(x,y,z));
542                else if (fieldsRead>=4) vertices.push_back(osg::Vec3(x/w,y/w,z/w));
543            }
544            else if (strncmp(line,"vn ",3)==0)
545            {
546                unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z);
547
548                if (fieldsRead==1) normals.push_back(osg::Vec3(x,0.0f,0.0f));
549                else if (fieldsRead==2) normals.push_back(osg::Vec3(x,y,0.0f));
550                else if (fieldsRead==3) normals.push_back(osg::Vec3(x,y,z));
551            }
552            else if (strncmp(line,"vt ",3)==0)
553            {
554                unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z);
555
556                if (fieldsRead==1) texcoords.push_back(osg::Vec2(x,0.0f));
557                else if (fieldsRead==2) texcoords.push_back(osg::Vec2(x,y));
558                else if (fieldsRead==3) texcoords.push_back(osg::Vec2(x,y));
559            }
560            else if (strncmp(line,"l ",2)==0 ||
561                     strncmp(line,"p ",2)==0 ||
562                     strncmp(line,"f ",2)==0)
563            {
564                char* ptr = line+2;
565
566                Element* element = new Element( (line[0]=='p') ? Element::POINTS :
567                                                (line[0]=='l') ? Element::POLYLINE :
568                                                Element::POLYGON );
569
570                // OSG_NOTICE<<"face"<<ptr<<std::endl;
571
572                int vi=0, ti=0, ni=0;
573                while(*ptr!=0)
574                {
575                    // skip white space
576                    while(*ptr==' ') ++ptr;
577
578                    if (sscanf(ptr, "%d/%d/%d", &vi, &ti, &ni) == 3)
579                    {
580                        // OSG_NOTICE<<"   vi="<<vi<<"/ti="<<ti<<"/ni="<<ni<<std::endl;
581                        element->vertexIndices.push_back(remapVertexIndex(vi));
582                        element->normalIndices.push_back(remapNormalIndex(ni));
583                        element->texCoordIndices.push_back(remapTexCoordIndex(ti));
584                    }
585                    else if (sscanf(ptr, "%d//%d", &vi, &ni) == 2)
586                    {
587                        // OSG_NOTICE<<"   vi="<<vi<<"//ni="<<ni<<std::endl;
588                        element->vertexIndices.push_back(remapVertexIndex(vi));
589                        element->normalIndices.push_back(remapNormalIndex(ni));
590                    }
591                    else if (sscanf(ptr, "%d/%d", &vi, &ti) == 2)
592                    {
593                        // OSG_NOTICE<<"   vi="<<vi<<"/ti="<<ti<<std::endl;
594                        element->vertexIndices.push_back(remapVertexIndex(vi));
595                        element->texCoordIndices.push_back(remapTexCoordIndex(ti));
596                    }
597                    else if (sscanf(ptr, "%d", &vi) == 1)
598                    {
599                        // OSG_NOTICE<<"   vi="<<vi<<std::endl;
600                        element->vertexIndices.push_back(remapVertexIndex(vi));
601                    }
602
603                    // skip to white space or end of line
604                    while(*ptr!=' ' && *ptr!=0) ++ptr;
605
606                }
607
608                if (!element->normalIndices.empty() && element->normalIndices.size() != element->vertexIndices.size())
609                {
610                    element->normalIndices.clear();
611                }
612
613                if (!element->texCoordIndices.empty() && element->texCoordIndices.size() != element->vertexIndices.size())
614                {
615                    element->texCoordIndices.clear();
616                }
617
618                if (!element->vertexIndices.empty())
619                {
620                    Element::CoordinateCombination coordateCombination = element->getCoordinateCombination();
621                    if (coordateCombination!=currentElementState.coordinateCombination)
622                    {
623                        currentElementState.coordinateCombination = coordateCombination;
624                        currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
625                    }
626                    addElement(element);
627                }
628                else
629                {
630                    // empty element, don't both adding, just unref to delete it.
631                    element->unref();
632                }
633
634            }
635            else if (strncmp(line,"usemtl ",7)==0)
636            {
637                std::string materialName( line+7 );
638                if (currentElementState.materialName != materialName)
639                {
640                    currentElementState.materialName = materialName;
641                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
642                }
643            }
644            else if (strncmp(line,"mtllib ",7)==0)
645            {
646                std::string materialFileName = trim( line+7 );
647                std::string fullPathFileName = osgDB::findDataFile( materialFileName, options );
648                if (!fullPathFileName.empty())
649                {
650                    osgDB::ifstream mfin( fullPathFileName.c_str() );
651                    if (mfin)
652                    {
653                        OSG_INFO << "Obj reading mtllib '" << fullPathFileName << "'\n";
654                        readMTL(mfin);
655                    }
656                    else
657                    {
658                        OSG_WARN << "Obj unable to load mtllib '" << fullPathFileName << "'\n";
659                    }
660                }
661                else
662                {
663                    OSG_WARN << "Obj unable to find mtllib '" << materialFileName << "'\n";
664                }
665            }
666            else if (strncmp(line,"o ",2)==0)
667            {
668                std::string objectName(line+2);
669                if (currentElementState.objectName != objectName)
670                {
671                    currentElementState.objectName = objectName;
672                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
673                }
674            }
675            else if (strcmp(line,"o")==0)
676            {
677                std::string objectName(""); // empty name
678                if (currentElementState.objectName != objectName)
679                {
680                    currentElementState.objectName = objectName;
681                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
682                }
683            }
684            else if (strncmp(line,"g ",2)==0)
685            {
686                std::string groupName(line+2);
687                if (currentElementState.groupName != groupName)
688                {
689                    currentElementState.groupName = groupName;
690                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
691                }
692            }
693            else if (strcmp(line,"g")==0)
694            {
695                std::string groupName(""); // empty name
696                if (currentElementState.groupName != groupName)
697                {
698                    currentElementState.groupName = groupName;
699                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
700                }
701            }
702            else if (strncmp(line,"s ",2)==0)
703            {
704                int smoothingGroup=0;
705                if (strncmp(line+2,"off",3)==0) smoothingGroup = 0;
706                else sscanf(line+2,"%d",&smoothingGroup);
707
708                if (currentElementState.smoothingGroup != smoothingGroup)
709                {
710                    currentElementState.smoothingGroup = smoothingGroup;
711                    currentElementList = 0; // reset the element list to force a recompute of which ElementList to use
712                }
713            }
714            else
715            {
716                OSG_NOTICE <<"*** line not handled *** :"<<line<<std::endl;
717            }
718
719        }
720
721    }
722#if 0
723    OSG_NOTICE <<"vertices :"<<vertices.size()<<std::endl;
724    OSG_NOTICE <<"normals :"<<normals.size()<<std::endl;
725    OSG_NOTICE <<"texcoords :"<<texcoords.size()<<std::endl;
726    OSG_NOTICE <<"materials :"<<materialMap.size()<<std::endl;
727    OSG_NOTICE <<"elementStates :"<<elementStateMap.size()<<std::endl;
728
729    unsigned int pos=0;
730    for(ElementStateMap::iterator itr=elementStateMap.begin();
731        itr!=elementStateMap.end();
732        ++itr,++pos)
733    {
734        const ElementState& es = itr->first;
735        ElementList& el = itr->second;
736        OSG_NOTICE<<"ElementState "<<pos<<std::endl;
737        OSG_NOTICE<<"    es.objectName="<<es.objectName<<std::endl;
738        OSG_NOTICE<<"    es.groupName="<<es.groupName<<std::endl;
739        OSG_NOTICE<<"    es.materialName="<<es.materialName<<std::endl;
740        OSG_NOTICE<<"    es.smoothGroup="<<es.smoothingGroup<<std::endl;
741        OSG_NOTICE<<"    ElementList ="<<el.size()<<std::endl;
742
743    }
744#endif
745    return true;
746}
747
748
749void Model::addElement(Element* element)
750{
751    if (!currentElementList)
752    {
753        currentElementList = & (elementStateMap[currentElementState]);
754    }
755    currentElementList->push_back(element);
756
757}
758
759osg::Vec3 Model::averageNormal(const Element& element) const
760{
761    osg::Vec3 normal;
762    for(Element::IndexList::const_iterator itr=element.normalIndices.begin();
763        itr!=element.normalIndices.end();
764        ++itr)
765    {
766        normal += normals[*itr];
767    }
768    normal.normalize();
769
770    return normal;
771}
772
773osg::Vec3 Model::computeNormal(const Element& element) const
774{
775    osg::Vec3 normal;
776    for(unsigned int i=0;i<element.vertexIndices.size()-2;++i)
777    {
778        osg::Vec3 a = vertices[element.vertexIndices[i]];
779        osg::Vec3 b = vertices[element.vertexIndices[i+1]];
780        osg::Vec3 c = vertices[element.vertexIndices[i+2]];
781        osg::Vec3 localNormal = (b-a)   ^(c-b);
782        normal += localNormal;
783    }
784    normal.normalize();
785
786    return normal;
787}
788
789bool Model::needReverse(const Element& element) const
790{
791    if (element.normalIndices.empty()) return false;
792
793    return computeNormal(element)*averageNormal(element) < 0.0f;
794}
Note: See TracBrowser for help on using the browser.