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

Revision 13557, 50.3 kB (checked in by robert, 11 hours ago)

Implemented callbacks for validate(), textChanged() and returnPressed()

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