两种提取OSG中纹理坐标的方法

时间:2022-03-15 12:37:35

OSG中提到的visitor通常都是使用NodeVisitor,在毕设论文中做场景重构的时候需要获取三角面片的纹理坐标时,用到了getTexCoorArray()函数,对他们的读取要用到ArrayVisitor。但是网上有关ArrayVisitor的资料相当少,可能是因为ArrayVisitor的处理相对比较简单的原因?

1.使用ArrayVisitor的方法获取。

类似于NodeVisitor一样,需要定义Visitor类:

#include <iostream>
#include <osgDB/ReadFile>
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osg/Array>
class TexCoorVisitor : public osg::ArrayVisitor
{
public:
    TexCoorVisitor(): osg::ArrayVisitor()
    {
        mTexCoorArray = new osg::Vec2Array;
    }
    virtual void apply(osg::Vec2Array &array)
    {
        mTexCoorArray = &array;
    }
    osg::Vec2Array* GetTexCoorArray()
    {
        return mTexCoorArray;
    }
private:
    osg::Vec2Array* mTexCoorArray;
};

void main(int argc, char* argv[])
{
    osg::Node* node = osgDB::readNodeFile("cow.osg");
    osgViewer::Viewer* view = new osgViewer::Viewer;
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(node);
    //view->setSceneData(group.get());
    //view->run();
    osg::Geometry* geom = node->asGroup()->getChild(0)->asGeode()->getDrawable(0)->asGeometry();
    osg::Array* tmp = geom->getTexCoordArray(0);
    TexCoorVisitor* tcv = new TexCoorVisitor;
    tmp->accept(*tcv);
    osg::Vec2Array* res = tcv->GetTexCoorArray();
    std::cout<<res->size()<<std::endl;
    auto it = res->begin();
    for(; it<res->end(); it++)
    {
        std::cout<<(*it).x()<<" "<<(*it).y()<<std::endl;
    }
    system("pause");
}

2.使用地址强转的方法来获取纹理坐标数组

如果明白ArrayVisitor的原理的话,其实还可以用地址强转这种比较简单的方法来获取纹理坐标。

osg::Vec2Array* coorArray = (osg::Vec2Array*) tmp;
    auto it = coorArray->begin();
// for(; it<tmp2->end(); it++)
// {
// std::cout<<it->x()<<std::endl;
// std::cout<<count++<<std::endl;
// }