From Roger James, "fixes mostly related to texture handling."

This commit is contained in:
Robert Osfield
2006-11-22 21:11:46 +00:00
parent a3b1d8cd54
commit 675e4a2cde
5 changed files with 119 additions and 38 deletions

View File

@@ -25,6 +25,8 @@
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <sstream>
using namespace osgdae;
void daeReader::processBindMaterial( domBind_material *bm, osg::Node *geo )
@@ -333,20 +335,8 @@ osg::StateAttribute **sa )
{
osg::Vec4 col;
domAny *dcol = (domAny*)(daeElement*)teq->getContents()[0];
char *val = (char *)dcol->getValue();
int cnt = 0;
while ( cnt < 4 && strlen( val ) != 0 )
{
char *space = strchr( val, ' ' );
if ( space != NULL )
{
*space = 0;
}
int tmp = atoi( val );
col[cnt] = tmp;
cnt++;
val = space + 1;
}
std::istringstream diffuse_colour((const char *)dcol->getValue());
diffuse_colour >> col.r() >> col.g() >> col.b() >> col.a();
mat->setDiffuse( osg::Material::FRONT_AND_BACK, col );
retVal = true;
break;

View File

@@ -31,12 +31,15 @@ void daeWriter::apply( osg::Geode &node )
debugPrint( node );
#endif
pushStateSet(node.getStateSet());
unsigned int count = node.getNumDrawables();
for ( unsigned int i = 0; i < count; i++ )
{
osg::Geometry *g = node.getDrawable( i )->asGeometry();
if ( g != NULL )
{
pushStateSet(g->getStateSet());
std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g );
if ( iter != geometryMap.end() )
{
@@ -44,11 +47,8 @@ void daeWriter::apply( osg::Geode &node )
std::string url = "#" + std::string( iter->second->getId() );
ig->setUrl( url.c_str() );
//osg::notify( osg::WARN ) << "Found a duplicate Geometry " << url << std::endl;
if ( node.getStateSet() != NULL )
{
processMaterial( node.getStateSet(), ig, iter->second->getId() );
}
if (!stateSetStack.empty())
processMaterial( currentStateSet.get(), ig, iter->second->getId() );
}
else
{
@@ -78,17 +78,16 @@ void daeWriter::apply( osg::Geode &node )
geometryMap.insert( std::make_pair( g, geo ) );
#endif
if ( node.getStateSet() != NULL )
{
processMaterial( node.getStateSet(), ig, name );
}
if (!stateSetStack.empty())
processMaterial( currentStateSet.get(), ig, name );
}
popStateSet(g->getStateSet());
}
}
lastVisited = GEODE;
traverse( node );
popStateSet(node.getStateSet());
}
/** append elements (verts, normals, colors and texcoord) for file write */

View File

