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
61 extern "C"
62 {
63
64 extern int
pfdStoreFile_osg(pfNode * root,char * fileName)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
ConvertFromPerformer()78 ConvertFromPerformer::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
~ConvertFromPerformer()92 ConvertFromPerformer::~ConvertFromPerformer()
93 {
94 }
95
96
convert(pfNode * node)97 osg::Node* ConvertFromPerformer::convert(pfNode* node)
98 {
99 if (node==NULL) return NULL;
100 return visitNode(NULL,node);
101 }
102
103
getOsgObject(pfObject * pfObj)104 osg::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
registerPfObjectForOsgObject(pfObject * pfObj,osg::Object * osgObj)116 void ConvertFromPerformer::registerPfObjectForOsgObject(pfObject* pfObj,osg::Object* osgObj)
117 {
118 _pfToOsgMap[pfObj] = osgObj;
119 }
120
121
visitNode(osg::Group * osgParent,pfNode * node)122 osg::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
visitScene(osg::Group * osgParent,pfScene * scene)140 osg::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
visitGroup(osg::Group * osgParent,pfGroup * group)165 osg::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
visitLOD(osg::Group * osgParent,pfLOD * lod)190 osg::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
visitSwitch(osg::Group * osgParent,pfSwitch * switchNode)227 osg::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
visitSequence(osg::Group * osgParent,pfSequence * sequence)267 osg::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
visitDCS(osg::Group * osgParent,pfDCS * dcs)338 osg::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
visitSCS(osg::Group * osgParent,pfSCS * scs)374 osg::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
visitGeode(osg::Group * osgParent,pfGeode * geode)411 osg::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
visitBillboard(osg::Group * osgParent,pfBillboard * billboard)437 osg::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
getNumVerts(pfGeoSet * gset)486 int 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
visitGeoSet(osg::Geode * osgGeode,pfGeoSet * geoset)532 osg::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
visitGeoState(osg::Drawable * osgDrawable,pfGeoState * geostate)981 osg::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
visitMaterial(osg::StateSet * osgStateSet,pfMaterial * front_mat,pfMaterial * back_mat)1333 osg::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
getTexfilter(int filter,int pftype)1435 static 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
visitTexture(osg::StateSet * osgStateSet,pfTexture * tex)1462 osg::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 }
1569