OSG获取模型坐标点、索引、法向量、纹理等数据

(文章很长,如果想直接看源码不想听我啰嗦的话,请直接跳到最后下载源码)

如果要做针对模型的算法,获取模型中所有图元(由于OSG多边形只支持三角形图元,而且自己做的科研也是针对三角网模型的,本文就针对三角形模型来说明)的坐标、纹理、法向量等数据,然后再进行处理是非常重要的,但是网上关于获取图元属性的教程实在太少,而且有的说的也不是很清楚,自己在做科研的过程中,探索以后,记录在此,希望能帮助到有需要的同学。

首先要知道,在osg中几何图元是被几何体(osg::Geometry)管理的,osg::Geometry提供了管理几何图元osg::PrimitiveSet的数组,用来添加和删除这些图元,这些图元共同构成了几何体对象。要访问图元的属性,应该就要在geometry中找,查看geometry的函数,发现有两个访问者函数:

virtual void accept(PrimitiveFunctor& pf) const;
virtual void accept(PrimitiveIndexFunctor& pf) const;

根据命名我们可以看出,这两个函数对应着图元的访问和图元索引的访问。Geometry的父类Drawable也有这两个函数。因为在Node中,我们很容易拿到Drawable,所以我们要获取图元的属性,应该是要给Drawable传入访问器,然后在访问器的apply中获取图元的属性了。

通过查文档,我们发现Drawale支持四个visitor来获取Drawable的信息,分别是:

virtual void accept(AttributeFunctor&);
virtual void accept(ConstAttributeFunctor&) const;
virtual void accept(PrimitiveFunctor&) const;
virtual void accept(PrimitiveIndexFunctor&) const;

我们要访问图元的属性和索引,主要用到的是AttributeFunctor还有PrimitiveIndexFunctor。首先看AttributeFunctor类的定义:

        class AttributeFunctor
        {
        public:
            virtual ~AttributeFunctor() {}

            virtual void apply(AttributeType,unsigned int,GLbyte*) {}
            virtual void apply(AttributeType,unsigned int,GLshort*) {}
            virtual void apply(AttributeType,unsigned int,GLint*) {}

            virtual void apply(AttributeType,unsigned int,GLubyte*) {}
            virtual void apply(AttributeType,unsigned int,GLushort*) {}
            virtual void apply(AttributeType,unsigned int,GLuint*) {}

            virtual void apply(AttributeType,unsigned int,float*) {}
            virtual void apply(AttributeType,unsigned int,Vec2*) {}
            virtual void apply(AttributeType,unsigned int,Vec3*) {}
            virtual void apply(AttributeType,unsigned int,Vec4*) {}
            virtual void apply(AttributeType,unsigned int,Vec4ub*) {}

            virtual void apply(AttributeType,unsigned int,double*) {}
            virtual void apply(AttributeType,unsigned int,Vec2d*) {}
            virtual void apply(AttributeType,unsigned int,Vec3d*) {}
            virtual void apply(AttributeType,unsigned int,Vec4d*) {}
        };

不出所料,就是在不同的apply函数中,可以获取不同类型的属性信息。

再看PrimitiveIndexFunctor的实现:

class PrimitiveIndexFunctor
{
public:
    virtual ~PrimitiveIndexFunctor() {}

    virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
    virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
    virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;

    virtual void setVertexArray(unsigned int count,const Vec2d* vertices) = 0;
    virtual void setVertexArray(unsigned int count,const Vec3d* vertices) = 0;
    virtual void setVertexArray(unsigned int count,const Vec4d* vertices) = 0;

    virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
    virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
    virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
    virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;

    virtual void begin(GLenum mode) = 0;
    virtual void vertex(unsigned int pos) = 0;
    virtual void end() = 0;

    void useVertexCacheAsVertexArray()
    {
        setVertexArray(_vertexCache.size(),&_vertexCache.front());
    }

    std::vector<Vec3>   _vertexCache;
    bool                _treatVertexDataAsTemporary;
};

可以看到,里面有函数drawElements函数,有openGL知识的通过应该知道这个函数时用来使用索引绘图的,里面通过各类参数应该可以拿到顶点的信息。但是在文档中我们看发现这个类是一个类中的函数都没有实现(如下图所示)

所以我们再去看看他的子类是否有实现,进一步看文档我们可以发现,PrimitiveIndexFunctor类有以下三个子类:

我们要处理的是三角形,再去看看TriangleIndexFunctor,

virtual void  setVertexArray (unsigned int, const Vec2 *) 
  
virtual void  setVertexArray (unsigned int, const Vec3 *) 
  
virtual void  setVertexArray (unsigned int, const Vec4 *) 
  
virtual void  setVertexArray (unsigned int, const Vec2d *) 
  
virtual void  setVertexArray (unsigned int, const Vec3d *) 
  
virtual void  setVertexArray (unsigned int, const Vec4d *) 
  
virtual void  begin (GLenum mode) 
  
virtual void  vertex (unsigned int vert) 
  
virtual void  end () 
  
virtual void  drawArrays (GLenum mode, GLint first, GLsizei count) 
  
virtual void  drawElements (GLenum mode, GLsizei count, const GLubyte *indices) 
  
virtual void  drawElements (GLenum mode, GLsizei count, const GLushort *indices) 
  
virtual void  drawElements (GLenum mode, GLsizei count, const GLuint *indices) 

我们发现里面仍然有drawElements函数,所以我们就直接用这个类来获取模型中三角形索引的信息。从文档中得知:TriangleIndexFunctor是一个类模板,而且它继承自自身模板参数T,在模板参数中必须实现T::operator()(const unsigned& v1, const unsig

  • 29
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 48
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 48
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MeteorChenBo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值