@@ -27,13 +27,14 @@ using namespace osgdae;
void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, const std::string &geoName )
{
osg::ref_ptr<osg::StateSet> ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it
domBind_material *bm = daeSafeCast< domBind_material >( ig->createAndPlace( COLLADA_ELEMENT_BIND_MATERIAL ) );
domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->createAndPlace( "technique_common" ) );
domInstance_material *im = daeSafeCast< domInstance_material >( tc->createAndPlace( COLLADA_ELEMENT_INSTANCE_MATERIAL ) );
std::string symbol = geoName + "_material";
im->setSymbol( symbol.c_str() );
std::map< osg::StateSet*, domMaterial* >::iterator iter = materialMap.find( ss );
MaterialMap::iterator iter = materialMap.find( ssClean );
if ( iter != materialMap.end() )
{
std::string url = "#" + std::string( iter->second->getId() );
@@ -47,7 +48,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
}
domMaterial *mat = daeSafeCast< domMaterial >( lib_mats->createAndPlace( COLLADA_ELEMENT_MATERIAL ) );
std::string name = ss->getName();
std::string name = ssClean->getName();
if ( name.empty() )
{
name = "material";
@@ -78,10 +79,10 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
pc_teq->setSid( "t0" );
domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->createAndPlace( "phong" ) );
osg::Texture *tex = static_cast<osg::Texture*>(ss->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ));
if ( ss->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ) != NULL )
osg::Texture *tex = static_cast<osg::Texture*>(ssClean->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ));
if ( ssClean->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ) != NULL )
{
tex = static_cast<osg::Texture*>(ss->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ));
tex = static_cast<osg::Texture*>(ssClean->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ));
}
if ( tex != NULL && tex->getImage( 0 ) != NULL )
{
@@ -93,12 +94,23 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
osg::Image *osgimg = tex->getImage( 0 );
domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->createAndPlace( "init_from" ) );
std::string imgstr = "/" + osgDB::convertFileNameToUnixStyle( osgDB::findDataFile( osgimg->getFileName() ) );
#ifdef WIN32
daeURI uri( _strlwr( (char *)imgstr.c_str() ) );
#else
daeURI uri( imgstr.c_str() );
#endif
uri.validate();
imgif->setValue( uri.getURI() );
//imgif->setValue( imgstr.c_str() );
//imgif->getValue().validate();
#ifdef WIN32
std::string docUriString = doc->getDocumentURI()->getFilepath();
docUriString += doc->getDocumentURI()->getFile();
daeURI docUri( _strlwr( (char *)docUriString.c_str() ) );
imgif->getValue().makeRelativeTo( &docUri );
#else
imgif->getValue().makeRelativeTo( doc->getDocumentURI() );
#endif
//imgif->setValue( osgimg->getFileName().c_str() );
//osg::notify( osg::WARN ) << "original img filename " << osgimg->getFileName() << std::endl;
//osg::notify( osg::WARN ) << "init_from filename " << imgstr << std::endl;
@@ -237,8 +249,8 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
bvi->setInput_set( 0 );
//take care of blending if any
osg::BlendFunc *bf = static_cast< osg::BlendFunc * >( ss->getAttribute( osg::StateAttribute::BLENDFUNC ) );
osg::BlendColor *bc = static_cast< osg::BlendColor * >( ss->getAttribute( osg::StateAttribute::BLENDCOLOR ) );
osg::BlendFunc *bf = static_cast< osg::BlendFunc * >( ssClean->getAttribute( osg::StateAttribute::BLENDFUNC ) );
osg::BlendColor *bc = static_cast< osg::BlendColor * >( ssClean->getAttribute( osg::StateAttribute::BLENDCOLOR ) );
if ( bc != NULL )
{
domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->createAndPlace( "transparent" ) );
@@ -263,7 +275,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
}
}
osg::Material *osgmat = static_cast<osg::Material*>(ss->getAttribute( osg::StateAttribute::MATERIAL ));
osg::Material *osgmat = static_cast<osg::Material*>(ssClean->getAttribute( osg::StateAttribute::MATERIAL ));
if ( osgmat != NULL )
{
const osg::Vec4 &eCol = osgmat->getEmissionFrontAndBack()?osgmat->getEmission( osg::Material::FRONT_AND_BACK ):osgmat->getEmission( osg::Material::FRONT );
@@ -288,7 +300,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
//### check if we really have a texture
if ((tex == NULL) || (!cot->getTexture()))
if ( phong->getDiffuse() == NULL )
{
cot = daeSafeCast< domCommon_color_or_texture_type >( phong->createAndPlace( "diffuse" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->createAndPlace( "color" ) );
@@ -309,7 +321,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
domAny *any = (domAny*)(daeElement*)teq->createAndPlace( "color" );
std::ostringstream colVal;
colVal << std::dec << " " << int(dCol[0]) << " " << int(dCol[1]) << " " << int(dCol[2]) << " " << int(dCol[3]);
colVal << dCol.r() << " " << dCol.g() << " " << dCol.b() << " " << dCol.a();
any->setValue( colVal.str().c_str() );
}
@@ -325,5 +337,22 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
f->setValue( shininess );
}
materialMap.insert( std::make_pair( ss, mat ) );
materialMap.insert( std::make_pair( ssClean, mat ) );
}
osg::StateSet* daeWriter::CleanStateSet(osg::StateSet* pStateSet) const
{
// TODO - clean out all the the attributes and modes not used to define materials
osg::StateSet* pCleanedStateSet = new osg::StateSet;
pCleanedStateSet->setTextureAttributeList(pStateSet->getTextureAttributeList());
if (NULL != pStateSet->getAttribute(osg::StateAttribute::BLENDFUNC))
pCleanedStateSet->setAttribute(pStateSet->getAttribute(osg::StateAttribute::BLENDFUNC));
if (NULL != pStateSet->getAttribute(osg::StateAttribute::BLENDCOLOR))
pCleanedStateSet->setAttribute(pStateSet->getAttribute(osg::StateAttribute::BLENDCOLOR));
if (NULL != pStateSet->getAttribute(osg::StateAttribute::MATERIAL))
pCleanedStateSet->setAttribute(pStateSet->getAttribute(osg::StateAttribute::MATERIAL));
return pCleanedStateSet;
}

