under Windows and IRIX. Also integrated small change to lib3ds from Drew for IRIX compilation.
1176 lines
37 KiB
C++
1176 lines
37 KiB
C++
#include "ConvertFromPerformer.h"
|
|
|
|
#include <osg/Group>
|
|
#include <osg/Transform>
|
|
#include <osg/LOD>
|
|
#include <osg/Switch>
|
|
#include <osg/Geode>
|
|
#include <osg/Billboard>
|
|
#include <osg/Texture>
|
|
#include <osg/Image>
|
|
#include <osg/CullFace>
|
|
#include <osg/TexGen>
|
|
#include <osg/TexMat>
|
|
#include <osg/Material>
|
|
#include <osg/Notify>
|
|
|
|
#include <osgDB/FileNameUtils>
|
|
#include <osgDB/Registry>
|
|
#include <osgDB/WriteFile>
|
|
|
|
#include <Performer/pf/pfNode.h>
|
|
#include <Performer/pf/pfGeode.h>
|
|
#include <Performer/pf/pfBillboard.h>
|
|
#include <Performer/pf/pfScene.h>
|
|
#include <Performer/pf/pfGroup.h>
|
|
#include <Performer/pf/pfDCS.h>
|
|
#include <Performer/pf/pfSCS.h>
|
|
#include <Performer/pf/pfLOD.h>
|
|
#include <Performer/pf/pfSwitch.h>
|
|
#include <Performer/pf/pfSequence.h>
|
|
#include <Performer/pr/pfGeoState.h>
|
|
#include <Performer/pr/pfMaterial.h>
|
|
#include <Performer/pr/pfTexture.h>
|
|
|
|
extern "C"
|
|
{
|
|
|
|
extern int
|
|
pfdStoreFile_osg (pfNode* root, char *fileName)
|
|
{
|
|
ConvertFromPerformer converter;
|
|
osg::Node* node = converter.convert(root);
|
|
|
|
if (node==NULL) return 0;
|
|
if (osgDB::writeNodeFile(*node,fileName)) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
ConvertFromPerformer::ConvertFromPerformer()
|
|
{
|
|
_osgRoot = NULL;
|
|
|
|
_gsetPrimMap[PFGS_POINTS] = osg::GeoSet::POINTS;
|
|
_gsetPrimMap[PFGS_LINES] = osg::GeoSet::LINES;
|
|
_gsetPrimMap[PFGS_LINESTRIPS] = osg::GeoSet::LINE_STRIP;
|
|
_gsetPrimMap[PFGS_TRIS] = osg::GeoSet::TRIANGLES;
|
|
_gsetPrimMap[PFGS_QUADS] = osg::GeoSet::QUADS;
|
|
_gsetPrimMap[PFGS_TRISTRIPS] = osg::GeoSet::TRIANGLE_STRIP;
|
|
_gsetPrimMap[PFGS_FLAT_LINESTRIPS] = osg::GeoSet::FLAT_LINE_STRIP;
|
|
_gsetPrimMap[PFGS_FLAT_TRISTRIPS] = osg::GeoSet::FLAT_TRIANGLE_STRIP;
|
|
_gsetPrimMap[PFGS_TRIFANS] = osg::GeoSet::TRIANGLE_FAN;
|
|
_gsetPrimMap[PFGS_FLAT_TRIFANS] = osg::GeoSet::FLAT_TRIANGLE_FAN;
|
|
_gsetPrimMap[PFGS_POLYS] = osg::GeoSet::POLYGON;
|
|
_gsetPrimMap[PFGS_NUM_PRIMS] = osg::GeoSet::NO_TYPE;
|
|
|
|
_gsetBindMap[PFGS_OFF] = osg::GeoSet::BIND_OFF;
|
|
_gsetBindMap[PFGS_OVERALL] = osg::GeoSet::BIND_OVERALL;
|
|
_gsetBindMap[PFGS_PER_PRIM] = osg::GeoSet::BIND_PERPRIM;
|
|
_gsetBindMap[PFGS_PER_VERTEX] = osg::GeoSet::BIND_PERVERTEX;
|
|
|
|
_saveImagesAsRGB = false;
|
|
_saveAbsoluteImagePath = false;
|
|
|
|
}
|
|
|
|
|
|
ConvertFromPerformer::~ConvertFromPerformer()
|
|
{
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::convert(pfNode* node)
|
|
{
|
|
if (node==NULL) return NULL;
|
|
return visitNode(NULL,node);
|
|
}
|
|
|
|
|
|
osg::Object* ConvertFromPerformer::getOsgObject(pfObject* pfObj)
|
|
{
|
|
PfObjectToOsgObjectMap::iterator fitr = _pfToOsgMap.find(pfObj);
|
|
if (fitr != _pfToOsgMap.end())
|
|
{
|
|
// osg::notify(DEBUG) << "Found shared object"<<endl;
|
|
return (*fitr).second;
|
|
}
|
|
else return NULL;
|
|
}
|
|
|
|
|
|
void ConvertFromPerformer::regisiterPfObjectForOsgObject(pfObject* pfObj,osg::Object* osgObj)
|
|
{
|
|
_pfToOsgMap[pfObj] = osgObj;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitNode(osg::Group* osgParent,pfNode* node)
|
|
{
|
|
if (node==NULL) return NULL;
|
|
|
|
if (node->getType()->isDerivedFrom( pfBillboard::getClassType())) return visitBillboard(osgParent,(pfBillboard*)node);
|
|
else if (node->getType()->isDerivedFrom( pfGeode::getClassType())) return visitGeode(osgParent,(pfGeode*)node);
|
|
else if (node->getType()->isDerivedFrom( pfScene::getClassType())) return visitScene(osgParent,(pfScene*)node);
|
|
else if (node->getType()->isDerivedFrom( pfDCS::getClassType())) return visitDCS(osgParent,(pfDCS*)node);
|
|
else if (node->getType()->isDerivedFrom( pfSCS::getClassType())) return visitSCS(osgParent,(pfSCS*)node);
|
|
else if (node->getType()->isDerivedFrom( pfLOD::getClassType())) return visitLOD(osgParent,(pfLOD*)node);
|
|
else if (node->getType()->isDerivedFrom( pfSequence::getClassType())) return visitSequence(osgParent,(pfSequence*)node);
|
|
else if (node->getType()->isDerivedFrom( pfSwitch::getClassType())) return visitSwitch(osgParent,(pfSwitch*)node);
|
|
else if (node->getType()->isDerivedFrom( pfGroup::getClassType())) return visitGroup(osgParent,(pfGroup*)node);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitScene(osg::Group* osgParent,pfScene* scene)
|
|
{
|
|
osg::Group* osgScene = dynamic_cast<osg::Group*>(getOsgObject(scene));
|
|
if (osgScene)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgScene);
|
|
return osgScene;
|
|
}
|
|
|
|
osgScene = new osg::Group;
|
|
if (osgParent) osgParent->addChild(osgScene);
|
|
|
|
regisiterPfObjectForOsgObject(scene,osgScene);
|
|
|
|
const char* name = scene->getName();
|
|
if (name) osgScene->setName(name);
|
|
|
|
for(int i=0;i<scene->getNumChildren();++i)
|
|
{
|
|
visitNode(osgScene,scene->getChild(i));
|
|
}
|
|
return (osg::Node*)osgScene;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitGroup(osg::Group* osgParent,pfGroup* group)
|
|
{
|
|
osg::Group* osgGroup = dynamic_cast<osg::Group*>(getOsgObject(group));
|
|
if (osgGroup)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgGroup);
|
|
return osgGroup;
|
|
}
|
|
|
|
osgGroup = new osg::Group;
|
|
if (osgParent) osgParent->addChild(osgGroup);
|
|
|
|
regisiterPfObjectForOsgObject(group,osgGroup);
|
|
|
|
const char* name = group->getName();
|
|
if (name) osgGroup->setName(name);
|
|
|
|
for(int i=0;i<group->getNumChildren();++i)
|
|
{
|
|
visitNode(osgGroup,group->getChild(i));
|
|
}
|
|
return (osg::Node*)osgGroup;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitLOD(osg::Group* osgParent,pfLOD* lod)
|
|
{
|
|
osg::LOD* osgLOD = dynamic_cast<osg::LOD*>(getOsgObject(lod));
|
|
if (osgLOD)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgLOD);
|
|
return osgLOD;
|
|
}
|
|
|
|
osgLOD = new osg::LOD;
|
|
if (osgParent) osgParent->addChild(osgLOD);
|
|
|
|
regisiterPfObjectForOsgObject(lod,osgLOD);
|
|
|
|
const char* name = lod->getName();
|
|
if (name) osgLOD->setName(name);
|
|
|
|
pfVec3 center;
|
|
lod->getCenter(center);
|
|
osg::Vec3 osgCenter(center[0],center[1],center[2]);
|
|
osgLOD->setCenter(osgCenter);
|
|
|
|
int i;
|
|
for(i=0;i<lod->getNumRanges();++i)
|
|
{
|
|
osgLOD->setRange(i,lod->getRange(i));
|
|
}
|
|
|
|
for(i=0;i<lod->getNumChildren();++i)
|
|
{
|
|
visitNode(osgLOD,lod->getChild(i));
|
|
}
|
|
return (osg::Node*)osgLOD;
|
|
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitSwitch(osg::Group* osgParent,pfSwitch* switchNode)
|
|
{
|
|
osg::Switch* osgSwitch = dynamic_cast<osg::Switch*>(getOsgObject(switchNode));
|
|
if (osgSwitch)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgSwitch);
|
|
return osgSwitch;
|
|
}
|
|
|
|
osgSwitch = new osg::Switch;
|
|
if (osgParent) osgParent->addChild(osgSwitch);
|
|
|
|
regisiterPfObjectForOsgObject(switchNode,osgSwitch);
|
|
|
|
const char* name = switchNode->getName();
|
|
if (name) osgSwitch->setName(name);
|
|
|
|
float val = switchNode->getVal();
|
|
if (val==PFSWITCH_ON)
|
|
{
|
|
osgSwitch->setValue(osg::Switch::ALL_CHILDREN_ON);
|
|
}
|
|
else if (val==PFSWITCH_OFF)
|
|
{
|
|
osgSwitch->setValue(osg::Switch::ALL_CHILDREN_OFF);
|
|
}
|
|
else
|
|
{
|
|
osgSwitch->setValue((int)val);
|
|
}
|
|
|
|
for(int i=0;i<switchNode->getNumChildren();++i)
|
|
{
|
|
visitNode(osgSwitch,switchNode->getChild(i));
|
|
}
|
|
return (osg::Node*)osgSwitch;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitSequence(osg::Group* osgParent,pfSequence* sequence)
|
|
{
|
|
|
|
osg::notify(osg::WARN)<<"Warning : cannot convert pfSequence as no osg::Sequence exists, using osg::Switch instead."<<endl;
|
|
|
|
osg::Switch* osgSequence = dynamic_cast<osg::Switch*>(getOsgObject(sequence));
|
|
if (osgSequence)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgSequence);
|
|
return osgSequence;
|
|
}
|
|
|
|
osgSequence = new osg::Switch;
|
|
if (osgParent) osgParent->addChild(osgSequence);
|
|
|
|
regisiterPfObjectForOsgObject(sequence,osgSequence);
|
|
|
|
if (sequence->getNumChildren()>0)
|
|
{
|
|
// set switch to first child as a 'hack' to prevent all
|
|
// children being traversed during rendering. Note,
|
|
// once osg::Sequence has been implemented this can all
|
|
// be removed.
|
|
osgSequence->setValue(0);
|
|
}
|
|
|
|
for(int i=0;i<sequence->getNumChildren();++i)
|
|
{
|
|
visitNode(osgSequence,sequence->getChild(i));
|
|
}
|
|
return (osg::Node*)osgSequence;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitDCS(osg::Group* osgParent,pfDCS* dcs)
|
|
{
|
|
|
|
osg::Transform* osgTransform = dynamic_cast<osg::Transform*>(getOsgObject(dcs));
|
|
if (osgTransform)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgTransform);
|
|
return osgTransform;
|
|
}
|
|
|
|
osgTransform = new osg::Transform;
|
|
if (osgParent) osgParent->addChild(osgTransform);
|
|
|
|
regisiterPfObjectForOsgObject(dcs,osgTransform);
|
|
|
|
const char* name = dcs->getName();
|
|
if (name) osgTransform->setName(name);
|
|
|
|
pfMatrix matrix;
|
|
dcs->getMat(matrix);
|
|
|
|
osg::Matrix osgMatrix(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
|
|
matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
|
|
matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
|
|
matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
|
|
|
|
osgTransform->setMatrix(osgMatrix);
|
|
|
|
for(int i=0;i<dcs->getNumChildren();++i)
|
|
{
|
|
visitNode(osgTransform,dcs->getChild(i));
|
|
}
|
|
return (osg::Node*)osgTransform;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitSCS(osg::Group* osgParent,pfSCS* scs)
|
|
{
|
|
// note the OSG does not currently have a SCS, so use DCS instead.
|
|
osg::Transform* osgTransform = dynamic_cast<osg::Transform*>(getOsgObject(scs));
|
|
if (osgTransform)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgTransform);
|
|
return osgTransform;
|
|
}
|
|
|
|
osgTransform = new osg::Transform;
|
|
if (osgParent) osgParent->addChild(osgTransform);
|
|
|
|
regisiterPfObjectForOsgObject(scs,osgTransform);
|
|
|
|
const char* name = scs->getName();
|
|
if (name) osgTransform->setName(name);
|
|
|
|
pfMatrix matrix;
|
|
scs->getMat(matrix);
|
|
osg::Matrix osgMatrix(matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3],
|
|
matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],
|
|
matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3],
|
|
matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3]);
|
|
|
|
osgTransform->setMatrix(osgMatrix);
|
|
|
|
for(int i=0;i<scs->getNumChildren();++i)
|
|
{
|
|
visitNode(osgTransform,scs->getChild(i));
|
|
}
|
|
return (osg::Node*)osgTransform;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitGeode(osg::Group* osgParent,pfGeode* geode)
|
|
{
|
|
osg::Geode* osgGeode = dynamic_cast<osg::Geode*>(getOsgObject(geode));
|
|
if (osgGeode)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgGeode);
|
|
return osgGeode;
|
|
}
|
|
|
|
osgGeode = new osg::Geode;
|
|
if (osgParent) osgParent->addChild(osgGeode);
|
|
|
|
regisiterPfObjectForOsgObject(geode,osgGeode);
|
|
|
|
const char* name = geode->getName();
|
|
if (name) osgGeode->setName(name);
|
|
|
|
for(int i=0;i<geode->getNumGSets();++i)
|
|
{
|
|
visitGeoSet(osgGeode,geode->getGSet(i));
|
|
}
|
|
|
|
return (osg::Node*)osgGeode;
|
|
}
|
|
|
|
|
|
osg::Node* ConvertFromPerformer::visitBillboard(osg::Group* osgParent,pfBillboard* billboard)
|
|
{
|
|
// return NULL;
|
|
|
|
osg::Billboard* osgBillboard = dynamic_cast<osg::Billboard*>(getOsgObject(billboard));
|
|
if (osgBillboard)
|
|
{
|
|
if (osgParent) osgParent->addChild(osgBillboard);
|
|
return osgBillboard;
|
|
}
|
|
|
|
osgBillboard = new osg::Billboard;
|
|
if (osgParent) osgParent->addChild(osgBillboard);
|
|
|
|
regisiterPfObjectForOsgObject(billboard,osgBillboard);
|
|
|
|
const char* name = billboard->getName();
|
|
if (name) osgBillboard->setName(name);
|
|
|
|
pfVec3 axis;
|
|
billboard->getAxis(axis);
|
|
osgBillboard->setAxis(osg::Vec3(axis[0],axis[1],axis[2]));
|
|
|
|
for(int i=0;i<billboard->getNumGSets();++i)
|
|
{
|
|
/* osg::GeoSet* osggset = */
|
|
visitGeoSet(osgBillboard,billboard->getGSet(i));
|
|
pfVec3 pos;
|
|
billboard->getPos(i,pos);
|
|
osgBillboard->setPos(i,osg::Vec3(pos[0],pos[1],pos[2]));
|
|
}
|
|
|
|
return (osg::Node*)osgBillboard;
|
|
}
|
|
|
|
|
|
int ConvertFromPerformer::getNumVerts(pfGeoSet *gset)
|
|
{
|
|
int nv;
|
|
int np;
|
|
int *lens;
|
|
int i;
|
|
|
|
np = gset->getNumPrims();
|
|
nv = 0;
|
|
|
|
switch( gset->getPrimType() )
|
|
{
|
|
case PFGS_POINTS :
|
|
nv = np;
|
|
break;
|
|
|
|
case PFGS_LINES :
|
|
nv = 2 * np;
|
|
break;
|
|
|
|
case PFGS_TRIS :
|
|
nv = 3 * np;
|
|
break;
|
|
|
|
case PFGS_QUADS :
|
|
nv = 4 * np;
|
|
break;
|
|
|
|
case PFGS_TRISTRIPS :
|
|
case PFGS_FLAT_TRISTRIPS :
|
|
case PFGS_POLYS :
|
|
case PFGS_LINESTRIPS :
|
|
case PFGS_FLAT_LINESTRIPS :
|
|
|
|
lens = gset->getPrimLengths();
|
|
for( i = 0; i < np; i++ )
|
|
nv += lens[i];
|
|
break;
|
|
|
|
}
|
|
|
|
return nv;
|
|
}
|
|
|
|
|
|
osg::GeoSet* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet* geoset)
|
|
{
|
|
if (geoset==NULL) return NULL;
|
|
|
|
osg::GeoSet* osgGeoSet = dynamic_cast<osg::GeoSet*>(getOsgObject(geoset));
|
|
if (osgGeoSet)
|
|
{
|
|
if (osgGeode) osgGeode->addDrawable(osgGeoSet);
|
|
return osgGeoSet;
|
|
}
|
|
|
|
osgGeoSet = new osg::GeoSet;
|
|
if (osgGeode) osgGeode->addDrawable(osgGeoSet);
|
|
|
|
regisiterPfObjectForOsgObject(geoset,osgGeoSet);
|
|
|
|
visitGeoState(osgGeoSet,geoset->getGState());
|
|
|
|
int i;
|
|
|
|
// number of prims
|
|
int np = geoset->getNumPrims();
|
|
int *plen = geoset->getPrimLengths();
|
|
|
|
// Number of verticies (may be different than number of coords)
|
|
int nv = getNumVerts( geoset );
|
|
|
|
int prim = geoset->getPrimType();
|
|
int flat_shaded_offset=0;
|
|
if (prim == PFGS_FLAT_LINESTRIPS) flat_shaded_offset=np;
|
|
else if (prim == PFGS_FLAT_TRISTRIPS) flat_shaded_offset=2*np;
|
|
else if (prim == PFGS_FLAT_TRIFANS) flat_shaded_offset=2*np;
|
|
|
|
osgGeoSet->setPrimType(_gsetPrimMap[geoset->getPrimType()]);
|
|
osgGeoSet->setNumPrims(np);
|
|
|
|
if (plen)
|
|
{
|
|
int *osg_plen = new int [np];
|
|
for(i=0;i<np;++i) osg_plen[i] = plen[i];
|
|
osgGeoSet->setPrimLengths(osg_plen);
|
|
}
|
|
|
|
pfVec3 *coords;
|
|
ushort *ilist;
|
|
geoset->getAttrLists( PFGS_COORD3, (void **)&coords, &ilist );
|
|
|
|
// copy the vertex coordinates across.
|
|
if( coords )
|
|
{
|
|
// calc the maximum num of vertex from the index list.
|
|
int cc;
|
|
if (ilist)
|
|
{
|
|
cc = 0;
|
|
for( i = 0; i < nv; i++ )
|
|
if( ilist[i] > cc ) cc = ilist[i];
|
|
cc++;
|
|
}
|
|
else
|
|
cc = nv;
|
|
|
|
osg::Vec3* osg_coords = new osg::Vec3 [cc];
|
|
for( i = 0; i < cc; i++ )
|
|
{
|
|
osg_coords[i][0] = coords[i][0];
|
|
osg_coords[i][1] = coords[i][1];
|
|
osg_coords[i][2] = coords[i][2];
|
|
}
|
|
|
|
if(ilist)
|
|
{
|
|
osg::ushort* osg_cindex = new osg::ushort [nv];
|
|
for( i = 0; i < nv; i++ )
|
|
{
|
|
osg_cindex[i] = ilist[i];
|
|
}
|
|
osgGeoSet->setCoords(osg_coords, osg_cindex );
|
|
}
|
|
else
|
|
{
|
|
osgGeoSet->setCoords(osg_coords);
|
|
}
|
|
|
|
}
|
|
|
|
pfVec3 *norms;
|
|
geoset->getAttrLists( PFGS_NORMAL3, (void **)&norms, &ilist );
|
|
|
|
// copy normals
|
|
if(norms)
|
|
{
|
|
int bind = geoset->getAttrBind( PFGS_NORMAL3 );
|
|
int nn = bind == PFGS_OFF ? 0 :
|
|
bind == PFGS_OVERALL ? 1 :
|
|
bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
|
|
bind == PFGS_PER_VERTEX ? nv-flat_shaded_offset : 0;
|
|
|
|
// set the normal binding type.
|
|
osgGeoSet->setNormalBinding(_gsetBindMap[bind]);
|
|
|
|
// calc the maximum num of vertex from the index list.
|
|
int cc;
|
|
if (ilist)
|
|
{
|
|
cc = 0;
|
|
for( i = 0; i < nn; i++ )
|
|
if( ilist[i] > cc ) cc = ilist[i];
|
|
cc++;
|
|
}
|
|
else
|
|
cc = nn;
|
|
|
|
osg::Vec3* osg_norms = new osg::Vec3 [cc];
|
|
for( i = 0; i < cc; i++ )
|
|
{
|
|
osg_norms[i][0] = norms[i][0];
|
|
osg_norms[i][1] = norms[i][1];
|
|
osg_norms[i][2] = norms[i][2];
|
|
}
|
|
|
|
if(ilist)
|
|
{
|
|
osg::ushort* osg_cindex = new osg::ushort [nn];
|
|
for( i = 0; i < nn; i++ )
|
|
{
|
|
osg_cindex[i] = ilist[i];
|
|
}
|
|
osgGeoSet->setNormals(osg_norms, osg_cindex );
|
|
}
|
|
else
|
|
{
|
|
osgGeoSet->setNormals(osg_norms);
|
|
}
|
|
|
|
}
|
|
|
|
pfVec2 *tcoords;
|
|
geoset->getAttrLists( PFGS_TEXCOORD2, (void **)&tcoords, &ilist );
|
|
|
|
// copy texture coords
|
|
if(tcoords)
|
|
{
|
|
int bind = geoset->getAttrBind( PFGS_TEXCOORD2 );
|
|
int nn = bind == PFGS_OFF ? 0 :
|
|
bind == PFGS_OVERALL ? 1 :
|
|
bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
|
|
bind == PFGS_PER_VERTEX ? nv : 0;
|
|
|
|
// set the normal binding type.
|
|
osgGeoSet->setTextureBinding(_gsetBindMap[bind]);
|
|
|
|
// calc the maximum num of vertex from the index list.
|
|
int cc;
|
|
if (ilist)
|
|
{
|
|
cc = 0;
|
|
for( i = 0; i < nv; i++ )
|
|
if( ilist[i] > cc ) cc = ilist[i];
|
|
cc++;
|
|
}
|
|
else
|
|
cc = nn;
|
|
|
|
osg::Vec2* osg_tcoords = new osg::Vec2 [cc];
|
|
for( i = 0; i < cc; i++ )
|
|
{
|
|
osg_tcoords[i][0] = tcoords[i][0];
|
|
osg_tcoords[i][1] = tcoords[i][1];
|
|
}
|
|
|
|
if(ilist)
|
|
{
|
|
osg::ushort* osg_cindex = new osg::ushort [nn];
|
|
for( i = 0; i < nn; i++ )
|
|
{
|
|
osg_cindex[i] = ilist[i];
|
|
}
|
|
osgGeoSet->setTextureCoords(osg_tcoords, osg_cindex );
|
|
}
|
|
else
|
|
{
|
|
osgGeoSet->setTextureCoords(osg_tcoords);
|
|
}
|
|
|
|
}
|
|
|
|
pfVec4 *colors;
|
|
geoset->getAttrLists( PFGS_COLOR4, (void **)&colors, &ilist );
|
|
|
|
// copy color coords
|
|
if(colors)
|
|
{
|
|
int bind = geoset->getAttrBind( PFGS_COLOR4 );
|
|
int nn = bind == PFGS_OFF ? 0 :
|
|
bind == PFGS_OVERALL ? 1 :
|
|
bind == PFGS_PER_PRIM ? geoset->getNumPrims() :
|
|
bind == PFGS_PER_VERTEX ? nv-flat_shaded_offset : 0;
|
|
|
|
// set the normal binding type.
|
|
osgGeoSet->setColorBinding(_gsetBindMap[bind]);
|
|
|
|
// calc the maximum num of vertex from the index list.
|
|
int cc;
|
|
if (ilist)
|
|
{
|
|
cc = 0;
|
|
for( i = 0; i < nn; i++ )
|
|
if( ilist[i] > cc ) cc = ilist[i];
|
|
cc++;
|
|
}
|
|
else
|
|
cc = nn;
|
|
|
|
osg::Vec4* osg_colors = new osg::Vec4 [cc];
|
|
for( i = 0; i < cc; i++ )
|
|
{
|
|
osg_colors[i][0] = colors[i][0];
|
|
osg_colors[i][1] = colors[i][1];
|
|
osg_colors[i][2] = colors[i][2];
|
|
osg_colors[i][3] = colors[i][3];
|
|
}
|
|
|
|
if(ilist)
|
|
{
|
|
osg::ushort* osg_cindex = new osg::ushort [nn];
|
|
for( i = 0; i < nn; i++ )
|
|
{
|
|
osg_cindex[i] = ilist[i];
|
|
}
|
|
osgGeoSet->setColors(osg_colors, osg_cindex );
|
|
}
|
|
else
|
|
{
|
|
osgGeoSet->setColors(osg_colors);
|
|
}
|
|
|
|
}
|
|
|
|
return osgGeoSet;
|
|
}
|
|
|
|
|
|
osg::StateSet* ConvertFromPerformer::visitGeoState(osg::GeoSet* osgGeoSet,pfGeoState* geostate)
|
|
{
|
|
if (geostate==NULL) return NULL;
|
|
|
|
osg::StateSet* osgStateSet = dynamic_cast<osg::StateSet*>(getOsgObject(geostate));
|
|
if (osgStateSet)
|
|
{
|
|
if (osgGeoSet) osgGeoSet->setStateSet(osgStateSet);
|
|
return osgStateSet;
|
|
}
|
|
|
|
osgStateSet = new osg::StateSet;
|
|
if (osgGeoSet) osgGeoSet->setStateSet(osgStateSet);
|
|
|
|
regisiterPfObjectForOsgObject(geostate,osgStateSet);
|
|
|
|
// Don could you fill in some of these blanks???
|
|
unsigned int inherit = geostate->getInherit();
|
|
// osg::notify(DEBUG) << endl << "Inherit = "<<inherit<<endl;
|
|
// if (inherit & PFSTATE_TRANSPARENCY) osg::notify(DEBUG) << "Inherit PFSTATE_TRANSPARENCY"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_TRANSPARENCY"<<endl;
|
|
// if (inherit & PFSTATE_ENTEXTURE) osg::notify(DEBUG) << "Inherit PFSTATE_ENTEXTURE"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENTEXTURE"<<endl;
|
|
// if (inherit & PFSTATE_CULLFACE) osg::notify(DEBUG) << "Inherit PFSTATE_CULLFACE"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_CULLFACE"<<endl;
|
|
// if (inherit & PFSTATE_ENLIGHTING) osg::notify(DEBUG) << "Inherit PFSTATE_ENLIGHTING"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENLIGHTING"<<endl;
|
|
// if (inherit & PFSTATE_ENFOG) osg::notify(DEBUG) << "Inherit PFSTATE_ENFOG"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENFOG"<<endl;
|
|
// if (inherit & PFSTATE_ENWIREFRAME) osg::notify(DEBUG) << "Inherit PFSTATE_ENWIREFRAME"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENWIREFRAME"<<endl;
|
|
// if (inherit & PFSTATE_ENTEXMAT) osg::notify(DEBUG) << "Inherit PFSTATE_ENTEXMAT"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENTEXMAT"<<endl;
|
|
// if (inherit & PFSTATE_ENTEXGEN) osg::notify(DEBUG) << "Inherit PFSTATE_ENTEXGEN"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENTEXGEN"<<endl;
|
|
//
|
|
// if (inherit & PFSTATE_ANTIALIAS) osg::notify(DEBUG) << "Inherit PFSTATE_ANTIALIAS"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ANTIALIAS"<<endl;
|
|
// if (inherit & PFSTATE_DECAL) osg::notify(DEBUG) << "Inherit PFSTATE_DECAL"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_DECAL"<<endl;
|
|
// if (inherit & PFSTATE_ALPHAFUNC) osg::notify(DEBUG) << "Inherit PFSTATE_ALPHAFUNC"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ALPHAFUNC"<<endl;
|
|
// if (inherit & PFSTATE_ENCOLORTABLE) osg::notify(DEBUG) << "Inherit PFSTATE_ENCOLORTABLE"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENCOLORTABLE"<<endl;
|
|
// if (inherit & PFSTATE_ENHIGHLIGHTING) osg::notify(DEBUG) << "Inherit PFSTATE_ENHIGHLIGHTING"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENHIGHLIGHTING"<<endl;
|
|
// if (inherit & PFSTATE_ENLPOINTSTATE) osg::notify(DEBUG) << "Inherit PFSTATE_ENLPOINTSTATE"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENLPOINTSTATE"<<endl;
|
|
// if (inherit & PFSTATE_ENTEXLOD) osg::notify(DEBUG) << "Inherit PFSTATE_ENTEXLOD"<<endl;
|
|
// else osg::notify(DEBUG) << "Define PFSTATE_ENTEXLOD"<<endl;
|
|
|
|
if (inherit & PFSTATE_TRANSPARENCY) osgStateSet->setMode(GL_BLEND,osg::StateAttribute::INHERIT);
|
|
else
|
|
{
|
|
int mode = geostate->getMode(PFSTATE_TRANSPARENCY);
|
|
switch(mode)
|
|
{
|
|
case(PFTR_FAST):
|
|
case(PFTR_HIGH_QUALITY):
|
|
case(PFTR_BLEND_ALPHA):
|
|
case(PFTR_MS_ALPHA):
|
|
case(PFTR_MS_ALPHA_MASK):
|
|
case(PFTR_NO_OCCLUDE):
|
|
case(PFTR_ON):
|
|
osgStateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
|
|
osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
|
break;
|
|
case(PFTR_OFF): osgStateSet->setMode(GL_BLEND,osg::StateAttribute::OFF);break;
|
|
default: osgStateSet->setMode(GL_BLEND,osg::StateAttribute::INHERIT);break;
|
|
}
|
|
}
|
|
|
|
if (inherit & PFSTATE_ENTEXTURE) osgStateSet->setMode(GL_TEXTURE_2D,osg::StateAttribute::INHERIT);
|
|
else
|
|
{
|
|
int mode = geostate->getMode(PFSTATE_ENTEXTURE);
|
|
switch(mode)
|
|
{
|
|
case(PF_ON): osgStateSet->setMode(GL_TEXTURE_2D,osg::StateAttribute::ON);break;
|
|
case(PF_OFF):
|
|
default: osgStateSet->setMode(GL_TEXTURE_2D,osg::StateAttribute::OFF);break;
|
|
}
|
|
}
|
|
|
|
if (inherit & PFSTATE_CULLFACE) osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::INHERIT);
|
|
else
|
|
{
|
|
int mode = geostate->getMode(PFSTATE_CULLFACE);
|
|
switch(mode)
|
|
{
|
|
case(PFCF_BACK):
|
|
{
|
|
osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
|
|
osg::CullFace *cf = new osg::CullFace;
|
|
cf->setMode(osg::CullFace::BACK);
|
|
osgStateSet->setAttribute(cf);
|
|
}
|
|
break;
|
|
|
|
case(PFCF_FRONT):
|
|
{
|
|
osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
|
|
osg::CullFace *cf = new osg::CullFace;
|
|
cf->setMode(osg::CullFace::FRONT);
|
|
osgStateSet->setAttribute(cf);
|
|
}
|
|
break;
|
|
case(PFCF_BOTH):
|
|
{
|
|
osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
|
|
osg::CullFace *cf = new osg::CullFace;
|
|
cf->setMode(osg::CullFace::FRONT_AND_BACK);
|
|
osgStateSet->setAttribute(cf);
|
|
}
|
|
break;
|
|
case(PFCF_OFF):
|
|
default: osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);break;
|
|
}
|
|
}
|
|
|
|
if (inherit & PFSTATE_ENLIGHTING) osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::INHERIT);
|
|
else
|
|
{
|
|
int mode = geostate->getMode(PFSTATE_ENLIGHTING);
|
|
switch(mode)
|
|
{
|
|
case(PF_ON): osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::ON);break;
|
|
case(PF_OFF):
|
|
default: osgStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);break;
|
|
}
|
|
}
|
|
|
|
if (inherit & PFSTATE_ENFOG) osgStateSet->setMode(GL_FOG,osg::StateAttribute::INHERIT);
|
|
else
|
|
{
|
|
int mode = geostate->getMode(PFSTATE_ENFOG);
|
|
switch(mode)
|
|
{
|
|
case(PF_ON): osgStateSet->setMode(GL_FOG,osg::StateAttribute::ON);break;
|
|
case(PF_OFF):
|
|
default: osgStateSet->setMode(GL_FOG,osg::StateAttribute::OFF);break;
|
|
}
|
|
}
|
|
|
|
// not currently supported by OSG
|
|
// if (inherit & PFSTATE_ENWIREFRAME) osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::INHERIT);
|
|
// else
|
|
// {
|
|
// int mode = geostate->getMode(PFSTATE_ENWIREFRAME);
|
|
// switch(mode)
|
|
// {
|
|
// case(PF_ON): osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::ON);break;
|
|
// case(PF_OFF):
|
|
// default: osgStateSet->setMode(osg::StateSet::WIREFRAME,osg::StateAttribute::OFF);break;
|
|
// }
|
|
// }
|
|
|
|
// redundent in OSG's implementation of texmat mode
|
|
// if (inherit & PFSTATE_ENTEXMAT) osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::INHERIT);
|
|
// else
|
|
// {
|
|
// int mode = geostate->getMode(PFSTATE_ENTEXMAT);
|
|
// switch(mode)
|
|
// {
|
|
// case(PF_ON): osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::ON);break;
|
|
// case(PF_OFF):
|
|
// default: osgStateSet->setMode(osg::StateSet::TEXMAT,osg::StateAttribute::OFF);break;
|
|
// }
|
|
// }
|
|
|
|
|
|
// commenting out the following block since the TexGen should be set
|
|
// appropriately by the osg::TexGen block below.
|
|
// if (inherit & PFSTATE_ENTEXGEN) osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::INHERIT);
|
|
// else
|
|
// {
|
|
// int mode = geostate->getMode(PFSTATE_ENTEXGEN);
|
|
// switch(mode)
|
|
// {
|
|
// case(PF_ON): osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::ON);break;
|
|
// case(PF_OFF):
|
|
// default: osgStateSet->setMode(osg::StateSet::TEXGEN,osg::StateAttribute::OFF);break;
|
|
// }
|
|
// }
|
|
//
|
|
|
|
|
|
pfMaterial* front_mat = (pfMaterial*)geostate->getAttr(PFSTATE_FRONTMTL);
|
|
pfMaterial* back_mat = (pfMaterial*)geostate->getAttr(PFSTATE_BACKMTL);
|
|
visitMaterial(osgStateSet,front_mat,back_mat);
|
|
|
|
pfTexture* tex = (pfTexture*)geostate->getAttr(PFSTATE_TEXTURE);
|
|
visitTexture(osgStateSet,tex);
|
|
|
|
pfTexGen* texgen = (pfTexGen*)geostate->getAttr(PFSTATE_TEXGEN);
|
|
|
|
if (texgen)
|
|
{
|
|
osg::TexGen* osgTexGen = new osg::TexGen();
|
|
int mode = texgen->getMode(PF_S);
|
|
|
|
// should this follow setPlane block be within the following switch?
|
|
float x, y, z, d;
|
|
texgen->getPlane(PF_S, &x, &y, &z, &d);
|
|
osgTexGen->setPlane(osg::TexGen::S, osg::Vec4(x,y,z,d));
|
|
texgen->getPlane(PF_T, &x, &y, &z, &d);
|
|
osgTexGen->setPlane(osg::TexGen::T, osg::Vec4(x,y,z,d));
|
|
|
|
switch(mode)
|
|
{
|
|
case(PFTG_OBJECT_LINEAR) :
|
|
osgTexGen->setMode(osg::TexGen::OBJECT_LINEAR);
|
|
osgStateSet->setAttribute(osgTexGen);
|
|
break;
|
|
case(PFTG_EYE_LINEAR_IDENT) :
|
|
cerr << "TexGen Mode PFTG_EYE_LINEAR_IDENT not currently supported by the OSG,"<<endl;
|
|
cerr << " assuming osg::TexGen::EYE_LINEAR."<<endl;
|
|
case(PFTG_EYE_LINEAR) :
|
|
osgTexGen->setMode(osg::TexGen::EYE_LINEAR);
|
|
osgStateSet->setAttribute(osgTexGen);
|
|
break;
|
|
case(PFTG_SPHERE_MAP) :
|
|
osgTexGen->setMode(osg::TexGen::SPHERE_MAP);
|
|
osgStateSet->setAttribute(osgTexGen);
|
|
break;
|
|
case(PFTG_OFF) :
|
|
osgTexGen->setStateSetModes(*osgStateSet,osg::StateAttribute::OFF);
|
|
break;
|
|
case(PFTG_OBJECT_DISTANCE_TO_LINE) :
|
|
cerr << "TexGen Mode PFTG_OBJECT_DISTANCE_TO_LINE not currently supported by the OSG."<<endl;
|
|
osgTexGen->setStateSetModes(*osgStateSet,osg::StateAttribute::OFF);
|
|
break;
|
|
case(PFTG_EYE_DISTANCE_TO_LINE) :
|
|
cerr << "TexGen Mode PFTG_EYE_DISTANCE_TO_LINE not currently supported by the OSG."<<endl;
|
|
osgTexGen->setStateSetModes(*osgStateSet,osg::StateAttribute::OFF);
|
|
break;
|
|
default:
|
|
cerr << "TexGen Mode "<<mode<<" not currently supported by the OSG."<<endl;
|
|
osgTexGen->setStateSetModes(*osgStateSet,osg::StateAttribute::OFF);
|
|
break;
|
|
}
|
|
}
|
|
|
|
pfMatrix* texmat = (pfMatrix*)geostate->getAttr(PFSTATE_TEXMAT);
|
|
if (texmat)
|
|
{
|
|
osg::Matrix osgMatrix((*texmat)[0][0],(*texmat)[0][1],(*texmat)[0][2],(*texmat)[0][3],
|
|
(*texmat)[1][0],(*texmat)[1][1],(*texmat)[1][2],(*texmat)[1][3],
|
|
(*texmat)[2][0],(*texmat)[2][1],(*texmat)[2][2],(*texmat)[2][3],
|
|
(*texmat)[3][0],(*texmat)[3][1],(*texmat)[3][2],(*texmat)[3][3]);
|
|
|
|
osg::TexMat* osgTexMat = new osg::TexMat();
|
|
osgTexMat->setMatrix(osgMatrix);
|
|
osgStateSet->setAttribute(osgTexMat);
|
|
}
|
|
|
|
return osgStateSet;
|
|
}
|
|
|
|
|
|
osg::Material* ConvertFromPerformer::visitMaterial(osg::StateSet* osgStateSet,pfMaterial* front_mat,pfMaterial* back_mat)
|
|
{
|
|
if (front_mat==NULL && back_mat==NULL) return NULL;
|
|
|
|
osg::Material* osgMaterial = new osg::Material;
|
|
if (osgStateSet) osgStateSet->setAttribute(osgMaterial);
|
|
|
|
pfMaterial* material = NULL;
|
|
if (front_mat==back_mat) material = front_mat;
|
|
else if (back_mat==NULL) material = front_mat;
|
|
else if (front_mat==NULL) material = back_mat;
|
|
|
|
if (material) // single materials for front and back.
|
|
{
|
|
|
|
int colorMode = material->getColorMode(material->getSide());
|
|
|
|
switch(colorMode)
|
|
{
|
|
case(PFMTL_CMODE_AMBIENT_AND_DIFFUSE): osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); break;
|
|
case(PFMTL_CMODE_AMBIENT): osgMaterial->setColorMode(osg::Material::AMBIENT); break;
|
|
case(PFMTL_CMODE_DIFFUSE): osgMaterial->setColorMode(osg::Material::DIFFUSE); break;
|
|
case(PFMTL_CMODE_EMISSION): osgMaterial->setColorMode(osg::Material::EMISSION); break;
|
|
case(PFMTL_CMODE_SPECULAR): osgMaterial->setColorMode(osg::Material::SPECULAR); break;
|
|
case(PFMTL_CMODE_OFF): osgMaterial->setColorMode(osg::Material::OFF); break;
|
|
}
|
|
|
|
float s = material->getShininess()/128.0f;
|
|
osgMaterial->setShininess(osg::Material::FRONT_AND_BACK,s);
|
|
|
|
float a = material->getAlpha();
|
|
float r,g,b;
|
|
|
|
material->getColor(PFMTL_AMBIENT,&r,&g,&b);
|
|
osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
|
|
|
|
material->getColor(PFMTL_DIFFUSE,&r,&g,&b);
|
|
osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
|
|
|
|
material->getColor(PFMTL_EMISSION,&r,&g,&b);
|
|
osgMaterial->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
|
|
|
|
material->getColor(PFMTL_SPECULAR,&r,&g,&b);
|
|
osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(r,g,b,a));
|
|
}
|
|
else // seperate materials for front and back.
|
|
{
|
|
|
|
int colorMode = front_mat->getColorMode(front_mat->getSide());
|
|
|
|
switch(colorMode)
|
|
{
|
|
case(PFMTL_CMODE_AMBIENT_AND_DIFFUSE): osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); break;
|
|
case(PFMTL_CMODE_AMBIENT): osgMaterial->setColorMode(osg::Material::AMBIENT); break;
|
|
case(PFMTL_CMODE_DIFFUSE): osgMaterial->setColorMode(osg::Material::DIFFUSE); break;
|
|
case(PFMTL_CMODE_EMISSION): osgMaterial->setColorMode(osg::Material::EMISSION); break;
|
|
case(PFMTL_CMODE_SPECULAR): osgMaterial->setColorMode(osg::Material::SPECULAR); break;
|
|
case(PFMTL_CMODE_OFF): osgMaterial->setColorMode(osg::Material::OFF); break;
|
|
}
|
|
|
|
float s;
|
|
float a;
|
|
float r,g,b;
|
|
|
|
// front material
|
|
s = front_mat->getShininess();
|
|
osgMaterial->setShininess(osg::Material::FRONT,s);
|
|
|
|
a = front_mat->getAlpha();
|
|
|
|
front_mat->getColor(PFMTL_AMBIENT,&r,&g,&b);
|
|
osgMaterial->setAmbient(osg::Material::FRONT,osg::Vec4(r,g,b,a));
|
|
|
|
front_mat->getColor(PFMTL_DIFFUSE,&r,&g,&b);
|
|
osgMaterial->setDiffuse(osg::Material::FRONT,osg::Vec4(r,g,b,a));
|
|
|
|
front_mat->getColor(PFMTL_EMISSION,&r,&g,&b);
|
|
osgMaterial->setEmission(osg::Material::FRONT,osg::Vec4(r,g,b,a));
|
|
|
|
front_mat->getColor(PFMTL_SPECULAR,&r,&g,&b);
|
|
osgMaterial->setSpecular(osg::Material::FRONT,osg::Vec4(r,g,b,a));
|
|
|
|
// back material
|
|
s = back_mat->getShininess();
|
|
osgMaterial->setShininess(osg::Material::BACK,s);
|
|
|
|
a = back_mat->getAlpha();
|
|
|
|
back_mat->getColor(PFMTL_AMBIENT,&r,&g,&b);
|
|
osgMaterial->setAmbient(osg::Material::BACK,osg::Vec4(r,g,b,a));
|
|
|
|
back_mat->getColor(PFMTL_DIFFUSE,&r,&g,&b);
|
|
osgMaterial->setDiffuse(osg::Material::BACK,osg::Vec4(r,g,b,a));
|
|
|
|
back_mat->getColor(PFMTL_EMISSION,&r,&g,&b);
|
|
osgMaterial->setEmission(osg::Material::BACK,osg::Vec4(r,g,b,a));
|
|
|
|
back_mat->getColor(PFMTL_SPECULAR,&r,&g,&b);
|
|
osgMaterial->setSpecular(osg::Material::BACK,osg::Vec4(r,g,b,a));
|
|
|
|
}
|
|
|
|
return osgMaterial;
|
|
}
|
|
|
|
|
|
static osg::Texture::FilterMode getTexfilter(int filter, int pftype)
|
|
{
|
|
if (filter == PFTEX_MINFILTER)
|
|
{
|
|
|
|
if (pftype & PFTEX_LINEAR)
|
|
return osg::Texture::NEAREST_MIPMAP_LINEAR;
|
|
else if (pftype & PFTEX_BILINEAR)
|
|
return osg::Texture::LINEAR_MIPMAP_NEAREST;
|
|
else if (pftype & PFTEX_TRILINEAR)
|
|
return osg::Texture::LINEAR_MIPMAP_LINEAR;
|
|
|
|
return osg::Texture::NEAREST_MIPMAP_LINEAR;
|
|
|
|
}
|
|
else
|
|
{
|
|
// MAGFILTER
|
|
|
|
// not quite sure what is supposed to be interpret the Peformer
|
|
// filter modes here so will simple go with OpenGL default.
|
|
|
|
return osg::Texture::LINEAR;
|
|
}
|
|
}
|
|
|
|
|
|
osg::Texture* ConvertFromPerformer::visitTexture(osg::StateSet* osgStateSet,pfTexture* tex)
|
|
{
|
|
if (tex==NULL) return NULL;
|
|
|
|
osg::Texture* osgTexture = new osg::Texture;
|
|
_pfToOsgMap[tex] = osgTexture;
|
|
|
|
if (osgStateSet) osgStateSet->setAttribute(osgTexture);
|
|
|
|
int repeat_r = tex->getRepeat(PFTEX_WRAP_R);
|
|
int repeat_s = tex->getRepeat(PFTEX_WRAP_S);
|
|
int repeat_t = tex->getRepeat(PFTEX_WRAP_T);
|
|
|
|
if (repeat_r==PFTEX_CLAMP) osgTexture->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP);
|
|
else osgTexture->setWrap(osg::Texture::WRAP_R,osg::Texture::REPEAT);
|
|
|
|
if (repeat_s==PFTEX_CLAMP) osgTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP);
|
|
else osgTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
|
|
|
|
if (repeat_t==PFTEX_CLAMP) osgTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP);
|
|
else osgTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
|
|
|
|
// filter
|
|
#if 1
|
|
osgTexture->setFilter(osg::Texture::MIN_FILTER,
|
|
getTexfilter(PFTEX_MINFILTER,
|
|
tex->getFilter(PFTEX_MINFILTER)));
|
|
osgTexture->setFilter(osg::Texture::MAG_FILTER,
|
|
getTexfilter(PFTEX_MAGFILTER,
|
|
tex->getFilter(PFTEX_MAGFILTER)));
|
|
#endif
|
|
|
|
// image
|
|
std::string texName = tex->getName();
|
|
|
|
if (_saveImagesAsRGB)
|
|
{
|
|
std::string strippedName = osgDB::getStrippedName(texName);
|
|
texName = _saveImageDirectory+strippedName+".rgb";
|
|
tex->saveFile(texName.c_str());
|
|
}
|
|
|
|
if (!_saveAbsoluteImagePath) texName = osgDB::getSimpleFileName(texName);
|
|
|
|
int s=0;
|
|
int t=0;
|
|
int r=0;
|
|
int comp=0;
|
|
unsigned int* imageData = NULL;
|
|
|
|
tex->getImage(&imageData,&comp,&s,&t,&r);
|
|
|
|
int internalFormat = comp;
|
|
|
|
unsigned int pixelFormat =
|
|
comp == 1 ? GL_LUMINANCE :
|
|
comp == 2 ? GL_LUMINANCE_ALPHA :
|
|
comp == 3 ? GL_RGB :
|
|
comp == 4 ? GL_RGBA : (GLenum)-1;
|
|
|
|
unsigned int dataType = GL_UNSIGNED_BYTE;
|
|
|
|
osg::Image* image = new osg::Image;
|
|
image->setFileName(texName.c_str());
|
|
image->setImage(s,t,r,
|
|
internalFormat,
|
|
pixelFormat,
|
|
dataType,
|
|
(unsigned char*)imageData);
|
|
|
|
osgTexture->setImage(image);
|
|
|
|
return osgTexture;
|
|
}
|