root/OpenSceneGraph/trunk/src/osgPlugins/pfb/ConvertFromPerformer.cpp @ 13497

Revision 13497, 50.3 kB (checked in by robert, 24 hours ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3#include <osg/Config>
4#ifndef OSG_USE_DEPRECATED_GEOMETRY_METHODS 
5#define OSG_USE_DEPRECATED_GEOMETRY_METHODS 1
6#endif
7
8#include "ConvertFromPerformer.h"
9
10#include <osg/Group>
11#include <osg/MatrixTransform>
12#include <osg/LOD>
13#include <osg/Switch>
14#include <osg/Geode>
15#include <osg/Billboard>
16#include <osg/Texture2D>
17#include <osg/Image>
18#include <osg/CullFace>
19#include <osg/TexGen>
20#include <osg/TexEnv>
21#include <osg/TexMat>
22#include <osg/Material>
23#include <osg/Notify>
24#include <osg/Geometry>
25#include <osg/Sequence>
26#include <osg/ShadeModel>
27#include <osg/Depth>
28#include <osg/AlphaFunc>
29
30#include <osgDB/FileNameUtils>
31#include <osgDB/Registry>
32#include <osgDB/WriteFile>
33
34#include <Performer/pf/pfNode.h>
35#include <Performer/pf/pfGeode.h>
36#include <Performer/pf/pfBillboard.h>
37#include <Performer/pf/pfScene.h>
38#include <Performer/pf/pfGroup.h>
39#include <Performer/pf/pfDCS.h>
40#include <Performer/pf/pfSCS.h>
41#include <Performer/pf/pfLOD.h>
42#include <Performer/pf/pfSwitch.h>
43#include <Performer/pf/pfSequence.h>
44#include <Performer/pr/pfGeoState.h>
45#include <Performer/pr/pfMaterial.h>
46#include <Performer/pr/pfTexture.h>
47
48#ifdef WIN32
49#define snprintf _snprintf
50#endif
51
52// Need to undefine these because Performer defines them and it causes a
53// compiler error in ConvertFromPerformer::visitBillboard.
54#ifdef   AXIAL_ROT
55#undef   AXIAL_ROT
56#endif
57
58#ifdef   POINT_ROT_EYE
59#undef   POINT_ROT_EYE
60#endif
61
62#ifdef   POINT_ROT_WORLD
63#undef   POINT_ROT_WORLD
64#endif
65
66extern "C"
67{
68
69    extern int
70        pfdStoreFile_osg (pfNode* root, char *fileName)
71    {
72        ConvertFromPerformer converter;
73        osg::Node* node =  converter.convert(root);
74
75        if (node==NULL) return 0;
76        if (osgDB::writeNodeFile(*node,fileName)) return 1;
77        else return 0;
78    }
79
80}
81
82
83ConvertFromPerformer::ConvertFromPerformer()
84{
85    _osgRoot = NULL;
86
87    _gsetBindMap[PFGS_OFF] = osg::Geometry::BIND_OFF;
88    _gsetBindMap[PFGS_OVERALL] = osg::Geometry::BIND_OVERALL;
89    _gsetBindMap[PFGS_PER_PRIM] = osg::Geometry::BIND_PER_PRIMITIVE;
90    _gsetBindMap[PFGS_PER_VERTEX] = osg::Geometry::BIND_PER_VERTEX;
91
92    _saveImagesAsRGB = false;
93    _saveAbsoluteImagePath = false;
94}
95
96
97ConvertFromPerformer::~ConvertFromPerformer()
98{
99}
100
101
102osg::Node* ConvertFromPerformer::convert(pfNode* node)
103{
104    if (node==NULL) return NULL;
105    return visitNode(NULL,node);
106}
107
108
109osg::Object* ConvertFromPerformer::getOsgObject(pfObject* pfObj)
110{
111    PfObjectToOsgObjectMap::iterator fitr = _pfToOsgMap.find(pfObj);
112    if (fitr != _pfToOsgMap.end())
113    {
114        //         OSG_DEBUG << "Found shared object"<<std::endl;
115        return (*fitr).second;
116    }
117    else return NULL;
118}
119
120
121void ConvertFromPerformer::registerPfObjectForOsgObject(pfObject* pfObj,osg::Object* osgObj)
122{
123    _pfToOsgMap[pfObj] = osgObj;
124}
125
126
127osg::Node* ConvertFromPerformer::visitNode(osg::Group* osgParent,pfNode* node)
128{
129    if (node==NULL) return NULL;
130
131    if      (node->getType()->isDerivedFrom( pfBillboard::getClassType()))  return visitBillboard(osgParent,(pfBillboard*)node);
132    else if (node->getType()->isDerivedFrom( pfGeode::getClassType()))      return visitGeode(osgParent,(pfGeode*)node);
133    else if (node->getType()->isDerivedFrom( pfScene::getClassType()))      return visitScene(osgParent,(pfScene*)node);
134    else if (node->getType()->isDerivedFrom( pfDCS::getClassType()))        return visitDCS(osgParent,(pfDCS*)node);
135    else if (node->getType()->isDerivedFrom( pfSCS::getClassType()))        return visitSCS(osgParent,(pfSCS*)node);
136    else if (node->getType()->isDerivedFrom( pfLOD::getClassType()))        return visitLOD(osgParent,(pfLOD*)node);
137    else if (node->getType()->isDerivedFrom( pfSequence::getClassType()))   return visitSequence(osgParent,(pfSequence*)node);
138    else if (node->getType()->isDerivedFrom( pfSwitch::getClassType()))     return visitSwitch(osgParent,(pfSwitch*)node);
139    else if (node->getType()->isDerivedFrom( pfGroup::getClassType()))      return visitGroup(osgParent,(pfGroup*)node);
140
141    return NULL;
142}
143
144
145osg::Node* ConvertFromPerformer::visitScene(osg::Group* osgParent,pfScene* scene)
146{
147    osg::Group* osgScene = dynamic_cast<osg::Group*>(getOsgObject(scene));
148    if (osgScene)
149    {
150        if (osgParent) osgParent->addChild(osgScene);
151        return osgScene;
152    }
153
154    osgScene = new osg::Group;
155    if (osgParent) osgParent->addChild(osgScene);
156
157    registerPfObjectForOsgObject(scene,osgScene);
158
159    const char* name = scene->getName();
160    if (name) osgScene->setName(name);
161
162    for(int i=0;i<scene->getNumChildren();++i)
163    {
164        visitNode(osgScene,scene->getChild(i));
165    }
166    return (osg::Node*)osgScene;
167}
168
169
170osg::Node* ConvertFromPerformer::visitGroup(osg::Group* osgParent,pfGroup* group)
171{
172    osg::Group* osgGroup = dynamic_cast<osg::Group*>(getOsgObject(group));
173    if (osgGroup)
174    {
175        if (osgParent) osgParent->addChild(osgGroup);
176        return osgGroup;
177    }
178
179    osgGroup = new osg::Group;
180    if (osgParent) osgParent->addChild(osgGroup);
181
182    registerPfObjectForOsgObject(group,osgGroup);
183
184    const char* name = group->getName();
185    if (name) osgGroup->setName(name);
186
187    for(int i=0;i<group->getNumChildren();++i)
188    {
189        visitNode(osgGroup,group->getChild(i));
190    }
191    return (osg::Node*)osgGroup;
192}
193
194
195osg::Node* ConvertFromPerformer::visitLOD(osg::Group* osgParent,pfLOD* lod)
196{
197    osg::LOD* osgLOD = dynamic_cast<osg::LOD*>(getOsgObject(lod));
198    if (osgLOD)
199    {
200        if (osgParent) osgParent->addChild(osgLOD);
201        return osgLOD;
202    }
203
204    osgLOD = new osg::LOD;
205    if (osgParent) osgParent->addChild(osgLOD);
206
207    registerPfObjectForOsgObject(lod,osgLOD);
208
209    const char* name = lod->getName();
210    if (name) osgLOD->setName(name);
211
212    pfVec3 center;
213    lod->getCenter(center);
214    osg::Vec3 osgCenter(center[0],center[1],center[2]);
215    osgLOD->setCenter(osgCenter);
216
217    int i;
218    for(i=0;i<lod->getNumRanges()-1;++i)
219    {
220        osgLOD->setRange(i,lod->getRange(i),lod->getRange(i+1));
221    }
222
223    for(i=0;i<lod->getNumChildren();++i)
224    {
225        visitNode(osgLOD,lod->getChild(i));
226    }
227    return (osg::Node*)osgLOD;
228
229}
230
231
232osg::Node* ConvertFromPerformer::visitSwitch(osg::Group* osgParent,pfSwitch* switchNode)
233{
234    osg::Switch* osgSwitch = dynamic_cast<osg::Switch*>(getOsgObject(switchNode));
235    if (osgSwitch)
236    {
237        if (osgParent) osgParent->addChild(osgSwitch);
238        return osgSwitch;
239    }
240
241    osgSwitch = new osg::Switch;
242    osgSwitch->setAllChildrenOff();
243    if (osgParent) osgParent->addChild(osgSwitch);
244
245    registerPfObjectForOsgObject(switchNode,osgSwitch);
246
247    const char* name = switchNode->getName();
248    if (name) osgSwitch->setName(name);
249
250    float val = switchNode->getVal();
251    if (val==PFSWITCH_ON)
252    {
253        osgSwitch->setAllChildrenOn();
254    }
255    else if (val==PFSWITCH_OFF)
256    {
257        osgSwitch->setAllChildrenOff();
258    }
259    else
260    {
261        osgSwitch->setSingleChildOn((unsigned int)val);
262    }
263
264    for(int i=0;i<switchNode->getNumChildren();++i)
265    {
266        visitNode(osgSwitch,switchNode->getChild(i));
267    }
268    return (osg::Node*)osgSwitch;
269}
270
271
272osg::Node* ConvertFromPerformer::visitSequence(osg::Group* osgParent,
273                                               pfSequence* sequence)
274{
275
276    //OSG_WARN<<"Warning : cannot convert pfSequence as no osg::Sequence exists, using osg::Switch instead."<<std::endl;
277
278    osg::Sequence* osgSequence = dynamic_cast<osg::Sequence*>(getOsgObject(sequence));
279    if (osgSequence)
280    {
281        if (osgParent) osgParent->addChild(osgSequence);
282        return osgSequence;
283    }
284
285    osgSequence = new osg::Sequence;
286    if (osgParent) osgParent->addChild(osgSequence);
287
288    registerPfObjectForOsgObject(sequence,osgSequence);
289
290#if 0
291    if (sequence->getNumChildren()>0)
292    {
293        // set switch to first child as a 'hack' to prevent all
294        // children being traversed during rendering.  Note,
295        // once osg::Sequence has been implemented this can all
296        // be removed.
297        osgSequence->setValue(0);
298    }
299#endif
300
301    // add children
302    for(int i=0;i<sequence->getNumChildren();++i)
303    {
304        //OSG_WARN << "child " << i << " time " << sequence->getTime(i) << std::endl;
305        osgSequence->setTime(i, sequence->getTime(i));
306        visitNode(osgSequence,sequence->getChild(i));
307    }
308
309    // interval
310    int mode, begin, end;
311    sequence->getInterval(&mode, &begin, &end);
312
313    //OSG_WARN << "loop " << mode << std::endl;
314    osg::Sequence::LoopMode loopMode = osg::Sequence::LOOP;
315    if (mode == PFSEQ_SWING)
316        loopMode = osg::Sequence::SWING;
317    osgSequence->setInterval(loopMode, begin, end);
318
319    // duration
320    float speed;
321    int repeat;
322    sequence->getDuration(&speed, &repeat);
323    osgSequence->setDuration(speed, repeat);
324
325    // mode
326    mode = sequence->getMode();
327
328    osg::Sequence::SequenceMode seqMode = osg::Sequence::START;
329    switch (mode) {
330    case PFSEQ_STOP:
331        seqMode = osg::Sequence::STOP;
332        break;
333    case PFSEQ_PAUSE:
334        seqMode = osg::Sequence::PAUSE;
335        break;
336    }
337    osgSequence->setMode(seqMode);
338
339    return (osg::Node*)osgSequence;
340}
341
342
343osg::Node* ConvertFromPerformer::visitDCS(osg::Group* osgParent,pfDCS* dcs)
344{
345
346    osg::MatrixTransform* osgTransform = dynamic_cast<osg::MatrixTransform*>(getOsgObject(dcs));
347    if (osgTransform)
348    {
349        if (osgParent) osgParent->addChild(osgTransform);
350        return osgTransform;
351    }
352
353    osgTransform = new osg::MatrixTransform;
354    if (osgParent) osgParent->addChild(osgTransform);
355
356    registerPfObjectForOsgObject(dcs,osgTransform);
357
358    const char* name = dcs->getName();
359    if (name) osgTransform->setName(name);
360
361    pfMatrix matrix;
362    dcs->getMat(matrix);
363
364    osg::Matrix osgMatrix(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
365        matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
366        matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
367        matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
368
369    osgTransform->setMatrix(osgMatrix);
370
371    for(int i=0;i<dcs->getNumChildren();++i)
372    {
373        visitNode(osgTransform,dcs->getChild(i));
374    }
375    return (osg::Node*)osgTransform;
376}
377
378
379osg::Node* ConvertFromPerformer::visitSCS(osg::Group* osgParent,pfSCS* scs)
380{
381    // note the OSG does not currently have a SCS, so use DCS instead.
382    osg::MatrixTransform* osgTransform = dynamic_cast<osg::MatrixTransform*>(getOsgObject(scs));
383    if (osgTransform)
384    {
385        if (osgParent) osgParent->addChild(osgTransform);
386        return osgTransform;
387    }
388
389    osgTransform = new osg::MatrixTransform;
390    if (osgParent) osgParent->addChild(osgTransform);
391
392    osgTransform->setDataVariance(osg::Object::STATIC);
393
394    registerPfObjectForOsgObject(scs,osgTransform);
395
396    const char* name = scs->getName();
397    if (name) osgTransform->setName(name);
398
399    pfMatrix matrix;
400    scs->getMat(matrix);
401    osg::Matrix osgMatrix(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
402        matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
403        matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
404        matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
405
406    osgTransform->setMatrix(osgMatrix);
407
408    for(int i=0;i<scs->getNumChildren();++i)
409    {
410        visitNode(osgTransform,scs->getChild(i));
411    }
412    return (osg::Node*)osgTransform;
413}
414
415
416osg::Node* ConvertFromPerformer::visitGeode(osg::Group* osgParent,pfGeode* geode)
417{
418    osg::Geode* osgGeode = dynamic_cast<osg::Geode*>(getOsgObject(geode));
419    if (osgGeode)
420    {
421        if (osgParent) osgParent->addChild(osgGeode);
422        return osgGeode;
423    }
424
425    osgGeode = new osg::Geode;
426    if (osgParent) osgParent->addChild(osgGeode);
427
428    registerPfObjectForOsgObject(geode,osgGeode);
429
430    const char* name = geode->getName();
431    if (name) osgGeode->setName(name);
432
433    for(int i=0;i<geode->getNumGSets();++i)
434    {
435        visitGeoSet(osgGeode,geode->getGSet(i));
436    }
437
438    return (osg::Node*)osgGeode;
439}
440
441
442osg::Node* ConvertFromPerformer::visitBillboard(osg::Group* osgParent,pfBillboard* billboard)
443{
444    //    return NULL;
445
446    osg::Billboard* osgBillboard = dynamic_cast<osg::Billboard*>(getOsgObject(billboard));
447    if (osgBillboard)
448    {
449        if (osgParent) osgParent->addChild(osgBillboard);
450        return osgBillboard;
451    }
452
453    osgBillboard = new osg::Billboard;
454    if (osgParent) osgParent->addChild(osgBillboard);
455
456    registerPfObjectForOsgObject(billboard,osgBillboard);
457
458    const char* name = billboard->getName();
459    if (name) osgBillboard->setName(name);
460
461    pfVec3 axis;
462    billboard->getAxis(axis);
463    osgBillboard->setAxis(osg::Vec3(axis[0],axis[1],axis[2]));
464
465    switch( billboard->getMode( PFBB_ROT ) )
466    {
467    case PFBB_AXIAL_ROT:
468       osgBillboard->setMode( osg::Billboard::AXIAL_ROT );
469       break;
470    case PFBB_POINT_ROT_EYE:
471       osgBillboard->setMode( osg::Billboard::POINT_ROT_EYE );
472       break;
473    case PFBB_POINT_ROT_WORLD:
474       osgBillboard->setMode( osg::Billboard::POINT_ROT_WORLD );
475       break;
476    }
477
478    for(int i=0;i<billboard->getNumGSets();++i)
479    {
480                                 /* osg::GeoSet* osggset = */
481        visitGeoSet(osgBillboard,billboard->getGSet(i));
482        pfVec3 pos;
483        billboard->getPos(i,pos);
484        osgBillboard->setPosition(i,osg::Vec3(pos[0],pos[1],pos[2]));
485    }
486
487    return (osg::Node*)osgBillboard;
488}
489
490
491int ConvertFromPerformer::getNumVerts(pfGeoSet *gset)
492{
493    int nv;
494    int np;
495    int *lens;
496    int i;
497
498    np = gset->getNumPrims();
499    nv = 0;
500
501    switch( gset->getPrimType() )
502    {
503        case PFGS_POINTS :
504            nv = np;
505            break;
506
507        case PFGS_LINES :
508            nv = 2 * np;
509            break;
510
511        case PFGS_TRIS :
512            nv = 3 * np;
513            break;
514
515        case PFGS_QUADS :
516            nv = 4 * np;
517            break;
518
519        case PFGS_TRISTRIPS :
520        case PFGS_TRIFANS :
521        case PFGS_FLAT_TRISTRIPS :
522        case PFGS_POLYS :
523        case PFGS_LINESTRIPS :
524        case PFGS_FLAT_LINESTRIPS :
525
526            lens = gset->getPrimLengths();
527            for( i = 0; i < np; i++ )
528                nv += lens[i];
529            break;
530
531    }
532
533    return nv;
534}
535
536
537osg::Drawable* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet* geoset)
538{
539    if (geoset==NULL) return NULL;
540
541    osg::Drawable* osgDrawable = dynamic_cast<osg::Drawable*>(getOsgObject(geoset));
542    if (osgDrawable)
543    {
544        if (osgGeode) osgGeode->addDrawable(osgDrawable);
545        return osgDrawable;
546    }
547
548    // we'll make it easy to convert by using the Performer style osg::GeoSet,
549    // and then convert back to a osg::Geometry afterwards.
550    //osg::ref_ptr<osg::GeoSet> geom = new osg::GeoSet;
551    osg::Geometry* geom = new osg::Geometry;
552
553    int i;
554
555    // number of prims
556    int np = geoset->getNumPrims();
557    int *plen = geoset->getPrimLengths();
558
559    // Number of verticies (may be different than number of coords)
560    int nv = getNumVerts( geoset );
561
562    int prim = geoset->getPrimType();
563    int flat_shaded_skip_per_primitive=0;
564    if (prim == PFGS_FLAT_LINESTRIPS)       flat_shaded_skip_per_primitive=1;
565    else if (prim == PFGS_FLAT_TRISTRIPS)   flat_shaded_skip_per_primitive=2;
566    else if (prim == PFGS_FLAT_TRIFANS)     flat_shaded_skip_per_primitive=2;
567
568    int flat_shaded_skip_all_primitives=flat_shaded_skip_per_primitive*np;
569
570    // create the primitive sets.
571    switch( geoset->getPrimType() )
572    {
573        case PFGS_POINTS :
574            geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,np));
575            break;
576
577        case PFGS_LINES :
578            geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,2*np));
579            break;
580
581        case PFGS_TRIS :
582            geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES,0,3*np));
583            break;
584
585        case PFGS_QUADS :
586            geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4*np));
587            break;
588
589        case PFGS_TRISTRIPS :
590            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_TRIANGLE_STRIP,0,np,plen));
591            break;
592
593        case PFGS_TRIFANS :
594            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_TRIANGLE_FAN,0,np,plen));
595            break;
596
597        case PFGS_FLAT_TRISTRIPS :
598            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_TRIANGLE_STRIP,0,np,plen));
599            break;
600
601        case PFGS_POLYS :
602            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_POLYGON,0,np,plen));
603            break;
604
605        case PFGS_LINESTRIPS :
606            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_LINE_STRIP,0,np,plen));
607            break;
608
609        case PFGS_FLAT_LINESTRIPS :
610            geom->addPrimitiveSet(new osg::DrawArrayLengths(GL_LINE_STRIP,0,np,plen));
611            break;
612
613        default:
614           OSG_INFO << "ConvertFromPerformer::visitGeoSet: Osg can't convert primitive "
615                     << geoset->getPrimType()
616                     << std::endl;
617            break;
618
619    }
620
621
622    pfVec3 *coords;
623    ushort *ilist;
624    geoset->getAttrLists( PFGS_COORD3,  (void **)&coords, &ilist );
625
626    // copy the vertex coordinates across.
627    if( coords )
628    {
629        // calc the maximum num of vertex from the index list.
630        int cc;
631        if (ilist)
632        {
633            cc = 0;
634            for( i = 0; i < nv; i++ )
635                if( ilist[i] > cc ) cc = ilist[i];
636            cc++;
637        }
638        else
639            cc = nv;
640
641        osg::Vec3Array* osg_coords = new osg::Vec3Array(cc);
642        for( i = 0; i < cc; i++ )
643        {
644            (*osg_coords)[i][0] = coords[i][0];
645            (*osg_coords)[i][1] = coords[i][1];
646            (*osg_coords)[i][2] = coords[i][2];
647        }
648
649        geom->setVertexArray(osg_coords);
650
651        if(ilist)
652        {
653            geom->setVertexIndices(new osg::UShortArray(nv,ilist));
654        }
655
656    }
657
658
659    pfVec2 *tcoords;
660    geoset->getAttrLists( PFGS_TEXCOORD2,  (void **)&tcoords, &ilist );
661
662    // copy texture coords
663    if(tcoords)
664    {
665        int bind = geoset->getAttrBind( PFGS_TEXCOORD2 );
666
667
668        if (bind==PFGS_PER_VERTEX && bind != PFGS_OFF)
669        {
670            int nn = bind == PFGS_OFF ? 0 :
671                     bind == PFGS_OVERALL ? 1 :
672                     bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
673                     bind == PFGS_PER_VERTEX ? nv : 0;
674
675            // set the normal binding type.
676            //geom->setTextureBinding(_gsetBindMap[bind]);
677
678            // calc the maximum num of vertex from the index list.
679            int cc;
680            if (ilist)
681            {
682                cc = 0;
683                for( i = 0; i < nv; i++ )
684                    if( ilist[i] > cc ) cc = ilist[i];
685                cc++;
686            }
687            else
688                cc = nn;
689
690            osg::Vec2Array* osg_tcoords = new osg::Vec2Array(cc);
691            for( i = 0; i < cc; i++ )
692            {
693                (*osg_tcoords)[i][0] = tcoords[i][0];
694                (*osg_tcoords)[i][1] = tcoords[i][1];
695            }
696
697            geom->setTexCoordArray(0,osg_tcoords);
698
699            if(ilist)
700            {
701                geom->setTexCoordIndices(0,new osg::UShortArray(nn,ilist));
702            }
703        }
704        else
705        {
706            OSG_INFO<<"OSG can't handle non PER_VERTEX tex coord binding at present"<<std::endl;
707        }
708
709    }
710
711    pfVec3 *norms;
712    geoset->getAttrLists( PFGS_NORMAL3,  (void **)&norms, &ilist );
713
714    // copy normals
715    if(norms)
716    {
717        int bind = geoset->getAttrBind( PFGS_NORMAL3 );
718        if (bind==PFGS_PER_VERTEX && flat_shaded_skip_all_primitives!=0)
719        {
720            // handle flat shaded skip of normals.
721            int nn = nv-flat_shaded_skip_all_primitives;
722
723
724            if (ilist)
725            {
726                // calc the maximum num of vertex from the index list.
727                int cc = 0;
728                for( i = 0; i < nn; i++ )
729                    if( ilist[i] > cc ) cc = ilist[i];
730                cc++;
731
732                // straight forward mapping of normals across.
733                osg::Vec3Array* osg_norms = new osg::Vec3Array(cc);
734                for( i = 0; i < cc; i++ )
735                {
736                    (*osg_norms)[i][0] = norms[i][0];
737                    (*osg_norms)[i][1] = norms[i][1];
738                    (*osg_norms)[i][2] = norms[i][2];
739                }
740                geom->setNormalArray(osg_norms);
741
742                // set the normal binding type.
743                geom->setNormalBinding(_gsetBindMap[bind]);
744
745                osg::UShortArray* osg_indices = new osg::UShortArray;
746                osg_indices->reserve(nv);
747
748                int ni=0;
749                for( i = 0; i < np; ++i)
750                {
751                    for(int si=0;si<flat_shaded_skip_per_primitive;++si)
752                    {
753                        osg_indices->push_back(ilist[ni]);
754                    }
755                    for( int pi=0; pi < plen[i]-flat_shaded_skip_per_primitive; ++pi)
756                    {
757                        osg_indices->push_back(ilist[ni++]);
758                    }
759                }
760
761                if (ni!=nn)
762                {
763                    OSG_INFO << "1 ni!=nn"<<std::endl;
764                }
765
766                geom->setNormalIndices(osg_indices);
767
768
769            }
770            else
771            {
772                osg::Vec3Array* osg_norms = new osg::Vec3Array;
773                osg_norms->reserve(nv);
774
775                int ni=0;
776                for( i = 0; i < np; ++i)
777                {
778                    for(int si=0;si<flat_shaded_skip_per_primitive;++si)
779                    {
780                        osg_norms->push_back(osg::Vec3(norms[ni][0],norms[ni][1],norms[ni][2]));
781                    }
782                    for( int pi=0; pi < plen[i]-flat_shaded_skip_per_primitive; ++pi)
783                    {
784                        osg_norms->push_back(osg::Vec3(norms[ni][0],norms[ni][1],norms[ni][2]));
785                        ni++;
786                    }
787                }
788
789                geom->setNormalArray(osg_norms);
790            }
791
792        }
793        else
794        {
795            int nn = bind == PFGS_OFF ? 0 :
796                     bind == PFGS_OVERALL ? 1 :
797                     bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
798                     bind == PFGS_PER_VERTEX ? nv : 0;
799
800            // calc the maximum num of vertex from the index list.
801            int cc;
802            if (ilist)
803            {
804                cc = 0;
805                for( i = 0; i < nn; i++ )
806                    if( ilist[i] > cc ) cc = ilist[i];
807                cc++;
808            }
809            else
810                cc = nn;
811
812            osg::Vec3Array* osg_norms = new osg::Vec3Array(cc);
813            for( i = 0; i < cc; i++ )
814            {
815                (*osg_norms)[i][0] = norms[i][0];
816                (*osg_norms)[i][1] = norms[i][1];
817                (*osg_norms)[i][2] = norms[i][2];
818            }
819            geom->setNormalArray(osg_norms);
820
821            // set the normal binding type.
822            geom->setNormalBinding(_gsetBindMap[bind]);
823
824            if(ilist)
825            {
826                geom->setNormalIndices(new osg::UShortArray(nn,ilist));
827            }
828
829        }
830    }
831
832    pfVec4 *colors;
833    geoset->getAttrLists( PFGS_COLOR4,  (void **)&colors, &ilist );
834
835    // copy color coords
836    if(colors)
837    {
838        int bind = geoset->getAttrBind( PFGS_COLOR4 );
839        if (bind==PFGS_PER_VERTEX && flat_shaded_skip_all_primitives!=0)
840        {
841            // handle flat shaded skip of colours.
842            // handle flat shaded skip of normals.
843            int nn = nv-flat_shaded_skip_all_primitives;
844
845            if (ilist)
846            {
847                // calc the maximum num of vertex from the index list.
848                int cc = 0;
849                for( i = 0; i < nn; i++ )
850                    if( ilist[i] > cc ) cc = ilist[i];
851                cc++;
852
853                // straight forward mapping of normals across.
854                osg::Vec4Array* osg_colors = new osg::Vec4Array(cc);
855                for( i = 0; i < cc; i++ )
856                {
857                    (*osg_colors)[i][0] = colors[i][0];
858                    (*osg_colors)[i][1] = colors[i][1];
859                    (*osg_colors)[i][2] = colors[i][2];
860                    (*osg_colors)[i][3] = colors[i][3];
861                }
862                geom->setColorArray(osg_colors);
863
864                // set the color binding type.
865                geom->setColorBinding(_gsetBindMap[bind]);
866
867
868                osg::UShortArray* osg_indices = new osg::UShortArray;
869                osg_indices->reserve(nv);
870
871                int ni=0;
872                for( i = 0; i < np; ++i)
873                {
874                    for(int si=0;si<flat_shaded_skip_per_primitive;++si)
875                    {
876                        osg_indices->push_back(ilist[ni]);
877                    }
878                    for( int pi=0; pi < plen[i]-flat_shaded_skip_per_primitive; ++pi)
879                    {
880                        osg_indices->push_back(ilist[ni++]);
881                    }
882                }
883
884                if (ni!=nn)
885                {
886                    OSG_INFO << "1 ni!=nn"<<std::endl;
887                }
888
889                geom->setColorIndices(osg_indices);
890
891
892            }
893            else
894            {
895                osg::Vec4Array* osg_colors = new osg::Vec4Array;
896                osg_colors->reserve(nv);
897
898                int ni=0;
899                for( i = 0; i < np; ++i)
900                {
901                    for(int si=0;si<flat_shaded_skip_per_primitive;++si)
902                    {
903                        osg_colors->push_back(osg::Vec4(colors[ni][0],colors[ni][1],colors[ni][2],colors[ni][3]));
904                    }
905                    for( int pi=0; pi < plen[i]-flat_shaded_skip_per_primitive; ++pi)
906                    {
907                        osg_colors->push_back(osg::Vec4(colors[ni][0],colors[ni][1],colors[ni][2],colors[ni][3]));
908                        ni++;
909                    }
910                }
911
912                geom->setColorArray(osg_colors);
913
914                // set the color binding type.
915                geom->setColorBinding(_gsetBindMap[bind]);
916            }
917        }
918        else
919        {
920            int nn = bind == PFGS_OFF ? 0 :
921                     bind == PFGS_OVERALL ? 1 :
922                     bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
923                     bind == PFGS_PER_VERTEX ? nv : 0;
924
925            // calc the maximum num of vertex from the index list.
926            int cc;
927            if (ilist)
928            {
929                cc = 0;
930                for( i = 0; i < nn; i++ )
931                    if( ilist[i] > cc ) cc = ilist[i];
932                cc++;
933            }
934            else
935                cc = nn;
936
937            osg::Vec4Array* osg_colors = new osg::Vec4Array(cc);
938            for( i = 0; i < cc; i++ )
939            {
940                (*osg_colors)[i][0] = colors[i][0];
941                (*osg_colors)[i][1] = colors[i][1];
942                (*osg_colors)[i][2] = colors[i][2];
943                (*osg_colors)[i][3] = colors[i][3];
944            }
945
946            geom->setColorArray(osg_colors);
947
948            // set the color binding type.
949            geom->setColorBinding(_gsetBindMap[bind]);
950
951
952            if(ilist)
953            {
954                geom->setColorIndices(new osg::UShortArray(nn,ilist));
955            }
956
957        }
958    }
959    else
960    {
961    }
962
963
964
965    visitGeoState(geom,geoset->getGState());
966
967    if (flat_shaded_skip_per_primitive)
968    {
969        osg::StateSet* stateset = geom->getOrCreateStateSet();
970        osg::ShadeModel* shademodel = dynamic_cast<osg::ShadeModel*>(stateset->getAttribute(osg::StateAttribute::SHADEMODEL));
971        if (!shademodel)
972        {
973            shademodel = new osg::ShadeModel;
974            stateset->setAttribute(shademodel);
975        }
976        shademodel->setMode( osg::ShadeModel::FLAT );
977    }
978
979    osgGeode->addDrawable(geom);
980    registerPfObjectForOsgObject(geoset,geom);
981
982    return geom;
983}
984
985
986osg::StateSet* ConvertFromPerformer::visitGeoState(osg::Drawable* osgDrawable,pfGeoState* geostate)
987{
988    if (geostate==NULL) return NULL;
989
990    osg::StateSet* osgStateSet = dynamic_cast<osg::StateSet*>(getOsgObject(geostate));
991    if (osgStateSet)
992    {
993        if (osgDrawable) osgDrawable->setStateSet(osgStateSet);
994        return osgStateSet;
995    }
996
997    osgStateSet = new osg::StateSet;
998    if (osgDrawable) osgDrawable->setStateSet(osgStateSet);
999
1000    registerPfObjectForOsgObject(geostate,osgStateSet);
1001
1002    // Don could you fill in some of these blanks???
1003    unsigned int inherit = geostate->getInherit();
1004    //     OSG_DEBUG << endl << "Inherit = "<<inherit<<std::endl;
1005    //     if (inherit & PFSTATE_TRANSPARENCY) OSG_DEBUG << "Inherit PFSTATE_TRANSPARENCY"<<std::endl;
1006    //     else OSG_DEBUG << "Define PFSTATE_TRANSPARENCY"<<std::endl;
1007    //     if (inherit & PFSTATE_ENTEXTURE) OSG_DEBUG << "Inherit PFSTATE_ENTEXTURE"<<std::endl;
1008    //     else OSG_DEBUG << "Define PFSTATE_ENTEXTURE"<<std::endl;
1009    //     if (inherit & PFSTATE_CULLFACE) OSG_DEBUG << "Inherit PFSTATE_CULLFACE"<<std::endl;
1010    //     else OSG_DEBUG << "Define PFSTATE_CULLFACE"<<std::endl;
1011    //     if (inherit & PFSTATE_ENLIGHTING) OSG_DEBUG << "Inherit PFSTATE_ENLIGHTING"<<std::endl;
1012    //     else OSG_DEBUG << "Define PFSTATE_ENLIGHTING"<<std::endl;
1013    //     if (inherit & PFSTATE_ENFOG) OSG_DEBUG << "Inherit PFSTATE_ENFOG"<<std::endl;
1014    //     else OSG_DEBUG << "Define PFSTATE_ENFOG"<<std::endl;
1015    //     if (inherit & PFSTATE_ENWIREFRAME) OSG_DEBUG << "Inherit PFSTATE_ENWIREFRAME"<<std::endl;
1016    //     else OSG_DEBUG << "Define PFSTATE_ENWIREFRAME"<<std::endl;
1017    //     if (inherit & PFSTATE_ENTEXMAT) OSG_DEBUG << "Inherit PFSTATE_ENTEXMAT"<<std::endl;
1018    //     else OSG_DEBUG << "Define PFSTATE_ENTEXMAT"<<std::endl;
1019    //     if (inherit & PFSTATE_ENTEXGEN) OSG_DEBUG << "Inherit PFSTATE_ENTEXGEN"<<std::endl;
1020    //     else OSG_DEBUG << "Define PFSTATE_ENTEXGEN"<<std::endl;
1021    //
1022    //     if (inherit & PFSTATE_ANTIALIAS) OSG_DEBUG << "Inherit PFSTATE_ANTIALIAS"<<std::endl;
1023    //     else OSG_DEBUG << "Define PFSTATE_ANTIALIAS"<<std::endl;
1024    //     if (inherit & PFSTATE_DECAL) OSG_DEBUG << "Inherit PFSTATE_DECAL"<<std::endl;
1025    //     else OSG_DEBUG << "Define PFSTATE_DECAL"<<std::endl;
1026    //     if (inherit & PFSTATE_ALPHAFUNC) OSG_DEBUG << "Inherit PFSTATE_ALPHAFUNC"<<std::endl;
1027    //     else OSG_DEBUG << "Define PFSTATE_ALPHAFUNC"<<std::endl;
1028    //     if (inherit & PFSTATE_ENCOLORTABLE) OSG_DEBUG << "Inherit PFSTATE_ENCOLORTABLE"<<std::endl;
1029    //     else OSG_DEBUG << "Define PFSTATE_ENCOLORTABLE"<<std::endl;
1030    //     if (inherit & PFSTATE_ENHIGHLIGHTING) OSG_DEBUG << "Inherit PFSTATE_ENHIGHLIGHTING"<<std::endl;
1031    //     else OSG_DEBUG << "Define PFSTATE_ENHIGHLIGHTING"<<std::endl;
1032    //     if (inherit & PFSTATE_ENLPOINTSTATE) OSG_DEBUG << "Inherit PFSTATE_ENLPOINTSTATE"<<std::endl;
1033    //     else OSG_DEBUG << "Define PFSTATE_ENLPOINTSTATE"<<std::endl;
1034    //     if (inherit & PFSTATE_ENTEXLOD) OSG_DEBUG << "Inherit PFSTATE_ENTEXLOD"<<std::endl;
1035    //     else OSG_DEBUG << "Define PFSTATE_ENTEXLOD"<<std::endl;
1036
1037    if (!(inherit & PFSTATE_ALPHAFUNC)) {
1038        int mode = geostate->getMode(PFSTATE_ALPHAFUNC);
1039        float value = geostate->getVal(PFSTATE_ALPHAREF);
1040        osg::AlphaFunc* aFunc = new osg::AlphaFunc();
1041        switch (mode) {
1042            case PFAF_ALWAYS:
1043                aFunc->setFunction(osg::AlphaFunc::ALWAYS); //==PFAF_OFF in performer 311
1044                break;
1045            case PFAF_EQUAL:
1046                aFunc->setFunction(osg::AlphaFunc::EQUAL);
1047                break;
1048            case PFAF_GEQUAL:
1049                aFunc->setFunction(osg::AlphaFunc::GEQUAL);
1050                break;
1051            case PFAF_GREATER:
1052                aFunc->setFunction(osg::AlphaFunc::GREATER);
1053                break;
1054            case PFAF_LEQUAL:
1055                aFunc->setFunction(osg::AlphaFunc::LEQUAL);
1056                break;
1057            case PFAF_LESS:
1058                aFunc->setFunction(osg::AlphaFunc::LESS);
1059                break;
1060            case PFAF_NEVER:
1061                aFunc->setFunction(osg::AlphaFunc::NEVER);
1062                break;
1063            case PFAF_NOTEQUAL:
1064                aFunc->setFunction(osg::AlphaFunc::NOTEQUAL);
1065                break;
1066//            case PFAF_OFF: //==PFAF_ALWAYS
1067//                break;
1068            default: //warn PFAF not recognized?
1069                break;
1070        }
1071        aFunc->setReferenceValue(value);
1072        if (mode != PFAF_OFF) {
1073            osgStateSet->setAttributeAndModes(aFunc);
1074        } else {
1075            osgStateSet->setAttributeAndModes(aFunc,osg::StateAttribute::OFF);
1076        }
1077    }
1078
1079    if (inherit & PFSTATE_TRANSPARENCY) osgStateSet->setMode(GL_BLEND,osg::StateAttribute::INHERIT);
1080    else
1081    {
1082        int mode = geostate->getMode(PFSTATE_TRANSPARENCY);
1083        if (mode & PFTR_NO_OCCLUDE) {
1084            mode &= ~PFTR_NO_OCCLUDE;//remove NO_OCCLUDE bit
1085            osg::Depth* depth = new osg::Depth(osg::Depth::LESS,0.0f,1.0f,false);
1086            osgStateSet->setAttributeAndModes(depth);
1087        }
1088        switch(mode)
1089        {
1090            case(PFTR_FAST):
1091            case(PFTR_HIGH_QUALITY):
1092            case(PFTR_BLEND_ALPHA):
1093            case(PFTR_MS_ALPHA):
1094            case(PFTR_MS_ALPHA_MASK):
1095//            case(PFTR_NO_OCCLUDE): //this is a bit flag.
1096            case(PFTR_ON):
1097                osgStateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
1098                osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
1099                break;
1100            case(PFTR_OFF): osgStateSet->setMode(GL_BLEND,osg::StateAttribute::OFF);break;
1101            default:        osgStateSet->setMode(GL_BLEND,osg::StateAttribute::INHERIT);break;
1102        }
1103    }
1104
1105    if (inherit & PFSTATE_ENTEXTURE) osgStateSet->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::INHERIT);
1106    else
1107    {
1108        int mode = geostate->getMode(PFSTATE_ENTEXTURE);
1109        switch(mode)
1110        {
1111            case(PF_ON):    osgStateSet->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);break;
1112            case(PF_OFF):
1113            default:        osgStateSet->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);break;
1114        }
1115    }
1116
1117    if (inherit & PFSTATE_CULLFACE) osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::INHERIT);
1118    else
1119    {
1120        int mode = geostate->getMode(PFSTATE_CULLFACE);
1121        switch(mode)
1122        {
1123            case(PFCF_BACK):
1124            {
1125                osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
1126                osg::CullFace *cf = new osg::CullFace;
1127                cf->setMode(osg::CullFace::BACK);
1128                osgStateSet->setAttribute(cf);
1129            }
1130            break;
1131
1132            case(PFCF_FRONT):
1133            {
1134                osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
1135                osg::CullFace *cf = new osg::CullFace;
1136                cf->setMode(osg::CullFace::FRONT);
1137                osgStateSet->setAttribute(cf);
1138            }
1139            break;
1140            case(PFCF_BOTH):
1141            {
1142                osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
1143                osg::CullFace *cf = new osg::CullFace;
1144                cf->setMode(osg::CullFace::FRONT_AND_BACK);
1145                osgStateSet->setAttribute(cf);
1146            }
1147            break;
1148            case(PFCF_OFF):
1149            default:        osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);break;
1150        }
1151    }
1152
1153    if (inherit & PFSTATE_ENLIGHTING) osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::INHERIT);
1154    else
1155    {
1156        int mode = geostate->getMode(PFSTATE_ENLIGHTING);
1157        switch(mode)
1158        {
1159            case(PF_ON):    osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::ON);break;
1160            case(PF_OFF):
1161            default:        osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);break;
1162        }
1163    }
1164
1165    if (inherit & PFSTATE_ENFOG) osgStateSet->setMode(GL_FOG,osg::StateAttribute::INHERIT);
1166    else
1167    {
1168        int mode = geostate->getMode(PFSTATE_ENFOG);
1169        switch(mode)
1170        {
1171            case(PF_ON):    osgStateSet->setMode(GL_FOG,osg::StateAttribute::ON);break;
1172            case(PF_OFF):
1173            default:        osgStateSet->setMode(GL_FOG,osg::StateAttribute::OFF);break;
1174        }
1175    }
1176
1177    // not currently supported by OSG
1178    //     if (inherit & PFSTATE_ENWIREFRAME)  osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::INHERIT);
1179    //     else
1180    //     {
1181    //         int mode = geostate->getMode(PFSTATE_ENWIREFRAME);
1182    //         switch(mode)
1183    //         {
1184    //         case(PF_ON):    osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::ON);break;
1185    //         case(PF_OFF):
1186    //         default:        osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::OFF);break;
1187    //         }
1188    //     }
1189
1190    // redundent in OSG's implementation of texmat mode
1191    //     if (inherit & PFSTATE_ENTEXMAT)  osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::INHERIT);
1192    //     else
1193    //     {
1194    //         int mode = geostate->getMode(PFSTATE_ENTEXMAT);
1195    //         switch(mode)
1196    //         {
1197    //         case(PF_ON):    osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::ON);break;
1198    //         case(PF_OFF):
1199    //         default:        osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::OFF);break;
1200    //         }
1201    //     }
1202
1203
1204    // commenting out the following block since the TexGen should be set
1205    // appropriately by the osg::TexGen block below.
1206    //     if (inherit & PFSTATE_ENTEXGEN)  osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::INHERIT);
1207    //     else
1208    //     {
1209    //         int mode = geostate->getMode(PFSTATE_ENTEXGEN);
1210    //         switch(mode)
1211    //         {
1212    //             case(PF_ON):    osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::ON);break;
1213    //             case(PF_OFF):
1214    //             default:        osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::OFF);break;
1215    //         }
1216    //     }
1217    //
1218
1219
1220    pfMaterial* front_mat = (pfMaterial*)geostate->getAttr(PFSTATE_FRONTMTL);
1221    pfMaterial* back_mat = (pfMaterial*)geostate->getAttr(PFSTATE_BACKMTL);
1222    visitMaterial(osgStateSet,front_mat,back_mat);
1223
1224    pfTexture* tex = (pfTexture*)geostate->getAttr(PFSTATE_TEXTURE);
1225    visitTexture(osgStateSet,tex);
1226
1227    pfTexEnv* texenv = (pfTexEnv*)geostate->getAttr(PFSTATE_TEXENV);
1228
1229    if(texenv)
1230    {
1231      osg::TexEnv* osgTexEnv = new osg::TexEnv();
1232      int mode = texenv->getMode();
1233
1234      float r,g,b,a;
1235      texenv->getBlendColor(&r, &g, &b, &a);
1236
1237      switch(mode)
1238      {
1239          case(PFTE_MODULATE) :
1240              osgTexEnv->setMode(osg::TexEnv::MODULATE);
1241              osgTexEnv->setColor(osg::Vec4(r,g,b,a));
1242              break;
1243          case(PFTE_DECAL) :
1244              osgTexEnv->setMode(osg::TexEnv::DECAL);
1245              osgTexEnv->setColor(osg::Vec4(r,g,b,a));
1246              break;
1247          case(PFTE_BLEND) :
1248              osgTexEnv->setMode(osg::TexEnv::BLEND);
1249              osgTexEnv->setColor(osg::Vec4(r,g,b,a));
1250              break;
1251          case(PFTE_REPLACE) :
1252              osgTexEnv->setMode(osg::TexEnv::REPLACE);
1253              osgTexEnv->setColor(osg::Vec4(r,g,b,a));
1254              break;
1255          case(PFTE_ADD) :
1256              osgTexEnv->setMode(osg::TexEnv::ADD);
1257              osgTexEnv->setColor(osg::Vec4(r,g,b,a));
1258              break;
1259          default:
1260              OSG_WARN << "TexEnv Mode "<<mode<<" not currently supported by the OSG."<<std::endl;
1261              break;
1262      }
1263      osgStateSet->setTextureAttribute(0,osgTexEnv);
1264    }
1265
1266    pfTexGen* texgen = (pfTexGen*)geostate->getAttr(PFSTATE_TEXGEN);
1267
1268    if (texgen)
1269    {
1270        osg::TexGen* osgTexGen = new osg::TexGen();
1271        int mode = texgen->getMode(PF_S);
1272
1273        // should this follow setPlane block be within the following switch?
1274        float x, y, z, d;
1275        texgen->getPlane(PF_S, &x, &y, &z, &d);
1276        osgTexGen->setPlane(osg::TexGen::S, osg::Vec4(x,y,z,d));
1277        texgen->getPlane(PF_T, &x, &y, &z, &d);
1278        osgTexGen->setPlane(osg::TexGen::T, osg::Vec4(x,y,z,d));
1279
1280        switch(mode)
1281        {
1282            case(PFTG_OBJECT_LINEAR) :
1283                osgTexGen->setMode(osg::TexGen::OBJECT_LINEAR);
1284                osgStateSet->setTextureAttribute(0,osgTexGen);
1285                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
1286                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
1287                break;
1288            case(PFTG_EYE_LINEAR_IDENT) :
1289                OSG_WARN << "TexGen Mode PFTG_EYE_LINEAR_IDENT not currently supported by the OSG,"<<std::endl;
1290                OSG_WARN << "       assuming osg::TexGen::EYE_LINEAR."<<std::endl;
1291            case(PFTG_EYE_LINEAR) :
1292                osgTexGen->setMode(osg::TexGen::EYE_LINEAR);
1293                osgStateSet->setTextureAttribute(0,osgTexGen);
1294                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
1295                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
1296                break;
1297            case(PFTG_SPHERE_MAP) :
1298                osgTexGen->setMode(osg::TexGen::SPHERE_MAP);
1299                osgStateSet->setTextureAttribute(0,osgTexGen);
1300                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
1301                osgStateSet->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
1302                break;
1303            case(PFTG_OFF) :
1304                osgStateSet->setAssociatedTextureModes(0,osgTexGen,osg::StateAttribute::OFF);
1305                break;
1306            case(PFTG_OBJECT_DISTANCE_TO_LINE) :
1307                OSG_WARN << "TexGen Mode PFTG_OBJECT_DISTANCE_TO_LINE not currently supported by the OSG."<<std::endl;
1308                osgStateSet->setAssociatedTextureModes(0,osgTexGen,osg::StateAttribute::OFF);
1309                break;
1310            case(PFTG_EYE_DISTANCE_TO_LINE) :
1311                OSG_WARN << "TexGen Mode PFTG_EYE_DISTANCE_TO_LINE not currently supported by the OSG."<<std::endl;
1312                osgStateSet->setAssociatedTextureModes(0,osgTexGen,osg::StateAttribute::OFF);
1313                break;
1314            default:
1315                OSG_WARN << "TexGen Mode "<<mode<<" not currently supported by the OSG."<<std::endl;
1316                osgStateSet->setAssociatedTextureModes(0,osgTexGen,osg::StateAttribute::OFF);
1317                break;
1318        }
1319    }
1320
1321    pfMatrix* texmat = (pfMatrix*)geostate->getAttr(PFSTATE_TEXMAT);
1322    if (texmat)
1323    {
1324        osg::Matrix osgMatrix((*texmat)[0][0],(*texmat)[0][1],(*texmat)[0][2],(*texmat)[0][3],
1325            (*texmat)[1][0],(*texmat)[1][1],(*texmat)[1][2],(*texmat)[1][3],
1326            (*texmat)[2][0],(*texmat)[2][1],(*texmat)[2][2],(*texmat)[2][3],
1327            (*texmat)[3][0],(*texmat)[3][1],(*texmat)[3][2],(*texmat)[3][3]);
1328
1329        osg::TexMat* osgTexMat = new osg::TexMat();
1330        osgTexMat->setMatrix(osgMatrix);
1331        osgStateSet->setTextureAttribute(0,osgTexMat);
1332    }
1333
1334    return osgStateSet;
1335}
1336
1337
1338osg::Material* ConvertFromPerformer::visitMaterial(osg::StateSet* osgStateSet,pfMaterial* front_mat,pfMaterial* back_mat)
1339{
1340    if (front_mat==NULL && back_mat==NULL) return NULL;
1341
1342    osg::Material* osgMaterial = new osg::Material;
1343    if (osgStateSet) osgStateSet->setAttribute(osgMaterial);
1344
1345    pfMaterial* material = NULL;
1346    if (front_mat==back_mat) material = front_mat;
1347    else if (back_mat==NULL) material = front_mat;
1348    else if (front_mat==NULL) material = back_mat;
1349
1350    if (material)                // single materials for front and back.
1351    {
1352
1353        int colorMode = material->getColorMode(material->getSide());
1354
1355        switch(colorMode)
1356        {
1357            case(PFMTL_CMODE_AMBIENT_AND_DIFFUSE): osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); break;
1358            case(PFMTL_CMODE_AMBIENT): osgMaterial->setColorMode(osg::Material::AMBIENT); break;
1359            case(PFMTL_CMODE_DIFFUSE): osgMaterial->setColorMode(osg::Material::DIFFUSE); break;
1360            case(PFMTL_CMODE_EMISSION): osgMaterial->setColorMode(osg::Material::EMISSION); break;
1361            case(PFMTL_CMODE_SPECULAR): osgMaterial->setColorMode(osg::Material::SPECULAR); break;
1362            case(PFMTL_CMODE_OFF): osgMaterial->setColorMode(osg::Material::OFF); break;
1363        }
1364
1365        osgMaterial->setShininess(osg::Material::FRONT_AND_BACK,material->getShininess());
1366
1367        float a = material->getAlpha();
1368        float r,g,b;
1369
1370        material->getColor(PFMTL_AMBIENT,&r,&g,&b);
1371        osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
1372
1373        material->getColor(PFMTL_DIFFUSE,&r,&g,&b);
1374        osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
1375
1376        material->getColor(PFMTL_EMISSION,&r,&g,&b);
1377        osgMaterial->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
1378
1379        material->getColor(PFMTL_SPECULAR,&r,&g,&b);
1380        osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
1381    }
1382    else                         // separate materials for front and back.
1383    {
1384
1385        int colorMode = front_mat->getColorMode(front_mat->getSide());
1386
1387        switch(colorMode)
1388        {
1389            case(PFMTL_CMODE_AMBIENT_AND_DIFFUSE): osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); break;
1390            case(PFMTL_CMODE_AMBIENT): osgMaterial->setColorMode(osg::Material::AMBIENT); break;
1391            case(PFMTL_CMODE_DIFFUSE): osgMaterial->setColorMode(osg::Material::DIFFUSE); break;
1392            case(PFMTL_CMODE_EMISSION): osgMaterial->setColorMode(osg::Material::EMISSION); break;
1393            case(PFMTL_CMODE_SPECULAR): osgMaterial->setColorMode(osg::Material::SPECULAR); break;
1394            case(PFMTL_CMODE_OFF): osgMaterial->setColorMode(osg::Material::OFF); break;
1395        }
1396
1397        float a;
1398        float r,g,b;
1399
1400        // front material
1401        osgMaterial->setShininess(osg::Material::FRONT,front_mat->getShininess());
1402
1403        a = front_mat->getAlpha();
1404
1405        front_mat->getColor(PFMTL_AMBIENT,&r,&g,&b);
1406        osgMaterial->setAmbient(osg::Material::FRONT,osg::Vec4(r,g,b,a));
1407
1408        front_mat->getColor(PFMTL_DIFFUSE,&r,&g,&b);
1409        osgMaterial->setDiffuse(osg::Material::FRONT,osg::Vec4(r,g,b,a));
1410
1411        front_mat->getColor(PFMTL_EMISSION,&r,&g,&b);
1412        osgMaterial->setEmission(osg::Material::FRONT,osg::Vec4(r,g,b,a));
1413
1414        front_mat->getColor(PFMTL_SPECULAR,&r,&g,&b);
1415        osgMaterial->setSpecular(osg::Material::FRONT,osg::Vec4(r,g,b,a));
1416
1417        // back material
1418        osgMaterial->setShininess(osg::Material::BACK,back_mat->getShininess());
1419
1420        a = back_mat->getAlpha();
1421
1422        back_mat->getColor(PFMTL_AMBIENT,&r,&g,&b);
1423        osgMaterial->setAmbient(osg::Material::BACK,osg::Vec4(r,g,b,a));
1424
1425        back_mat->getColor(PFMTL_DIFFUSE,&r,&g,&b);
1426        osgMaterial->setDiffuse(osg::Material::BACK,osg::Vec4(r,g,b,a));
1427
1428        back_mat->getColor(PFMTL_EMISSION,&r,&g,&b);
1429        osgMaterial->setEmission(osg::Material::BACK,osg::Vec4(r,g,b,a));
1430
1431        back_mat->getColor(PFMTL_SPECULAR,&r,&g,&b);
1432        osgMaterial->setSpecular(osg::Material::BACK,osg::Vec4(r,g,b,a));
1433
1434    }
1435
1436    return osgMaterial;
1437}
1438
1439
1440static osg::Texture2D::FilterMode getTexfilter(int filter, int pftype)
1441{
1442    if (filter == PFTEX_MINFILTER)
1443    {
1444
1445        if (pftype & PFTEX_LINEAR)
1446            return osg::Texture2D::NEAREST_MIPMAP_LINEAR;
1447        else if (pftype & PFTEX_BILINEAR)
1448            return osg::Texture2D::LINEAR_MIPMAP_NEAREST;
1449        else if (pftype & PFTEX_TRILINEAR)
1450            return osg::Texture2D::LINEAR_MIPMAP_LINEAR;
1451
1452        return osg::Texture2D::NEAREST_MIPMAP_LINEAR;
1453
1454    }
1455    else
1456    {
1457        // MAGFILTER
1458
1459        // not quite sure what is supposed to be interpret the Peformer
1460        // filter modes here so will simple go with OpenGL default.
1461
1462        return osg::Texture2D::LINEAR;
1463    }
1464}
1465
1466
1467osg::Texture2D* ConvertFromPerformer::visitTexture(osg::StateSet* osgStateSet,pfTexture* tex)
1468{
1469    if (tex==NULL) return NULL;
1470
1471    osg::Texture2D* osgTexture = dynamic_cast<osg::Texture2D*>(getOsgObject(tex));
1472    if (osgTexture) {
1473        if (osgStateSet) osgStateSet->setTextureAttribute(0,osgTexture);
1474        return osgTexture;
1475    }
1476
1477    osgTexture = new osg::Texture2D;
1478    registerPfObjectForOsgObject(tex, osgTexture);
1479
1480    if (osgStateSet) osgStateSet->setTextureAttribute(0,osgTexture);
1481
1482    int repeat_r = tex->getRepeat(PFTEX_WRAP_R);
1483    int repeat_s = tex->getRepeat(PFTEX_WRAP_S);
1484    int repeat_t = tex->getRepeat(PFTEX_WRAP_T);
1485
1486    if (repeat_r==PFTEX_CLAMP)
1487        osgTexture->setWrap(osg::Texture2D::WRAP_R,osg::Texture2D::CLAMP);
1488    else
1489        osgTexture->setWrap(osg::Texture2D::WRAP_R,osg::Texture2D::REPEAT);
1490
1491    if (repeat_s==PFTEX_CLAMP)
1492        osgTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP);
1493    else
1494        osgTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);
1495
1496    if (repeat_t==PFTEX_CLAMP)
1497        osgTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP);
1498    else
1499        osgTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);
1500
1501    // filter
1502#if 1
1503    osgTexture->setFilter(osg::Texture2D::MIN_FILTER,
1504                          getTexfilter(PFTEX_MINFILTER,
1505                                       tex->getFilter(PFTEX_MINFILTER)));
1506    osgTexture->setFilter(osg::Texture2D::MAG_FILTER,
1507                          getTexfilter(PFTEX_MAGFILTER,
1508                                       tex->getFilter(PFTEX_MAGFILTER)));
1509#endif
1510
1511    // image
1512    std::string texName = tex->getName();
1513
1514    if (_saveImagesAsRGB) {
1515        std::string strippedName = osgDB::getStrippedName(texName);
1516
1517        pfList* imgList = tex->getList();
1518        if (imgList) {
1519            // save image list
1520            char buf[8];
1521            for (int i = 0; i < imgList->getNum(); i++) {
1522                pfTexture* t = (pfTexture*) imgList->get(i);
1523                if (t) {
1524                    snprintf(buf, sizeof(buf)-1, "_%04d", i);
1525                    texName = _saveImageDirectory+strippedName+buf+".rgb";
1526                    t->saveFile(texName.c_str());
1527                }
1528            }
1529        }
1530        else {
1531            // save single image
1532            texName = _saveImageDirectory+strippedName+".rgb";
1533            tex->saveFile(texName.c_str());
1534        }
1535    }
1536
1537    if (!_saveAbsoluteImagePath) texName = osgDB::getSimpleFileName(texName);
1538
1539    int s=0;
1540    int t=0;
1541    int r=0;
1542    int comp=0;
1543    unsigned int* imageData = NULL;
1544
1545    tex->getImage(&imageData,&comp,&s,&t,&r);
1546
1547    int internalFormat = comp;
1548
1549    unsigned int pixelFormat =
1550        comp == 1 ? GL_LUMINANCE :
1551        comp == 2 ? GL_LUMINANCE_ALPHA :
1552        comp == 3 ? GL_RGB :
1553        comp == 4 ? GL_RGBA : (GLenum)-1;
1554
1555    unsigned int dataType = GL_UNSIGNED_BYTE;
1556
1557    // copy image data
1558    int size = s * t * r * comp;
1559    unsigned char* data = (unsigned char*) malloc(size);
1560    memcpy(data, imageData, size);
1561
1562    osg::Image* image = new osg::Image;
1563    image->setFileName(texName.c_str());
1564    image->setImage(s,t,r,
1565                    internalFormat,
1566                    pixelFormat,
1567                    dataType,data,
1568                    osg::Image::USE_MALLOC_FREE);
1569
1570    osgTexture->setImage(image);
1571
1572    return osgTexture;
1573}
Note: See TracBrowser for help on using the browser.