View File

@@ -23,8 +23,8 @@
using namespace osgdae;
daeWriter::daeWriter( DAE *dae_, const std::string &fname,bool _usePolygons ) : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ),
dae(dae_),
usePolygons (_usePolygons)
dae(dae_),
usePolygons (_usePolygons)
{
success = true;
@@ -54,6 +54,8 @@ daeWriter::daeWriter( DAE *dae_, const std::string &fname,bool _usePolygons ) :
lib_mats = NULL;
lastDepth = 0;
currentStateSet = new osg::StateSet();
}
daeWriter::~daeWriter()
@@ -143,3 +145,35 @@ void daeWriter::createAssetTag()
u->setName( "meter" );
u->setMeter( 1 );
}
void daeWriter::traverse (osg::Node &node)
{
pushStateSet(node.getStateSet());
osg::NodeVisitor::traverse( node );
popStateSet(node.getStateSet());
}
void daeWriter::pushStateSet(osg::StateSet* ss)
{
if (NULL!=ss) {
// Save our current stateset
stateSetStack.push(currentStateSet.get());
// merge with node stateset
currentStateSet = static_cast<osg::StateSet*>(currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
currentStateSet->merge(*ss);
}
}
void daeWriter::popStateSet(osg::StateSet* ss)
{
if (NULL!=ss) {
// restore the previous stateset
currentStateSet = stateSetStack.top();
stateSetStack.pop();
}
}

View File

@@ -15,6 +15,7 @@
#define _DAE_WRITER_H_
#include <map>
#include <stack>
#include <osg/Node>
#include <osg/Geode>
@@ -106,6 +107,8 @@ public:
//virtual void apply( osg::ClearNode &node)
//virtual void apply( osg::OccluderNode &node)
void traverse (osg::Node &node);
/*protected:
struct MeshData {
domMesh *mesh;
@@ -130,6 +133,10 @@ protected: //methods
void createAssetTag();
void pushStateSet(osg::StateSet* ss);
void popStateSet(osg::StateSet* ss);
protected: //members
DAE *dae;
daeDocument *doc;
@@ -147,15 +154,37 @@ protected: //members
NodeType lastVisited;
unsigned int lastDepth;
struct CompareStateSet
{
bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
{
//std::cout << "CompareStateSet: " << ss1->compare(*ss2, false) << " " << ss1 << " " << ss2 << std::endl;
return ss1->compare(*ss2, true) < 0;
}
};
std::map< std::string, int > uniqueNames;
std::map< osg::Geometry*, domGeometry * > geometryMap;
std::map< osg::StateSet*, domMaterial * > materialMap;
typedef std::map< osg::ref_ptr<osg::StateSet>, domMaterial *, CompareStateSet> MaterialMap;
MaterialMap materialMap;
typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
StateSetStack stateSetStack;
osg::ref_ptr<osg::StateSet> currentStateSet;
daeURI rootName;
bool usePolygons;
osg::StateSet* CleanStateSet(osg::StateSet* pStateSet) const;
protected: //inner classes
class ArrayNIndices
{