After having slept on it, I think one possible approach would be as
follows:-


1. A method that is executed as each node (including geodes is traversed.
This method would need to detect whenever a new "material" was encountered.
It would name and store each new material for inclusion in the "library".
Additionally this method would maintain a list of "currently active
materials". Maybe there is something in one of the other osg plugins we can
model this on. Anyone know?

2. A method that is executed per geode after method 1 has been executed for
that geode. This method would scan the stateSet associated which each
geometry contained in the geode and add any new "materials" found to the
"library". The method would then set the local material name bindings for
the DOM geometry such that the materials are correctly applied to each DOM
mesh.

The main thing that I not sure on is whether any new materials encountered
at the osg::Geode and osg::Geometry stateSet levels need to be put in a
global "library" as they can never be referenced outside of the scope of the
geode node in the osg tree(on reviewing this I am not sure I am correct
here, what about geometries shared between geodes?). I do not know whether
there is any local material mechanism or if the way the writer puts
geometries into a library-geometries forces a library_materials to be used.
I still cannot get my head round this. It may be better to implement as
closely as possible to original model used in the writer and then look for
optimisations later.

Any comments?

Roger


Roger,

If I'm understanding you correctly, your method supposes we can apply several collada materials on one geometry. I'm not sure this is possible in collada (but then again I'm not very knowledgable with it), maybe Heinrich can answer us ?

As a first simple approach I'm thinking of modifying the daeWriter class like this (pseudo-code) :

void daeWriter::apply(osg::Node node)
{
   if (node.hasStateSet()) {
     statesetStack.push(currentStateSet);
     currentStateSet.merge(node.getStateSet());
   }
  traverse(node);
  if (node.hasStateSet())
     statesetStack.pop();
}

void daeWriter::apply(osg::Geode geode)
{
 // get the geode stateset
  apply((osg::Node)geode);
for each geom in geode {
     if (geom.hasStateSet()) {
       statesetStack.push(currentStateSet);
       currentStateSet.merge(geom.getStateSet());
     }

     // Get domInstanceGeom like in the original daeWriter

     processMaterial(currentStateSet, domInstanceGeom);

     if (geom.hasStateSet())
       statesetStack.pop();
  }
}

For this to work I'll have to change processMaterial to search for an identical StateSet (in sense of the compare() method) and not only the same StateSet as a pointer. I think this should work well and at least all statesets would be taken into account, even if it may not be optimal in terms of state switches.


--
Sebastien Grignard
R&D Developer
Archivideo
40, rue des Veyettes - 35000 Rennes FRANCE
Phone: +033 2 99 86 30 20

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

Reply via email to