Tutorials
Analysing a Scenegraph
- Details
- Category: Tutorials
- Published: 02 October 2012
- Written by openscenegraph
- Hits: 74983
Once a scenegraph is loaded you may wish to analyse the in memory tree of nodes. Ideally you would use a nodevisitor, but here is a simple piece of C++ code that works:
void analyseGeode(osg::Geode *geode); void analysePrimSet(osg::PrimitiveSet*prset, const osg::Vec3Array *verts); void analyse(osg::Node *nd) { /// here you have found a group. osg::Geode *geode = dynamic_cast<osg::Geode *> (nd); if (geode) { // analyse the geode. If it isnt a geode the dynamic cast gives NULL. analyseGeode(geode); } else { osg::Group *gp = dynamic_cast<osg::Group *> (nd); if (gp) { osg::notify(osg::WARN) << "Group "<< gp->getName() <<std::endl; for (unsigned int ic=0; ic<gp->getNumChildren(); ic++) { analyse(gp->getChild(ic)); } } else { osg::notify(osg::WARN) << "Unknown node "<< nd <<std::endl; } } } // divide the geode into its drawables and primitivesets: void analyseGeode(osg::Geode *geode) { for (unsigned int i=0; i<geode->getNumDrawables(); i++) { osg::Drawable *drawable=geode->getDrawable(i); osg::Geometry *geom=dynamic_cast<osg::Geometry *> (drawable); for (unsigned int ipr=0; ipr<geom->getNumPrimitiveSets(); ipr++) { osg::PrimitiveSet* prset=geom->getPrimitiveSet(ipr); osg::notify(osg::WARN) << "Primitive Set "<< ipr << std::endl; analysePrimSet(prset, dynamic_cast<const osg::Vec3Array*>(geom->getVertexArray())); } } } void analysePrimSet(osg::PrimitiveSet*prset, const osg::Vec3Array *verts) { unsigned int ic; unsigned int i2; unsigned int nprim=0; osg::notify(osg::WARN) << "Prim set type "<< prset->getMode() << std::endl; for (ic=0; ic<prset->getNumIndices(); ic++) { // NB the vertices are held in the drawable - osg::notify(osg::WARN) << "vertex "<< ic << " is index "<<prset->index(ic) << " at " << (* verts)[prset->index(ic)].x() << "," << (* verts)[prset->index(ic)].y() << "," << (* verts)[prset->index(ic)].z() << std::endl; } // you might want to handle each type of primset differently: such as: switch (prset->getMode()) { case osg::PrimitiveSet::TRIANGLES: // get vertices of triangle osg::notify(osg::WARN) << "Triangles "<< nprim << " is index "<<prset->index(ic) << std::endl; for (i2=0; i2<prset->getNumIndices()-2; i2+=3) { } break; case osg::PrimitiveSet::TRIANGLE_STRIP: // look up how tristrips are coded break; // etc for all the primitive types you expect. EG quads, quadstrips lines line loops.... } }
This code can be inserted into (say) osgviewer.cpp, and called thus:
analyse(loadedModel.get());