• NodeVisitor的使用-遍历Geode节点下的Geometry并获取顶点、法向量等数据


    struct Subset
    {
        std::vector<float> vertexs;//位置
        std::vector<float> normals;//法向
        std::vector<float> texCoords;//纹理
        std::vector<unsigned int> indices;//索引下标
        std::vector<unsigned int> faceMtrls;//面材质索引
    };
    
    class GetSimplifySTLDataVisitor : public osg::NodeVisitor
    {
    public:
        GetSimplifySTLDataVisitor(Subset &s):dstSubset(s),
            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
        {
        }
    
        virtual void apply(osg::Geode& geode)
        {
            unsigned int count = geode.getNumDrawables();
            for ( unsigned int i = 0; i < count; i++ )
            {
                osg::Geometry *geometry = geode.getDrawable( i )->asGeometry();
                if ( !geometry )
                    continue;
                // 顶点数据
                osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
                int vertexlNum = vertices->size();
                for ( int i=0; i<vertexlNum; i++) {
                    dstSubset.vertexs.push_back( vertices->at(i).x() );
                    dstSubset.vertexs.push_back( vertices->at(i).y() );
                    dstSubset.vertexs.push_back( vertices->at(i).z() );
                }
                // 法向量
                osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
                int normalNum = normals->size();
                for (int i=0; i<normalNum; i++) {
                    dstSubset.normals.push_back( normals->at(i).x() );
                    dstSubset.normals.push_back( normals->at(i).y() );
                    dstSubset.normals.push_back( normals->at(i).z() );
                }
                normalBindKinds.insert(geometry->getNormalBinding());
                if(osg::Geometry::BIND_PER_VERTEX != geometry->getNormalBinding() )
                {
                    std::string msg="未处理的法向量绑定方式";
                    MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                }
                // 索引数组
                for ( unsigned int i = 0; i < geometry->getNumPrimitiveSets(); ++i )
                {
                    osg::PrimitiveSet* ps = geometry->getPrimitiveSet( i );
                    if ( !ps ) continue;
                    pts.insert(ps->getType());
                    modes.insert(ps->getMode());
                    switch( ps->getType() )
                    {
                    case osg::PrimitiveSet::DrawElementsUIntPrimitiveType :
                        {
                            osg::DrawElementsUInt* deui = dynamic_cast<osg::DrawElementsUInt*>(ps);
                            const unsigned indexNum = deui->getNumIndices();
                            switch( deui->getMode() )
                            {
                            case osg::PrimitiveSet::TRIANGLES :
                                {
                                    for (unsigned int i=0; i<indexNum; i++) 
                                    {
                                        dstSubset.indices.push_back( deui->at(i) );
                                    }
                                    break;
                                }
                            default:
                                {
                                    std::string msg="未处理的绘制模式";
                                    MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                                }
                            }
                            break;
                        }
                    case osg::PrimitiveSet::DrawElementsUShortPrimitiveType :
                        {
                            osg::DrawElementsUShort* de = dynamic_cast<osg::DrawElementsUShort*>(ps);
                            const unsigned indexNum = de->getNumIndices();
                            switch( de->getMode() )
                            {
                            case osg::PrimitiveSet::TRIANGLES :
                                {
                                    for (unsigned int i=0; i<indexNum; i++) 
                                    {
                                        dstSubset.indices.push_back( de->at(i) );
                                    }
                                    break;
                                }
                            case osg::PrimitiveSet::TRIANGLE_STRIP :
                                {
                                    for (unsigned int i=0; i<indexNum-2; i++) 
                                    {
                                        //此处索引为何与基数偶数有关,可百度GL_TRIANGLE_STRIP
                                        if (i%2==0)
                                        {
                                            dstSubset.indices.push_back( de->at(i) );
                                            dstSubset.indices.push_back( de->at(i+1) );
                                            dstSubset.indices.push_back( de->at(i+2) );
                                        }
                                        else
                                        {
                                            dstSubset.indices.push_back( de->at(i) );
                                            dstSubset.indices.push_back( de->at(i+2) );
                                            dstSubset.indices.push_back( de->at(i+1) );
                                        }
                                    }
                                    break;
                                }
                            default:
                                {
                                    std::string msg="未处理的绘制模式";
                                    MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                                }
                            }
                            break;
                        }
                    case osg::PrimitiveSet::DrawArraysPrimitiveType :
                        {
                            osg::DrawArrays* da = dynamic_cast<osg::DrawArrays*>(ps);
                            int first=da->getFirst();
                            int count=da->getCount();
                            switch( da->getMode() )
                            {
                            case osg::PrimitiveSet::TRIANGLES :
                                {
                                    for ( int i=first; i<first+count; i++) {
                                        dstSubset.indices.push_back( i );
                                    }
                                    break;
                                }
                            case osg::PrimitiveSet::TRIANGLE_STRIP :
                                {
                                    for ( int i=first; i<first+count-2; i++) {
                                        if(i%2==0)
                                        {
                                            dstSubset.indices.push_back( i );
                                            dstSubset.indices.push_back( i+1 );
                                            dstSubset.indices.push_back( i+2 );
                                        }
                                        else
                                        {
                                            dstSubset.indices.push_back( i );
                                            dstSubset.indices.push_back( i+2 );
                                            dstSubset.indices.push_back( i+1 );
                                        }
                                    }
                                    break;
                                }
                            default:
                                {
                                    std::string msg="未处理的绘制模式";
                                    MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                                }
                            }
                            break;
                        }
                    default:
                        {
                            std::string msg="未处理的图元类型";
                            MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                        }
                    }
                }
            }
        }
    private:
        Subset &dstSubset;
        //以下三个数组用来测试
        std::set<osg::Geometry::AttributeBinding> normalBindKinds;
        std::set<osg::PrimitiveSet::Type> pts;
        std::set<GLenum> modes;
    };
  • 相关阅读:
    Java基础-IO流对象之字节流(Stream)
    Java基础-IO流对象之File类
    Java基础-集合的嵌套
    rsync命令的基本使用
    java基础-Map集合
    Java基础-Collection子接口之Set接口
    Java基础-Collection子接口之List接口
    Java基础-泛型
    Unity4.3 bug GetChild顺序错乱
    Windows系统上的.Net版本和.NETFramework的C#版本
  • 原文地址:https://www.cnblogs.com/coolbear/p/4587748.html
Copyright © 2020-2023  润新知