class MyNodeVisitor:public osg::NodeVisitor
{
pulic:
MyNodeVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{}
void apply(osg::Geode& geode)
{
//計算當前geode節點對應的世界變換矩陣,用來計算geode中頂點對應的世界坐標
osg::Matrix geodeMatrix=osg::computeLocalToWorld(getNodePath());
unsigned int count=geode.getNumDrawables();
for(unsigned int geomIdx=0; geomIdx<count; geomIdx++)
{
osg::Geometery *geometry = geode.getDrawable(geomIdx)->asGeometry();
if(!geometry) continue;
//頂點數據
osg::Vec3Array* vertices=dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
//法向量
osg::Vec3Array* normals=dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
//索引數組
for(unsigned int primitiveIdx=0; primitiveIdx<geometry->getNumPrimitiveSets(); ++primitiveIdx)
{
osg::PrimitiveSet* ps=geometry->getPrimitiveSet(primitiveIdx);
if(!ps) continue;
switch(ps->getType())
{
case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
{
osg::DrawElementsUShort* deus=dynamic_cast<osg::DrawElementsUShort*>(ps);
const unsigned int indexNum=deus->getNumIndices();
switch(deus->getMode)
{
case osg::PrimitiveSet::TRIANGLES:
//假設geometry->getNormalBinding()==osg::Geometry::BIND_PER_VERTEX)
//即每一個頂點對應一個法向量
for(unsigned int i=0; i<indexNum; i++)
{
//頂點索引
unsigned int idx=deus->at(i);
//法向量。需要轉換成世界坐標,需要乘以geodeMatrix的逆矩陣的轉置,具體原因可以參考計算法向量那篇隨筆
Vec3 normalWorld=normals->at(idx)*(geodeMatrix的逆矩陣的轉置);
//頂點坐標
Vec3 vertexWorld=vertices->at(idx)*geodeMatrix;
}
break;
}
}
}
}
}
}
}