From Roger James, "fixes mostly related to texture handling."
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user