This topic was originally raised under [osg-users] Collada plugin and textured models.

 

I thought it would be better to start this thread off with a new topic as the original thread is mostly concerned now with issues on the reader side.

 

Sebastien Grignard’s original observation was

 

>>Hi all.

>>I tried OSG 1.2 with the collada/dae ReaderWriter, but when I convert a textured model (like cow.osg or skydome.osg) the geometry is correctly converted but the texture is not applied.

>>Looking at the output dae file I don't see any reference to a texture (except texture coordinates).

>>Is it that the dae plugin doesn't support textured models writing or am I missing something ?

 

>>Thanks.

 

He tracked this down to.

 

>>I investigated a bit and found that the dae writer doesn't take into account the statesets set directly on the geometries.

>>This was the problem for cow.osg for example. I fixed this by also processing the geometries' statesets. This only a quick'n dirty patch though and I'll have to look into the collada materials definition to find a better solution.

>>I also noticed that the collada writer doesn't support TexGen attributes (in cow.dae, texcoords are present but all at 0).

>>I guess this can be fixed by manually computing the texcoords according to the Texgen, but isn't there a similar way as OpenGL's texgen to define textures coordinates in collada ?

>>Also the collada writer doesn't seem to support BIND_PER_PRIMITIVE normals. I tried to look into the daeWGeometry.cpp code but without success for now. Can somebody point me in the right direction ? I'll then be happy to make the changes >>and share them.

 

>>Thanks.

 

I experienced the same problem and produced another “quick and dirty” patch.

 

void daeWriter::apply( osg::Geode &node )

{

#ifdef _DEBUG

    debugPrint( node );

#endif

 

    unsigned int count = node.getNumDrawables();

    for ( unsigned int i = 0; i < count; i++ )

    {

        osg::Geometry *g = node.getDrawable( i )->asGeometry();

        if ( g != NULL )

        {

            std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g );

            if ( iter != geometryMap.end() )

            {

                domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) );

                   

                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 (g->getStateSet() != NULL)

                    processMaterial( g->getStateSet(), ig, iter->second->getId() );

                else if ( node.getStateSet() != NULL )

                    processMaterial( node.getStateSet(), ig, iter->second->getId() );

            }

            else

            {

                if ( lib_geoms == NULL )

                {

                    lib_geoms = daeSafeCast< domLibrary_geometries >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) );

                }

                std::string name = node.getName();

                if ( name.empty() ) name = "geometry";

                name = uniquify( name );

 

                domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->createAndPlace( COLLADA_ELEMENT_GEOMETRY ) );

                geo->setId( name.c_str() );

 

                if ( !processGeometry( g, geo, name ) )

                {

                    daeElement::removeFromParent( geo );

                    continue;

                }

 

                domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) );

                   

                std::string url = "" + name;

                ig->setUrl( url.c_str() );

 

#ifndef EARTH_GEO

                geometryMap.insert( std::make_pair( g, geo ) );

#endif

 

                                                if (g->getStateSet() != NULL)

                    processMaterial( g->getStateSet(), ig, name );

                else if ( node.getStateSet() != NULL )

                    processMaterial( node.getStateSet(), ig, name );

            }

        }

    }

 

    lastVisited = GEODE;

 

    traverse( node );

}

 

This does not address the fundamental issue; that is that when a geode is rendered in the OSG model in inherits the accumulated state from its parents in the graph. It is this inherited state which defines which “materials” in Collada terms are applied to the geometries. This is further complicated by the fact that each geometry in a geode can have its own state that may modify the inherited state. So to replicate the OSG rendering in Collada terms it would appear as changes to the inherited stateSet are encountered during a traversal of the of the OSG graph then each new “material” should be named and defined in the “library”. This means that when  geode is encountered any new “materials” encountered in the local geode stateSet and any of the stateSets of the associated geometries need to be named and defined in the “library”. I don’t know enough about Collada to decide if the “materials” defined in the geometry stateSets can be locally defined! The currently “active” materials then need to be bound to the Collada geometry node and the local naming mechanism used to control the application of materials defined in geometry(drawable) stateSets to their relevant meshes.

 

I knew I should have written this before I went to the pub!

 

Does it make any sense?

 

I don’t know enough about Collada to code this up myself. But maybe we can work out the design together and I might be able to give it a go.

 

Roger

 

 

 

 

 

_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to